diff options
author | David 'Digit' Turner <digit@google.com> | 2009-07-18 01:11:10 +0200 |
---|---|---|
committer | David 'Digit' Turner <digit@google.com> | 2009-07-18 01:11:10 +0200 |
commit | b56b5659b3996e98c2060f168d1cff1474e77d2a (patch) | |
tree | 11135868d3dc4a731f7288bcb00abdf48c5c7202 /libc/bionic/libc_init_common.c | |
parent | ef0bd1857041ffde069cf52138aaf22c1af7130e (diff) | |
download | bionic-b56b5659b3996e98c2060f168d1cff1474e77d2a.zip bionic-b56b5659b3996e98c2060f168d1cff1474e77d2a.tar.gz bionic-b56b5659b3996e98c2060f168d1cff1474e77d2a.tar.bz2 |
Fix the C library runtime initialization order.
This allows libc.so to run the C runtime initializer as soon as the
dynamic linker loads the shared library, i.e. before any other initializers
(e.g. static C++ constructors in other shared libraries the executable depends
on).
This also removes the bug where the initializers from the executable itself
were run twice: once by the dynamic linker, and another time by __libc_init
as defined by libc_init_dynamic.c
Diffstat (limited to 'libc/bionic/libc_init_common.c')
-rw-r--r-- | libc/bionic/libc_init_common.c | 77 |
1 files changed, 25 insertions, 52 deletions
diff --git a/libc/bionic/libc_init_common.c b/libc/bionic/libc_init_common.c index de4919d..c77c162 100644 --- a/libc/bionic/libc_init_common.c +++ b/libc/bionic/libc_init_common.c @@ -39,23 +39,6 @@ #include <bionic_tls.h> #include <errno.h> -extern void _init(void); -extern void _fini(void); - -static void call_array(void(**list)()) -{ - // First element is -1, list is null-terminated - while (*++list) { - (*list)(); - } -} - -static void __bionic_do_global_dtors(structors_array_t const * const p) -{ - call_array(p->fini_array); - //_fini(); -} - extern unsigned __get_sp(void); extern pid_t gettid(void); @@ -69,23 +52,23 @@ unsigned int __page_shift = PAGE_SHIFT; int __system_properties_init(void); -void __libc_init_common(uintptr_t *elfdata, - void (*onexit)(void), - int (*slingshot)(int, char**, char**), - structors_array_t const * const structors, - void (*pre_ctor_hook)()) +#ifdef MALLOCK_LEAK_CHECK +void malloc_debug_init(void); +#endif + +void __libc_init_common(uintptr_t *elfdata) { - pthread_internal_t thread; - pthread_attr_t thread_attr; - void *tls_area[BIONIC_TLS_SLOTS]; - int argc; - char **argv, **envp, **envend; - struct auxentry *auxentry; - unsigned int page_size = 0, page_shift = 0; - - /* The main thread's stack has empirically shown to be 84k */ + int argc = *elfdata; + char** argv = (char**)(elfdata + 1); + char** envp = argv + argc + 1; + + pthread_attr_t thread_attr; + static pthread_internal_t thread; + static void* tls_area[BIONIC_TLS_SLOTS]; + + /* setup pthread runtime and maint thread descriptor */ unsigned stacktop = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; - unsigned stacksize = 128 * 1024; //84 * 1024; + unsigned stacksize = 128 * 1024; unsigned stackbottom = stacktop - stacksize; pthread_attr_init(&thread_attr); @@ -93,30 +76,20 @@ void __libc_init_common(uintptr_t *elfdata, _init_thread(&thread, gettid(), &thread_attr, (void*)stackbottom); __init_tls(tls_area, &thread); - argc = (int) *elfdata++; - argv = (char**) elfdata; - envp = argv+(argc+1); - environ = envp; + /* clear errno - requires TLS area */ + errno = 0; + /* set program name */ __progname = argv[0] ? argv[0] : "<unknown>"; - errno = 0; + /* setup environment pointer */ + environ = envp; + /* setup system properties - requires environment */ __system_properties_init(); - if (pre_ctor_hook) pre_ctor_hook(); - - // XXX: we should execute the .fini_array upon exit - - // pre-init array. - // XXX: I'm not sure what's the different with the init array. - call_array(structors->preinit_array); - - // for compatibility with non-eabi binary, call the .ctors section - call_array(structors->ctors_array); - - // call static constructors - call_array(structors->init_array); - - exit(slingshot(argc, argv, envp)); + /* setup malloc leak checker, requires system properties */ +#if MALLOC_LEAK_CHECK + malloc_debug_init(); +#endif } |