Merge "Make it possible to build bionic with -I instead of -isystem."
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 01bb9bb..2643eee 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -28,14 +28,24 @@
 
 #include "libc_init_common.h"
 
+#include "private/KernelArgumentBlock.h"
 #include "private/bionic_auxv.h"
 #include "private/bionic_globals.h"
-#include "private/KernelArgumentBlock.h"
+#include "private/bionic_ssp.h"
 #include "pthread_internal.h"
 
 extern "C" int __set_tls(void* ptr);
 extern "C" int __set_tid_address(int* tid_address);
 
+// Declared in "private/bionic_ssp.h".
+uintptr_t __stack_chk_guard = 0;
+
+void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) {
+  // AT_RANDOM is a pointer to 16 bytes of randomness on the stack.
+  // Take the first 4/8 for the -fstack-protector implementation.
+  __stack_chk_guard = *reinterpret_cast<uintptr_t*>(args.getauxval(AT_RANDOM));
+}
+
 // Setup for the main thread. For dynamic executables, this is called by the
 // linker _before_ libc is mapped in memory. This means that all writes to
 // globals from this function will apply to linker-private copies and will not
@@ -78,7 +88,8 @@
   // TODO: the main thread's sched_policy and sched_priority need to be queried.
 
   // The TLS stack guard is set from the global, so ensure that we've initialized the global
-  // before we initialize the TLS.
+  // before we initialize the TLS. Dynamic executables will initialize their copy of the global
+  // stack protector from the one in the main thread's TLS.
   __libc_init_global_stack_chk_guard(args);
 
   __init_thread(&main_thread);
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 2070c9c..919080b 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -45,7 +45,6 @@
 #include "private/WriteProtected.h"
 #include "private/bionic_auxv.h"
 #include "private/bionic_globals.h"
-#include "private/bionic_ssp.h"
 #include "private/bionic_tls.h"
 #include "private/libc_logging.h"
 #include "private/thread_private.h"
@@ -62,15 +61,6 @@
 // Declared in <unistd.h>.
 char** environ;
 
-// Declared in "private/bionic_ssp.h".
-uintptr_t __stack_chk_guard = 0;
-
-void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) {
-  // AT_RANDOM is a pointer to 16 bytes of randomness on the stack.
-  // Take the first 4/8 for the -fstack-protector implementation.
-  __stack_chk_guard = *reinterpret_cast<uintptr_t*>(args.getauxval(AT_RANDOM));
-}
-
 #if defined(__i386__)
 __LIBC_HIDDEN__ void* __libc_sysinfo = nullptr;
 
@@ -91,7 +81,6 @@
   // Initialize libc globals that are needed in both the linker and in libc.
   // In dynamic binaries, this is run at least twice for different copies of the
   // globals, once for the linker's copy and once for the one in libc.so.
-  __libc_init_global_stack_chk_guard(args);
   __libc_auxv = args.auxv;
   __libc_globals.initialize();
   __libc_globals.mutate([&args](libc_globals* globals) {
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index ab48fb8..43bca30 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -52,6 +52,7 @@
 #include "libc_init_common.h"
 
 #include "private/bionic_globals.h"
+#include "private/bionic_ssp.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
 
@@ -74,6 +75,10 @@
   // __libc_init_common() will change the TLS area so the old one won't be accessible anyway.
   *args_slot = NULL;
 
+  // The linker has initialized its copy of the global stack_chk_guard, and filled in the main
+  // thread's TLS slot with that value. Initialize the local global stack guard with its value.
+  __stack_chk_guard = reinterpret_cast<uintptr_t>(tls[TLS_SLOT_STACK_GUARD]);
+
   __libc_init_globals(*args);
   __libc_init_common(*args);
 
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index d1494d7..5e06d39 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -39,6 +39,7 @@
 #include "libc_init_common.h"
 #include "pthread_internal.h"
 
+#include "private/bionic_globals.h"
 #include "private/bionic_page.h"
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
@@ -85,6 +86,7 @@
   __libc_init_main_thread(args);
 
   // Initializing the globals requires TLS to be available for errno.
+  __init_thread_stack_guard(__get_thread());
   __libc_init_globals(args);
 
   __libc_init_AT_SECURE(args);
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 08d9bed..1956a8f 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -56,6 +56,10 @@
   // Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
   thread->tls[TLS_SLOT_SELF] = thread->tls;
   thread->tls[TLS_SLOT_THREAD_ID] = thread;
+  __init_thread_stack_guard(thread);
+}
+
+void __init_thread_stack_guard(pthread_internal_t* thread) {
   // GCC looks in the TLS for the stack guard on x86, so copy it there from our global.
   thread->tls[TLS_SLOT_STACK_GUARD] = reinterpret_cast<void*>(__stack_chk_guard);
 }
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 1d9e03e..d2abea0 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -114,6 +114,7 @@
 
 __LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);
 __LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);
+__LIBC_HIDDEN__ void __init_thread_stack_guard(pthread_internal_t* thread);
 __LIBC_HIDDEN__ void __init_alternate_signal_stack(pthread_internal_t*);
 
 __LIBC_HIDDEN__ pthread_t           __pthread_internal_add(pthread_internal_t* thread);
@@ -123,7 +124,13 @@
 
 // Make __get_thread() inlined for performance reason. See http://b/19825434.
 static inline __always_inline pthread_internal_t* __get_thread() {
-  return reinterpret_cast<pthread_internal_t*>(__get_tls()[TLS_SLOT_THREAD_ID]);
+  void** tls = __get_tls();
+  if (__predict_true(tls)) {
+    return reinterpret_cast<pthread_internal_t*>(tls[TLS_SLOT_THREAD_ID]);
+  }
+
+  // This happens when called during libc initialization before TLS has been initialized.
+  return nullptr;
 }
 
 __LIBC_HIDDEN__ void pthread_key_clean_all(void);
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index b45c0c3..94dd7e8 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -44,7 +44,6 @@
 __LIBC_HIDDEN__ extern WriteProtected<libc_globals> __libc_globals;
 
 class KernelArgumentBlock;
-__LIBC_HIDDEN__ void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args);
 __LIBC_HIDDEN__ void __libc_init_malloc(libc_globals* globals);
 __LIBC_HIDDEN__ void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args);
 __LIBC_HIDDEN__ void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args);