am 450aaa01: Merge "Register __libc_fini as early as possible."
* commit '450aaa018df19464cb4e01ea3059a2a075ebde52': Register __libc_fini as early as possible.
This commit is contained in:
commit
bd00ae8992
@ -36,9 +36,6 @@ void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
|
|||||||
__attribute__ ((section (".init_array")))
|
__attribute__ ((section (".init_array")))
|
||||||
void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
|
void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
|
||||||
|
|
||||||
__attribute__ ((section (".fini_array")))
|
|
||||||
void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
|
|
||||||
|
|
||||||
__LIBC_HIDDEN__
|
__LIBC_HIDDEN__
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
__attribute__((force_align_arg_pointer))
|
__attribute__((force_align_arg_pointer))
|
||||||
@ -47,7 +44,6 @@ void _start() {
|
|||||||
structors_array_t array;
|
structors_array_t array;
|
||||||
array.preinit_array = &__PREINIT_ARRAY__;
|
array.preinit_array = &__PREINIT_ARRAY__;
|
||||||
array.init_array = &__INIT_ARRAY__;
|
array.init_array = &__INIT_ARRAY__;
|
||||||
array.fini_array = &__FINI_ARRAY__;
|
|
||||||
|
|
||||||
void* raw_args = (void*) ((uintptr_t) __builtin_frame_address(0) + sizeof(void*));
|
void* raw_args = (void*) ((uintptr_t) __builtin_frame_address(0) + sizeof(void*));
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
@ -36,15 +36,11 @@ void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
|
|||||||
__attribute__ ((section (".init_array")))
|
__attribute__ ((section (".init_array")))
|
||||||
void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
|
void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
|
||||||
|
|
||||||
__attribute__ ((section (".fini_array")))
|
|
||||||
void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
|
|
||||||
|
|
||||||
|
|
||||||
__LIBC_HIDDEN__ void do_mips_start(void *raw_args) {
|
__LIBC_HIDDEN__ void do_mips_start(void *raw_args) {
|
||||||
structors_array_t array;
|
structors_array_t array;
|
||||||
array.preinit_array = &__PREINIT_ARRAY__;
|
array.preinit_array = &__PREINIT_ARRAY__;
|
||||||
array.init_array = &__INIT_ARRAY__;
|
array.init_array = &__INIT_ARRAY__;
|
||||||
array.fini_array = &__FINI_ARRAY__;
|
|
||||||
|
|
||||||
__libc_init(raw_args, NULL, &main, &array);
|
__libc_init(raw_args, NULL, &main, &array);
|
||||||
}
|
}
|
||||||
|
@ -36,15 +36,10 @@ void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
|
|||||||
__attribute__ ((section (".init_array")))
|
__attribute__ ((section (".init_array")))
|
||||||
void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
|
void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
|
||||||
|
|
||||||
__attribute__ ((section (".fini_array")))
|
|
||||||
void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
|
|
||||||
|
|
||||||
|
|
||||||
__LIBC_HIDDEN__ void do_mips_start(void *raw_args) {
|
__LIBC_HIDDEN__ void do_mips_start(void *raw_args) {
|
||||||
structors_array_t array;
|
structors_array_t array;
|
||||||
array.preinit_array = &__PREINIT_ARRAY__;
|
array.preinit_array = &__PREINIT_ARRAY__;
|
||||||
array.init_array = &__INIT_ARRAY__;
|
array.init_array = &__INIT_ARRAY__;
|
||||||
array.fini_array = &__FINI_ARRAY__;
|
|
||||||
|
|
||||||
__libc_init(raw_args, NULL, &main, &array);
|
__libc_init(raw_args, NULL, &main, &array);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
void (**preinit_array)(void);
|
void (**preinit_array)(void);
|
||||||
void (**init_array)(void);
|
void (**init_array)(void);
|
||||||
void (**fini_array)(void);
|
|
||||||
} structors_array_t;
|
} structors_array_t;
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
@ -60,6 +60,9 @@ extern "C" {
|
|||||||
extern int __cxa_atexit(void (*)(void *), void *, void *);
|
extern int __cxa_atexit(void (*)(void *), void *, void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
__attribute__ ((section (".fini_array")))
|
||||||
|
void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
|
||||||
|
|
||||||
// We flag the __libc_preinit function as a constructor to ensure
|
// We flag the __libc_preinit function as a constructor to ensure
|
||||||
// that its address is listed in libc.so's .init_array section.
|
// that its address is listed in libc.so's .init_array section.
|
||||||
// This ensures that the function is called by the dynamic linker
|
// This ensures that the function is called by the dynamic linker
|
||||||
@ -79,6 +82,11 @@ __attribute__((constructor)) static void __libc_preinit() {
|
|||||||
// Hooks for various libraries to let them know that we're starting up.
|
// Hooks for various libraries to let them know that we're starting up.
|
||||||
malloc_debug_init();
|
malloc_debug_init();
|
||||||
netdClientInit();
|
netdClientInit();
|
||||||
|
|
||||||
|
// The executable may have its own destructors listed in its .fini_array
|
||||||
|
// so we need to ensure that these are called when the program exits
|
||||||
|
// normally.
|
||||||
|
__cxa_atexit(__libc_fini, &__FINI_ARRAY__, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
__LIBC_HIDDEN__ void __libc_postfini() {
|
__LIBC_HIDDEN__ void __libc_postfini() {
|
||||||
@ -96,19 +104,11 @@ __LIBC_HIDDEN__ void __libc_postfini() {
|
|||||||
__noreturn void __libc_init(void* raw_args,
|
__noreturn void __libc_init(void* raw_args,
|
||||||
void (*onexit)(void) __unused,
|
void (*onexit)(void) __unused,
|
||||||
int (*slingshot)(int, char**, char**),
|
int (*slingshot)(int, char**, char**),
|
||||||
structors_array_t const * const structors) {
|
structors_array_t const * const structors __unused) {
|
||||||
|
|
||||||
KernelArgumentBlock args(raw_args);
|
KernelArgumentBlock args(raw_args);
|
||||||
|
|
||||||
// Several Linux ABIs don't pass the onexit pointer, and the ones that
|
// Several Linux ABIs don't pass the onexit pointer, and the ones that
|
||||||
// do never use it. Therefore, we ignore it.
|
// do never use it. Therefore, we ignore it.
|
||||||
|
|
||||||
// The executable may have its own destructors listed in its .fini_array
|
|
||||||
// so we need to ensure that these are called when the program exits
|
|
||||||
// normally.
|
|
||||||
if (structors->fini_array) {
|
|
||||||
__cxa_atexit(__libc_fini,structors->fini_array,NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(slingshot(args.argc, args.argv, args.envp));
|
exit(slingshot(args.argc, args.argv, args.envp));
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,9 @@
|
|||||||
|
|
||||||
extern "C" int __cxa_atexit(void (*)(void *), void *, void *);
|
extern "C" int __cxa_atexit(void (*)(void *), void *, void *);
|
||||||
|
|
||||||
|
__attribute__ ((section (".fini_array")))
|
||||||
|
void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
|
||||||
|
|
||||||
static void call_array(void(**list)()) {
|
static void call_array(void(**list)()) {
|
||||||
// First element is -1, list is null-terminated
|
// First element is -1, list is null-terminated
|
||||||
while (*++list) {
|
while (*++list) {
|
||||||
@ -99,14 +102,13 @@ __noreturn void __libc_init(void* raw_args,
|
|||||||
// do never use it. Therefore, we ignore it.
|
// do never use it. Therefore, we ignore it.
|
||||||
|
|
||||||
call_array(structors->preinit_array);
|
call_array(structors->preinit_array);
|
||||||
call_array(structors->init_array);
|
|
||||||
|
|
||||||
// The executable may have its own destructors listed in its .fini_array
|
// The executable may have its own destructors listed in its .fini_array
|
||||||
// so we need to ensure that these are called when the program exits
|
// so we need to ensure that these are called when the program exits
|
||||||
// normally.
|
// normally.
|
||||||
if (structors->fini_array != NULL) {
|
__cxa_atexit(__libc_fini,&__FINI_ARRAY__, NULL);
|
||||||
__cxa_atexit(__libc_fini,structors->fini_array,NULL);
|
|
||||||
}
|
call_array(structors->init_array);
|
||||||
|
|
||||||
exit(slingshot(args.argc, args.argv, args.envp));
|
exit(slingshot(args.argc, args.argv, args.envp));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user