Loading libunwindstack/ElfInterface.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading libunwindstack/ElfInterfaceArm.cpp +9 −7 Original line number Diff line number Diff line Loading @@ -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; } Loading libunwindstack/ElfInterfaceArm.h +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading libunwindstack/include/unwindstack/ElfInterface.h +1 −1 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ class ElfInterface { 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); Loading libunwindstack/tests/ElfInterfaceArmTest.cpp +20 −35 Original line number Diff line number Diff line Loading @@ -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<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) { Loading Loading
libunwindstack/ElfInterface.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading
libunwindstack/ElfInterfaceArm.cpp +9 −7 Original line number Diff line number Diff line Loading @@ -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; } Loading
libunwindstack/ElfInterfaceArm.h +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
libunwindstack/include/unwindstack/ElfInterface.h +1 −1 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ class ElfInterface { 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); Loading
libunwindstack/tests/ElfInterfaceArmTest.cpp +20 −35 Original line number Diff line number Diff line Loading @@ -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<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) { Loading