Fix offsets when shared lib split across maps.

The linker was modified so that a shared library has a read-only
map, then a read-execute map to represent the whole shared library.
When backtraces are created, then the offsets are set incorrectly
for backtraces. For example, all backtraces wind up with an offset now,
and a shared library loaded out of an apk shows the wrong offset.

Changes:
- Fix the FormatFrame function which was putting the offset before the
  map name.
- Refactor the Maps and MapInfo classes to keep track of the previous map
  instead of all maps. This was the only map that was ever needed.
- Modify the unwind_for_offline tool to capture both the read-only and
  read-execute map when using the read-only segment option.

Bug: 120981155

Test: Updated unit tests pass.
Test: Unwinds on device don't show the offsets everywhere any more.
Change-Id: I75b3727221be9c20316dfdcd7a1c6d242d7ce948
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index c4b8763..1fdeee5 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -42,84 +42,64 @@
 
 namespace unwindstack {
 
-class MapsFake : public Maps {
- public:
-  MapsFake() = default;
-  virtual ~MapsFake() = default;
-
-  bool Parse() { return true; }
-
-  void FakeClear() { maps_.clear(); }
-
-  void FakeAddMapInfo(MapInfo* map_info) { maps_.push_back(map_info); }
-};
-
 class UnwinderTest : public ::testing::Test {
  protected:
+  static void AddMapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
+                         const char* name, Elf* elf = nullptr) {
+    std::string str_name(name);
+    maps_->Add(start, end, offset, flags, name, static_cast<uint64_t>(-1));
+    if (elf != nullptr) {
+      MapInfo* map_info = *--maps_->end();
+      map_info->elf.reset(elf);
+    }
+  }
+
   static void SetUpTestCase() {
-    maps_.FakeClear();
-    MapInfo* info =
-        new MapInfo(&maps_, 0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so");
+    maps_.reset(new Maps);
+
     ElfFake* elf = new ElfFake(new MemoryFake);
-    info->elf.reset(elf);
     elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
 
-    info = new MapInfo(&maps_, 0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
 
-    info = new MapInfo(&maps_, 0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
-                       "/dev/fake_device");
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
+               "/dev/fake_device");
 
-    info = new MapInfo(&maps_, 0x20000, 0x22000, 0, PROT_READ | PROT_WRITE,
-                       "/system/fake/libunwind.so");
     elf = new ElfFake(new MemoryFake);
-    info->elf.reset(elf);
     elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
 
-    info = new MapInfo(&maps_, 0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so");
     elf = new ElfFake(new MemoryFake);
-    info->elf.reset(elf);
     elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
 
-    info = new MapInfo(&maps_, 0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so");
     elf = new ElfFake(new MemoryFake);
-    info->elf.reset(elf);
     elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
 
-    info = new MapInfo(&maps_, 0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk");
     elf = new ElfFake(new MemoryFake);
-    info->elf.reset(elf);
     elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
 
-    info = new MapInfo(&maps_, 0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
 
-    info = new MapInfo(&maps_, 0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
-                       "/fake/fake.vdex");
+    AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
+    MapInfo* info = *--maps_->end();
     info->load_bias = 0;
-    maps_.FakeAddMapInfo(info);
 
-    info = new MapInfo(&maps_, 0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
-                       "/fake/fake_load_bias.so");
     elf = new ElfFake(new MemoryFake);
-    info->elf.reset(elf);
     elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
     elf->FakeSetLoadBias(0x5000);
-    maps_.FakeAddMapInfo(info);
+    AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
+               elf);
 
-    info = new MapInfo(&maps_, 0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
-                       "/fake/fake_offset.oat");
     elf = new ElfFake(new MemoryFake);
-    info->elf.reset(elf);
     elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
+    AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_offset.oat",
+               elf);
+    info = *--maps_->end();
     info->elf_offset = 0x8000;
-    maps_.FakeAddMapInfo(info);
 
     process_memory_.reset(new MemoryFake);
   }
@@ -130,12 +110,12 @@
     regs_.FakeSetReturnAddressValid(false);
   }
 
-  static MapsFake maps_;
+  static std::unique_ptr<Maps> maps_;
   static RegsFake regs_;
   static std::shared_ptr<Memory> process_memory_;
 };
 
-MapsFake UnwinderTest::maps_;
+std::unique_ptr<Maps> UnwinderTest::maps_;
 RegsFake UnwinderTest::regs_(5);
 std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
 
@@ -150,7 +130,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -164,7 +144,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -178,7 +159,8 @@
   EXPECT_EQ("Frame1", frame->function_name);
   EXPECT_EQ(1U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -192,7 +174,8 @@
   EXPECT_EQ("Frame2", frame->function_name);
   EXPECT_EQ(2U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -210,7 +193,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.SetResolveNames(false);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
@@ -225,7 +208,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -239,7 +223,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -253,7 +238,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -267,7 +253,7 @@
   regs_.set_sp(0x10000);
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -281,7 +267,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0xa5000U, frame->map_start);
   EXPECT_EQ(0xa6000U, frame->map_end);
   EXPECT_EQ(0x5000U, frame->map_load_bias);
@@ -295,7 +282,7 @@
   regs_.set_sp(0x10000);
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -309,7 +296,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0xa7000U, frame->map_start);
   EXPECT_EQ(0xa8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -323,7 +311,7 @@
   regs_.set_sp(0x10000);
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -337,7 +325,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/fake/fake.apk", frame->map_name);
-  EXPECT_EQ(0x1d000U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0x1d000U, frame->map_exact_offset);
   EXPECT_EQ(0x43000U, frame->map_start);
   EXPECT_EQ(0x44000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -358,7 +347,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
   ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -372,7 +361,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -389,7 +379,7 @@
   regs_.set_pc(0x1000);
   regs_.set_sp(0x10000);
 
-  Unwinder unwinder(20, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
 
@@ -404,7 +394,8 @@
     EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
     EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
     EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
-    EXPECT_EQ(0U, frame->map_offset) << "Failed at frame " << i;
+    EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
+    EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
     EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
     EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
     EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
@@ -429,7 +420,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
   unwinder.Unwind(&skip_libs);
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
@@ -444,7 +435,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -458,7 +450,8 @@
   EXPECT_EQ("Frame1", frame->function_name);
   EXPECT_EQ(1U, frame->function_offset);
   EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x20000U, frame->map_start);
   EXPECT_EQ(0x22000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -472,7 +465,7 @@
   EXPECT_EQ("Frame2", frame->function_name);
   EXPECT_EQ(2U, frame->function_offset);
   EXPECT_EQ("/fake/libanother.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x23000U, frame->map_start);
   EXPECT_EQ(0x24000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -489,7 +482,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -503,7 +496,7 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -517,7 +510,7 @@
   EXPECT_EQ("Frame1", frame->function_name);
   EXPECT_EQ(1U, frame->function_offset);
   EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x20000U, frame->map_start);
   EXPECT_EQ(0x22000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -536,7 +529,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -555,7 +548,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -569,7 +562,7 @@
   regs_.set_pc(0x41000);
   regs_.set_sp(0x13000);
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
 
@@ -583,7 +576,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0U, frame->map_start);
   EXPECT_EQ(0U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -604,7 +598,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -618,7 +612,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0U, frame->map_start);
   EXPECT_EQ(0U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -632,7 +627,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -646,7 +642,8 @@
   EXPECT_EQ("Frame1", frame->function_name);
   EXPECT_EQ(1U, frame->function_offset);
   EXPECT_EQ("/fake/libanother.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x23000U, frame->map_start);
   EXPECT_EQ(0x24000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -666,7 +663,7 @@
   regs_.FakeSetReturnAddress(0x12);
   regs_.FakeSetReturnAddressValid(true);
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
 
@@ -680,7 +677,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x20000U, frame->map_start);
   EXPECT_EQ(0x22000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -694,7 +692,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0U, frame->map_start);
   EXPECT_EQ(0U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -713,7 +712,7 @@
   regs_.FakeSetReturnAddress(0x1202);
   regs_.FakeSetReturnAddressValid(true);
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -727,7 +726,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0U, frame->map_start);
   EXPECT_EQ(0U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -741,7 +741,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -762,14 +763,14 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   std::vector<std::string> suffixes{"oat"};
   unwinder.Unwind(nullptr, &suffixes);
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
   // Make sure the elf was not initialized.
-  MapInfo* map_info = maps_.Find(0x53000);
+  MapInfo* map_info = maps_->Find(0x53000);
   ASSERT_TRUE(map_info != nullptr);
   EXPECT_TRUE(map_info->elf == nullptr);
 
@@ -781,7 +782,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -795,7 +797,8 @@
   EXPECT_EQ("Frame1", frame->function_name);
   EXPECT_EQ(1U, frame->function_offset);
   EXPECT_EQ("/fake/fake.apk", frame->map_name);
-  EXPECT_EQ(0x1d000U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0x1d000U, frame->map_exact_offset);
   EXPECT_EQ(0x43000U, frame->map_start);
   EXPECT_EQ(0x44000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -819,7 +822,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
 
@@ -833,7 +836,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -847,7 +851,8 @@
   EXPECT_EQ("Frame1", frame->function_name);
   EXPECT_EQ(1U, frame->function_offset);
   EXPECT_EQ("/fake/compressed.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x33000U, frame->map_start);
   EXPECT_EQ(0x34000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -861,7 +866,8 @@
   EXPECT_EQ("Frame2", frame->function_name);
   EXPECT_EQ(2U, frame->function_offset);
   EXPECT_EQ("/fake/compressed.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x33000U, frame->map_start);
   EXPECT_EQ(0x34000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -874,7 +880,7 @@
   regs_.set_sp(0x10000);
   regs_.FakeSetDexPc(0xa3400);
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -888,7 +894,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/fake/fake.vdex", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0xa3000U, frame->map_start);
   EXPECT_EQ(0xa4000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -902,7 +909,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -915,7 +923,7 @@
   regs_.set_sp(0x10000);
   regs_.FakeSetDexPc(0x50000);
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -929,7 +937,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0U, frame->map_start);
   EXPECT_EQ(0U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -943,7 +952,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -959,7 +969,7 @@
   ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
 
-  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
 
@@ -973,7 +983,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/fake/fake.vdex", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0xa3000U, frame->map_start);
   EXPECT_EQ(0xa4000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -987,7 +998,8 @@
   EXPECT_EQ("Frame0", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/system/fake/libc.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x1000U, frame->map_start);
   EXPECT_EQ(0x8000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -1001,7 +1013,8 @@
   EXPECT_EQ("Frame1", frame->function_name);
   EXPECT_EQ(1U, frame->function_offset);
   EXPECT_EQ("/fake/compressed.so", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0x33000U, frame->map_start);
   EXPECT_EQ(0x34000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -1014,7 +1027,7 @@
   regs_.set_sp(0x10000);
   regs_.FakeSetDexPc(0xa3400);
 
-  Unwinder unwinder(1, &maps_, &regs_, process_memory_);
+  Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
 
@@ -1028,7 +1041,8 @@
   EXPECT_EQ("", frame->function_name);
   EXPECT_EQ(0U, frame->function_offset);
   EXPECT_EQ("/fake/fake.vdex", frame->map_name);
-  EXPECT_EQ(0U, frame->map_offset);
+  EXPECT_EQ(0U, frame->map_elf_start_offset);
+  EXPECT_EQ(0U, frame->map_exact_offset);
   EXPECT_EQ(0xa3000U, frame->map_start);
   EXPECT_EQ(0xa4000U, frame->map_end);
   EXPECT_EQ(0U, frame->map_load_bias);
@@ -1045,17 +1059,17 @@
   frame.function_name = "function";
   frame.function_offset = 100;
   frame.map_name = "/fake/libfake.so";
-  frame.map_offset = 0x2000;
+  frame.map_elf_start_offset = 0x2000;
   frame.map_start = 0x3000;
   frame.map_end = 0x6000;
   frame.map_flags = PROT_READ;
 
-  EXPECT_EQ("  #01 pc 0000000000001000 (offset 0x2000)  /fake/libfake.so (function+100)",
+  EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so (offset 0x2000) (function+100)",
             Unwinder::FormatFrame(frame, false));
-  EXPECT_EQ("  #01 pc 00001000 (offset 0x2000)  /fake/libfake.so (function+100)",
+  EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (offset 0x2000) (function+100)",
             Unwinder::FormatFrame(frame, true));
 
-  frame.map_offset = 0;
+  frame.map_elf_start_offset = 0;
   EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so (function+100)",
             Unwinder::FormatFrame(frame, false));
   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (function+100)",
@@ -1130,7 +1144,7 @@
   for (auto regs : reg_list) {
     ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
 
-    Unwinder unwinder(64, &maps_, regs, process_memory_);
+    Unwinder unwinder(64, maps_.get(), regs, process_memory_);
     unwinder.Unwind();
 
     ASSERT_EQ(1U, unwinder.NumFrames());