diff options
author | Mike Frysinger <vapier@gentoo.org> | 2006-02-14 01:02:26 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2006-02-14 01:02:26 +0000 |
commit | 2525195d77d4ab4be720a077d1e30c6a3d8d7a84 (patch) | |
tree | 2b0a36008e182161474cf6ee35b4992181e23ef2 /libc/misc/internals/__uClibc_main.c | |
parent | 7f7444e68d69f90fd36bfc8488de7b183d998236 (diff) |
after much deliberation, may i present Joseph S. Myers patch to add support for .init and .fini array processing
for the gory details, see the mailing list:
http://www.uclibc.org/lists/uclibc/2006-January/014079.html
http://www.uclibc.org/lists/uclibc/2006-February/014285.html
Diffstat (limited to 'libc/misc/internals/__uClibc_main.c')
-rw-r--r-- | libc/misc/internals/__uClibc_main.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index 8d834595c..0531892c6 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -84,6 +84,20 @@ extern void weak_function _locale_init(void) attribute_hidden; extern void weak_function __pthread_initialize_minimal(void); #endif +#ifdef __UCLIBC_CTOR_DTOR__ +extern void _dl_app_init_array(void); +extern void _dl_app_fini_array(void); +#ifndef SHARED +/* These magic symbols are provided by the linker. */ +extern void (*__preinit_array_start []) (void) attribute_hidden; +extern void (*__preinit_array_end []) (void) attribute_hidden; +extern void (*__init_array_start []) (void) attribute_hidden; +extern void (*__init_array_end []) (void) attribute_hidden; +extern void (*__fini_array_start []) (void) attribute_hidden; +extern void (*__fini_array_end []) (void) attribute_hidden; +#endif +#endif + attribute_hidden const char *__uclibc_progname = NULL; #ifdef __UCLIBC_HAS___PROGNAME__ strong_alias (__uclibc_progname, __progname) @@ -228,6 +242,26 @@ void attribute_hidden (*__app_fini)(void) = NULL; void attribute_hidden (*__rtld_fini)(void) = NULL; +extern void __uClibc_fini(void); +libc_hidden_proto(__uClibc_fini) +void __uClibc_fini(void) +{ +#ifdef __UCLIBC_CTOR_DTOR__ +#ifdef SHARED + _dl_app_fini_array(); +#else + size_t i = __fini_array_end - __fini_array_start; + while (i-- > 0) + (*__fini_array_start [i]) (); +#endif + if (__app_fini != NULL) + (__app_fini)(); +#endif + if (__rtld_fini != NULL) + (__rtld_fini)(); +} +libc_hidden_def(__uClibc_fini) + /* __uClibc_main is the new main stub for uClibc. This function is * called from crt1 (version 0.9.28 or newer), after ALL shared libraries * are initialized, just before we call the application's main function. @@ -313,10 +347,31 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, /* Arrange for the application's dtors to run before we exit. */ __app_fini = app_fini; +#ifndef SHARED + /* For dynamically linked executables the preinit array is executed by + the dynamic linker (before initializing any shared object). + For static executables, preinit happens rights before init. */ + { + const size_t size = __preinit_array_end - __preinit_array_start; + size_t i; + for (i = 0; i < size; i++) + (*__preinit_array_start [i]) (); + } +#endif /* Run all the application's ctors now. */ if (app_init!=NULL) { app_init(); } +#ifdef SHARED + _dl_app_init_array(); +#else + { + const size_t size = __init_array_end - __init_array_start; + size_t i; + for (i = 0; i < size; i++) + (*__init_array_start [i]) (); + } +#endif #endif /* Note: It is possible that any initialization done above could |