Merge "Fix soname reading code."
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
index 0f049fd..7b04e71 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
@@ -68,7 +68,7 @@
 class Memory;
 }
 
-void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const char* fmt, ...);
+void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const std::string&);
 
 void read_with_default(const char* path, char* buf, size_t len, const char* default_value);
 
diff --git a/debuggerd/libdebuggerd/test/dump_memory_test.cpp b/debuggerd/libdebuggerd/test/dump_memory_test.cpp
index 7c8a0ea..be39582 100644
--- a/debuggerd/libdebuggerd/test/dump_memory_test.cpp
+++ b/debuggerd/libdebuggerd/test/dump_memory_test.cpp
@@ -201,7 +201,7 @@
   }
   memory_mock_->SetReadData(buffer, sizeof(buffer));
 
-  dump_memory(&log_, memory_mock_.get(), 0x12345678, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0x12345678, "memory near r1");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -221,7 +221,7 @@
   memory_mock_->SetReadData(buffer, sizeof(buffer));
   memory_mock_->SetPartialReadAmount(96);
 
-  dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near r1");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -240,7 +240,7 @@
   }
   memory_mock_->SetReadData(buffer, sizeof(buffer));
 
-  dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near r1");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -253,7 +253,7 @@
 }
 
 TEST_F(DumpMemoryTest, memory_unreadable) {
-  dump_memory(&log_, memory_mock_.get(), 0xa2345678, "memory near pc:");
+  dump_memory(&log_, memory_mock_.get(), 0xa2345678, "memory near pc");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -309,7 +309,7 @@
   }
   memory_mock_->SetReadData(buffer, sizeof(buffer));
 
-  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc:");
+  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -329,7 +329,7 @@
   memory_mock_->SetReadData(buffer, sizeof(buffer));
   memory_mock_->SetPartialReadAmount(102);
 
-  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc:");
+  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -354,7 +354,7 @@
   memory_mock_->SetReadData(buffer, sizeof(buffer));
   memory_mock_->SetPartialReadAmount(45);
 
-  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc:");
+  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -380,7 +380,7 @@
   memset(buffer, 0, sizeof(buffer));
   memory_mock_->SetReadData(buffer, sizeof(buffer));
 
-  dump_memory(&log_, memory_mock_.get(), 0x1000, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0x1000, "memory near r1");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -434,7 +434,7 @@
   memset(buffer, 0, sizeof(buffer));
   memory_mock_->SetReadData(buffer, sizeof(buffer));
 
-  dump_memory(&log_, memory_mock_.get(), 0, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0, "memory near r1");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -452,13 +452,13 @@
   memory_mock_->SetReadData(buffer, sizeof(buffer));
 
 #if defined(__LP64__)
-  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL, "memory near %.2s:", "r1");
-  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 32, "memory near %.2s:", "r1");
-  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 216, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL, "memory near r1");
+  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 32, "memory near r1");
+  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 216, "memory near r1");
 #else
-  dump_memory(&log_, memory_mock_.get(), 0xffff0000, "memory near %.2s:", "r1");
-  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 32, "memory near %.2s:", "r1");
-  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 220, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0xffff0000, "memory near r1");
+  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 32, "memory near r1");
+  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 220, "memory near r1");
 #endif
 
   std::string tombstone_contents;
@@ -477,9 +477,9 @@
   memory_mock_->SetReadData(buffer, sizeof(buffer));
 
 #if defined(__LP64__)
-  dump_memory(&log_, memory_mock_.get(), 0xfffffffffffffff0, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0xfffffffffffffff0, "memory near r1");
 #else
-  dump_memory(&log_, memory_mock_.get(), 0xfffffff0, "memory near %.2s:", "r1");
+  dump_memory(&log_, memory_mock_.get(), 0xfffffff0, "memory near r1");
 #endif
 
   std::string tombstone_contents;
@@ -500,9 +500,9 @@
   memory_mock_->SetReadData(buffer, sizeof(buffer));
 
 #if defined(__LP64__)
-  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 224, "memory near %.2s:", "r4");
+  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 224, "memory near r4");
 #else
-  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 224, "memory near %.2s:", "r4");
+  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 224, "memory near r4");
 #endif
 
   std::string tombstone_contents;
@@ -562,7 +562,7 @@
 
   size_t page_size = sysconf(_SC_PAGE_SIZE);
   uintptr_t addr = 0x10000020 + page_size - 120;
-  dump_memory(&log_, memory_mock_.get(), addr, "memory near %.2s:", "r4");
+  dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -621,7 +621,7 @@
 
   size_t page_size = sysconf(_SC_PAGE_SIZE);
   uintptr_t addr = 0x10000020 + page_size - 192;
-  dump_memory(&log_, memory_mock_.get(), addr, "memory near %.2s:", "r4");
+  dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -679,7 +679,7 @@
   memory_mock_->SetPartialReadAmount(0);
 
   uintptr_t addr = 0x10000020;
-  dump_memory(&log_, memory_mock_.get(), addr, "memory near %.2s:", "r4");
+  dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -739,7 +739,7 @@
   size_t page_size = sysconf(_SC_PAGE_SIZE);
   uintptr_t addr = 0x10000020 + page_size - 256;
 
