From 0140e68885e249ac2b2d6ec3cfa8cc5a1e02a8fd Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Fri, 15 Dec 2017 11:17:45 -0800 Subject: Fix issues in libunwindstack. - Add a load_bias field in MapInfo so that it can be loaded offline, and also so it can be cached. - Add an Add function to the Maps class so that it's possible to manually create a map. - Remove the OfflineMaps class since I haven't found a reason for this to exist. - Add a pointer to the gnu debugdata compressed section in the interface itself and modify the step path to try eh_frame, then debug_frame, then gnu_debugdata. This way arm can add exidx as the last step behind gnu_debugdata. Add an offline test to verify the order of unwind. - Fix x86_64_ucontext_t since it was a different size on 32 bit and 64 bit systems. Test: Pass new unit tests. Change-Id: I978b70d6c244bd307c62a29886d24c1a8cb2af23 --- libunwindstack/ElfInterface.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'libunwindstack/ElfInterface.cpp') diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp index 334cf76..df1642e 100644 --- a/libunwindstack/ElfInterface.cpp +++ b/libunwindstack/ElfInterface.cpp @@ -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; -- cgit v1.2.3