Merge "Implement Library Load Order Randomization"
diff --git a/libc/bionic/libgen.cpp b/libc/bionic/libgen.cpp
index 5c27bb5..c415c0f 100644
--- a/libc/bionic/libgen.cpp
+++ b/libc/bionic/libgen.cpp
@@ -92,7 +92,7 @@
 }
 
 // Since this is a non-standard symbol, it might be hijacked by a basename_r in the executable.
-__LIBC64_HIDDEN__ int basename_r(const char* path, char* buffer, size_t buffer_size) {
+__LIBC32_LEGACY_PUBLIC__ int basename_r(const char* path, char* buffer, size_t buffer_size) {
   return __basename_r(path, buffer, buffer_size);
 }
 
@@ -156,7 +156,7 @@
 }
 
 // Since this is a non-standard symbol, it might be hijacked by a basename_r in the executable.
-__LIBC64_HIDDEN__ int dirname_r(const char* path, char* buffer, size_t buffer_size) {
+__LIBC32_LEGACY_PUBLIC__ int dirname_r(const char* path, char* buffer, size_t buffer_size) {
   return __dirname_r(path, buffer, buffer_size);
 }
 
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index e260e97..ce43009 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -193,8 +193,7 @@
   // notify gdb about this thread before we start doing anything.
   // This also provides the memory barrier needed to ensure that all memory
   // accesses previously made by the creating thread are visible to us.
-  pthread_mutex_lock(&thread->startup_handshake_mutex);
-  pthread_mutex_destroy(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.lock();
 
   __init_alternate_signal_stack(thread);
 
@@ -233,14 +232,14 @@
     return result;
   }
 
-  // Create a mutex for the thread in TLS to wait on once it starts so we can keep
+  // Create a lock for the thread to wait on once it starts so we can keep
   // it from doing anything until after we notify the debugger about it
   //
   // This also provides the memory barrier we need to ensure that all
   // memory accesses previously performed by this thread are visible to
   // the new thread.
-  pthread_mutex_init(&thread->startup_handshake_mutex, NULL);
-  pthread_mutex_lock(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.init(false);
+  thread->startup_handshake_lock.lock();
 
   thread->start_routine = start_routine;
   thread->start_routine_arg = arg;
@@ -263,7 +262,7 @@
     // We don't have to unlock the mutex at all because clone(2) failed so there's no child waiting to
     // be unblocked, but we're about to unmap the memory the mutex is stored in, so this serves as a
     // reminder that you can't rewrite this function to use a ScopedPthreadMutexLocker.
-    pthread_mutex_unlock(&thread->startup_handshake_mutex);
+    thread->startup_handshake_lock.unlock();
     if (thread->mmap_size != 0) {
       munmap(thread->attr.stack_base, thread->mmap_size);
     }
@@ -278,13 +277,13 @@
     atomic_store(&thread->join_state, THREAD_DETACHED);
     __pthread_internal_add(thread);
     thread->start_routine = __do_nothing;
-    pthread_mutex_unlock(&thread->startup_handshake_mutex);
+    thread->startup_handshake_lock.unlock();
     return init_errno;
   }
 
   // Publish the pthread_t and unlock the mutex to let the new thread start running.
   *thread_out = __pthread_internal_add(thread);
-  pthread_mutex_unlock(&thread->startup_handshake_mutex);
+  thread->startup_handshake_lock.unlock();
 
   return 0;
 }
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 6a39a21..d5d62a7 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -31,6 +31,7 @@
 #include <pthread.h>
 #include <stdatomic.h>
 
+#include "private/bionic_lock.h"
 #include "private/bionic_tls.h"
 
 /* Has the thread been detached by a pthread_join or pthread_detach call? */
@@ -89,7 +90,7 @@
 
   void* alternate_signal_stack;
 
