Merge "Use single module for libclang_rt.builtins-exported"
diff --git a/libc/Android.bp b/libc/Android.bp
index c7b9930..7175c77 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -2615,10 +2615,6 @@
     stl: "none",
 }
 
-subdirs = [
-    "bionic/scudo",
-]
-
 // Export kernel uapi headers to be used in the musl sysroot.
 // Also include the execinfo headers for the libexecinfo and the
 // b64 headers for libb64 embedded in musl libc.
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index 90c9136..b982c0a 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -66,7 +66,8 @@
 std::unordered_map<FrameKeyType, size_t> PointerData::key_to_index_ GUARDED_BY(
     PointerData::frame_mutex_);
 std::unordered_map<size_t, FrameInfoType> PointerData::frames_ GUARDED_BY(PointerData::frame_mutex_);
-std::unordered_map<size_t, std::vector<unwindstack::LocalFrameData>> PointerData::backtraces_info_ GUARDED_BY(PointerData::frame_mutex_);
+std::unordered_map<size_t, std::vector<unwindstack::FrameData>> PointerData::backtraces_info_
+    GUARDED_BY(PointerData::frame_mutex_);
 constexpr size_t kBacktraceEmptyIndex = 1;
 size_t PointerData::cur_hash_index_ GUARDED_BY(PointerData::frame_mutex_);
 
