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/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;
}