Fix ARM program header values used for exidx.

Before, I was using p_vaddr to get the offset into the elf file where
the exidx frame starts. I changed that to use p_offset since this already
has the load bias offset in it and some elf files do not set p_vaddr
properly.

Also, use p_filesz instead of p_memsz, since again, some elf files do
not set p_memsz to the same as p_filesz.

Bug: 110704153

Test: All libbacktrace/libunwindstack unit tests pass.
Test: Randomly unwind process on a walleye.
Test: Verified that this properly dumps and unwinds the shared
Test: library that sets p_vaddr and p_memsz differently.
Change-Id: Ic7b1e5d07439f4636fa02cd884a8727a5737372b
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 954a821..915cddb 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -211,7 +211,7 @@
       return false;
     }
 
-    if (HandleType(offset, phdr.p_type, *load_bias)) {
+    if (HandleType(offset, phdr.p_type)) {
       continue;
     }
 
diff --git a/libunwindstack/ElfInterfaceArm.cpp b/libunwindstack/ElfInterfaceArm.cpp
index 9b61599..a3244e8 100644
--- a/libunwindstack/ElfInterfaceArm.cpp
+++ b/libunwindstack/ElfInterfaceArm.cpp
@@ -87,20 +87,22 @@
 #define PT_ARM_EXIDX 0x70000001
 #endif
 
-bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type, uint64_t load_bias) {
+bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) {
   if (type != PT_ARM_EXIDX) {
     return false;
   }
 
   Elf32_Phdr phdr;
-  if (!memory_->ReadField(offset, &phdr, &phdr.p_vaddr, sizeof(phdr.p_vaddr))) {
+  if (!memory_->ReadFully(offset, &phdr, sizeof(phdr))) {
     return true;
   }
-  if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) {
-    return true;
-  }
-  start_offset_ = phdr.p_vaddr - load_bias;
-  total_entries_ = phdr.p_memsz / 8;
+
+  // The offset already takes into account the load bias.
+  start_offset_ = phdr.p_offset;
+
+  // Always use filesz instead of memsz. In most cases they are the same,
+  // but some shared libraries wind up setting one correctly and not the other.
+  total_entries_ = phdr.p_filesz / 8;
   return true;
 }
 
diff --git a/libunwindstack/ElfInterfaceArm.h b/libunwindstack/ElfInterfaceArm.h
index 18efb6c..3bee9cf 100644
--- a/libunwindstack/ElfInterfaceArm.h
+++ b/libunwindstack/ElfInterfaceArm.h
@@ -70,7 +70,7 @@
 
   bool FindEntry(uint32_t pc, uint64_t* entry_offset);
 
-  bool HandleType(uint64_t offset, uint32_t type, uint64_t load_bias) override;
+  bool HandleType(uint64_t offset, uint32_t type) override;
 
   bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) override;
 
diff --git a/libunwindstack/include/unwindstack/ElfInterface.h b/libunwindstack/include/unwindstack/ElfInterface.h
index 4d25c40..0c588da 100644
--- a/libunwindstack/include/unwindstack/ElfInterface.h
+++ b/libunwindstack/include/unwindstack/ElfInterface.h
@@ -118,7 +118,7 @@
   template <typename SymType>
   bool GetGlobalVariableWithTemplate(const std::string& name, uint64_t* memory_address);
 
-  virtual bool HandleType(uint64_t, uint32_t, uint64_t) { return false; }
+  virtual bool HandleType(uint64_t, uint32_t) { return false; }
 
   template <typename EhdrType>
   static void GetMaxSizeWithTemplate(Memory* memory, uint64_t* size);
