summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/ldso.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 75b6e9c12..b87d4b693 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -75,16 +75,36 @@ void _dl_debug_state(void)
static unsigned char *_dl_malloc_addr = 0; /* Lets _dl_malloc use the already allocated memory page */
static unsigned char *_dl_mmap_zero = 0; /* Also used by _dl_malloc */
-#if defined (__SUPPORT_LD_DEBUG__)
-static void debug_fini (int status, void *arg)
-{
- (void)status;
- _dl_dprintf(_dl_debug_file,"\ncalling fini: %s\n\n", (const char*)arg);
-}
-#endif
+static struct elf_resolve **init_fini_list;
+static int nlist; /* # items in init_fini_list */
extern void _start(void);
+static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
+{
+ int i;
+ struct elf_resolve * tpnt;
+
+ for (i = 0; i < nlist; ++i) {
+ tpnt = init_fini_list[i];
+ if (tpnt->init_flag & FINI_FUNCS_CALLED)
+ continue;
+ tpnt->init_flag |= FINI_FUNCS_CALLED;
+ if (tpnt->dynamic_info[DT_FINI]) {
+ void (*dl_elf_func) (void);
+
+ dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+#if defined (__SUPPORT_LD_DEBUG__)
+ if(_dl_debug)
+ _dl_dprintf(_dl_debug_file,
+ "\ncalling FINI: %s\n\n",
+ tpnt->libname);
+#endif
+ (*dl_elf_func) ();
+ }
+ }
+}
+
void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
Elf32_auxv_t auxvt[AT_EGID + 1], char **envp,
char **argv)
@@ -92,8 +112,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
ElfW(Phdr) *ppnt;
Elf32_Dyn *dpnt;
char *lpntstr;
- int i, nlist, goof = 0, unlazy = 0, trace_loaded_objects = 0;
- struct elf_resolve **init_fini_list;
+ int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
struct dyn_elf *rpnt;
struct elf_resolve *tcurr;
struct elf_resolve *tpnt1;
@@ -101,13 +120,9 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
struct elf_resolve *app_tpnt = &app_tpnt_tmp;
struct r_debug *debug_addr;
unsigned long *lpnt;
- int (*_dl_atexit) (void *);
unsigned long *_dl_envp; /* The environment address */
ElfW(Addr) relro_addr = 0;
size_t relro_size = 0;
-#if defined (__SUPPORT_LD_DEBUG__)
- int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
-#endif
#ifdef __SUPPORT_LD_DEBUG_EARLY__
/* Wahoo!!! */
@@ -613,12 +628,7 @@ next_lib2:
_dl_unmap_cache();
--nlist; /* Exclude the application. */
-
- /* As long as atexit() is used to run the FINI functions, we can use
- * alloca here. The use of atexit() should go away at some time as that
- * will make Valgring happy.
- */
- init_fini_list = alloca(nlist * sizeof(struct elf_resolve *));
+ init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
i = 0;
for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
init_fini_list[i++] = tcurr;
@@ -787,13 +797,6 @@ next_lib2:
}
#endif
-
- _dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
-#if defined (__SUPPORT_LD_DEBUG__)
- _dl_on_exit = (int (*)(void (*)(int, void *),void*))
- (intptr_t) _dl_find_hash("on_exit", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
-#endif
-
/* Notify the debugger we have added some objects. */
_dl_debug_addr->r_state = RT_ADD;
_dl_debug_state();
@@ -812,33 +815,23 @@ next_lib2:
#if defined (__SUPPORT_LD_DEBUG__)
if(_dl_debug)
_dl_dprintf(_dl_debug_file,
- "\ncalling init: %s\n\n",
+ "\ncalling INIT: %s\n\n",
tpnt->libname);
#endif
(*dl_elf_func) ();
}
- tpnt->init_flag |= FINI_FUNCS_CALLED;
- if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
- void (*dl_elf_func) (void);
-
- dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
- (*_dl_atexit) (dl_elf_func);
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug && _dl_on_exit) {
- (*_dl_on_exit)(debug_fini, tpnt->libname);
- }
-#endif
- }
-#if defined (__SUPPORT_LD_DEBUG__)
- else {
- if (!_dl_atexit)
- _dl_dprintf(_dl_debug_file, "%s: The address of atexit () is 0x0.\n", tpnt->libname);
- }
-#endif
}
+#ifndef _DL_DO_FINI_IN_LIBC
+/* arches that has moved their ldso FINI handling should ship this part */
+ {
+ int (*_dl_atexit) (void *) = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
- /* Notify the debugger that all objects are now mapped in. */
+ if (_dl_atexit)
+ (*_dl_atexit) (_dl_fini);
+ /* Notify the debugger that all objects are now mapped in. */
+ }
+#endif
_dl_debug_addr->r_state = RT_CONSISTENT;
_dl_debug_state();