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
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 @@
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;