From 91a9925998f2b878f0245ce03aab22cc412a4d8b Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 12 Feb 2013 21:56:42 -0800 Subject: [PATCH] Everyone has a TLS register. Change-Id: Id7cdf67087aa7d5074c9c59b7e595bc391d9f146 --- libc/Android.mk | 41 +++++++---------------------------- libc/private/bionic_tls.h | 54 +++++++++++------------------------------------ linker/Android.mk | 8 +------ 3 files changed, 21 insertions(+), 82 deletions(-) diff --git a/libc/Android.mk b/libc/Android.mk index 9e6f4ddbe..606fda267 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -270,6 +270,7 @@ libc_bionic_src_files := \ bionic/brk.cpp \ bionic/debug_format.cpp \ bionic/dirent.cpp \ + bionic/__errno.c \ bionic/eventfd.cpp \ bionic/__fgets_chk.cpp \ bionic/getauxval.cpp \ @@ -299,6 +300,7 @@ libc_bionic_src_files := \ bionic/__strncpy_chk.cpp \ bionic/strsignal.cpp \ bionic/stubs.cpp \ + bionic/sysconf.cpp \ bionic/tdestroy.cpp \ bionic/tmpfile.cpp \ bionic/__umask_chk.cpp \ @@ -349,23 +351,6 @@ libc_upstream_netbsd_src_files := \ upstream-netbsd/libc/string/strxfrm.c \ upstream-netbsd/libc/unistd/killpg.c \ -# The following files are common, but must be compiled -# with different C flags when building a static C library. -# -# The reason for this is the implementation of __get_tls() -# that will differ between the shared and static versions -# of the library. -# -# See comments in private/bionic_tls.h for more details. -# -# NOTE: bionic/pthread.c is added later to this list -# because it needs special handling on ARM, see -# below. -# -libc_static_common_src_files := \ - bionic/__errno.c \ - bionic/sysconf.cpp \ - # Architecture specific source files go here # ========================================================= ifeq ($(TARGET_ARCH),arm) @@ -545,18 +530,8 @@ ifeq ($(TARGET_ARCH),arm) libc_common_cflags += -fstrict-aliasing libc_crt_target_cflags := -mthumb-interwork # - # Define HAVE_ARM_TLS_REGISTER macro to indicate to the C library - # that it should access the hardware TLS register directly in - # private/bionic_tls.h - # - # The value must match your kernel configuration - # - ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) - libc_common_cflags += -DHAVE_ARM_TLS_REGISTER - endif - # - # Define HAVE_32_BYTE_CACHE_LINES to indicate to C - # library it should use to 32-byte version of memcpy, and not + # Define HAVE_32_BYTE_CACHE_LINES to indicate to the C library + # that it should use the 32-byte version of memcpy, not # the 64-byte version. # ifeq ($(ARCH_ARM_HAVE_32_BYTE_CACHE_LINES),true) @@ -822,10 +797,10 @@ include $(BUILD_STATIC_LIBRARY) # ======================================================== # # This is a version of the static C library that does not -# include malloc. It's useful in situations when calling -# the user wants to provide their own malloc implementation, -# or wants to explicitly disallow the use of the use of malloc, -# like the dynamic loader. +# include malloc. It's useful in situations when the user wants +# to provide their own malloc implementation, or wants to +# explicitly disallow the use of the use of malloc, +# such as in the dynamic loader. include $(CLEAR_VARS) diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h index 4dd66c0d0..dfbb14290 100644 --- a/libc/private/bionic_tls.h +++ b/libc/private/bionic_tls.h @@ -79,54 +79,19 @@ enum { #define BIONIC_TLS_SLOTS 64 /* set the Thread Local Storage, must contain at least BIONIC_TLS_SLOTS pointers */ -extern void __init_tls(void** tls, void* thread_info); +extern void __init_tls(void** tls, void* thread_info); /* syscall only, do not call directly */ -extern int __set_tls(void *ptr); +extern int __set_tls(void* ptr); /* get the TLS */ -#ifdef __arm__ -/* The standard way to get the TLS is to call a kernel helper - * function (i.e. a function provided at a fixed address in a - * "magic page" mapped in all user-space address spaces ), which - * contains the most appropriate code path for the target device. - * - * However, for performance reasons, we're going to use our own - * machine code for the system's C shared library. - * - * We cannot use this optimization in the static version of the - * C library, because we don't know where the corresponding code - * is going to run. - */ -# ifdef LIBC_STATIC - -/* Use the kernel helper in static C library. */ - typedef volatile void* (__kernel_get_tls_t)(void); -# define __get_tls() (*(__kernel_get_tls_t *)0xffff0fe0)() - -# else /* !LIBC_STATIC */ -/* Use optimized code path. - * Note that HAVE_ARM_TLS_REGISTER is build-specific - * (it must match your kernel configuration) - */ -# ifdef HAVE_ARM_TLS_REGISTER - /* We can read the address directly from a coprocessor - * register, which avoids touching the data cache - * completely. - */ -# define __get_tls() \ +#if defined(__arm__) +# define __get_tls() \ ({ register unsigned int __val asm("r0"); \ asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \ (volatile void*)__val; }) -# else /* !HAVE_ARM_TLS_REGISTER */ - /* The kernel provides the address of the TLS at a fixed - * address of the magic page too. - */ -# define __get_tls() ( *((volatile void **) 0xffff0ff0) ) -# endif -# endif /* !LIBC_STATIC */ #elif defined(__mips__) -# define __get_tls() \ +# define __get_tls() \ ({ register unsigned int __val asm("v1"); \ asm ( \ " .set push\n" \ @@ -136,12 +101,17 @@ extern int __set_tls(void *ptr); : "=r"(__val) \ ); \ (volatile void*)__val; }) +#elif defined(__i386__) +# define __get_tls() \ + ({ register void* __val; \ + asm ("movl %%gs:0, %0" : "=r"(__val)); \ + (volatile void*) __val; }) #else -extern void* __get_tls( void ); +#error unsupported architecture #endif /* return the stack base and size, used by our malloc debugger */ -extern void* __get_stack_base(int *p_stack_size); +extern void* __get_stack_base(int* p_stack_size); __END_DECLS diff --git a/linker/Android.mk b/linker/Android.mk index 9718d9083..5a18f6a7b 100644 --- a/linker/Android.mk +++ b/linker/Android.mk @@ -23,15 +23,9 @@ LOCAL_CFLAGS += -fno-stack-protector \ -fvisibility=hidden \ -Wall -Wextra -Werror -# We need to access Bionic private headers in the linker... +# We need to access Bionic private headers in the linker. LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/ -# ...one of which is , for which we -# need HAVE_ARM_TLS_REGISTER. -ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true) - LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER -endif - ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -DANDROID_ARM_LINKER endif -- 2.11.0