simpleperf: fix symbolization in multi-executable-segments libraries.
Apps may run with libraries with multiple executable segments.
Symbolization ip addresses in these libraries need to use map.pgoff.
The old formula converting ip to vaddr_in_file:
vaddr_in_file = ip - map.start + min_executable_vaddr
The new formula converting ip to vaddr_in_file:
offset_in_file = ip - map.start + map.pgoff
vaddr_in_file = offset_in_file - file_offset_of_min_executable_vaddr
+ min_executable_vaddr
Bug: 124056476
Test: run simpleperf_unit_test.
Test: use simpleperf to profile facebook app, ip addresses hitting libc.so
Test: and libart.so are symbolized correctly.
Change-Id: I5fd3ed822a916c4d04a9868d6d209c43ee190c5b
diff --git a/simpleperf/dso_test.cpp b/simpleperf/dso_test.cpp
index e126575..04d039a 100644
--- a/simpleperf/dso_test.cpp
+++ b/simpleperf/dso_test.cpp
@@ -98,7 +98,11 @@
ASSERT_EQ(symbol->len, static_cast<uint64_t>(0x16));
ASSERT_STREQ(symbol->DemangledName(),
"com.example.simpleperf.simpleperfexamplewithnative.MixActivity$1.run");
- ASSERT_EQ(0u, dso->MinVirtualAddress());
+ uint64_t min_vaddr;
+ uint64_t file_offset_of_min_vaddr;
+ dso->GetMinExecutableVaddr(&min_vaddr, &file_offset_of_min_vaddr);
+ ASSERT_EQ(min_vaddr, 0);
+ ASSERT_EQ(file_offset_of_min_vaddr, 0);
// Don't crash on not exist zip entry.
dso = Dso::CreateDso(dso_type, GetTestData("base.zip!/not_exist_entry"));
@@ -125,7 +129,11 @@
ASSERT_TRUE(dso);
ASSERT_EQ(dso->Path(), file_path);
ASSERT_EQ(dso->GetDebugFilePath(), file_path);
- ASSERT_EQ(dso->MinVirtualAddress(), 0u);
+ uint64_t min_vaddr;
+ uint64_t file_offset_of_min_vaddr;
+ dso->GetMinExecutableVaddr(&min_vaddr, &file_offset_of_min_vaddr);
+ ASSERT_EQ(min_vaddr, 0);
+ ASSERT_EQ(file_offset_of_min_vaddr, 0);
const Symbol* symbol = dso->FindSymbol(0x9a4);
ASSERT_TRUE(symbol != nullptr);
ASSERT_STREQ(symbol->Name(), "Java_com_example_hellojni_HelloJni_callFunc1");
@@ -133,3 +141,9 @@
ASSERT_TRUE(GetBuildIdFromDsoPath(file_path, &build_id));
ASSERT_EQ(build_id, native_lib_build_id);
}
+
+TEST(dso, IpToVaddrInFile) {
+ std::unique_ptr<Dso> dso = Dso::CreateDso(DSO_ELF_FILE, GetTestData("libc.so"));
+ ASSERT_TRUE(dso);
+ ASSERT_EQ(0xa5140, dso->IpToVaddrInFile(0xe9201140, 0xe9201000, 0xa5000));
+}