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_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