diff --git a/libunwindstack/tests/ElfInterfaceArmTest.cpp b/libunwindstack/tests/ElfInterfaceArmTest.cpp
index 5f1c2ac..a8bb4aa 100644
--- a/libunwindstack/tests/ElfInterfaceArmTest.cpp
+++ b/libunwindstack/tests/ElfInterfaceArmTest.cpp
@@ -245,56 +245,41 @@
 TEST_F(ElfInterfaceArmTest, HandleType_not_arm_exidx) {
   ElfInterfaceArmFake interface(&memory_);
 
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_NULL, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_LOAD, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_DYNAMIC, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_INTERP, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_NOTE, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_SHLIB, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_PHDR, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_TLS, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_LOOS, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_HIOS, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_LOPROC, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_HIPROC, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_GNU_EH_FRAME, 0));
-  ASSERT_FALSE(interface.HandleType(0x1000, PT_GNU_STACK, 0));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_NULL));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_LOAD));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_DYNAMIC));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_INTERP));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_NOTE));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_SHLIB));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_PHDR));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_TLS));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_LOOS));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_HIOS));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_LOPROC));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_HIPROC));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_GNU_EH_FRAME));
+  ASSERT_FALSE(interface.HandleType(0x1000, PT_GNU_STACK));
 }
 
 TEST_F(ElfInterfaceArmTest, HandleType_arm_exidx) {
   ElfInterfaceArmFake interface(&memory_);
 
-  Elf32_Phdr phdr;
+  Elf32_Phdr phdr = {};
   interface.FakeSetStartOffset(0x1000);
   interface.FakeSetTotalEntries(100);
-  phdr.p_vaddr = 0x2000;
-  phdr.p_memsz = 0xa00;
+  phdr.p_offset = 0x2000;
+  phdr.p_filesz = 0xa00;
 
   // Verify that if reads fail, we don't set the values but still get true.
-  ASSERT_TRUE(interface.HandleType(0x1000, 0x70000001, 0));
-  ASSERT_EQ(0x1000U, interface.start_offset());
-  ASSERT_EQ(100U, interface.total_entries());
-
-  // Verify that if the second read fails, we still don't set the values.
-  memory_.SetData32(
-      0x1000 + reinterpret_cast<uint64_t>(&phdr.p_vaddr) - reinterpret_cast<uint64_t>(&phdr),
-      phdr.p_vaddr);
-  ASSERT_TRUE(interface.HandleType(0x1000, 0x70000001, 0));
+  ASSERT_TRUE(interface.HandleType(0x1000, 0x70000001));
   ASSERT_EQ(0x1000U, interface.start_offset());
   ASSERT_EQ(100U, interface.total_entries());
 
   // Everything is correct and present.
-  memory_.SetData32(
-      0x1000 + reinterpret_cast<uint64_t>(&phdr.p_memsz) - reinterpret_cast<uint64_t>(&phdr),
-      phdr.p_memsz);
-  ASSERT_TRUE(interface.HandleType(0x1000, 0x70000001, 0));
+  memory_.SetMemory(0x1000, &phdr, sizeof(phdr));
+  ASSERT_TRUE(interface.HandleType(0x1000, 0x70000001));
   ASSERT_EQ(0x2000U, interface.start_offset());
   ASSERT_EQ(320U, interface.total_entries());
-
-  // Non-zero load bias.
-  ASSERT_TRUE(interface.HandleType(0x1000, 0x70000001, 0x1000));
-  ASSERT_EQ(0x1000U, interface.start_offset());
-  ASSERT_EQ(320U, interface.total_entries());
 }
 
 TEST_F(ElfInterfaceArmTest, StepExidx) {
diff --git a/libunwindstack/tests/ElfInterfaceTest.cpp b/libunwindstack/tests/ElfInterfaceTest.cpp
index 4008e9b..487d39c 100644
--- a/libunwindstack/tests/ElfInterfaceTest.cpp
+++ b/libunwindstack/tests/ElfInterfaceTest.cpp
@@ -116,8 +116,7 @@
 template <typename Sym>
 void ElfInterfaceTest::InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
                                uint64_t sym_offset, const char* name) {
-  Sym sym;
-  memset(&sym, 0, sizeof(sym));
+  Sym sym = {};
   sym.st_info = STT_FUNC;
   sym.st_value = value;
   sym.st_size = size;
@@ -132,15 +131,13 @@
 void ElfInterfaceTest::SinglePtLoad() {
   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
 
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_phoff = 0x100;
   ehdr.e_phnum = 1;
   ehdr.e_phentsize = sizeof(Phdr);
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Phdr phdr;
-  memset(&phdr, 0, sizeof(phdr));
+  Phdr phdr = {};
   phdr.p_type = PT_LOAD;
   phdr.p_vaddr = 0x2000;
   phdr.p_memsz = 0x10000;
@@ -172,15 +169,13 @@
 void ElfInterfaceTest::MultipleExecutablePtLoads() {
   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
 
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_phoff = 0x100;
   ehdr.e_phnum = 3;
   ehdr.e_phentsize = sizeof(Phdr);
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Phdr phdr;
-  memset(&phdr, 0, sizeof(phdr));
+  Phdr phdr = {};
   phdr.p_type = PT_LOAD;
   phdr.p_vaddr = 0x2000;
   phdr.p_memsz = 0x10000;
@@ -241,15 +236,13 @@
 void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
 
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_phoff = 0x100;
   ehdr.e_phnum = 3;
   ehdr.e_phentsize = sizeof(Phdr) + 100;
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Phdr phdr;
-  memset(&phdr, 0, sizeof(phdr));
+  Phdr phdr = {};
   phdr.p_type = PT_LOAD;
   phdr.p_vaddr = 0x2000;
   phdr.p_memsz = 0x10000;
@@ -312,15 +305,13 @@
 void ElfInterfaceTest::NonExecutablePtLoads() {
   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
 
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_phoff = 0x100;
   ehdr.e_phnum = 3;
   ehdr.e_phentsize = sizeof(Phdr);
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Phdr phdr;
-  memset(&phdr, 0, sizeof(phdr));
+  Phdr phdr = {};
   phdr.p_type = PT_LOAD;
   phdr.p_vaddr = 0x2000;
   phdr.p_memsz = 0x10000;
@@ -371,17 +362,15 @@
 void ElfInterfaceTest::ManyPhdrs() {
   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
 
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_phoff = 0x100;
   ehdr.e_phnum = 7;
   ehdr.e_phentsize = sizeof(Phdr);
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Phdr phdr;
   uint64_t phdr_offset = 0x100;
 
-  memset(&phdr, 0, sizeof(phdr));
+  Phdr phdr = {};
   phdr.p_type = PT_LOAD;
   phdr.p_vaddr = 0x2000;
   phdr.p_memsz = 0x10000;
@@ -444,18 +433,16 @@
 TEST_F(ElfInterfaceTest, elf32_arm) {
   ElfInterfaceArm elf_arm(&memory_);
 
-  Elf32_Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Elf32_Ehdr ehdr = {};
   ehdr.e_phoff = 0x100;
   ehdr.e_phnum = 1;
   ehdr.e_phentsize = sizeof(Elf32_Phdr);
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Elf32_Phdr phdr;
-  memset(&phdr, 0, sizeof(phdr));
+  Elf32_Phdr phdr = {};
   phdr.p_type = PT_ARM_EXIDX;
-  phdr.p_vaddr = 0x2000;
-  phdr.p_memsz = 16;
+  phdr.p_offset = 0x2000;
+  phdr.p_filesz = 16;
   memory_.SetMemory(0x100, &phdr, sizeof(phdr));
 
   // Add arm exidx entries.
@@ -480,8 +467,7 @@
 
 template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
 void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) {
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_shoff = 0x200;
   ehdr.e_shnum = 2;
   ehdr.e_shentsize = sizeof(Shdr);
@@ -490,8 +476,7 @@
   ehdr.e_phentsize = sizeof(Phdr);
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Shdr shdr;
-  memset(&shdr, 0, sizeof(shdr));
+  Shdr shdr = {};
   shdr.sh_type = SHT_STRTAB;
   if (test_type == SONAME_MISSING_MAP) {
     shdr.sh_addr = 0x20100;
@@ -501,8 +486,7 @@
   shdr.sh_offset = 0x10000;
   memory_.SetMemory(0x200 + sizeof(shdr), &shdr, sizeof(shdr));
 
-  Phdr phdr;
-  memset(&phdr, 0, sizeof(phdr));
+  Phdr phdr = {};
   phdr.p_type = PT_DYNAMIC;
   phdr.p_offset = 0x2000;
   phdr.p_memsz = sizeof(Dyn) * 3;
@@ -748,8 +732,7 @@
 void ElfInterfaceTest::InitSectionHeadersMalformed() {
   std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
 
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_shoff = 0x1000;
   ehdr.e_shnum = 10;
   ehdr.e_shentsize = sizeof(Shdr);
@@ -774,8 +757,7 @@
 
   uint64_t offset = 0x1000;
 
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_shoff = offset;
   ehdr.e_shnum = 10;
   ehdr.e_shentsize = entry_size;
@@ -783,8 +765,7 @@
 
   offset += ehdr.e_shentsize;
 
-  Shdr shdr;
-  memset(&shdr, 0, sizeof(shdr));
+  Shdr shdr = {};
   shdr.sh_type = SHT_SYMTAB;
   shdr.sh_link = 4;
   shdr.sh_addr = 0x5000;
@@ -863,8 +844,7 @@
 
   uint64_t offset = 0x2000;
 
-  Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Ehdr ehdr = {};
   ehdr.e_shoff = offset;
   ehdr.e_shnum = 10;
   ehdr.e_shentsize = sizeof(Shdr);
@@ -873,8 +853,7 @@
 
   offset += ehdr.e_shentsize;
 
-  Shdr shdr;
-  memset(&shdr, 0, sizeof(shdr));
+  Shdr shdr = {};
   shdr.sh_type = SHT_PROGBITS;
   shdr.sh_link = 2;
   shdr.sh_name = 0x200;
@@ -956,15 +935,13 @@
 TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
   std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
 
-  Elf32_Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Elf32_Ehdr ehdr = {};
   ehdr.e_phoff = 0x100;
   ehdr.e_phnum = 1;
   ehdr.e_phentsize = sizeof(Elf32_Phdr);
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Elf32_Phdr phdr;
-  memset(&phdr, 0, sizeof(phdr));
+  Elf32_Phdr phdr = {};
   phdr.p_type = PT_LOAD;
   phdr.p_vaddr = 0;
   phdr.p_memsz = 0x10000;
@@ -984,15 +961,13 @@
 TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
   std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
 
-  Elf32_Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Elf32_Ehdr ehdr = {};
   ehdr.e_phoff = 0x100;
   ehdr.e_phnum = 1;
   ehdr.e_phentsize = sizeof(Elf32_Phdr);
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Elf32_Phdr phdr;
-  memset(&phdr, 0, sizeof(phdr));
+  Elf32_Phdr phdr = {};
   phdr.p_type = PT_LOAD;
   phdr.p_vaddr = 0x2000;
   phdr.p_memsz = 0x10000;
@@ -1017,16 +992,14 @@
 
   uint64_t sh_offset = 0x100;
 
-  Elf32_Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Elf32_Ehdr ehdr = {};
   ehdr.e_shstrndx = 1;
   ehdr.e_shoff = sh_offset;
   ehdr.e_shentsize = sizeof(Elf32_Shdr);
   ehdr.e_shnum = 3;
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Elf32_Shdr shdr;
-  memset(&shdr, 0, sizeof(shdr));
+  Elf32_Shdr shdr = {};
   shdr.sh_type = SHT_NULL;
   memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
 
@@ -1080,16 +1053,14 @@
 
   uint64_t sh_offset = 0x100;
 
-  Elf32_Ehdr ehdr;
-  memset(&ehdr, 0, sizeof(ehdr));
+  Elf32_Ehdr ehdr = {};
   ehdr.e_shstrndx = 1;
   ehdr.e_shoff = sh_offset;
   ehdr.e_shentsize = sizeof(Elf32_Shdr);
   ehdr.e_shnum = 3;
   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
 
-  Elf32_Shdr shdr;
-  memset(&shdr, 0, sizeof(shdr));
+  Elf32_Shdr shdr = {};
   shdr.sh_type = SHT_NULL;
   memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));