am 450aaa01: Merge "Register __libc_fini as early as possible."
				
					
				
			* commit '450aaa018df19464cb4e01ea3059a2a075ebde52': Register __libc_fini as early as possible.
This commit is contained in:
		@@ -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));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user