diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp index 954a82104..915cddb08 100644 --- a/libunwindstack/ElfInterface.cpp +++ b/libunwindstack/ElfInterface.cpp @@ -211,7 +211,7 @@ bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr, uint64_t* load_bias) 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 9b61599ce..a3244e824 100644 --- a/libunwindstack/ElfInterfaceArm.cpp +++ b/libunwindstack/ElfInterfaceArm.cpp @@ -87,20 +87,22 @@ bool ElfInterfaceArm::GetPrel31Addr(uint32_t offset, uint32_t* addr) { #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 18efb6cc4..3bee9cff1 100644 --- a/libunwindstack/ElfInterfaceArm.h +++ b/libunwindstack/ElfInterfaceArm.h @@ -70,7 +70,7 @@ class ElfInterfaceArm : public ElfInterface32 { 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 4d25c4027..0c588da7d 100644 --- a/libunwindstack/include/unwindstack/ElfInterface.h +++ b/libunwindstack/include/unwindstack/ElfInterface.h @@ -118,7 +118,7 @@ class ElfInterface { template 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 static void GetMaxSizeWithTemplate(Memory* memory, uint64_t* size); diff --git a/libunwindstack/tests/ElfInterfaceArmTest.cpp b/libunwindstack/tests/ElfInterfaceArmTest.cpp index 5f1c2ac64..a8bb4aaf4 100644 --- a/libunwindstack/tests/ElfInterfaceArmTest.cpp +++ b/libunwindstack/tests/ElfInterfaceArmTest.cpp @@ -245,56 +245,41 @@ TEST_F(ElfInterfaceArmTest, iterate) { 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(&phdr.p_vaddr) - reinterpret_cast(&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(&phdr.p_memsz) - reinterpret_cast(&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 4008e9ba6..487d39c87 100644 --- a/libunwindstack/tests/ElfInterfaceTest.cpp +++ b/libunwindstack/tests/ElfInterfaceTest.cpp @@ -116,8 +116,7 @@ class ElfInterfaceTest : public ::testing::Test { template 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 @@ template void ElfInterfaceTest::SinglePtLoad() { std::unique_ptr 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 @@ template void ElfInterfaceTest::MultipleExecutablePtLoads() { std::unique_ptr 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 @@ template void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() { std::unique_ptr 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 @@ template void ElfInterfaceTest::NonExecutablePtLoads() { std::unique_ptr 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 @@ template void ElfInterfaceTest::ManyPhdrs() { std::unique_ptr 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, elf64_many_phdrs) { 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 @@ TEST_F(ElfInterfaceTest, elf32_arm) { template 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 @@ void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) { 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 @@ void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) { 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 @@ template void ElfInterfaceTest::InitSectionHeadersMalformed() { std::unique_ptr 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 @@ void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) { 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 @@ void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) { 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 @@ void ElfInterfaceTest::InitSectionHeadersOffsets() { 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 @@ void ElfInterfaceTest::InitSectionHeadersOffsets() { 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, init_section_headers_offsets64) { TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) { std::unique_ptr 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) { TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) { std::unique_ptr 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 @@ TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) { 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 @@ TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) { 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));