-  dump_memory(&log_, memory_mock_.get(), addr, "memory near %.2s:", "r4");
+  dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");
 
   std::string tombstone_contents;
   ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 7d85602..140ef6d 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -65,6 +65,8 @@
 using unwindstack::Memory;
 using unwindstack::Regs;
 
+using namespace std::literals::string_literals;
+
 #define STACK_WORDS 16
 
 static void dump_header_info(log_t* log) {
@@ -148,8 +150,9 @@
 
     backtrace_map_t map;
     backtrace_map->FillIn(stack_data[i], &map);
-    if (BacktraceMap::IsValid(map) && !map.name.empty()) {
-      line += "  " + map.name;
+    std::string map_name{map.Name()};
+    if (BacktraceMap::IsValid(map) && !map_name.empty()) {
+      line += "  " + map_name;
       uint64_t offset = 0;
       std::string func_name = backtrace_map->GetFunctionName(stack_data[i], &offset);
       if (!func_name.empty()) {
@@ -382,9 +385,16 @@
   print_register_row(log, special_row);
 }
 
-void dump_memory_and_code(log_t* log, Memory* memory, Regs* regs) {
-  regs->IterateRegisters([log, memory](const char* name, uint64_t value) {
-    dump_memory(log, memory, value, "memory near %s:", name);
+void dump_memory_and_code(log_t* log, BacktraceMap* map, Memory* memory, Regs* regs) {
+  regs->IterateRegisters([log, map, memory](const char* reg_name, uint64_t reg_value) {
+    std::string label{"memory near "s + reg_name};
+    if (map) {
+      backtrace_map_t map_info;
+      map->FillIn(reg_value, &map_info);
+      std::string map_name{map_info.Name()};
+      if (!map_name.empty()) label += " (" + map_info.Name() + ")";
+    }
+    dump_memory(log, memory, reg_value, label);
   });
 }
 
@@ -423,7 +433,7 @@
   }
 
   if (primary_thread) {
-    dump_memory_and_code(log, process_memory, thread_info.registers.get());
+    dump_memory_and_code(log, map, process_memory, thread_info.registers.get());
     if (map) {
       uint64_t addr = 0;
       siginfo_t* si = thread_info.siginfo;
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index 3ac98f5..d153865 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -124,13 +124,7 @@
 #define MEMORY_BYTES_TO_DUMP 256
 #define MEMORY_BYTES_PER_LINE 16
 
-void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const char* fmt, ...) {
-  std::string log_msg;
-  va_list ap;
-  va_start(ap, fmt);
-  android::base::StringAppendV(&log_msg, fmt, ap);
-  va_end(ap);
-
+void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const std::string& label) {
   // Align the address to sizeof(long) and start 32 bytes before the address.
   addr &= ~(sizeof(long) - 1);
   if (addr >= 4128) {
@@ -147,7 +141,7 @@
     return;
   }
 
-  _LOG(log, logtype::MEMORY, "\n%s\n", log_msg.c_str());
+  _LOG(log, logtype::MEMORY, "\n%s:\n", label.c_str());
 
   // Dump 256 bytes
   uintptr_t data[MEMORY_BYTES_TO_DUMP/sizeof(uintptr_t)];
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp
index dec241c..6445a7c 100644
--- a/libbacktrace/Backtrace.cpp
+++ b/libbacktrace/Backtrace.cpp
@@ -85,14 +85,12 @@
 std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) {
   std::string map_name;
   if (BacktraceMap::IsValid(frame->map)) {
+    map_name = frame->map.Name();
     if (!frame->map.name.empty()) {
-      map_name = frame->map.name.c_str();
       if (map_name[0] == '[' && map_name[map_name.size() - 1] == ']') {
         map_name.resize(map_name.size() - 1);
         map_name += StringPrintf(":%" PRIPTR "]", frame->map.start);
       }
-    } else {
-      map_name = StringPrintf("<anonymous:%" PRIPTR ">", frame->map.start);
     }
   } else {
     map_name = "<unknown>";
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index c8a500c..bdae140 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -24,11 +24,21 @@
 
 #include <log/log.h>
 
-#include <backtrace/backtrace_constants.h>
+#include <android-base/stringprintf.h>
+#include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
+#include <backtrace/backtrace_constants.h>
 
 #include "thread_utils.h"
 
+using android::base::StringPrintf;
+
+std::string backtrace_map_t::Name() const {
+  if (!name.empty()) return name;
+  if (start == 0 && end == 0) return "";
+  return StringPrintf("<anonymous:%" PRIPTR ">", start);
+}
+
 BacktraceMap::BacktraceMap(pid_t pid) : pid_(pid) {
   if (pid_ < 0) {
     pid_ = getpid();
diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h
index e19c413..7b26079 100644
--- a/libbacktrace/include/backtrace/BacktraceMap.h
+++ b/libbacktrace/include/backtrace/BacktraceMap.h
@@ -48,6 +48,9 @@
   uint64_t load_bias = 0;
   int flags = 0;
   std::string name;
+
+  // Returns `name` if non-empty, or `<anonymous:0x...>` otherwise.
+  std::string Name() const;
 };
 
 namespace unwindstack {