libc_shared_globals: add a constexpr ctor
Having a constexpr constructor should guarantee that the static
`globals` variable in __libc_shared_globals is initialized statically
(as opposed to dynamically), which is important because
__libc_shared_globals is called very early (before the linker has
relocated itself). With the constructor, though, the fields can safely
have in-line default initializers.
Bug: none
Test: bionic unit tests
Change-Id: Icde821557369625734a4d85d7ff55428bad5c247
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index ba510b1..ceda38a 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -50,21 +50,26 @@
// Globals shared between the dynamic linker and libc.so.
struct libc_shared_globals {
+ // Construct the shared globals using a constexpr constructor to ensure that
+ // the object doesn't need dynamic initialization. The object is accessed
+ // before the dynamic linker has relocated itself.
+ constexpr libc_shared_globals() {}
+
FdTable fd_table;
// When the linker is invoked on a binary (e.g. `linker64 /system/bin/date`),
// record the number of arguments passed to the linker itself rather than to
// the program it's loading. Typically 0, sometimes 1.
- int initial_linker_arg_count;
+ int initial_linker_arg_count = 0;
- ElfW(auxv_t)* auxv;
+ ElfW(auxv_t)* auxv = nullptr;
- pthread_mutex_t abort_msg_lock;
- abort_msg_t* abort_msg;
+ pthread_mutex_t abort_msg_lock = PTHREAD_MUTEX_INITIALIZER;
+ abort_msg_t* abort_msg = nullptr;
// Values passed from the linker to libc.so.
- const char* init_progname;
- char** init_environ;
+ const char* init_progname = nullptr;
+ char** init_environ = nullptr;
};
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();