Linker和主线程初始化
NOTE: 这里分析arm64的情况。
two-pass初始化
主线程初始化流程在linker
要分为三部分(都在__linker_init
的中),分别为__libc_init_main_thread_early
、__libc_init_main_thread_late
和__libc_init_main_thread_final
。
1-pass : __libc_init_main_thread_early
//-------------------------------------------------------------
//bionic/libc/platform/bionic/tls_defines.h
#if defined(__arm__) || defined(__aarch64__)
// The ARM ELF TLS ABI specifies[1] that the thread pointer points at a 2-word
// TCB followed by the executable's TLS segment. Both the TCB and the
// executable's segment are aligned according to the segment, so Bionic requires
// a minimum segment alignment, which effectively reserves an 8-word TCB. The
// ARM spec allocates the first TCB word to the DTV.
//
// [1] "Addenda to, and Errata in, the ABI for the ARM Architecture". Section 3.
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0045e/IHI0045E_ABI_addenda.pdf
#define MIN_TLS_SLOT (-1) // update this value when reserving a slot
#define TLS_SLOT_BIONIC_TLS (-1)
#define TLS_SLOT_DTV 0
#define TLS_SLOT_THREAD_ID 1
#define TLS_SLOT_APP 2 // was historically used for errno
#define TLS_SLOT_OPENGL 3
#define TLS_SLOT_OPENGL_API 4
#define TLS_SLOT_STACK_GUARD 5
#define TLS_SLOT_SANITIZER 6 // was historically used for dlerror
#define TLS_SLOT_ART_THREAD_SELF 7
// The maximum slot is fixed by the minimum TLS alignment in Bionic executables.
#define MAX_TLS_SLOT
//-------------------------------------------------------------
//bionic/linker/linker_main.cpp
// Initialize TLS early so system calls and errno work.
KernelArgumentBlock args(raw_args);
bionic_tcb temp_tcb __attribute__((uninitialized));
linker_memclr(&temp_tcb, sizeof(temp_tcb));//初始化tcb空间
__libc_init_main_thread_early(args, &temp_tcb);
//-------------------------------------------------------------
//bionic/libc/bionic/__libc_init_main_thread.cpp
static pthread_internal_t main_thread;
// Setup for the main thread. For dynamic executables, this is called by the
// linker _before_ libc is mapped in memory. This means that all writes to
// globals from this function will apply to linker-private copies and will not
// be visible from libc later on.
//
// Note: this function creates a pthread_internal_t for the initial thread and
// stores the pointer in TLS, but does not add it to pthread's thread list. This
// has to be done later from libc itself (see __libc_init_common).
//
// This is in a file by itself because it needs to be built with
// -fno-stack-protector because it's responsible for setting up the main
// thread's