Let executables not rely on sentinels in preinit_array/init_array/fini_array
Currently, we use sentinels (starting with -1 and ending with 0) in
preinit_array/init_array/fini_array in executables. But after using LTO,
the sentinels can be reordered by LLD and no longer work. So make below
changes to not rely on them:
1. In crtbegin.c, use symbols (like __init_array_start) inserted by the
linker.
2. Add array_count fields in structors_array_t.
3. In static libc, use array_count fields to decide array lengths.
4. To make new dynamic executables work with old libc.so, create a fake
fini_array with sentinels, and pass it to __libc_init. The fake
fini_array contains a function to call functions in real fini_array.
5. To make old dynamic executables work with new libc.so, libc.so
still uses sentinels to decide the length of fini_array.
Bug: 295944813
Bug: https://github.com/android/ndk/issues/1461
Test: run bionic-unit-tests-static
Test: test static executables manually
Test: boot cf_gwear_x86-trunk_staging-userdebug
Change-Id: I1ce31f07bcfe0e99b4237984898a8fc9e98ff426
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 6b39d6d..126f002 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -38,6 +38,10 @@
init_func_t** preinit_array;
init_func_t** init_array;
fini_func_t** fini_array;
+ // Below fields are only available in static executables.
+ size_t preinit_array_count;
+ size_t init_array_count;
+ size_t fini_array_count;
} structors_array_t;
__BEGIN_DECLS