Merge "libm: sync with upstream."
diff --git a/docs/status.md b/docs/status.md
index 9d3ad88..9521da8 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -50,6 +50,21 @@
 
 Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt
 
+New libc functions in T (API level 32):
+  * `backtrace`, `backtrace_symbols`, `backtrace_symbols_fd` (`<execinfo.h>`).
+  * New system call wrappers: `preadv2`, `preadv64v2`, `pwritev2`,
+    `pwritev64v2`.
+
+New libc functions in S (API level 31):
+  * New hooks for sanitizers for TLS access: `__libc_get_static_tls_bounds`,
+    `__libc_register_thread_exit_callback`, `__libc_iterate_dynamic_tls`,
+    `__libc_register_dynamic_tls_listeners`.
+  * New helper to allow the zygote to give each zygote child its own stack
+    cookie (currently unused): `android_reset_stack_guards`.
+  * Non-inline symbols for `ffsl`, `ffsll`.
+  * New system call wrappers: `pidfd_getfd`, `pidfd_open`, `pidfd_send_signal`,
+    `process_madvise`.
+
 New libc functions in R (API level 30):
   * Full C11 `<threads.h>` (available as inlines for older API levels).
   * `memfd_create` and `mlock2` (Linux-specific GNU extensions).
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index 214acf2..efe4354 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -51,7 +51,7 @@
 // those APIs will still cause a link error.
 #if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
 #define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,__what)))
-#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN_X86(api_level)
+#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN(api_level)
 #define __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN_X86(api_level)
 #else
 #define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,strict,__what)))
diff --git a/tests/Android.bp b/tests/Android.bp
index e7273c0..19d18ab 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -741,7 +741,6 @@
     name: "libBionicLoaderTests",
     defaults: [
         "bionic_tests_defaults",
-        "llvm-defaults",
     ],
     srcs: [
         "atexit_test.cpp",
@@ -772,12 +771,6 @@
                 "libmeminfo",
                 "libprocinfo",
                 "libziparchive",
-                "libLLVMObject",
-                "libLLVMBitReader",
-                "libLLVMMC",
-                "libLLVMMCParser",
-                "libLLVMCore",
-                "libLLVMSupport",
             ],
         },
     },
@@ -867,12 +860,6 @@
                 "libziparchive",
                 "libz",
                 "libutils",
-                "libLLVMObject",
-                "libLLVMBitReader",
-                "libLLVMMC",
-                "libLLVMMCParser",
-                "libLLVMCore",
-                "libLLVMSupport",
             ],
             ldflags: [
                 "-Wl,--rpath,${ORIGIN}/bionic-loader-test-libs",
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index a9c2b87..0bf8775 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -17,7 +17,9 @@
 #include <gtest/gtest.h>
 
 #include <dlfcn.h>
+#include <elf.h>
 #include <limits.h>
+#include <link.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
@@ -38,24 +40,6 @@
 #include "dlfcn_symlink_support.h"
 #include "utils.h"
 
-#if defined(__BIONIC__) && (defined(__arm__) || defined(__i386__))
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-parameter"
-
-#include <llvm/ADT/StringRef.h>
-#include <llvm/Object/Binary.h>
-#include <llvm/Object/ELFObjectFile.h>
-#include <llvm/Object/ObjectFile.h>
-
-#pragma clang diagnostic pop
-#endif //  defined(__ANDROID__) && (defined(__arm__) || defined(__i386__))
-
-// Declared manually because the macro definitions in <elf.h> conflict with LLVM headers.
-#ifdef __arm__
-typedef uintptr_t _Unwind_Ptr;
-extern "C" _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int*);
-#endif
-
 #define ASSERT_SUBSTR(needle, haystack) \
     ASSERT_PRED_FORMAT2(::testing::IsSubstring, needle, haystack)
 
@@ -1542,75 +1526,35 @@
 #if defined(__BIONIC__)
 
 #if defined(__arm__)
-const llvm::ELF::Elf32_Dyn* to_dynamic_table(const char* p) {
-  return reinterpret_cast<const llvm::ELF::Elf32_Dyn*>(p);
-}
 
