Fix __get_tls() in static C library to use kernel helpers.
This is needed to fix gdbserver's handling of threaded programs, among other things. Change-Id: I823387c602cef9891532da946a01db14be780ab0
This commit is contained in:
parent
22f1e3d4fa
commit
6a51defa03
3 changed files with 74 additions and 15 deletions
|
@ -64,7 +64,6 @@ libc_common_src_files := \
|
||||||
unistd/sleep.c \
|
unistd/sleep.c \
|
||||||
unistd/statfs.c \
|
unistd/statfs.c \
|
||||||
unistd/strsignal.c \
|
unistd/strsignal.c \
|
||||||
unistd/sysconf.c \
|
|
||||||
unistd/syslog.c \
|
unistd/syslog.c \
|
||||||
unistd/system.c \
|
unistd/system.c \
|
||||||
unistd/tcgetpgrp.c \
|
unistd/tcgetpgrp.c \
|
||||||
|
@ -245,7 +244,6 @@ libc_common_src_files := \
|
||||||
tzcode/localtime.c \
|
tzcode/localtime.c \
|
||||||
tzcode/strftime.c \
|
tzcode/strftime.c \
|
||||||
tzcode/strptime.c \
|
tzcode/strptime.c \
|
||||||
bionic/__errno.c \
|
|
||||||
bionic/__set_errno.c \
|
bionic/__set_errno.c \
|
||||||
bionic/_rand48.c \
|
bionic/_rand48.c \
|
||||||
bionic/cpuacct.c \
|
bionic/cpuacct.c \
|
||||||
|
@ -314,6 +312,23 @@ libc_common_src_files := \
|
||||||
regex/regexec.c \
|
regex/regexec.c \
|
||||||
regex/regfree.c \
|
regex/regfree.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 := \
|
||||||
|
unistd/sysconf.c \
|
||||||
|
bionic/__errno.c \
|
||||||
|
|
||||||
# Architecture specific source files go here
|
# Architecture specific source files go here
|
||||||
# =========================================================
|
# =========================================================
|
||||||
ifeq ($(TARGET_ARCH),arm)
|
ifeq ($(TARGET_ARCH),arm)
|
||||||
|
@ -348,11 +363,13 @@ libc_common_src_files += \
|
||||||
# can set breakpoints in them without messing
|
# can set breakpoints in them without messing
|
||||||
# up any thumb code.
|
# up any thumb code.
|
||||||
libc_common_src_files += \
|
libc_common_src_files += \
|
||||||
bionic/pthread.c.arm \
|
|
||||||
bionic/pthread-rwlocks.c.arm \
|
bionic/pthread-rwlocks.c.arm \
|
||||||
bionic/pthread-timers.c.arm \
|
bionic/pthread-timers.c.arm \
|
||||||
bionic/ptrace.c.arm
|
bionic/ptrace.c.arm
|
||||||
|
|
||||||
|
libc_static_common_src_files += \
|
||||||
|
bionic/pthread.c.arm \
|
||||||
|
|
||||||
# these are used by the static and dynamic versions of the libc
|
# these are used by the static and dynamic versions of the libc
|
||||||
# respectively
|
# respectively
|
||||||
libc_arch_static_src_files := \
|
libc_arch_static_src_files := \
|
||||||
|
@ -383,11 +400,13 @@ libc_common_src_files += \
|
||||||
arch-x86/string/strcmp_wrapper.S \
|
arch-x86/string/strcmp_wrapper.S \
|
||||||
arch-x86/string/strncmp_wrapper.S \
|
arch-x86/string/strncmp_wrapper.S \
|
||||||
arch-x86/string/strlen.S \
|
arch-x86/string/strlen.S \
|
||||||
bionic/pthread.c \
|
|
||||||
bionic/pthread-rwlocks.c \
|
bionic/pthread-rwlocks.c \
|
||||||
bionic/pthread-timers.c \
|
bionic/pthread-timers.c \
|
||||||
bionic/ptrace.c
|
bionic/ptrace.c
|
||||||
|
|
||||||
|
libc_static_common_src_files += \
|
||||||
|
bionic/pthread.c \
|
||||||
|
|
||||||
# this is needed for static versions of libc
|
# this is needed for static versions of libc
|
||||||
libc_arch_static_src_files := \
|
libc_arch_static_src_files := \
|
||||||
arch-x86/bionic/dl_iterate_phdr_static.c
|
arch-x86/bionic/dl_iterate_phdr_static.c
|
||||||
|
@ -420,11 +439,14 @@ libc_common_src_files += \
|
||||||
string/strncmp.c \
|
string/strncmp.c \
|
||||||
string/memcmp.c \
|
string/memcmp.c \
|
||||||
string/strlen.c \
|
string/strlen.c \
|
||||||
bionic/pthread.c \
|
|
||||||
bionic/pthread-rwlocks.c \
|
bionic/pthread-rwlocks.c \
|
||||||
bionic/pthread-timers.c \
|
bionic/pthread-timers.c \
|
||||||
bionic/ptrace.c \
|
bionic/ptrace.c \
|
||||||
unistd/socketcalls.c
|
unistd/socketcalls.c
|
||||||
|
|
||||||
|
libc_static_common_src_files += \
|
||||||
|
bionic/pthread.c \
|
||||||
|
|
||||||
endif # sh
|
endif # sh
|
||||||
|
|
||||||
endif # !x86
|
endif # !x86
|
||||||
|
@ -584,10 +606,12 @@ include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
$(libc_arch_static_src_files) \
|
$(libc_arch_static_src_files) \
|
||||||
|
$(libc_static_common_src_files) \
|
||||||
bionic/libc_init_static.c
|
bionic/libc_init_static.c
|
||||||
|
|
||||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||||
LOCAL_CFLAGS := $(libc_common_cflags)
|
LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||||
|
-DLIBC_STATIC
|
||||||
|
|
||||||
LOCAL_MODULE := libc_nomalloc
|
LOCAL_MODULE := libc_nomalloc
|
||||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||||
|
@ -603,6 +627,7 @@ include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
$(libc_arch_static_src_files) \
|
$(libc_arch_static_src_files) \
|
||||||
|
$(libc_static_common_src_files) \
|
||||||
bionic/dlmalloc.c \
|
bionic/dlmalloc.c \
|
||||||
bionic/malloc_debug_common.c \
|
bionic/malloc_debug_common.c \
|
||||||
bionic/libc_init_static.c
|
bionic/libc_init_static.c
|
||||||
|
@ -627,6 +652,7 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
$(libc_arch_dynamic_src_files) \
|
$(libc_arch_dynamic_src_files) \
|
||||||
|
$(libc_static_common_src_files) \
|
||||||
bionic/dlmalloc.c \
|
bionic/dlmalloc.c \
|
||||||
bionic/malloc_debug_common.c \
|
bionic/malloc_debug_common.c \
|
||||||
bionic/libc_init_dynamic.c
|
bionic/libc_init_dynamic.c
|
||||||
|
|
|
@ -73,6 +73,13 @@ Differences between current and Android 2.2:
|
||||||
- <dlfcn.h>: fixed dlopen() implementation to support dlopen(NULL, ...).
|
- <dlfcn.h>: fixed dlopen() implementation to support dlopen(NULL, ...).
|
||||||
This allows one to look at the dynamic symbols exported by an executable.
|
This allows one to look at the dynamic symbols exported by an executable.
|
||||||
|
|
||||||
|
- <private/bionic_tls.h>: use kernel helper functions for static versions
|
||||||
|
of the C library. This is necessary because we don't know where the corresponding
|
||||||
|
machine code is going to run, and the optimization for __get_tls() might
|
||||||
|
not match the features of the target device where we run a static executable
|
||||||
|
linked to the C library. This fixes one of the bug that explains why gdbserver
|
||||||
|
didn't work well with threads.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Differences between Android 2.2. and Android 2.1:
|
Differences between Android 2.2. and Android 2.1:
|
||||||
|
|
||||||
|
|
|
@ -88,22 +88,48 @@ extern int __set_tls(void *ptr);
|
||||||
|
|
||||||
/* get the TLS */
|
/* get the TLS */
|
||||||
#ifdef __arm__
|
#ifdef __arm__
|
||||||
/* Linux kernel helpers for its TLS implementation */
|
/* The standard way to get the TLS is to call a kernel helper
|
||||||
/* For performance reasons, avoid calling the 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
|
* Note that HAVE_ARM_TLS_REGISTER is build-specific
|
||||||
* (it must match your kernel configuration)
|
* (it must match your kernel configuration)
|
||||||
*/
|
*/
|
||||||
# ifdef HAVE_ARM_TLS_REGISTER
|
# ifdef HAVE_ARM_TLS_REGISTER
|
||||||
# define __get_tls() \
|
/* We can read the address directly from a coprocessor
|
||||||
|
* register, which avoids touching the data cache
|
||||||
|
* completely.
|
||||||
|
*/
|
||||||
|
# define __get_tls() \
|
||||||
({ register unsigned int __val asm("r0"); \
|
({ register unsigned int __val asm("r0"); \
|
||||||
asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
|
asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
|
||||||
(volatile void*)__val; })
|
(volatile void*)__val; })
|
||||||
# else /* !HAVE_ARM_TLS_REGISTER */
|
# else /* !HAVE_ARM_TLS_REGISTER */
|
||||||
# define __get_tls() ( *((volatile void **) 0xffff0ff0) )
|
/* The kernel provides the address of the TLS at a fixed
|
||||||
# endif
|
* address of the magic page too.
|
||||||
#else
|
*/
|
||||||
|
# define __get_tls() ( *((volatile void **) 0xffff0ff0) )
|
||||||
|
# endif
|
||||||
|
# endif /* !LIBC_STATIC */
|
||||||
|
#else /* !ARM */
|
||||||
extern void* __get_tls( void );
|
extern void* __get_tls( void );
|
||||||
#endif
|
#endif /* !ARM */
|
||||||
|
|
||||||
/* return the stack base and size, used by our malloc debugger */
|
/* 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);
|
||||||
|
|
Loading…
Reference in a new issue