|
Lines 74-86
void _dl_debug_state(void)
|
Link Here
|
|---|
|
static unsigned char *_dl_malloc_addr = 0; /* Lets _dl_malloc use the already allocated memory page */ | 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 */ | static unsigned char *_dl_mmap_zero = 0; /* Also used by _dl_malloc */ |
| |
#if defined (__SUPPORT_LD_DEBUG__) |
static struct elf_resolve **init_fini_list; |
static void debug_fini (int status, void *arg) |
static int nlist; |
|
static void __attribute_used__ _dl_fini(void) |
{ | { |
(void)status; |
int i; |
_dl_dprintf(_dl_debug_file,"\ncalling fini: %s\n\n", (const char*)arg); |
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__) |
|
_dl_dprintf(_dl_debug_file,"\ncalling fini: %s\n\n", tpnt->libname); |
#endif | #endif |
|
(*dl_elf_func) (); |
|
} |
|
} |
|
} |
| |
void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr, | void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr, |
Elf32_auxv_t auxvt[AT_EGID + 1], char **envp, | Elf32_auxv_t auxvt[AT_EGID + 1], char **envp, |
|
Lines 89-110
void _dl_get_ready_to_run(struct elf_res
|
Link Here
|
|---|
|
ElfW(Phdr) *ppnt; | ElfW(Phdr) *ppnt; |
Elf32_Dyn *dpnt; | Elf32_Dyn *dpnt; |
char *lpntstr; | char *lpntstr; |
int i, nlist, goof = 0, unlazy = 0, trace_loaded_objects = 0; |
int i, goof = 0, unlazy = 0, trace_loaded_objects = 0; |
struct elf_resolve **init_fini_list; |
|
struct dyn_elf *rpnt; | struct dyn_elf *rpnt; |
struct elf_resolve *tcurr; | struct elf_resolve *tcurr; |
struct elf_resolve *tpnt1; | struct elf_resolve *tpnt1; |
struct elf_resolve app_tpnt_tmp; | struct elf_resolve app_tpnt_tmp; |
struct elf_resolve *app_tpnt = &app_tpnt_tmp; | struct elf_resolve *app_tpnt = &app_tpnt_tmp; |
struct r_debug *debug_addr; | struct r_debug *debug_addr; |
unsigned long *lpnt; | unsigned long *lpnt; |
int (*_dl_atexit) (void *); |
|
unsigned long *_dl_envp; /* The environment address */ | unsigned long *_dl_envp; /* The environment address */ |
ElfW(Addr) relro_addr = 0; | ElfW(Addr) relro_addr = 0; |
size_t relro_size = 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__ | #ifdef __SUPPORT_LD_DEBUG_EARLY__ |
/* Wahoo!!! */ | /* Wahoo!!! */ |
|
|
_dl_unmap_cache(); | _dl_unmap_cache(); |
| |
--nlist; /* Exclude the application. */ | --nlist; /* Exclude the application. */ |
|
init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *)); |
/* 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 *)); |
|
i = 0; | i = 0; |
for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) { | for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) { |
init_fini_list[i++] = tcurr; | init_fini_list[i++] = tcurr; |
|
|
} | } |
#endif | #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. */ | /* Notify the debugger we have added some objects. */ |
_dl_debug_addr->r_state = RT_ADD; | _dl_debug_addr->r_state = RT_ADD; |
_dl_debug_state(); | _dl_debug_state(); |
|
|
| |
(*dl_elf_func) (); | (*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 |
|
} | } |
| |
|
{ |
|
void (*__set__dl_fini) (void *); |
|
|
|
__set__dl_fini = (void (*)(void *)) (intptr_t) _dl_find_hash("_set__dl_fini", |
|
_dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT); |
|
|
|
if (__set__dl_fini) |
|
(*__set__dl_fini) (_dl_fini); |
|
} |
|
|
/* Notify the debugger that all objects are now mapped in. */ | /* Notify the debugger that all objects are now mapped in. */ |
_dl_debug_addr->r_state = RT_CONSISTENT; | _dl_debug_addr->r_state = RT_CONSISTENT; |
_dl_debug_state(); | _dl_debug_state(); |
|
Lines 158-163
void __uClibc_init(void)
|
Link Here
|
|---|
|
void (*__app_fini)(void) = NULL; | void (*__app_fini)(void) = NULL; |
#endif | #endif |
| |
|
void attribute_hidden (*__dl_fini)(void) = NULL; |
|
|
|
void _set__dl_fini(void *fini_func) |
|
{ |
|
if (fini_func != NULL) |
|
__dl_fini = fini_func; |
|
} |
|
|
/* __uClibc_start_main is the new main stub for uClibc. This function is | /* __uClibc_start_main is the new main stub for uClibc. This function is |
* called from crt0 (version 0.9.16 or newer), after ALL shared libraries | * called from crt0 (version 0.9.16 or newer), after ALL shared libraries |
* are initialized, just before we call the application's main function. | * are initialized, just before we call the application's main function. |
|
Lines 222-227
pthread_mutex_t mylock = PTHREAD_RECURSI
|
Link Here
|
|---|
|
extern void (*__app_fini)(void); | extern void (*__app_fini)(void); |
#endif | #endif |
| |
|
extern void (*__dl_fini)(void); |
|
|
/* | /* |
* Normal program termination | * Normal program termination |
*/ | */ |
|
|
(__app_fini)(); | (__app_fini)(); |
#endif | #endif |
| |
|
if (__dl_fini != NULL) |
|
(__dl_fini)(); |
|
|
/* If we are using stdio, try to shut it down. At the very least, | /* If we are using stdio, try to shut it down. At the very least, |
* this will attempt to commit all buffered writes. It may also | * this will attempt to commit all buffered writes. It may also |
* unbuffer all writable files, or close them outright. | * unbuffer all writable files, or close them outright. |