summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-10-02 03:09:56 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-10-02 03:09:56 +0000
commitba82663cc644bb77e7787374ffcc197755dfa591 (patch)
tree48e0b2403de19a1475a492a80459cc9a7b14edf8
parent8bd2468cbd0ebc97ecfce32cdb26193f4c45e053 (diff)
parent6497234a597c9f681b8120a2599a11be71016f99 (diff)
downloadunwinding-android12-qpr1-release.tar.gz
Snap for 7787524 from 6497234a597c9f681b8120a2599a11be71016f99 to sc-qpr1-releaseandroid-12.0.0_r28android-12.0.0_r26android-12.0.0_r16android12-qpr1-release
Change-Id: I934c3144c9c024212ebe43405f23ac1926249ea4
-rw-r--r--libunwindstack/AndroidVersions.md16
-rw-r--r--libunwindstack/MapInfo.cpp2
-rw-r--r--libunwindstack/tests/MapInfoCreateMemoryTest.cpp31
3 files changed, 49 insertions, 0 deletions
diff --git a/libunwindstack/AndroidVersions.md b/libunwindstack/AndroidVersions.md
index b4e29ca..ff46829 100644
--- a/libunwindstack/AndroidVersions.md
+++ b/libunwindstack/AndroidVersions.md
@@ -114,3 +114,19 @@ included in linker arguments when using lld.
and uses pc relative FDEs, the unwind will be incorrect. This tends
to truncate unwinds since the unwinder could not find the correct unwind
information for a given pc.
+
+## Android 12 ("S", API level 31)
+* Fix bug where, if a shared library is dlopen'ed from within an apk file,
+ is not readable, and the shared library only produces a single read-
+ executable map for the elf data and executable data, the offset into the
+ apk will not be displayed. Previously the line would look like:
+
+ #01 pc 000000000222675c GoogleCamera.apk
+
+ to:
+
+ #01 pc 000000000222675c GoogleCamera.apk (offset 0x269f000)
+
+ If the apk file is readable, or dlopen'ing the shared library creates
+ a read-only map of the elf data, and a read-executable map of the
+ code, the offset will be displayed properly without this fix.
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp
index 8fb6f7e..1127cd9 100644
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -166,6 +166,8 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
// option is used.
std::unique_ptr<MemoryRange> memory(new MemoryRange(process_memory, start(), end() - start(), 0));
if (Elf::IsValidElf(memory.get())) {
+ set_elf_start_offset(offset());
+
// Might need to peek at the next map to create a memory object that
// includes that map too.
if (offset() != 0 || name().empty() || next_real_map() == nullptr ||
diff --git a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
index d5e04a1..1f7f8bf 100644
--- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
+++ b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
@@ -367,6 +367,37 @@ TEST_F(MapInfoCreateMemoryTest, valid_rosegment_non_zero_offset) {
}
}
+TEST_F(MapInfoCreateMemoryTest, valid_single_rx_non_zero_offset) {
+ Maps maps;
+ maps.Add(0x3000, 0x5000, 0xa000, PROT_READ | PROT_EXEC, "/only/in/memory.apk", 0);
+
+ Elf32_Ehdr ehdr = {};
+ TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
+
+ // Setup an elf at offset 0x3000 in memory..
+ memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr));
+ memory_->SetMemoryBlock(0x3000 + sizeof(ehdr), 0x5000 - sizeof(ehdr), 0x34);
+
+ MapInfo* map_info = maps.Find(0x3000);
+ ASSERT_TRUE(map_info != nullptr);
+
+ std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
+ ASSERT_TRUE(mem.get() != nullptr);
+ EXPECT_TRUE(map_info->memory_backed_elf());
+ EXPECT_EQ(0UL, map_info->elf_offset());
+ EXPECT_EQ(0xa000UL, map_info->offset());
+ EXPECT_EQ(0xa000UL, map_info->elf_start_offset());
+
+ // Verify that reading values from this memory works properly.
+ std::vector<uint8_t> buffer(0x3000);
+ size_t bytes = mem->Read(0, buffer.data(), buffer.size());
+ ASSERT_EQ(0x2000UL, bytes);
+ ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr)));
+ for (size_t i = sizeof(ehdr); i < bytes; i++) {
+ ASSERT_EQ(0x34, buffer[i]) << "Failed at byte " << i;
+ }
+}
+
TEST_F(MapInfoCreateMemoryTest, rosegment_from_file) {
Maps maps;
maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0);