Put __*_ARRAY__ symbols before prioritized init/fini funcs

A constructor or destructor function with an integral priority is
placed in an .init_array or .fini_array section with the priority
suffixed to the section name:
 - __attribute__((constructor)) ==> .init_array
 - __attribute__((constructor(42))) ==> .init_array.42

The suffixed init/fini sections appear before the unsuffixed sections,
so the prioritized functions appeared before the __{INIT,FINI}_ARRAY__
symbols and were dropped when the symbols were used.

The (static) linker doesn't recognize priority suffixes on
.preinit_array.

This bug affected .init_array and .fini_array for static executables.
For dynamic executables, only .fini_array was affected, because
.init_array is handled by the dynamic loader instead, which uses
DT_INIT_ARRAY[SZ]. For DSOs, neither is affected, because the two
sections are only handled by the dynamic loader.

This patch also fixes a minor inconsistency where dynamic init/preinit
were passed argc/argv/envp, but static were not.

Bug: http://b/170983066
Test: bionic-unit-tests
Change-Id: I0fffa776e5d9bdb6f8af06b4c1af148236742fef
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 0c2e78a..be7526f 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -30,10 +30,13 @@
 
 #include <sys/cdefs.h>
 
+typedef void init_func_t(int, char*[], char*[]);
+typedef void fini_func_t(void);
+
 typedef struct {
-  void (**preinit_array)(void);
-  void (**init_array)(void);
-  void (**fini_array)(void);
+  init_func_t** preinit_array;
+  init_func_t** init_array;
+  fini_func_t** fini_array;
 } structors_array_t;
 
 __BEGIN_DECLS
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index e3a447d..4a73918 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -60,10 +60,10 @@
 
 extern "C" int __cxa_atexit(void (*)(void *), void *, void *);
 
-static void call_array(void(**list)()) {
+static void call_array(init_func_t** list, int argc, char* argv[], char* envp[]) {
   // First element is -1, list is null-terminated
   while (*++list) {
-    (*list)();
+    (*list)(argc, argv, envp);
   }
 }
 
@@ -183,8 +183,8 @@
   // Several Linux ABIs don't pass the onexit pointer, and the ones that
   // do never use it.  Therefore, we ignore it.
 
-  call_array(structors->preinit_array);
-  call_array(structors->init_array);
+  call_array(structors->preinit_array, args.argc, args.argv, args.envp);
+  call_array(structors->init_array, args.argc, args.argv, args.envp);
 
   // 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