platform_bionic/linker
Ryan Prichard 45d1349c63 Reorganize static TLS memory for ELF TLS
For ELF TLS "local-exec" accesses, the static linker assumes that an
executable's TLS segment is located at a statically-known offset from the
thread pointer (i.e. "variant 1" for ARM and "variant 2" for x86).
Because these layouts are incompatible, Bionic generally needs to allocate
its TLS slots differently between different architectures.

To allow per-architecture TLS slots:
 - Replace the TLS_SLOT_xxx enumerators with macros. New ARM slots are
   generally negative, while new x86 slots are generally positive.
 - Define a bionic_tcb struct that provides two things:
    - a void* raw_slots_storage[BIONIC_TLS_SLOTS] field
    - an inline accessor function: void*& tls_slot(size_t tpindex);

For ELF TLS, it's necessary to allocate a temporary TCB (i.e. TLS slots),
because the runtime linker doesn't know how large the static TLS area is
until after it has loaded all of the initial solibs.

To accommodate Golang, it's necessary to allocate the pthread keys at a
fixed, small, positive offset from the thread pointer.

This CL moves the pthread keys into bionic_tls, then allocates a single
mapping per thread that looks like so:
 - stack guard
 - stack [omitted for main thread and with pthread_attr_setstack]
 - static TLS:
    - bionic_tcb [exec TLS will either precede or succeed the TCB]
    - bionic_tls [prefixed by the pthread keys]
    - [solib TLS segments will be placed here]
 - guard page

As before, if the new mapping includes a stack, the pthread_internal_t
is allocated on it.

At startup, Bionic allocates a temporary bionic_tcb object on the stack,
then allocates a temporary bionic_tls object using mmap. This mmap is
delayed because the linker can't currently call async_safe_fatal() before
relocating itself.

Later, Bionic allocates a stack-less thread mapping for the main thread,
and copies slots from the temporary TCB to the new TCB.
(See *::copy_from_bootstrap methods.)

