summaryrefslogtreecommitdiff
path: root/simpleperf/dso_test.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2020-11-25 15:37:38 -0800
committerYabin Cui <yabinc@google.com>2020-11-25 15:55:31 -0800
commitf3da1edd7d18db0c89c02c786cbd5eb76c0c1425 (patch)
treeaf4f2e6635dd42f62af77d6bb06653b322b666c4 /simpleperf/dso_test.cpp
parentdacfcca550b5d72ffb08a6d1f0ac30fda8243aaf (diff)
downloadextras-f3da1edd7d18db0c89c02c786cbd5eb76c0c1425.tar.gz
simpleperf: fix symbolization for kernel modules.
Simpleperf makes a wrong assumption that the kernel always load .text section of a kernel module at the start of its module memory. This can map an ip addr of a module to a wrong symbol. To fix it: 1. In KernelModuleDso, calculate min_vaddr and memory_offset, which are used to do the conversion in IpToVaddrInFile(). 2. Change record_file_reader/writer to store min_vaddr and memory_offset of KernelModuleDso in the recording file. 3. To get module start addresses, Use CheckKernelSymbolAddress() in GetLoadedModules(). Bug: 174076407 Test: run simpleperf_unit_test. Test: run simpleperf manually to check symbols of kernel modules. Change-Id: I2498564f78dcc34761c5fe3ae9ffa6b88a98a048
Diffstat (limited to 'simpleperf/dso_test.cpp')
-rw-r--r--simpleperf/dso_test.cpp34
1 files changed, 33 insertions, 1 deletions
diff --git a/simpleperf/dso_test.cpp b/simpleperf/dso_test.cpp
index 96663d6b..331353f8 100644
--- a/simpleperf/dso_test.cpp
+++ b/simpleperf/dso_test.cpp
@@ -257,10 +257,42 @@ TEST(dso, kernel_module) {
std::vector<std::pair<std::string, BuildId>> build_ids;
build_ids.emplace_back(ELF_FILE, BuildId(ELF_FILE_BUILD_ID));
Dso::SetBuildIds(build_ids);
- std::unique_ptr<Dso> dso = Dso::CreateDso(DSO_KERNEL_MODULE, ELF_FILE, false);
+ std::unique_ptr<Dso> kernel_dso = Dso::CreateDso(DSO_KERNEL, DEFAULT_KERNEL_MMAP_NAME);
+ ASSERT_TRUE(kernel_dso);
+ std::unique_ptr<Dso> dso = Dso::CreateKernelModuleDso(ELF_FILE, 0, 0, kernel_dso.get());
ASSERT_EQ(dso->GetDebugFilePath(), GetTestData(ELF_FILE));
}
+TEST(dso, kernel_module_CalculateMinVaddr) {
+ // Create fake Dso objects.
+ auto kernel_dso = Dso::CreateDso(DSO_KERNEL, DEFAULT_KERNEL_MMAP_NAME);
+ ASSERT_TRUE(kernel_dso);
+ const uint64_t module_memory_start = 0xffffffa9bc790000ULL;
+ const uint64_t module_memory_size = 0x8d7000ULL;
+ auto module_dso =
+ Dso::CreateKernelModuleDso("fake_module.ko", module_memory_start,
+ module_memory_start + module_memory_size, kernel_dso.get());
+ ASSERT_TRUE(module_dso);
+
+ // Provide symbol info for calculating min vaddr.
+ std::vector<Symbol> kernel_symbols;
+ kernel_symbols.emplace_back("fake_module_function [fake_module]", 0xffffffa9bc7a64e8ULL, 0x60c);
+ kernel_dso->SetSymbols(&kernel_symbols);
+ std::vector<Symbol> module_symbols;
+ module_symbols.emplace_back("fake_module_function", 0x144e8, 0x60c);
+ module_dso->SetSymbols(&module_symbols);
+
+ // Calculate min vaddr.
+ uint64_t min_vaddr;
+ uint64_t memory_offset;
+ module_dso->GetMinExecutableVaddr(&min_vaddr, &memory_offset);
+ ASSERT_EQ(min_vaddr, 0x144e8);
+ ASSERT_EQ(memory_offset, 0x164e8);
+
+ // Use min vaddr in IpToVaddrInFile().
+ ASSERT_EQ(module_dso->IpToVaddrInFile(0xffffffa9bc7a64e8ULL, module_memory_start, 0), 0x144e8);
+}
+
TEST(dso, symbol_map_file) {
auto dso = Dso::CreateDso(DSO_SYMBOL_MAP_FILE, "perf-123.map");
ASSERT_TRUE(dso);