Expose libc_shared_globals to libc.so with symbol

Previously, the address of the global variable was communicated from the
dynamic linker to libc.so using a field of KernelArgumentBlock, which is
communicated using the TLS_SLOT_BIONIC_PREINIT slot.

As long as this function isn't called during relocations (i.e. while
executing an ifunc), it always return a non-NULL value. If it's called
before its PLT entry is relocated, I expect a crash.

I removed the __libc_init_shared_globals function. It's currently empty,
and I don't think there's one point in libc's initialization where
shared globals should be initialized.

Bug: http://b/25751302
Test: bionic unit tests
Change-Id: I614d25e7ef5e0d2ccc40d5c821dee10f1ec61c2e
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 9a9fee2..6440ae0 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -132,17 +132,13 @@
       nullptr);
 }
 
-static FdTable* GetFdTable() {
-  if (!__libc_shared_globals) {
-    return nullptr;
-  }
-
-  return &__libc_shared_globals->fd_table;
+static FdTable& GetFdTable() {
+  return __libc_shared_globals()->fd_table;
 }
 
 // Exposed to the platform to allow crash_dump to print out the fd table.
 extern "C" void* android_fdsan_get_fd_table() {
-  return GetFdTable();
+  return &GetFdTable();
 }
 
 static FdEntry* GetFdEntry(int fd) {
@@ -150,21 +146,13 @@
     return nullptr;
   }
 
-  auto* fd_table = GetFdTable();
-  if (!fd_table) {
-    return nullptr;
-  }
-
-  return fd_table->at(fd);
+  return GetFdTable().at(fd);
 }
 
 __printflike(1, 0) static void fdsan_error(const char* fmt, ...) {
-  auto* fd_table = GetFdTable();
-  if (!fd_table) {
-    return;
-  }
+  auto& fd_table = GetFdTable();
 
-  auto error_level = atomic_load(&fd_table->error_level);
+  auto error_level = atomic_load(&fd_table.error_level);
   if (error_level == ANDROID_FDSAN_ERROR_LEVEL_DISABLED) {
     return;
   }
@@ -198,7 +186,7 @@
 
   switch (error_level) {
     case ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE:
-      atomic_compare_exchange_strong(&fd_table->error_level, &error_level,
+      atomic_compare_exchange_strong(&fd_table.error_level, &error_level,
                                      ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
       __BIONIC_FALLTHROUGH;
     case ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS:
@@ -360,21 +348,11 @@
 }
 
 android_fdsan_error_level android_fdsan_get_error_level() {
-  auto* fd_table = GetFdTable();
-  if (!fd_table) {
-    async_safe_fatal("attempted to get fdsan error level before libc initialization?");
-  }
-
-  return fd_table->error_level;
+  return GetFdTable().error_level;
 }
 
 android_fdsan_error_level android_fdsan_set_error_level(android_fdsan_error_level new_level) {
-  auto* fd_table = GetFdTable();
-  if (!fd_table) {
-    async_safe_fatal("attempted to get fdsan error level before libc initialization?");
-  }
-
-  return atomic_exchange(&fd_table->error_level, new_level);
+  return atomic_exchange(&GetFdTable().error_level, new_level);
 }
 
 int close(int fd) {
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index a860b98..bd20775 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -56,7 +56,6 @@
 extern "C" int __system_properties_init(void);
 
 __LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
-__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals;
 
 // Not public, but well-known in the BSDs.
 const char* __progname;
@@ -72,9 +71,6 @@
   });
 }
 
-void __libc_init_shared_globals(libc_shared_globals*) {
-}
-
 #if !defined(__LP64__)
 static void __check_max_thread_id() {
   if (gettid() > 65535) {
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 08d3df4..24f40ba 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -84,7 +84,6 @@
   __libc_init_sysinfo(args);
 #endif
 
-  __libc_shared_globals = args.shared_globals;
   __libc_init_globals(args);
   __libc_init_common(args);
 
@@ -138,7 +137,13 @@
     __cxa_atexit(__libc_fini,structors->fini_array,nullptr);
   }
 
-  exit(slingshot(args.argc - __libc_shared_globals->initial_linker_arg_count,
-                 args.argv + __libc_shared_globals->initial_linker_arg_count,
+  exit(slingshot(args.argc - __libc_shared_globals()->initial_linker_arg_count,
+                 args.argv + __libc_shared_globals()->initial_linker_arg_count,
                  args.envp));
 }
+
+extern "C" libc_shared_globals* __loader_shared_globals();
+
+__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals() {
+  return __loader_shared_globals();
+}
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index ef1c393..10fc151 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -100,10 +100,6 @@
   // Initializing the globals requires TLS to be available for errno.
   __libc_init_main_thread(args);
 
-  static libc_shared_globals shared_globals;
-  __libc_shared_globals = &shared_globals;
-  __libc_init_shared_globals(&shared_globals);
-
   __libc_init_globals(args);
 
   __libc_init_AT_SECURE(args);
@@ -155,3 +151,8 @@
 extern "C" void android_set_application_target_sdk_version(int target) {
   g_target_sdk_version = target;
 }
+
+__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals() {
+  static libc_shared_globals globals;
+  return &globals;
+}