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/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index 962f744..8f28036 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -96,6 +96,54 @@
frame_info);
}
+TEST(UnwindOfflineTest, pc_in_gnu_debugdata_arm32) {
+ std::string dir(TestGetFileDirectory() + "offline/gnu_debugdata_arm32/");
+
+ MemoryOffline* memory = new MemoryOffline;
+ ASSERT_TRUE(memory->Init((dir + "stack.data").c_str(), 0));
+
+ FILE* fp = fopen((dir + "regs.txt").c_str(), "r");
+ ASSERT_TRUE(fp != nullptr);
+ RegsArm regs;
+ uint64_t reg_value;
+ ASSERT_EQ(1, fscanf(fp, "pc: %" SCNx64 "\n", ®_value));
+ regs[ARM_REG_PC] = reg_value;
+ ASSERT_EQ(1, fscanf(fp, "sp: %" SCNx64 "\n", ®_value));
+ regs[ARM_REG_SP] = reg_value;
+ regs.SetFromRaw();
+ fclose(fp);
+
+ fp = fopen((dir + "maps.txt").c_str(), "r");
+ ASSERT_TRUE(fp != nullptr);
+ // The file is guaranteed to be less than 4096 bytes.
+ std::vector<char> buffer(4096);
+ ASSERT_NE(0U, fread(buffer.data(), 1, buffer.size(), fp));
+ fclose(fp);
+
+ BufferMaps maps(buffer.data());
+ ASSERT_TRUE(maps.Parse());
+
+ ASSERT_EQ(ARCH_ARM, regs.Arch());
+
+ std::shared_ptr<Memory> process_memory(memory);
+
+ char* cwd = getcwd(nullptr, 0);
+ ASSERT_EQ(0, chdir(dir.c_str()));
+ Unwinder unwinder(128, &maps, ®s, process_memory);
+ unwinder.Unwind();
+ ASSERT_EQ(0, chdir(cwd));
+ free(cwd);
+
+ std::string frame_info(DumpFrames(unwinder));
+ ASSERT_EQ(2U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
+ EXPECT_EQ(
+ " #00 pc 0006dc49 libandroid_runtime.so "
+ "(_ZN7android14AndroidRuntime15javaThreadShellEPv+80)\n"
+ " #01 pc 0006dce5 libandroid_runtime.so "
+ "(_ZN7android14AndroidRuntime19javaCreateThreadEtcEPFiPvES1_PKcijPS1_)\n",
+ frame_info);
+}
+
TEST(UnwindOfflineTest, pc_straddle_arm64) {
std::string dir(TestGetFileDirectory() + "offline/straddle_arm64/");