Support a map that represents gdb jit elf data.
Changes:
- Add a new flag to the libbacktrace and libunwindstack map data.
- Modify the unwinder to handle this map to use the raw pc when stepping.
- Add new unit tests for this case.
Bug: http://b/73127105
Test: Run simpleperf to unwind through jit symfiles.
Test: Run new unit tests.
Test: Run 137-cfi test on host.
Change-Id: I10bc0410680accc6d35fe51e9f1098911f667e01
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index 532640f..6c242a5 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -18,6 +18,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/mman.h>
#include <unistd.h>
#include <gtest/gtest.h>
@@ -1070,4 +1071,44 @@
EXPECT_EQ(0xcd4ff960U, unwinder.frames()[24].sp);
}
+TEST_F(UnwindOfflineTest, jit_map_arm) {
+ Init("jit_map_arm/", ARCH_ARM);
+
+ maps_->Add(0xd025c788, 0xd025c9f0, 0, PROT_READ | PROT_EXEC | MAPS_FLAGS_JIT_SYMFILE_MAP,
+ "jit_map0.so", 0);
+ maps_->Add(0xd025cd98, 0xd025cff4, 0, PROT_READ | PROT_EXEC | MAPS_FLAGS_JIT_SYMFILE_MAP,
+ "jit_map1.so", 0);
+ maps_->Sort();
+
+ Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
+ unwinder.Unwind();
+
+ std::string frame_info(DumpFrames(unwinder));
+ ASSERT_EQ(6U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
+ EXPECT_EQ(
+ " #00 pc 00000000 jit_map0.so "
+ "(com.example.simpleperf.simpleperfexamplewithnative.MixActivity.access$000)\n"
+ " #01 pc 0000003d jit_map1.so "
+ "(com.example.simpleperf.simpleperfexamplewithnative.MixActivity$1.run+60)\n"
+ " #02 pc 004135bb libart.so (art_quick_osr_stub+42)\n"
+
+ " #03 pc 003851dd libart.so (_ZN3art6Thread14CreateCallbackEPv+868)\n"
+ " #04 pc 00062925 libc.so (_ZL15__pthread_startPv+22)\n"
+ " #05 pc 0001de39 libc.so (__start_thread+24)\n",
+ frame_info);
+
+ EXPECT_EQ(0xd025c788U, unwinder.frames()[0].pc);
+ EXPECT_EQ(0xcd4ff140U, unwinder.frames()[0].sp);
+ EXPECT_EQ(0xd025cdd5U, unwinder.frames()[1].pc);
+ EXPECT_EQ(0xcd4ff140U, unwinder.frames()[1].sp);
+ EXPECT_EQ(0xe4a755bbU, unwinder.frames()[2].pc);
+ EXPECT_EQ(0xcd4ff160U, unwinder.frames()[2].sp);
+ EXPECT_EQ(0xe49e71ddU, unwinder.frames()[3].pc);
+ EXPECT_EQ(0xcd4ff8e8U, unwinder.frames()[3].sp);
+ EXPECT_EQ(0xe7df3925U, unwinder.frames()[4].pc);
+ EXPECT_EQ(0xcd4ff958U, unwinder.frames()[4].sp);
+ EXPECT_EQ(0xe7daee39U, unwinder.frames()[5].pc);
+ EXPECT_EQ(0xcd4ff960U, unwinder.frames()[5].sp);
+}
+
} // namespace unwindstack
diff --git a/libunwindstack/tests/files/offline/jit_map_arm/jit_map0.so b/libunwindstack/tests/files/offline/jit_map_arm/jit_map0.so
new file mode 100644
index 0000000..e667883
--- /dev/null
+++ b/libunwindstack/tests/files/offline/jit_map_arm/jit_map0.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/jit_map_arm/jit_map1.so b/libunwindstack/tests/files/offline/jit_map_arm/jit_map1.so
new file mode 100644
index 0000000..9a1d714
--- /dev/null
+++ b/libunwindstack/tests/files/offline/jit_map_arm/jit_map1.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/jit_map_arm/libart.so b/libunwindstack/tests/files/offline/jit_map_arm/libart.so
new file mode 100644
index 0000000..09ba495
--- /dev/null
+++ b/libunwindstack/tests/files/offline/jit_map_arm/libart.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/jit_map_arm/libc.so b/libunwindstack/tests/files/offline/jit_map_arm/libc.so
new file mode 100644
index 0000000..39c9025
--- /dev/null
+++ b/libunwindstack/tests/files/offline/jit_map_arm/libc.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/jit_map_arm/maps.txt b/libunwindstack/tests/files/offline/jit_map_arm/maps.txt
new file mode 100644
index 0000000..5aaec54
--- /dev/null
+++ b/libunwindstack/tests/files/offline/jit_map_arm/maps.txt
@@ -0,0 +1,2 @@
+e466e000-e4ae8000 r-xp 0 00:00 0 libart.so
+e7d91000-e7e31000 r-xp 0 00:00 0 libc.so
diff --git a/libunwindstack/tests/files/offline/jit_map_arm/regs.txt b/libunwindstack/tests/files/offline/jit_map_arm/regs.txt
new file mode 100644
index 0000000..0b51814
--- /dev/null
+++ b/libunwindstack/tests/files/offline/jit_map_arm/regs.txt
@@ -0,0 +1,16 @@
+r0: e814103c
+r1: 12dcf218
+r2: 1a90df75
+r3: ffffffbf
+r4: 0
+r5: 12dc0800
+r6: 12dcf218
+r7: 1a90df75
+r8: 0
+r9: dd23cc00
+r10: 1c
+r11: cd4ff16c
+ip: 0
+sp: cd4ff140
+lr: d025cdd7
+pc: d025c788
diff --git a/libunwindstack/tests/files/offline/jit_map_arm/stack.data b/libunwindstack/tests/files/offline/jit_map_arm/stack.data
new file mode 100644
index 0000000..fb8feeb
--- /dev/null
+++ b/libunwindstack/tests/files/offline/jit_map_arm/stack.data
Binary files differ