Bug: http://b/78026329
Test: bionic unit tests
Test: verify that a Golang app still works
Test: verify that a Golang app crashes if bionic_{tls,tcb} are swapped
Merged-In: I6543063752f4ec8ef6dc9c7f2a06ce2a18fc5af3
Change-Id: I6543063752f4ec8ef6dc9c7f2a06ce2a18fc5af3
(cherry picked from commit 1e660b70da)
2019-01-11 15:34:22 -08:00
..
arch Switch x86 begin.c to asm; align ESP correctly 2018-02-12 21:43:12 -08:00
tests switch to using android-base/file.h instead of android-base/test_utils.h 2018-11-14 15:46:49 -08:00
Android.bp Reorganize static TLS memory for ELF TLS 2019-01-11 15:34:22 -08:00
Android.mk Convert linker from Android.mk to Android.bp 2016-07-15 13:39:29 -07:00
dlfcn.cpp Move dlerror out of a TLS slot and into a pthread_internal_t member. 2018-12-06 05:19:57 +00:00
ld.config.format.md Load namespace configuration from ld.config.txt 2017-03-24 15:50:45 -07:00
ld_android.cpp Expose libc_shared_globals to libc.so with symbol 2018-11-28 14:26:14 -08:00
linked_list.h Clean up bionic_macros.h a bit. 2018-10-25 11:00:00 -07:00
linker.arm.map Expose libc_shared_globals to libc.so with symbol 2018-11-28 14:26:14 -08:00
linker.cpp Fix performance-for-range-copy warnings 2018-12-11 10:22:11 -08:00
linker.generic.map Expose libc_shared_globals to libc.so with symbol 2018-11-28 14:26:14 -08:00
linker.h Move API levels from uint32_t to int. 2018-11-13 21:25:07 -08:00
linker_allocator.cpp Further improve of linker memory allocators 2018-12-12 17:39:07 -08:00
linker_allocator.h Further improve of linker memory allocators 2018-12-12 17:39:07 -08:00
linker_block_allocator.cpp Add PR_SET_VMA and PR_SET_VMA_ANON_NAME to <sys/prctl.h>. 2018-08-22 10:36:23 -07:00
linker_block_allocator.h Clean up bionic_macros.h a bit. 2018-10-25 11:00:00 -07:00
linker_cfi.cpp Add PR_SET_VMA and PR_SET_VMA_ANON_NAME to <sys/prctl.h>. 2018-08-22 10:36:23 -07:00
linker_cfi.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_common_types.h Clean up bionic_macros.h a bit. 2018-10-25 11:00:00 -07:00
linker_config.cpp dir.${section}: downgrade "can't resolve" diag 2019-01-04 15:05:44 -08:00
linker_config.h Move API levels from uint32_t to int. 2018-11-13 21:25:07 -08:00
linker_debug.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_dlwarning.cpp Unify linker files under one license (BSD) 2017-02-15 15:35:33 -08:00
linker_dlwarning.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_exidx_static.c Implement __gnu_Unwind_Find_exidx/__cxa_type_match 2017-08-29 18:18:27 +02:00
linker_gdb_support.cpp Unify linker files under one license (BSD) 2017-02-15 15:35:33 -08:00
linker_gdb_support.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_globals.cpp Be clearer about linker warnings. 2018-02-28 12:37:28 -08:00
linker_globals.h Be clearer about linker warnings. 2018-02-28 12:37:28 -08:00
linker_libc_support.c Unify linker files under one license (BSD) 2017-02-15 15:35:33 -08:00
linker_libcxx_support.cpp Adapt to the new libc++/libc++abi update. 2018-01-08 14:44:42 -08:00
linker_logger.cpp Allow invoking the linker on an executable. 2018-10-10 14:31:06 -07:00
linker_logger.h Clean up bionic_macros.h a bit. 2018-10-25 11:00:00 -07:00
linker_main.cpp Reorganize static TLS memory for ELF TLS 2019-01-11 15:34:22 -08:00
linker_main.h Allow invoking the linker on an executable. 2018-10-10 14:31:06 -07:00
linker_mapped_file_fragment.cpp Unify linker files under one license (BSD) 2017-02-15 15:35:33 -08:00
linker_mapped_file_fragment.h Clean up bionic_macros.h a bit. 2018-10-25 11:00:00 -07:00
linker_memory.cpp Add reallocarray(3). 2018-09-26 14:24:18 -07:00
linker_mips.cpp MIPS: Fix MIPS linker VDSO issues 2017-10-13 12:08:30 +02:00
linker_namespaces.cpp Be clearer about linker warnings. 2018-02-28 12:37:28 -08:00
linker_namespaces.h Libraries without dt_soname are inaccessible 2018-04-29 13:39:46 +02:00
linker_phdr.cpp Merge "linker: changes to init work arounds" 2018-11-29 16:50:37 +00:00
linker_phdr.h Allow invoking the linker on an executable. 2018-10-10 14:31:06 -07:00
linker_reloc_iterators.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_relocs.h Add generic TLS linker reloc macros 2019-01-02 14:36:26 -08:00
linker_sdk_versions.cpp Move API levels from uint32_t to int. 2018-11-13 21:25:07 -08:00
linker_sleb128.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_soinfo.cpp Merge "linker: changes to init work arounds" 2018-11-29 16:50:37 +00:00
linker_soinfo.h Move API levels from uint32_t to int. 2018-11-13 21:25:07 -08:00
linker_tls.cpp Reorganize static TLS memory for ELF TLS 2019-01-11 15:34:22 -08:00
linker_tls.h Reorganize static TLS memory for ELF TLS 2019-01-11 15:34:22 -08:00
linker_utils.cpp Merge "linker: changes to init work arounds" 2018-11-29 16:50:37 +00:00
linker_utils.h linker: changes to init work arounds 2018-11-08 21:50:19 +00:00
linker_wrapper.cpp Rework the linker_wrapper to work with lld 2018-10-22 22:52:25 +00:00
MODULE_LICENSE_BSD Unify linker files under one license (BSD) 2017-02-15 15:35:33 -08:00
rt.cpp More dynamic linker cleanup. 2012-10-30 16:35:38 -07:00