Move the abort message to libc_shared_globals

__libc_shared_globals() is available in dynamic modules as soon as
relocation has finished (i.e. after ifuncs run). Before ifuncs have run,
the android_set_abort_message() function already doesn't work because it
calls public APIs via the PLT. (If this matters, we can use a static
bool variable to enable android_set_abort_message after libc
initialization).

__libc_shared_globals() is hidden, so it's available in the linker
immediately (i.e. before relocation). TLS memory (e.g. errno) currently
isn't accessible until after relocation, but a later patch fixes that.

Bug: none
Test: bionic unit tests
Change-Id: Ied4433758ed2da9ee404c6158e319cf502d05a53
diff --git a/libc/bionic/android_set_abort_message.cpp b/libc/bionic/android_set_abort_message.cpp
index 58f24cf..56e6771 100644
--- a/libc/bionic/android_set_abort_message.cpp
+++ b/libc/bionic/android_set_abort_message.cpp
@@ -35,10 +35,9 @@
 #include <sys/mman.h>
 
 #include "private/bionic_defs.h"
+#include "private/bionic_globals.h"
 #include "private/ScopedPthreadMutexLocker.h"
 
-static pthread_mutex_t g_abort_msg_lock = PTHREAD_MUTEX_INITIALIZER;
-
 struct abort_msg_t {
   size_t size;
   char msg[0];
@@ -56,8 +55,6 @@
               "The in-memory layout of magic_abort_msg_t is not consistent with what automated "
               "tools expect.");
 
-abort_msg_t** __abort_message_ptr; // Accessible to __libc_init_common.
-
 [[clang::optnone]]
 static void fill_abort_message_magic(magic_abort_msg_t* new_magic_abort_message) {
   // 128-bit magic for the abort message. Chosen by fair dice roll.
@@ -71,14 +68,9 @@
 
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void android_set_abort_message(const char* msg) {
-  ScopedPthreadMutexLocker locker(&g_abort_msg_lock);
+  ScopedPthreadMutexLocker locker(&__libc_shared_globals()->abort_msg_lock);
 
-  if (__abort_message_ptr == nullptr) {
-    // We must have crashed _very_ early.
-    return;
-  }
-
-  if (*__abort_message_ptr != nullptr) {
+  if (__libc_shared_globals()->abort_msg != nullptr) {
     // We already have an abort message.
     // Assume that the first crash is the one most worth reporting.
     return;
@@ -94,5 +86,5 @@
   fill_abort_message_magic(new_magic_abort_message);
   new_magic_abort_message->msg.size = size;
   strcpy(new_magic_abort_message->msg.msg, msg);
-  *__abort_message_ptr = &new_magic_abort_message->msg;
+  __libc_shared_globals()->abort_msg = &new_magic_abort_message->msg;
 }
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index bd20775..f78a11a 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -52,7 +52,6 @@
 #include "private/thread_private.h"
 #include "pthread_internal.h"
 
-extern "C" abort_msg_t** __abort_message_ptr;
 extern "C" int __system_properties_init(void);
 
 __LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
@@ -97,7 +96,6 @@
   environ = args.envp;
   errno = 0;
   __progname = args.argv[0] ? args.argv[0] : "<unknown>";
-  __abort_message_ptr = args.abort_message_ptr;
 
 #if !defined(__LP64__)
   __check_max_thread_id();
@@ -297,8 +295,6 @@
 }
 
 void __libc_init_AT_SECURE(KernelArgumentBlock& args) {
-  __abort_message_ptr = args.abort_message_ptr;
-
   // Check that the kernel provided a value for AT_SECURE.
   errno = 0;
   unsigned long is_AT_SECURE = getauxval(AT_SECURE);
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 10fc151..f2168b8 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -153,6 +153,8 @@
 }
 
 __LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals() {
-  static libc_shared_globals globals;
+  static libc_shared_globals globals = {
+    .abort_msg_lock = PTHREAD_MUTEX_INITIALIZER,
+  };
   return &globals;
 }
diff --git a/libc/private/KernelArgumentBlock.h b/libc/private/KernelArgumentBlock.h
index 1e053a1..c8ce841 100644
--- a/libc/private/KernelArgumentBlock.h
+++ b/libc/private/KernelArgumentBlock.h
@@ -23,8 +23,6 @@
 
 #include "private/bionic_macros.h"
 
-struct abort_msg_t;
-
 // When the kernel starts the dynamic linker, it passes a pointer to a block
 // of memory containing argc, the argv array, the environment variable array,
 // and the array of ELF aux vectors. This class breaks that block up into its
@@ -64,9 +62,6 @@
   char** envp;
   ElfW(auxv_t)* auxv;
 
-  // Other data that we want to pass from the dynamic linker to libc.so.
-  abort_msg_t** abort_message_ptr;
-
  private:
   BIONIC_DISALLOW_COPY_AND_ASSIGN(KernelArgumentBlock);
 };
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 44ec2e3..e9eaee0 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -30,6 +30,7 @@
 #define _PRIVATE_BIONIC_GLOBALS_H
 
 #include <sys/cdefs.h>
+#include <pthread.h>
 
 #include "private/bionic_fdsan.h"
 #include "private/bionic_malloc_dispatch.h"
@@ -44,6 +45,8 @@
 
 __LIBC_HIDDEN__ extern WriteProtected<libc_globals> __libc_globals;
 
+struct abort_msg_t;
+
 // Globals shared between the dynamic linker and libc.so.
 struct libc_shared_globals {
   FdTable fd_table;
@@ -52,6 +55,9 @@
   // 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;
+
+  pthread_mutex_t abort_msg_lock;
+  abort_msg_t* abort_msg;
 };
 
 __LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();