diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp index a49fd9ed4..b7650a178 100644 --- a/libunwindstack/Android.bp +++ b/libunwindstack/Android.bp @@ -248,6 +248,7 @@ cc_test { "tests/files/offline/offset_arm/*", "tests/files/offline/shared_lib_in_apk_arm64/*", "tests/files/offline/shared_lib_in_apk_memory_only_arm64/*", + "tests/files/offline/shared_lib_in_apk_single_map_arm64/*", "tests/files/offline/straddle_arm/*", "tests/files/offline/straddle_arm64/*", ], diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp index 89a6a79c9..a38236c60 100644 --- a/libunwindstack/MapInfo.cpp +++ b/libunwindstack/MapInfo.cpp @@ -88,6 +88,7 @@ Memory* MapInfo::GetFileMemory() { // Check if the start of this map is an embedded elf. uint64_t max_size = 0; if (Elf::GetInfo(memory.get(), &max_size)) { + elf_start_offset = offset; if (max_size > map_size) { if (memory->Init(name, offset, max_size)) { return memory.release(); @@ -96,6 +97,7 @@ Memory* MapInfo::GetFileMemory() { if (memory->Init(name, offset, map_size)) { return memory.release(); } + elf_start_offset = 0; return nullptr; } return memory.release(); diff --git a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp index a66685a26..2ddadef37 100644 --- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp +++ b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp @@ -178,7 +178,7 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file) { std::unique_ptr memory(info.CreateMemory(process_memory_)); ASSERT_TRUE(memory.get() != nullptr); ASSERT_EQ(0U, info.elf_offset); - EXPECT_EQ(0U, info.elf_start_offset); + EXPECT_EQ(0x1000U, info.elf_start_offset); // Read the valid part of the file. std::vector buffer(0x100); @@ -202,7 +202,7 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_e std::unique_ptr memory(info.CreateMemory(process_memory_)); ASSERT_TRUE(memory.get() != nullptr); ASSERT_EQ(0U, info.elf_offset); - EXPECT_EQ(0U, info.elf_start_offset); + EXPECT_EQ(0x1000U, info.elf_start_offset); // Verify the memory is a valid elf. uint8_t e_ident[SELFMAG + 1]; @@ -219,7 +219,7 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_e std::unique_ptr memory(info.CreateMemory(process_memory_)); ASSERT_TRUE(memory.get() != nullptr); ASSERT_EQ(0U, info.elf_offset); - EXPECT_EQ(0U, info.elf_start_offset); + EXPECT_EQ(0x2000U, info.elf_start_offset); // Verify the memory is a valid elf. uint8_t e_ident[SELFMAG + 1]; diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp index b5feb3845..86bc4654c 100644 --- a/libunwindstack/tests/UnwindOfflineTest.cpp +++ b/libunwindstack/tests/UnwindOfflineTest.cpp @@ -1372,4 +1372,56 @@ TEST_F(UnwindOfflineTest, shared_lib_in_apk_memory_only_arm64) { // Ignore top frame since the test code was modified to end in __libc_init. } +TEST_F(UnwindOfflineTest, shared_lib_in_apk_single_map_arm64) { + ASSERT_NO_FATAL_FAILURE(Init("shared_lib_in_apk_single_map_arm64/", ARCH_ARM64)); + + Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); + unwinder.Unwind(); + + std::string frame_info(DumpFrames(unwinder)); + ASSERT_EQ(13U, unwinder.NumFrames()) << "Unwind:\n" << frame_info; + EXPECT_EQ( + " #00 pc 00000000000814bc libc.so (syscall+28)\n" + " #01 pc 00000000008cdf5c test.apk (offset 0x5000)\n" + " #02 pc 00000000008cde9c test.apk (offset 0x5000)\n" + " #03 pc 00000000008cdd70 test.apk (offset 0x5000)\n" + " #04 pc 00000000008ce408 test.apk (offset 0x5000)\n" + " #05 pc 00000000008ce8d8 test.apk (offset 0x5000)\n" + " #06 pc 00000000008ce814 test.apk (offset 0x5000)\n" + " #07 pc 00000000008bcf60 test.apk (offset 0x5000)\n" + " #08 pc 0000000000133024 test.apk (offset 0x5000)\n" + " #09 pc 0000000000134ad0 test.apk (offset 0x5000)\n" + " #10 pc 0000000000134b64 test.apk (offset 0x5000)\n" + " #11 pc 00000000000e406c libc.so (__pthread_start(void*)+36)\n" + " #12 pc 0000000000085e18 libc.so (__start_thread+64)\n", + frame_info); + + EXPECT_EQ(0x7cbe0b14bcULL, unwinder.frames()[0].pc); + EXPECT_EQ(0x7be4f077d0ULL, unwinder.frames()[0].sp); + EXPECT_EQ(0x7be6715f5cULL, unwinder.frames()[1].pc); + EXPECT_EQ(0x7be4f077d0ULL, unwinder.frames()[1].sp); + EXPECT_EQ(0x7be6715e9cULL, unwinder.frames()[2].pc); + EXPECT_EQ(0x7be4f07800ULL, unwinder.frames()[2].sp); + EXPECT_EQ(0x7be6715d70ULL, unwinder.frames()[3].pc); + EXPECT_EQ(0x7be4f07840ULL, unwinder.frames()[3].sp); + EXPECT_EQ(0x7be6716408ULL, unwinder.frames()[4].pc); + EXPECT_EQ(0x7be4f07860ULL, unwinder.frames()[4].sp); + EXPECT_EQ(0x7be67168d8ULL, unwinder.frames()[5].pc); + EXPECT_EQ(0x7be4f07880ULL, unwinder.frames()[5].sp); + EXPECT_EQ(0x7be6716814ULL, unwinder.frames()[6].pc); + EXPECT_EQ(0x7be4f078f0ULL, unwinder.frames()[6].sp); + EXPECT_EQ(0x7be6704f60ULL, unwinder.frames()[7].pc); + EXPECT_EQ(0x7be4f07910ULL, unwinder.frames()[7].sp); + EXPECT_EQ(0x7be5f7b024ULL, unwinder.frames()[8].pc); + EXPECT_EQ(0x7be4f07950ULL, unwinder.frames()[8].sp); + EXPECT_EQ(0x7be5f7cad0ULL, unwinder.frames()[9].pc); + EXPECT_EQ(0x7be4f07aa0ULL, unwinder.frames()[9].sp); + EXPECT_EQ(0x7be5f7cb64ULL, unwinder.frames()[10].pc); + EXPECT_EQ(0x7be4f07ce0ULL, unwinder.frames()[10].sp); + EXPECT_EQ(0x7cbe11406cULL, unwinder.frames()[11].pc); + EXPECT_EQ(0x7be4f07d00ULL, unwinder.frames()[11].sp); + EXPECT_EQ(0x7cbe0b5e18ULL, unwinder.frames()[12].pc); + EXPECT_EQ(0x7be4f07d20ULL, unwinder.frames()[12].sp); +} + } // namespace unwindstack diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/libc.so b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/libc.so new file mode 100644 index 000000000..cac1dd9b8 Binary files /dev/null and b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/libc.so differ diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/maps.txt b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/maps.txt new file mode 100644 index 000000000..2c5ca62e1 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/maps.txt @@ -0,0 +1,3 @@ +7be5e48000-7be6b2b000 r-xp 5000 00:00 0 test.apk +7cbe030000-7cbe070000 r--p 0 00:00 0 libc.so +7cbe070000-7cbe11a000 r-xp 40000 00:00 0 libc.so diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/regs.txt b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/regs.txt new file mode 100644 index 000000000..090aedae6 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/regs.txt @@ -0,0 +1,33 @@ +x0: 7c326f6568 +x1: 80 +x2: 0 +x3: 0 +x4: 0 +x5: 0 +x6: 0 +x7: 7f7f7f7f7f7f7f7f +x8: 62 +x9: 1 +x10: 1 +x11: 0 +x12: ffffffffc4653600 +x13: 17645696f +x14: 2742ed97ca77a3 +x15: 3ab49084 +x16: 7be6b6bdb8 +x17: 7cbe0b14a0 +x18: 7c2b02a000 +x19: 0 +x20: 7c326f6568 +x21: 7be69c827c +x22: 7be69c8272 +x23: 1 +x24: 7be74f7100 +x25: 881 +x26: 7be4f07a00 +x27: c479c000 +x28: 7be4f07998 +x29: 7be4f079b4 +sp: 7be4f077d0 +lr: 7be6715f60 +pc: 7cbe0b14bc diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/stack.data b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/stack.data new file mode 100644 index 000000000..27d5bf34b Binary files /dev/null and b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/stack.data differ diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/test.apk b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/test.apk new file mode 100644 index 000000000..70a9c71ea Binary files /dev/null and b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/test.apk differ