-// Duplicate these definitions here because they are android specific
-//  - note that we cannot include <elf.h> because #defines conflict with
-//    enum names provided by LLVM.
-//  - we also don't use llvm::ELF::DT_LOOS because its value is 0x60000000
-//    rather than the 0x6000000d we expect
-#define DT_LOOS 0x6000000d
-#define DT_ANDROID_REL (DT_LOOS + 2)
-#define DT_ANDROID_RELA (DT_LOOS + 4)
+void validate_compatibility_of_native_library(const std::string& soname, const std::string& path) {
+  // Grab the dynamic section in text form...
+  ExecTestHelper eth;
+  eth.SetArgs({"readelf", "-dW", path.c_str(), nullptr});
+  eth.Run([&]() { execvpe("readelf", eth.GetArgs(), eth.GetEnv()); }, 0, nullptr);
+  std::string output = eth.GetOutput();
 
-template<typename ELFT>
-void validate_compatibility_of_native_library(const std::string& soname,
-                                              const std::string& path, ELFT* elf) {
-  bool has_elf_hash = false;
-  bool has_android_rel = false;
-  bool has_rel = false;
-  // Find dynamic section and check that DT_HASH and there is no DT_ANDROID_REL
-  for (auto it = elf->section_begin(); it != elf->section_end(); ++it) {
-    const llvm::object::ELFSectionRef& section_ref = *it;
-    if (section_ref.getType() == llvm::ELF::SHT_DYNAMIC) {
-      llvm::StringRef data;
-      ASSERT_TRUE(!it->getContents(data)) << "unable to get SHT_DYNAMIC section data";
-      for (auto d = to_dynamic_table(data.data()); d->d_tag != llvm::ELF::DT_NULL; ++d) {
-        if (d->d_tag == llvm::ELF::DT_HASH) {
-          has_elf_hash = true;
-        } else if (d->d_tag == DT_ANDROID_REL || d->d_tag == DT_ANDROID_RELA) {
-          has_android_rel = true;
-        } else if (d->d_tag == llvm::ELF::DT_REL || d->d_tag == llvm::ELF::DT_RELA) {
-          has_rel = true;
-        }
-      }
+  // Check that there *is* a legacy DT_HASH (not just a GNU hash)...
+  ASSERT_TRUE(std::regex_search(output, std::regex("\\(HASH\\)"))) << output;
+  // Check that there is no DT_ANDROID_REL or DT_ANDROID_RELA...
+  ASSERT_FALSE(std::regex_search(output, std::regex("\\(ANDROID_REL\\)"))) << output;
+  ASSERT_FALSE(std::regex_search(output, std::regex("\\(ANDROID_RELA\\)"))) << output;
 
-      break;
-    }
-  }
-
-  ASSERT_TRUE(has_elf_hash) << path.c_str() << ": missing elf hash (DT_HASH)";
-  ASSERT_TRUE(!has_android_rel) << path.c_str() << ": has packed relocations";
-  // libdl.so is simple enough that it might not have any relocations, so
-  // exempt it from the DT_REL/DT_RELA check.
-  if (soname != "libdl.so") {
-    ASSERT_TRUE(has_rel) << path.c_str() << ": missing DT_REL/DT_RELA";
-  }
+  // Check that we have regular non-packed relocations.
+  // libdl.so is simple enough that it doesn't have any relocations.
+  ASSERT_TRUE(std::regex_search(output, std::regex("\\(RELA?\\)")) || soname == "libdl.so")
+      << output;
 }
 
 void validate_compatibility_of_native_library(const std::string& soname) {
   // On the systems with emulation system libraries would be of different
   // architecture.  Try to use alternate paths first.
   std::string path = std::string(ALTERNATE_PATH_TO_SYSTEM_LIB) + soname;
-  auto binary_or_error = llvm::object::createBinary(path);
-  if (!binary_or_error) {
+  if (access(path.c_str(), R_OK) != 0) {
     path = std::string(PATH_TO_SYSTEM_LIB) + soname;
-    binary_or_error = llvm::object::createBinary(path);
+    ASSERT_EQ(0, access(path.c_str(), R_OK));
   }
-  ASSERT_FALSE(!binary_or_error);
-
-  llvm::object::Binary* binary = binary_or_error.get().getBinary();
-
-  auto obj = llvm::dyn_cast<llvm::object::ObjectFile>(binary);
-  ASSERT_TRUE(obj != nullptr);
-
-  auto elf = llvm::dyn_cast<llvm::object::ELF32LEObjectFile>(obj);
-
-  ASSERT_TRUE(elf != nullptr);
-
-  validate_compatibility_of_native_library(soname, path, elf);
+  validate_compatibility_of_native_library(soname, path);
 }
 
 // This is a test for app compatibility workaround for arm apps