Revert "Register __libc_fini as early as possible."

This reverts commit e880c736d6c1d947f6309d5f1f63c74e8345c6a6.

Change-Id: Ide83e442eb5dbfef5298a15bc602c3fe1dda1862
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index dad265e..fa9f3f3 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -36,6 +36,9 @@
 __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))
@@ -44,6 +47,7 @@
   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 33f7f40..28e8817 100644
--- a/libc/arch-mips/bionic/crtbegin.c
+++ b/libc/arch-mips/bionic/crtbegin.c
@@ -36,11 +36,15 @@
 __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 fe6985d..2ea31ad 100644
--- a/libc/arch-mips64/bionic/crtbegin.c
+++ b/libc/arch-mips64/bionic/crtbegin.c
@@ -36,10 +36,15 @@
 __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 ee3d32b..3032f99 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -33,6 +33,7 @@
 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 3d9fa1a..78125f9 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -60,9 +60,6 @@
   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
@@ -82,11 +79,6 @@
   // 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() {
@@ -104,11 +96,19 @@
 __noreturn void __libc_init(void* raw_args,
                             void (*onexit)(void) __unused,
                             int (*slingshot)(int, char**, char**),
-                            structors_array_t const * const structors __unused) {
+                            structors_array_t const * const structors) {
+
   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 f2e34c2..bc11f3d 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -61,9 +61,6 @@
 
 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) {
@@ -102,13 +99,14 @@
   // 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.
-  __cxa_atexit(__libc_fini,&__FINI_ARRAY__, NULL);
-
-  call_array(structors->init_array);
+  if (structors->fini_array != NULL) {
+    __cxa_atexit(__libc_fini,structors->fini_array,NULL);
+  }
 
   exit(slingshot(args.argc, args.argv, args.envp));
 }