Loading libunwindstack/Elf.cpp +30 −19 Original line number Diff line number Diff line Loading @@ -35,7 +35,8 @@ namespace unwindstack { bool Elf::Init() { bool Elf::Init(bool init_gnu_debugdata) { load_bias_ = 0; if (!memory_) { return false; } Loading @@ -45,9 +46,14 @@ bool Elf::Init() { return false; } valid_ = interface_->Init(); valid_ = interface_->Init(&load_bias_); if (valid_) { interface_->InitHeaders(); if (init_gnu_debugdata) { InitGnuDebugdata(); } else { gnu_debugdata_interface_.reset(nullptr); } } else { interface_.reset(nullptr); } Loading @@ -67,7 +73,11 @@ void Elf::InitGnuDebugdata() { if (gnu == nullptr) { return; } if (gnu->Init()) { // Ignore the load_bias from the compressed section, the correct load bias // is in the uncompressed data. uint64_t load_bias; if (gnu->Init(&load_bias)) { gnu->InitHeaders(); } else { // Free all of the memory associated with the gnu_debugdata section. Loading @@ -81,38 +91,39 @@ bool Elf::GetSoname(std::string* name) { } uint64_t Elf::GetRelPc(uint64_t pc, const MapInfo* map_info) { uint64_t load_bias = 0; if (valid()) { load_bias = interface_->load_bias(); } return pc - map_info->start + load_bias + map_info->elf_offset; return pc - map_info->start + load_bias_ + map_info->elf_offset; } bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) { return valid_ && (interface_->GetFunctionName(addr, name, func_offset) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->GetFunctionName(addr, name, func_offset))); return valid_ && (interface_->GetFunctionName(addr, load_bias_, name, func_offset) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->GetFunctionName( addr, load_bias_, name, func_offset))); } bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished) { // The relative pc is always relative to the start of the map from which it comes. bool Elf::Step(uint64_t rel_pc, uint64_t elf_offset, Regs* regs, Memory* process_memory, bool* finished) { if (!valid_) { return false; } if (regs->StepIfSignalHandler(rel_pc, this, process_memory)) { // The relative pc expectd by StepIfSignalHandler is relative to the start of the elf. if (regs->StepIfSignalHandler(rel_pc + elf_offset, this, process_memory)) { *finished = false; return true; } // Adjust the load bias to get the real relative pc. if (rel_pc < load_bias_) { return false; } rel_pc -= load_bias_; return interface_->Step(rel_pc, regs, process_memory, finished) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->Step(rel_pc, regs, process_memory, finished)); } uint64_t Elf::GetLoadBias() { if (!valid_) return 0; return interface_->load_bias(); } bool Elf::IsValidElf(Memory* memory) { if (memory == nullptr) { return false; Loading libunwindstack/ElfInterface.cpp +13 −19 Original line number Diff line number Diff line Loading @@ -118,13 +118,13 @@ void ElfInterface::InitHeadersWithTemplate() { } template <typename EhdrType, typename PhdrType, typename ShdrType> bool ElfInterface::ReadAllHeaders() { bool ElfInterface::ReadAllHeaders(uint64_t* load_bias) { EhdrType ehdr; if (!memory_->Read(0, &ehdr, sizeof(ehdr))) { return false; } if (!ReadProgramHeaders<EhdrType, PhdrType>(ehdr)) { if (!ReadProgramHeaders<EhdrType, PhdrType>(ehdr, load_bias)) { return false; } Loading @@ -137,7 +137,7 @@ bool ElfInterface::ReadAllHeaders() { } template <typename EhdrType, typename PhdrType> bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) { bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr, uint64_t* load_bias) { uint64_t offset = ehdr.e_phoff; for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) { PhdrType phdr; Loading @@ -145,7 +145,7 @@ bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) { return false; } if (HandleType(offset, phdr.p_type)) { if (HandleType(offset, phdr.p_type, *load_bias)) { continue; } Loading @@ -172,7 +172,7 @@ bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) { pt_loads_[phdr.p_offset] = LoadInfo{phdr.p_offset, phdr.p_vaddr, static_cast<size_t>(phdr.p_memsz)}; if (phdr.p_offset == 0) { load_bias_ = phdr.p_vaddr; *load_bias = phdr.p_vaddr; } break; } Loading Loading @@ -334,14 +334,14 @@ bool ElfInterface::GetSonameWithTemplate(std::string* soname) { } template <typename SymType> bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, std::string* name, bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, uint64_t load_bias, std::string* name, uint64_t* func_offset) { if (symbols_.empty()) { return false; } for (const auto symbol : symbols_) { if (symbol->GetName<SymType>(addr, load_bias_, memory_, name, func_offset)) { if (symbol->GetName<SymType>(addr, load_bias, memory_, name, func_offset)) { return true; } } Loading @@ -349,12 +349,6 @@ bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, std::string* name, } bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { // Need to subtract off the load_bias to get the correct pc. if (pc < load_bias_) { return false; } pc -= load_bias_; // Try the eh_frame first. DwarfSection* eh_frame = eh_frame_.get(); if (eh_frame != nullptr && eh_frame->Step(pc, regs, process_memory, finished)) { Loading Loading @@ -389,11 +383,11 @@ void ElfInterface::GetMaxSizeWithTemplate(Memory* memory, uint64_t* size) { template void ElfInterface::InitHeadersWithTemplate<uint32_t>(); template void ElfInterface::InitHeadersWithTemplate<uint64_t>(); template bool ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(); template bool ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(); template bool ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(uint64_t*); template bool ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(uint64_t*); template bool ElfInterface::ReadProgramHeaders<Elf32_Ehdr, Elf32_Phdr>(const Elf32_Ehdr&); template bool ElfInterface::ReadProgramHeaders<Elf64_Ehdr, Elf64_Phdr>(const Elf64_Ehdr&); template bool ElfInterface::ReadProgramHeaders<Elf32_Ehdr, Elf32_Phdr>(const Elf32_Ehdr&, uint64_t*); template bool ElfInterface::ReadProgramHeaders<Elf64_Ehdr, Elf64_Phdr>(const Elf64_Ehdr&, uint64_t*); template bool ElfInterface::ReadSectionHeaders<Elf32_Ehdr, Elf32_Shdr>(const Elf32_Ehdr&); template bool ElfInterface::ReadSectionHeaders<Elf64_Ehdr, Elf64_Shdr>(const Elf64_Ehdr&); Loading @@ -401,9 +395,9 @@ template bool ElfInterface::ReadSectionHeaders<Elf64_Ehdr, Elf64_Shdr>(const Elf template bool ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(std::string*); template bool ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(std::string*); template bool ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(uint64_t, std::string*, template bool ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(uint64_t, uint64_t, std::string*, uint64_t*); template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, std::string*, template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, uint64_t, std::string*, uint64_t*); template void ElfInterface::GetMaxSizeWithTemplate<Elf32_Ehdr>(Memory*, uint64_t*); Loading libunwindstack/ElfInterfaceArm.cpp +2 −9 Original line number Diff line number Diff line Loading @@ -31,12 +31,6 @@ bool ElfInterfaceArm::FindEntry(uint32_t pc, uint64_t* entry_offset) { return false; } // Need to subtract the load_bias from the pc. if (pc < load_bias_) { return false; } pc -= load_bias_; size_t first = 0; size_t last = total_entries_; while (first < last) { Loading Loading @@ -81,7 +75,7 @@ bool ElfInterfaceArm::GetPrel31Addr(uint32_t offset, uint32_t* addr) { #define PT_ARM_EXIDX 0x70000001 #endif bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) { bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type, uint64_t load_bias) { if (type != PT_ARM_EXIDX) { return false; } Loading @@ -93,8 +87,7 @@ bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) { if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) { return true; } // The load_bias_ should always be set by this time. start_offset_ = phdr.p_vaddr - load_bias_; start_offset_ = phdr.p_vaddr - load_bias; total_entries_ = phdr.p_memsz / 8; return true; } Loading libunwindstack/ElfInterfaceArm.h +2 −6 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ class ElfInterfaceArm : public ElfInterface32 { bool FindEntry(uint32_t pc, uint64_t* entry_offset); bool HandleType(uint64_t offset, uint32_t type) override; bool HandleType(uint64_t offset, uint32_t type, uint64_t load_bias) override; bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) override; Loading @@ -76,13 +76,9 @@ class ElfInterfaceArm : public ElfInterface32 { uint64_t start_offset() { return start_offset_; } void set_start_offset(uint64_t start_offset) { start_offset_ = start_offset; } size_t total_entries() { return total_entries_; } void set_total_entries(size_t total_entries) { total_entries_ = total_entries; } private: protected: uint64_t start_offset_ = 0; size_t total_entries_ = 0; Loading libunwindstack/MapInfo.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -110,9 +110,8 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gn } elf = new Elf(CreateMemory(process_memory)); if (elf->Init() && init_gnu_debugdata) { elf->InitGnuDebugdata(); } elf->Init(init_gnu_debugdata); // If the init fails, keep the elf around as an invalid object so we // don't try to reinit the object. return elf; Loading Loading
libunwindstack/Elf.cpp +30 −19 Original line number Diff line number Diff line Loading @@ -35,7 +35,8 @@ namespace unwindstack { bool Elf::Init() { bool Elf::Init(bool init_gnu_debugdata) { load_bias_ = 0; if (!memory_) { return false; } Loading @@ -45,9 +46,14 @@ bool Elf::Init() { return false; } valid_ = interface_->Init(); valid_ = interface_->Init(&load_bias_); if (valid_) { interface_->InitHeaders(); if (init_gnu_debugdata) { InitGnuDebugdata(); } else { gnu_debugdata_interface_.reset(nullptr); } } else { interface_.reset(nullptr); } Loading @@ -67,7 +73,11 @@ void Elf::InitGnuDebugdata() { if (gnu == nullptr) { return; } if (gnu->Init()) { // Ignore the load_bias from the compressed section, the correct load bias // is in the uncompressed data. uint64_t load_bias; if (gnu->Init(&load_bias)) { gnu->InitHeaders(); } else { // Free all of the memory associated with the gnu_debugdata section. Loading @@ -81,38 +91,39 @@ bool Elf::GetSoname(std::string* name) { } uint64_t Elf::GetRelPc(uint64_t pc, const MapInfo* map_info) { uint64_t load_bias = 0; if (valid()) { load_bias = interface_->load_bias(); } return pc - map_info->start + load_bias + map_info->elf_offset; return pc - map_info->start + load_bias_ + map_info->elf_offset; } bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) { return valid_ && (interface_->GetFunctionName(addr, name, func_offset) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->GetFunctionName(addr, name, func_offset))); return valid_ && (interface_->GetFunctionName(addr, load_bias_, name, func_offset) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->GetFunctionName( addr, load_bias_, name, func_offset))); } bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished) { // The relative pc is always relative to the start of the map from which it comes. bool Elf::Step(uint64_t rel_pc, uint64_t elf_offset, Regs* regs, Memory* process_memory, bool* finished) { if (!valid_) { return false; } if (regs->StepIfSignalHandler(rel_pc, this, process_memory)) { // The relative pc expectd by StepIfSignalHandler is relative to the start of the elf. if (regs->StepIfSignalHandler(rel_pc + elf_offset, this, process_memory)) { *finished = false; return true; } // Adjust the load bias to get the real relative pc. if (rel_pc < load_bias_) { return false; } rel_pc -= load_bias_; return interface_->Step(rel_pc, regs, process_memory, finished) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->Step(rel_pc, regs, process_memory, finished)); } uint64_t Elf::GetLoadBias() { if (!valid_) return 0; return interface_->load_bias(); } bool Elf::IsValidElf(Memory* memory) { if (memory == nullptr) { return false; Loading
libunwindstack/ElfInterface.cpp +13 −19 Original line number Diff line number Diff line Loading @@ -118,13 +118,13 @@ void ElfInterface::InitHeadersWithTemplate() { } template <typename EhdrType, typename PhdrType, typename ShdrType> bool ElfInterface::ReadAllHeaders() { bool ElfInterface::ReadAllHeaders(uint64_t* load_bias) { EhdrType ehdr; if (!memory_->Read(0, &ehdr, sizeof(ehdr))) { return false; } if (!ReadProgramHeaders<EhdrType, PhdrType>(ehdr)) { if (!ReadProgramHeaders<EhdrType, PhdrType>(ehdr, load_bias)) { return false; } Loading @@ -137,7 +137,7 @@ bool ElfInterface::ReadAllHeaders() { } template <typename EhdrType, typename PhdrType> bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) { bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr, uint64_t* load_bias) { uint64_t offset = ehdr.e_phoff; for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) { PhdrType phdr; Loading @@ -145,7 +145,7 @@ bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) { return false; } if (HandleType(offset, phdr.p_type)) { if (HandleType(offset, phdr.p_type, *load_bias)) { continue; } Loading @@ -172,7 +172,7 @@ bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) { pt_loads_[phdr.p_offset] = LoadInfo{phdr.p_offset, phdr.p_vaddr, static_cast<size_t>(phdr.p_memsz)}; if (phdr.p_offset == 0) { load_bias_ = phdr.p_vaddr; *load_bias = phdr.p_vaddr; } break; } Loading Loading @@ -334,14 +334,14 @@ bool ElfInterface::GetSonameWithTemplate(std::string* soname) { } template <typename SymType> bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, std::string* name, bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, uint64_t load_bias, std::string* name, uint64_t* func_offset) { if (symbols_.empty()) { return false; } for (const auto symbol : symbols_) { if (symbol->GetName<SymType>(addr, load_bias_, memory_, name, func_offset)) { if (symbol->GetName<SymType>(addr, load_bias, memory_, name, func_offset)) { return true; } } Loading @@ -349,12 +349,6 @@ bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, std::string* name, } bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { // Need to subtract off the load_bias to get the correct pc. if (pc < load_bias_) { return false; } pc -= load_bias_; // Try the eh_frame first. DwarfSection* eh_frame = eh_frame_.get(); if (eh_frame != nullptr && eh_frame->Step(pc, regs, process_memory, finished)) { Loading Loading @@ -389,11 +383,11 @@ void ElfInterface::GetMaxSizeWithTemplate(Memory* memory, uint64_t* size) { template void ElfInterface::InitHeadersWithTemplate<uint32_t>(); template void ElfInterface::InitHeadersWithTemplate<uint64_t>(); template bool ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(); template bool ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(); template bool ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(uint64_t*); template bool ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(uint64_t*); template bool ElfInterface::ReadProgramHeaders<Elf32_Ehdr, Elf32_Phdr>(const Elf32_Ehdr&); template bool ElfInterface::ReadProgramHeaders<Elf64_Ehdr, Elf64_Phdr>(const Elf64_Ehdr&); template bool ElfInterface::ReadProgramHeaders<Elf32_Ehdr, Elf32_Phdr>(const Elf32_Ehdr&, uint64_t*); template bool ElfInterface::ReadProgramHeaders<Elf64_Ehdr, Elf64_Phdr>(const Elf64_Ehdr&, uint64_t*); template bool ElfInterface::ReadSectionHeaders<Elf32_Ehdr, Elf32_Shdr>(const Elf32_Ehdr&); template bool ElfInterface::ReadSectionHeaders<Elf64_Ehdr, Elf64_Shdr>(const Elf64_Ehdr&); Loading @@ -401,9 +395,9 @@ template bool ElfInterface::ReadSectionHeaders<Elf64_Ehdr, Elf64_Shdr>(const Elf template bool ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(std::string*); template bool ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(std::string*); template bool ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(uint64_t, std::string*, template bool ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(uint64_t, uint64_t, std::string*, uint64_t*); template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, std::string*, template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, uint64_t, std::string*, uint64_t*); template void ElfInterface::GetMaxSizeWithTemplate<Elf32_Ehdr>(Memory*, uint64_t*); Loading
libunwindstack/ElfInterfaceArm.cpp +2 −9 Original line number Diff line number Diff line Loading @@ -31,12 +31,6 @@ bool ElfInterfaceArm::FindEntry(uint32_t pc, uint64_t* entry_offset) { return false; } // Need to subtract the load_bias from the pc. if (pc < load_bias_) { return false; } pc -= load_bias_; size_t first = 0; size_t last = total_entries_; while (first < last) { Loading Loading @@ -81,7 +75,7 @@ bool ElfInterfaceArm::GetPrel31Addr(uint32_t offset, uint32_t* addr) { #define PT_ARM_EXIDX 0x70000001 #endif bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) { bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type, uint64_t load_bias) { if (type != PT_ARM_EXIDX) { return false; } Loading @@ -93,8 +87,7 @@ bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) { if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) { return true; } // The load_bias_ should always be set by this time. start_offset_ = phdr.p_vaddr - load_bias_; start_offset_ = phdr.p_vaddr - load_bias; total_entries_ = phdr.p_memsz / 8; return true; } Loading
libunwindstack/ElfInterfaceArm.h +2 −6 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ class ElfInterfaceArm : public ElfInterface32 { bool FindEntry(uint32_t pc, uint64_t* entry_offset); bool HandleType(uint64_t offset, uint32_t type) override; bool HandleType(uint64_t offset, uint32_t type, uint64_t load_bias) override; bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) override; Loading @@ -76,13 +76,9 @@ class ElfInterfaceArm : public ElfInterface32 { uint64_t start_offset() { return start_offset_; } void set_start_offset(uint64_t start_offset) { start_offset_ = start_offset; } size_t total_entries() { return total_entries_; } void set_total_entries(size_t total_entries) { total_entries_ = total_entries; } private: protected: uint64_t start_offset_ = 0; size_t total_entries_ = 0; Loading
libunwindstack/MapInfo.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -110,9 +110,8 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gn } elf = new Elf(CreateMemory(process_memory)); if (elf->Init() && init_gnu_debugdata) { elf->InitGnuDebugdata(); } elf->Init(init_gnu_debugdata); // If the init fails, keep the elf around as an invalid object so we // don't try to reinit the object. return elf; Loading