Merge commit '994b68f5c7d637d2945c06260fe35b266c10379d' * commit '994b68f5c7d637d2945c06260fe35b266c10379d': Fix __get_tls() in static C library to use kernel helpers.
This commit is contained in:
commit
db0017e5e2
3 changed files with 74 additions and 15 deletions
|
@ -64,7 +64,6 @@ libc_common_src_files := \
|
|||
unistd/sleep.c \
|
||||
unistd/statfs.c \
|
||||
unistd/strsignal.c \
|
||||
unistd/sysconf.c \
|
||||
unistd/syslog.c \
|
||||
unistd/system.c \
|
||||
unistd/tcgetpgrp.c \
|
||||
|
@ -249,7 +248,6 @@ libc_common_src_files := \
|
|||
tzcode/localtime.c \
|
||||
tzcode/strftime.c \
|
||||
tzcode/strptime.c \
|
||||
bionic/__errno.c \
|
||||
bionic/__set_errno.c \
|
||||
bionic/_rand48.c \
|
||||
bionic/cpuacct.c \
|
||||
|
@ -318,6 +316,23 @@ libc_common_src_files := \
|
|||
regex/regexec.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
|
||||
# =========================================================
|
||||
ifeq ($(TARGET_ARCH),arm)
|
||||
|
@ -352,12 +367,14 @@ libc_common_src_files += \
|
|||
# can set breakpoints in them without messing
|
||||
# up any thumb code.
|
||||
libc_common_src_files += \
|
||||
bionic/pthread.c.arm \
|
||||
bionic/pthread-atfork.c.arm \
|
||||
bionic/pthread-rwlocks.c.arm \
|
||||
bionic/pthread-timers.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
|
||||
# respectively
|
||||
libc_arch_static_src_files := \
|
||||
|
@ -388,12 +405,14 @@ libc_common_src_files += \
|
|||
arch-x86/string/strcmp_wrapper.S \
|
||||
arch-x86/string/strncmp_wrapper.S \
|
||||
arch-x86/string/strlen.S \
|
||||
bionic/pthread.c \
|
||||
bionic/pthread-atfork.c \
|
||||
bionic/pthread-rwlocks.c \
|
||||
bionic/pthread-timers.c \
|
||||
bionic/ptrace.c
|
||||
|
||||
libc_static_common_src_files += \
|
||||
bionic/pthread.c \
|
||||
|
||||
# this is needed for static versions of libc
|
||||
libc_arch_static_src_files := \
|
||||
arch-x86/bionic/dl_iterate_phdr_static.c
|
||||
|
@ -426,12 +445,15 @@ libc_common_src_files += \
|
|||
string/strncmp.c \
|
||||
string/memcmp.c \
|
||||
string/strlen.c \
|
||||
bionic/pthread.c \
|
||||
bionic/pthread-atfork.c \
|
||||
bionic/pthread-rwlocks.c \
|
||||
bionic/pthread-timers.c \
|
||||
bionic/ptrace.c \
|
||||
unistd/socketcalls.c
|
||||
|
||||
libc_static_common_src_files += \
|
||||
bionic/pthread.c \
|
||||
|
||||
endif # sh
|
||||
|
||||
endif # !x86
|
||||
|
@ -595,10 +617,12 @@ include $(CLEAR_VARS)
|
|||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(libc_arch_static_src_files) \
|
||||
$(libc_static_common_src_files) \
|
||||
bionic/libc_init_static.c
|
||||
|
||||
LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags)
|
||||
LOCAL_CFLAGS := $(libc_common_cflags) \
|
||||
-DLIBC_STATIC
|
||||
|
||||
LOCAL_MODULE := libc_nomalloc
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
|
||||
|
@ -614,6 +638,7 @@ include $(CLEAR_VARS)
|
|||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(libc_arch_static_src_files) \
|
||||
$(libc_static_common_src_files) \
|
||||
bionic/dlmalloc.c \
|
||||
bionic/malloc_debug_common.c \
|
||||
bionic/libc_init_static.c
|
||||
|
@ -638,6 +663,7 @@ LOCAL_C_INCLUDES := $(libc_common_c_includes)
|
|||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(libc_arch_dynamic_src_files) \
|
||||
$(libc_static_common_src_files) \
|
||||
bionic/dlmalloc.c \
|
||||
bionic/malloc_debug_common.c \
|
||||
bionic/libc_init_dynamic.c
|
||||
|
|
|
@ -75,6 +75,13 @@ Differences between current and Android 2.2:
|
|||
- <dlfcn.h>: fixed dlopen() implementation to support dlopen(NULL, ...).
|
||||
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:
|
||||
|
||||
|
|
|
@ -88,22 +88,48 @@ extern int __set_tls(void *ptr);
|
|||
|
||||
/* get the TLS */
|
||||
#ifdef __arm__
|
||||
/* Linux kernel helpers for its TLS implementation */
|
||||
/* For performance reasons, avoid calling the kernel helper
|
||||
/* 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
|
||||
# define __get_tls() \
|
||||
# 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() \
|
||||
({ register unsigned int __val asm("r0"); \
|
||||
asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
|
||||
(volatile void*)__val; })
|
||||
# else /* !HAVE_ARM_TLS_REGISTER */
|
||||
# define __get_tls() ( *((volatile void **) 0xffff0ff0) )
|
||||
# endif
|
||||
#else
|
||||
# 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 */
|
||||
#else /* !ARM */
|
||||
extern void* __get_tls( void );
|
||||
#endif
|
||||
#endif /* !ARM */
|
||||
|
||||
/* return the stack base and size, used by our malloc debugger */
|
||||
extern void* __get_stack_base(int *p_stack_size);
|
||||
|
|
Loading…
Reference in a new issue