From e880c736d6c1d947f6309d5f1f63c74e8345c6a6 Mon Sep 17 00:00:00 2001 From: Dmitriy Ivanov Date: Wed, 3 Sep 2014 14:56:05 -0700 Subject: [PATCH] Register __libc_fini as early as possible. We want __libc_fini to be called after all the destructors. Bug: 14611536 Change-Id: Ibb83a94436795ec178fd605fa531ac29608f4a3e --- libc/arch-common/bionic/crtbegin.c | 4 ---- libc/arch-mips/bionic/crtbegin.c | 4 ---- libc/arch-mips64/bionic/crtbegin.c | 5 ----- libc/bionic/libc_init_common.h | 1 - libc/bionic/libc_init_dynamic.cpp | 18 +++++++++--------- libc/bionic/libc_init_static.cpp | 10 ++++++---- 6 files changed, 15 insertions(+), 27 deletions(-) diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c index fa9f3f32b..dad265e1d 100644 --- a/libc/arch-common/bionic/crtbegin.c +++ b/libc/arch-common/bionic/crtbegin.c @@ -36,9 +36,6 @@ void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1; __attribute__ ((section (".init_array"))) void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1; -__attribute__ ((section (".fini_array"))) -void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1; - __LIBC_HIDDEN__ #ifdef __i386__ __attribute__((force_align_arg_pointer)) @@ -47,7 +44,6 @@ void _start() { structors_array_t array; array.preinit_array = &__PREINIT_ARRAY__; array.init_array = &__INIT_ARRAY__; - array.fini_array = &__FINI_ARRAY__; void* raw_args = (void*) ((uintptr_t) __builtin_frame_address(0) + sizeof(void*)); #ifdef __x86_64__ diff --git a/libc/arch-mips/bionic/crtbegin.c b/libc/arch-mips/bionic/crtbegin.c index 28e8817f9..33f7f407d 100644 --- a/libc/arch-mips/bionic/crtbegin.c +++ b/libc/arch-mips/bionic/crtbegin.c @@ -36,15 +36,11 @@ void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1; __attribute__ ((section (".init_array"))) 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) { structors_array_t array; array.preinit_array = &__PREINIT_ARRAY__; array.init_array = &__INIT_ARRAY__; - array.fini_array = &__FINI_ARRAY__; __libc_init(raw_args, NULL, &main, &array); } diff --git a/libc/arch-mips64/bionic/crtbegin.c b/libc/arch-mips64/bionic/crtbegin.c index 2ea31ad64..fe6985dbe 100644 --- a/libc/arch-mips64/bionic/crtbegin.c +++ b/libc/arch-mips64/bionic/crtbegin.c @@ -36,15 +36,10 @@ void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1; __attribute__ ((section (".init_array"))) 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) { structors_array_t array; array.preinit_array = &__PREINIT_ARRAY__; array.init_array = &__INIT_ARRAY__; - array.fini_array = &__FINI_ARRAY__; __libc_init(raw_args, NULL, &main, &array); } diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h index 3032f99c2..ee3d32b89 100644 --- a/libc/bionic/libc_init_common.h +++ b/libc/bionic/libc_init_common.h @@ -33,7 +33,6 @@ typedef struct { void (**preinit_array)(void); void (**init_array)(void); - void (**fini_array)(void); } structors_array_t; __BEGIN_DECLS diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp index 78125f968..3d9fa1ab7 100644 --- a/libc/bionic/libc_init_dynamic.cpp +++ b/libc/bionic/libc_init_dynamic.cpp @@ -60,6 +60,9 @@ extern "C" { 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 // that its address is listed in libc.so's .init_array section. // 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. malloc_debug_init(); 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() { @@ -96,19 +104,11 @@ __LIBC_HIDDEN__ void __libc_postfini() { __noreturn void __libc_init(void* raw_args, void (*onexit)(void) __unused, int (*slingshot)(int, char**, char**), - structors_array_t const * const structors) { - + structors_array_t const * const structors __unused) { KernelArgumentBlock args(raw_args); // Several Linux ABIs don't pass the onexit pointer, and the ones that // 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)); } diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp index bc11f3d93..f2e34c227 100644 --- a/libc/bionic/libc_init_static.cpp +++ b/libc/bionic/libc_init_static.cpp @@ -61,6 +61,9 @@ 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)()) { // First element is -1, list is null-terminated while (*++list) { @@ -99,14 +102,13 @@ __noreturn void __libc_init(void* raw_args, // do never use it. Therefore, we ignore it. call_array(structors->preinit_array); - call_array(structors->init_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 // normally. - if (structors->fini_array != NULL) { - __cxa_atexit(__libc_fini,structors->fini_array,NULL); - } + __cxa_atexit(__libc_fini,&__FINI_ARRAY__, NULL); + + call_array(structors->init_array); exit(slingshot(args.argc, args.argv, args.envp)); }