-  pthread_mutex_t startup_handshake_mutex;
+  Lock startup_handshake_lock;
 
   size_t mmap_size;
 
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 58038cd..342cfad 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -432,9 +432,9 @@
 
 /* Like __LIBC_HIDDEN__, but preserves binary compatibility for LP32. */
 #ifdef __LP64__
-#define __LIBC64_HIDDEN__ __LIBC_HIDDEN__
+#define __LIBC32_LEGACY_PUBLIC__ __LIBC_HIDDEN__
 #else
-#define __LIBC64_HIDDEN__ __LIBC_ABI_PUBLIC__
+#define __LIBC32_LEGACY_PUBLIC__ __LIBC_ABI_PUBLIC__
 #endif
 
 /* Used to tag non-static symbols that are public and exposed by the shared library. */
diff --git a/libc/private/bionic_lock.h b/libc/private/bionic_lock.h
index 6a0fd06..a36d1ed 100644
--- a/libc/private/bionic_lock.h
+++ b/libc/private/bionic_lock.h
@@ -31,6 +31,8 @@
 #include <stdatomic.h>
 #include "private/bionic_futex.h"
 
+// Lock is used in places like pthread_rwlock_t, which can be initialized without calling
+// an initialization function. So make sure Lock can be initialized by setting its memory to 0.
 class Lock {
  private:
   enum LockState {
@@ -42,10 +44,6 @@
   bool process_shared;
 
  public:
-  Lock(bool process_shared = false) {
-    init(process_shared);
-  }
-
   void init(bool process_shared) {
     atomic_init(&state, Unlocked);
     this->process_shared = process_shared;
diff --git a/libc/stdio/glue.h b/libc/stdio/glue.h
index a9e5d10..cb1d182 100644
--- a/libc/stdio/glue.h
+++ b/libc/stdio/glue.h
@@ -47,6 +47,6 @@
 };
 
 /* This was referenced by a couple of different pieces of middleware and the Crystax NDK. */
-__LIBC64_HIDDEN__ extern struct glue __sglue;
+__LIBC32_LEGACY_PUBLIC__ extern struct glue __sglue;
 
 __END_DECLS
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 749de7b..ced94e3 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -145,27 +145,27 @@
  * to __srget/__swbuf, so those symbols need to be public for LP32
  * but can be hidden for LP64.
  */
-__LIBC64_HIDDEN__ int __srget(FILE*);
-__LIBC64_HIDDEN__ int __swbuf(int, FILE*);
-__LIBC64_HIDDEN__ int __srefill(FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __srget(FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __swbuf(int, FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __srefill(FILE*);
 
 /* This was referenced by the apportable middleware for LP32. */
-__LIBC64_HIDDEN__ int __swsetup(FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __swsetup(FILE*);
 
 /* These were referenced by a couple of different pieces of middleware and the Crystax NDK. */
-__LIBC64_HIDDEN__ extern int __sdidinit;
-__LIBC64_HIDDEN__ int __sflags(const char*, int*);
-__LIBC64_HIDDEN__ FILE* __sfp(void);
-__LIBC64_HIDDEN__ void __sinit(void);
-__LIBC64_HIDDEN__ void __smakebuf(FILE*);
+__LIBC32_LEGACY_PUBLIC__ extern int __sdidinit;
+__LIBC32_LEGACY_PUBLIC__ int __sflags(const char*, int*);
+__LIBC32_LEGACY_PUBLIC__ FILE* __sfp(void);
+__LIBC32_LEGACY_PUBLIC__ void __sinit(void);
+__LIBC32_LEGACY_PUBLIC__ void __smakebuf(FILE*);
 
 /* These are referenced by the Greed for Glory franchise. */
-__LIBC64_HIDDEN__ int __sflush(FILE *);
-__LIBC64_HIDDEN__ int __sread(void *, char *, int);
-__LIBC64_HIDDEN__ int __swrite(void *, const char *, int);
-__LIBC64_HIDDEN__ fpos_t __sseek(void *, fpos_t, int);
-__LIBC64_HIDDEN__ int __sclose(void *);
-__LIBC64_HIDDEN__ int _fwalk(int (*)(FILE *));
+__LIBC32_LEGACY_PUBLIC__ int __sflush(FILE *);
+__LIBC32_LEGACY_PUBLIC__ int __sread(void *, char *, int);
+__LIBC32_LEGACY_PUBLIC__ int __swrite(void *, const char *, int);
+__LIBC32_LEGACY_PUBLIC__ fpos_t __sseek(void *, fpos_t, int);
+__LIBC32_LEGACY_PUBLIC__ int __sclose(void *);
+__LIBC32_LEGACY_PUBLIC__ int _fwalk(int (*)(FILE *));
 
 #pragma GCC visibility push(hidden)
 
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 47bacc3..b07f55d 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -71,8 +71,8 @@
 __LIBC_HIDDEN__ void* reallocarray(void*, size_t, size_t);
 
 /* LP32 NDK ctype.h contained references to these. */
-__LIBC64_HIDDEN__ extern const short* _tolower_tab_;
-__LIBC64_HIDDEN__ extern const short* _toupper_tab_;
+__LIBC32_LEGACY_PUBLIC__ extern const short* _tolower_tab_;
+__LIBC32_LEGACY_PUBLIC__ extern const short* _toupper_tab_;
 
 __LIBC_HIDDEN__ extern const char _C_ctype_[];
 __LIBC_HIDDEN__ extern const short _C_toupper_[];
diff --git a/libm/Android.mk b/libm/Android.mk
index fb8df07..f6c49aa 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -485,6 +485,7 @@
     -D__BIONIC_NO_MATH_INLINES \
     -DFLT_EVAL_METHOD=0 \
     -include $(LOCAL_PATH)/freebsd-compat.h \
+    -Werror \
     -Wno-missing-braces \
     -Wno-parentheses \
     -Wno-sign-compare \
diff --git a/libm/arm64/fenv.c b/libm/arm64/fenv.c
index ce560a7..19a2393 100644
--- a/libm/arm64/fenv.c
+++ b/libm/arm64/fenv.c
@@ -26,6 +26,7 @@
  * $FreeBSD: libm/aarch64/fenv.c $
  */
 
+#include <stdint.h>
 #include <fenv.h>
 
 #define FPCR_EXCEPT_SHIFT 8
@@ -38,10 +39,20 @@
 typedef __uint32_t fpu_control_t;   // FPCR, Floating-point Control Register.
 typedef __uint32_t fpu_status_t;    // FPSR, Floating-point Status Register.
 
-#define __get_fpcr(__fpcr) __asm__ __volatile__("mrs %0,fpcr" : "=r" (__fpcr))
-#define __get_fpsr(__fpsr) __asm__ __volatile__("mrs %0,fpsr" : "=r" (__fpsr))
-#define __set_fpcr(__fpcr) __asm__ __volatile__("msr fpcr,%0" : :"ri" (__fpcr))
-#define __set_fpsr(__fpsr) __asm__ __volatile__("msr fpsr,%0" : :"ri" (__fpsr))
+#define __get(REGISTER, __value) { \
+  uint64_t __value64; \
+  __asm__ __volatile__("mrs %0," REGISTER : "=r" (__value64)); \
+  __value = (__uint32_t) __value64; \
+}
+#define __get_fpcr(__fpcr) __get("fpcr", __fpcr)
+#define __get_fpsr(__fpsr) __get("fpsr", __fpsr)
+
+#define __set(REGISTER, __value) { \
+  uint64_t __value64 = __value; \
+  __asm__ __volatile__("msr " REGISTER ",%0" : : "ri" (__value64)); \
+}
+#define __set_fpcr(__fpcr) __set("fpcr", __fpcr)
+#define __set_fpsr(__fpsr) __set("fpsr", __fpsr)
 
 int fegetenv(fenv_t* envp) {
   __get_fpcr(envp->__control);