Loading libunwindstack/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ cc_test { data: [ "tests/files/elf32.xz", "tests/files/elf64.xz", "tests/files/offline/gnu_debugdata_arm32/*", "tests/files/offline/straddle_arm32/*", "tests/files/offline/straddle_arm64/*", ], Loading libunwindstack/Elf.cpp +2 −9 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ void Elf::InitGnuDebugdata() { uint64_t load_bias; if (gnu->Init(&load_bias)) { gnu->InitHeaders(); interface_->SetGnuDebugdataInterface(gnu); } else { // Free all of the memory associated with the gnu_debugdata section. gnu_debugdata_memory_.reset(nullptr); Loading Loading @@ -115,17 +116,9 @@ bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, R return true; } // Adjust the load bias to get the real relative pc. if (adjusted_rel_pc < load_bias_) { return false; } adjusted_rel_pc -= load_bias_; // Lock during the step which can update information in the object. std::lock_guard<std::mutex> guard(lock_); return interface_->Step(adjusted_rel_pc, regs, process_memory, finished) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->Step(adjusted_rel_pc, regs, process_memory, finished)); return interface_->Step(adjusted_rel_pc, load_bias_, regs, process_memory, finished); } bool Elf::IsValidElf(Memory* memory) { Loading libunwindstack/ElfInterface.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -386,16 +386,29 @@ bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, uint64_t load_bias return false; } bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { bool ElfInterface::Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished) { // Adjust the load bias to get the real relative pc. if (pc < load_bias) { return false; } uint64_t adjusted_pc = 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)) { if (eh_frame != nullptr && eh_frame->Step(adjusted_pc, regs, process_memory, finished)) { return true; } // Try the debug_frame next. DwarfSection* debug_frame = debug_frame_.get(); if (debug_frame != nullptr && debug_frame->Step(pc, regs, process_memory, finished)) { if (debug_frame != nullptr && debug_frame->Step(adjusted_pc, regs, process_memory, finished)) { return true; } // Finally try the gnu_debugdata interface, but always use a zero load bias. if (gnu_debugdata_interface_ != nullptr && gnu_debugdata_interface_->Step(pc, 0, regs, process_memory, finished)) { return true; } return false; Loading libunwindstack/ElfInterfaceArm.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -92,16 +92,24 @@ bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type, uint64_t load_b return true; } bool ElfInterfaceArm::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { bool ElfInterfaceArm::Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished) { // Dwarf unwind information is precise about whether a pc is covered or not, // but arm unwind information only has ranges of pc. In order to avoid // incorrectly doing a bad unwind using arm unwind information for a // different function, always try and unwind with the dwarf information first. return ElfInterface32::Step(pc, regs, process_memory, finished) || StepExidx(pc, regs, process_memory, finished); return ElfInterface32::Step(pc, load_bias, regs, process_memory, finished) || StepExidx(pc, load_bias, regs, process_memory, finished); } bool ElfInterfaceArm::StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { bool ElfInterfaceArm::StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished) { // Adjust the load bias to get the real relative pc. if (pc < load_bias) { return false; } pc -= load_bias; RegsArm* regs_arm = reinterpret_cast<RegsArm*>(regs); uint64_t entry_offset; if (!FindEntry(pc, &entry_offset)) { Loading libunwindstack/ElfInterfaceArm.h +4 −2 Original line number Diff line number Diff line Loading @@ -70,9 +70,11 @@ class ElfInterfaceArm : public ElfInterface32 { 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; bool Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished) override; bool StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished); bool StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished); uint64_t start_offset() { return start_offset_; } Loading Loading
libunwindstack/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ cc_test { data: [ "tests/files/elf32.xz", "tests/files/elf64.xz", "tests/files/offline/gnu_debugdata_arm32/*", "tests/files/offline/straddle_arm32/*", "tests/files/offline/straddle_arm64/*", ], Loading
libunwindstack/Elf.cpp +2 −9 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ void Elf::InitGnuDebugdata() { uint64_t load_bias; if (gnu->Init(&load_bias)) { gnu->InitHeaders(); interface_->SetGnuDebugdataInterface(gnu); } else { // Free all of the memory associated with the gnu_debugdata section. gnu_debugdata_memory_.reset(nullptr); Loading Loading @@ -115,17 +116,9 @@ bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, R return true; } // Adjust the load bias to get the real relative pc. if (adjusted_rel_pc < load_bias_) { return false; } adjusted_rel_pc -= load_bias_; // Lock during the step which can update information in the object. std::lock_guard<std::mutex> guard(lock_); return interface_->Step(adjusted_rel_pc, regs, process_memory, finished) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->Step(adjusted_rel_pc, regs, process_memory, finished)); return interface_->Step(adjusted_rel_pc, load_bias_, regs, process_memory, finished); } bool Elf::IsValidElf(Memory* memory) { Loading
libunwindstack/ElfInterface.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -386,16 +386,29 @@ bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, uint64_t load_bias return false; } bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { bool ElfInterface::Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished) { // Adjust the load bias to get the real relative pc. if (pc < load_bias) { return false; } uint64_t adjusted_pc = 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)) { if (eh_frame != nullptr && eh_frame->Step(adjusted_pc, regs, process_memory, finished)) { return true; } // Try the debug_frame next. DwarfSection* debug_frame = debug_frame_.get(); if (debug_frame != nullptr && debug_frame->Step(pc, regs, process_memory, finished)) { if (debug_frame != nullptr && debug_frame->Step(adjusted_pc, regs, process_memory, finished)) { return true; } // Finally try the gnu_debugdata interface, but always use a zero load bias. if (gnu_debugdata_interface_ != nullptr && gnu_debugdata_interface_->Step(pc, 0, regs, process_memory, finished)) { return true; } return false; Loading
libunwindstack/ElfInterfaceArm.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -92,16 +92,24 @@ bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type, uint64_t load_b return true; } bool ElfInterfaceArm::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { bool ElfInterfaceArm::Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished) { // Dwarf unwind information is precise about whether a pc is covered or not, // but arm unwind information only has ranges of pc. In order to avoid // incorrectly doing a bad unwind using arm unwind information for a // different function, always try and unwind with the dwarf information first. return ElfInterface32::Step(pc, regs, process_memory, finished) || StepExidx(pc, regs, process_memory, finished); return ElfInterface32::Step(pc, load_bias, regs, process_memory, finished) || StepExidx(pc, load_bias, regs, process_memory, finished); } bool ElfInterfaceArm::StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { bool ElfInterfaceArm::StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished) { // Adjust the load bias to get the real relative pc. if (pc < load_bias) { return false; } pc -= load_bias; RegsArm* regs_arm = reinterpret_cast<RegsArm*>(regs); uint64_t entry_offset; if (!FindEntry(pc, &entry_offset)) { Loading
libunwindstack/ElfInterfaceArm.h +4 −2 Original line number Diff line number Diff line Loading @@ -70,9 +70,11 @@ class ElfInterfaceArm : public ElfInterface32 { 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; bool Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished) override; bool StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished); bool StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory, bool* finished); uint64_t start_offset() { return start_offset_; } Loading