@@ -136,7 +137,7 @@
 
 size_t PointerData::AddBacktrace(size_t num_frames) {
   std::vector<uintptr_t> frames;
-  std::vector<unwindstack::LocalFrameData> frames_info;
+  std::vector<unwindstack::FrameData> frames_info;
   if (g_debug->config().options() & BACKTRACE_FULL) {
     if (!Unwind(&frames, &frames_info, num_frames)) {
       return kBacktraceEmptyIndex;
@@ -386,7 +387,7 @@
     REQUIRES(pointer_mutex_, frame_mutex_) {
   for (const auto& entry : pointers_) {
     FrameInfoType* frame_info = nullptr;
-    std::vector<unwindstack::LocalFrameData>* backtrace_info = nullptr;
+    std::vector<unwindstack::FrameData>* backtrace_info = nullptr;
     size_t hash_index = entry.second.hash_index;
     if (hash_index > kBacktraceEmptyIndex) {
       auto frame_entry = frames_.find(hash_index);
diff --git a/libc/malloc_debug/PointerData.h b/libc/malloc_debug/PointerData.h
index 37d87db..92d2653 100644
--- a/libc/malloc_debug/PointerData.h
+++ b/libc/malloc_debug/PointerData.h
@@ -39,7 +39,7 @@
 #include <vector>
 
 #include <platform/bionic/macros.h>
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 #include "OptionData.h"
 #include "UnwindBacktrace.h"
@@ -109,7 +109,7 @@
   size_t size;
   bool zygote_child_alloc;
   FrameInfoType* frame_info;
-  std::vector<unwindstack::LocalFrameData>* backtrace_info;
+  std::vector<unwindstack::FrameData>* backtrace_info;
 };
 
 class PointerData : public OptionData {
@@ -181,7 +181,7 @@
   static std::mutex frame_mutex_;
   static std::unordered_map<FrameKeyType, size_t> key_to_index_;
   static std::unordered_map<size_t, FrameInfoType> frames_;
-  static std::unordered_map<size_t, std::vector<unwindstack::LocalFrameData>> backtraces_info_;
+  static std::unordered_map<size_t, std::vector<unwindstack::FrameData>> backtraces_info_;
   static size_t cur_hash_index_;
 
   static std::mutex free_pointer_mutex_;
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index da26d15..662f5f8 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -641,6 +641,13 @@
 for the best way to use malloc debug in Android O or later on non-rooted
 devices.
 
+**NOTE**: Android 12 introduced a bug that can cause the wrap.\<APP\> property to
+no longer work. Use the commands below so that the wrap.\<APP\> instructions will work:
+
+    adb shell setprop dalvik.vm.force-java-zygote-fork-loop true
+    adb shell stop
+    adb shell start
+
 If you do have a rooted device, you can enable malloc debug for a specific
 program/application (Android O or later):
 
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index a7036d9..f6c3e69 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -36,8 +36,12 @@
 #include <vector>
 
 #include <android-base/stringprintf.h>
-#include <unwindstack/LocalUnwinder.h>
 #include <unwindstack/MapInfo.h>
+#include <unwindstack/Maps.h>
+#include <unwindstack/Memory.h>
+#include <unwindstack/Regs.h>
+#include <unwindstack/RegsGetLocal.h>
+#include <unwindstack/Unwinder.h>
 
 #include "UnwindBacktrace.h"
 #include "debug_log.h"
@@ -52,42 +56,56 @@
 
 static pthread_once_t g_setup_once = PTHREAD_ONCE_INIT;
 
-static unwindstack::LocalUnwinder* g_unwinder;
-
-static void Setup() {
+static unwindstack::LocalUpdatableMaps* g_maps;
+static std::shared_ptr<unwindstack::Memory> g_process_memory;
 #if defined(__LP64__)
-  std::vector<std::string> skip_libraries{"/system/lib64/libunwindstack.so", "/system/lib64/libc_malloc_debug.so"};
+static std::vector<std::string> g_skip_libraries{"/system/lib64/libunwindstack.so",
+                                                 "/system/lib64/libc_malloc_debug.so"};
 #else
-  std::vector<std::string> skip_libraries{"/system/lib/libunwindstack.so", "/system/lib/libc_malloc_debug.so"};
+static std::vector<std::string> g_skip_libraries{"/system/lib/libunwindstack.so",
+                                                 "/system/lib/libc_malloc_debug.so"};
 #endif
 
-  g_unwinder = new unwindstack::LocalUnwinder(skip_libraries);
-  g_unwinder->Init();
+static void Setup() {
+  g_maps = new unwindstack::LocalUpdatableMaps;
+  if (!g_maps->Parse()) {
+    delete g_maps;
+    g_maps = nullptr;
+  }
+
+  g_process_memory = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
 }
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* frame_info, size_t max_frames) {
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* frame_info,
+            size_t max_frames) {
   pthread_once(&g_setup_once, Setup);
 
-  if (g_unwinder == nullptr) {
+  if (g_maps == nullptr) {
     return false;
   }
 
-  if (!g_unwinder->Unwind(frame_info, max_frames)) {
+  std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
+  unwindstack::RegsGetLocal(regs.get());
+  unwindstack::Unwinder unwinder(max_frames, g_maps, regs.get(), g_process_memory);
+  unwinder.Unwind(&g_skip_libraries);
+  if (unwinder.NumFrames() == 0) {
     frames->clear();
     frame_info->clear();
     return false;
   }
+  *frame_info = unwinder.ConsumeFrames();
 
-  for (const auto& frame : *frame_info) {
-    frames->push_back(frame.pc);
+  frames->resize(frame_info->size());
+  for (size_t i = 0; i < frame_info->size(); i++) {
+    frames->at(i) = frame_info->at(i).pc;
   }
   return true;
 }
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info) {
+void UnwindLog(const std::vector<unwindstack::FrameData>& frame_info) {
   for (size_t i = 0; i < frame_info.size(); i++) {
-    const unwindstack::LocalFrameData* info = &frame_info[i];
-    std::shared_ptr<unwindstack::MapInfo> map_info = info->map_info;
+    const unwindstack::FrameData* info = &frame_info[i];
+    auto map_info = info->map_info;
 
     std::string line = android::base::StringPrintf("          #%0zd  pc %" PAD_PTR "  ", i, info->rel_pc);
     if (map_info != nullptr && map_info->offset() != 0) {
diff --git a/libc/malloc_debug/UnwindBacktrace.h b/libc/malloc_debug/UnwindBacktrace.h
index 4c6c8d4..7f89907 100644
--- a/libc/malloc_debug/UnwindBacktrace.h
+++ b/libc/malloc_debug/UnwindBacktrace.h
@@ -33,9 +33,10 @@
 #include <string>
 #include <vector>
 
-#include <unwindstack/LocalUnwinder.h>
 #include <unwindstack/MapInfo.h>
+#include <unwindstack/Unwinder.h>
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* info, size_t max_frames);
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* info,
+            size_t max_frames);
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info);
+void UnwindLog(const std::vector<unwindstack::FrameData>& frame_info);
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index d23ab15..9f38946 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -49,6 +49,7 @@
 #include <platform/bionic/reserved_signals.h>
 #include <private/MallocXmlElem.h>
 #include <private/bionic_malloc_dispatch.h>
+#include <unwindstack/Unwinder.h>
 
 #include "Config.h"
 #include "DebugData.h"
@@ -193,7 +194,7 @@
 void BacktraceAndLog() {
   if (g_debug->config().options() & BACKTRACE_FULL) {
     std::vector<uintptr_t> frames;
-    std::vector<unwindstack::LocalFrameData> frames_info;
+    std::vector<unwindstack::FrameData> frames_info;
     if (!Unwind(&frames, &frames_info, 256)) {
       error_log("  Backtrace failed to get any frames.");
     } else {
diff --git a/libc/malloc_debug/tests/backtrace_fake.cpp b/libc/malloc_debug/tests/backtrace_fake.cpp
index ad16c02..f54bae8 100644
--- a/libc/malloc_debug/tests/backtrace_fake.cpp
+++ b/libc/malloc_debug/tests/backtrace_fake.cpp
@@ -20,7 +20,7 @@
 #include <vector>
 #include <utility>
 
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 #include "backtrace.h"
 #include "backtrace_fake.h"
@@ -60,17 +60,17 @@
   }
 }
 
-static std::deque<std::vector<unwindstack::LocalFrameData>> g_fake_local_frame_data;
+static std::deque<std::vector<unwindstack::FrameData>> g_fake_local_frame_data;
 
 void BacktraceUnwindFakeClearAll() {
   g_fake_local_frame_data.clear();
 }
 
-void BacktraceUnwindFake(const std::vector<unwindstack::LocalFrameData>& frames) {
+void BacktraceUnwindFake(const std::vector<unwindstack::FrameData>& frames) {
   g_fake_local_frame_data.push_back(frames);
 }
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* info, size_t) {
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* info, size_t) {
   if (g_fake_local_frame_data.empty()) {
     return false;
   }
@@ -85,5 +85,4 @@
   return true;
 }
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& /*frame_info*/) {
-}
+void UnwindLog(const std::vector<unwindstack::FrameData>& /*frame_info*/) {}
diff --git a/libc/malloc_debug/tests/backtrace_fake.h b/libc/malloc_debug/tests/backtrace_fake.h
index a9ee97d..246fc61 100644
--- a/libc/malloc_debug/tests/backtrace_fake.h
+++ b/libc/malloc_debug/tests/backtrace_fake.h
@@ -21,12 +21,12 @@
 
 #include <vector>
 
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 void backtrace_fake_clear_all();
 void backtrace_fake_add(const std::vector<uintptr_t>& ips);
 
 void BacktraceUnwindFakeClearAll();
-void BacktraceUnwindFake(const std::vector<unwindstack::LocalFrameData>& frames);
+void BacktraceUnwindFake(const std::vector<unwindstack::FrameData>& frames);
 
 #endif // MALLOC_DEBUG_TESTS_BACKTRACE_FAKE_H
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 7b58f31..46de3e9 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -44,6 +44,8 @@
 #include <platform/bionic/macros.h>
 #include <private/bionic_malloc_dispatch.h>
 
+#include <unwindstack/Unwinder.h>
+
 #include "Config.h"
 #include "malloc_debug.h"
 
@@ -1530,16 +1532,18 @@
   if ((pid = fork()) == 0) {
     std::shared_ptr<unwindstack::MapInfo> empty_map;
     Init("backtrace=4 backtrace_full backtrace_dump_on_exit");
-    BacktraceUnwindFake(std::vector<unwindstack::LocalFrameData>{
-        {empty_map, 0x1100, 0x100, "fake1", 10}, {empty_map, 0x1200, 0x200, "fake2", 20}});
+    BacktraceUnwindFake(
+        std::vector<unwindstack::FrameData>{{0, 0x100, 0x1100, 0, "fake1", 10, empty_map},
+                                            {1, 0x200, 0x1200, 0, "fake2", 20, empty_map}});
     std::shared_ptr<unwindstack::MapInfo> map_info =
         unwindstack::MapInfo::Create(0x10000, 0x20000, 0, PROT_READ | PROT_EXEC, "/data/fake.so");
-    BacktraceUnwindFake(std::vector<unwindstack::LocalFrameData>{
-        {map_info, 0x1a000, 0xa000, "level1", 0}, {map_info, 0x1b000, 0xb000, "level2", 10}});
     BacktraceUnwindFake(
-        std::vector<unwindstack::LocalFrameData>{{empty_map, 0x1a000, 0xa000, "func1", 0},
-                                                 {empty_map, 0x1b000, 0xb000, "func2", 10},
-                                                 {empty_map, 0x1c000, 0xc000, "", 30}});
+        std::vector<unwindstack::FrameData>{{0, 0xa000, 0x1a000, 0, "level1", 0, map_info},
+                                            {1, 0xb000, 0x1b000, 0, "level2", 10, map_info}});
+    BacktraceUnwindFake(
+        std::vector<unwindstack::FrameData>{{0, 0xa000, 0x1a000, 0, "func1", 0, empty_map},
+                                            {1, 0xb000, 0x1b000, 0, "func2", 10, empty_map},
+                                            {2, 0xc000, 0x1c000, 0, "", 30, empty_map}});
 
     std::vector<void*> pointers;
     pointers.push_back(debug_malloc(300));
diff --git a/libfdtrack/Android.bp b/libfdtrack/Android.bp
index fb28623..83ea7cb 100644
--- a/libfdtrack/Android.bp
+++ b/libfdtrack/Android.bp
@@ -38,4 +38,5 @@
     whole_static_libs: ["libBionicCtsGtestMain"],
     static_libs: ["liblog"],
     test_suites: ["device-tests"],
+    runtime_libs: ["libfdtrack"],
 }
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index 2e9cfbc..2d114f2 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -31,6 +31,8 @@
 
 #include <array>
 #include <mutex>
+#include <string>
+#include <string_view>
 #include <thread>
 #include <utility>
 #include <vector>
@@ -43,11 +45,14 @@
 #include <android-base/thread_annotations.h>
 #include <async_safe/log.h>
 #include <bionic/reserved_signals.h>
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Maps.h>
+#include <unwindstack/Regs.h>
+#include <unwindstack/RegsGetLocal.h>
+#include <unwindstack/Unwinder.h>
 
 struct FdEntry {
   std::mutex mutex;
-  std::vector<unwindstack::LocalFrameData> backtrace GUARDED_BY(mutex);
+  std::vector<unwindstack::FrameData> backtrace GUARDED_BY(mutex);
 };
 
 extern "C" void fdtrack_dump();
@@ -62,15 +67,21 @@
 // Backtraces for the first 4k file descriptors ought to be enough to diagnose an fd leak.
 static constexpr size_t kFdTableSize = 4096;
 
-// 32 frames, plus two to skip from fdtrack itself.
-static constexpr size_t kStackDepth = 34;
-static constexpr size_t kStackFrameSkip = 2;
+// Only unwind up to 32 frames outside of libfdtrack.so.
+static constexpr size_t kStackDepth = 32;
+
+// Skip any initial frames from libfdtrack.so.
+static std::vector<std::string> kSkipFdtrackLib [[clang::no_destroy]] = {"libfdtrack.so"};
 
 static bool installed = false;
 static std::array<FdEntry, kFdTableSize> stack_traces [[clang::no_destroy]];
-static unwindstack::LocalUnwinder& Unwinder() {
-  static android::base::NoDestructor<unwindstack::LocalUnwinder> unwinder;
-  return *unwinder.get();
+static unwindstack::LocalUpdatableMaps& Maps() {
+  static android::base::NoDestructor<unwindstack::LocalUpdatableMaps> maps;
+  return *maps.get();
+}
+static std::shared_ptr<unwindstack::Memory>& ProcessMemory() {
+  static android::base::NoDestructor<std::shared_ptr<unwindstack::Memory>> process_memory;
+  return *process_memory.get();
 }
 
 __attribute__((constructor)) static void ctor() {
@@ -89,7 +100,8 @@
   sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
   sigaction(BIONIC_SIGNAL_FDTRACK, &sa, nullptr);
 
-  if (Unwinder().Init()) {
+  if (Maps().Parse()) {
+    ProcessMemory() = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
     android_fdtrack_hook_t expected = nullptr;
     installed = android_fdtrack_compare_exchange_hook(&expected, &fd_hook);
   }
@@ -116,7 +128,12 @@
     if (FdEntry* entry = GetFdEntry(event->fd); entry) {
       std::lock_guard<std::mutex> lock(entry->mutex);
       entry->backtrace.clear();
-      Unwinder().Unwind(&entry->backtrace, kStackDepth);
+
+      std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
+      unwindstack::RegsGetLocal(regs.get());
+      unwindstack::Unwinder unwinder(kStackDepth, &Maps(), regs.get(), ProcessMemory());
+      unwinder.Unwind(&kSkipFdtrackLib);
+      entry->backtrace = unwinder.ConsumeFrames();
     }
   } else if (event->type == ANDROID_FDTRACK_EVENT_TYPE_CLOSE) {
     if (FdEntry* entry = GetFdEntry(event->fd); entry) {
@@ -153,14 +170,13 @@
       continue;
     }
 
-    for (size_t i = kStackFrameSkip; i < entry->backtrace.size(); ++i) {
-      size_t j = i - kStackFrameSkip;
-      function_names[j] = entry->backtrace[i].function_name.c_str();
-      function_offsets[j] = entry->backtrace[i].function_offset;
+    for (size_t i = 0; i < entry->backtrace.size(); ++i) {
+      function_names[i] = entry->backtrace[i].function_name.c_str();
+      function_offsets[i] = entry->backtrace[i].function_offset;
     }
 
-    bool should_continue = callback(fd, function_names, function_offsets,
-                                    entry->backtrace.size() - kStackFrameSkip, arg);
+    bool should_continue =
+        callback(fd, function_names, function_offsets, entry->backtrace.size(), arg);
 
     entry->mutex.unlock();
 
@@ -200,8 +216,8 @@
     size_t count = 0;
 
     size_t stack_depth = 0;
-    const char* function_names[kStackDepth - kStackFrameSkip];
-    uint64_t function_offsets[kStackDepth - kStackFrameSkip];
+    const char* function_names[kStackDepth];
+    uint64_t function_offsets[kStackDepth];
   };
   struct StackList {
     size_t count = 0;