OSDN Git Service

simpleperf: fix reading jit debug descriptors.
authorYabin Cui <yabinc@google.com>
Thu, 12 Dec 2019 00:50:24 +0000 (16:50 -0800)
committerYabin Cui <yabinc@google.com>
Thu, 12 Dec 2019 01:09:46 +0000 (17:09 -0800)
Clang may generate elf files with segments not starting from
page-aligned addresses. For these segments, dynamic linker
creates maps mapping to (segment.p_offset & PAGE_MASK). So
map.start is mapped to file vaddr (segment.p_vaddr & PAGE_MASK)
instead of segment.p_vaddr.

So add PAGE_MASK when calculating memory address of descriptors,
using below formula:
descriptor.vaddr_in_file - (segment.p_vaddr & PAGE_MASK) + map.start.

Bug: 145920143
Bug: 145930241
Test: run simpleperf_unit_test.

Change-Id: Id185a6d6b766ecaa30b5067664687e556f92ef27

simpleperf/JITDebugReader.cpp

index 7ef3f25..2897a06 100644 (file)
@@ -19,6 +19,7 @@
 #include <inttypes.h>
 #include <sys/mman.h>
 #include <sys/uio.h>
+#include <sys/user.h>
 
 #include <algorithm>
 #include <unordered_map>
@@ -432,6 +433,9 @@ const JITDebugReader::DescriptorsLocation* JITDebugReader::GetDescriptorsLocatio
     LOG(ERROR) << "ReadMinExecutableVirtualAddress failed, status = " << status;
     return nullptr;
   }
+  // min_vaddr_in_file is the min vaddr of executable segments. It may not be page aligned.
+  // And dynamic linker will create map mapping to (segment.p_vaddr & PAGE_MASK).
+  uint64_t aligned_segment_vaddr = min_vaddr_in_file & PAGE_MASK;
   const char* jit_str = "__jit_debug_descriptor";
   const char* dex_str = "__dex_debug_descriptor";
   uint64_t jit_addr = 0u;
@@ -439,9 +443,9 @@ const JITDebugReader::DescriptorsLocation* JITDebugReader::GetDescriptorsLocatio
 
   auto callback = [&](const ElfFileSymbol& symbol) {
     if (symbol.name == jit_str) {
-      jit_addr = symbol.vaddr - min_vaddr_in_file;
+      jit_addr = symbol.vaddr - aligned_segment_vaddr;
     } else if (symbol.name == dex_str) {
-      dex_addr = symbol.vaddr - min_vaddr_in_file;
+      dex_addr = symbol.vaddr - aligned_segment_vaddr;
     }
   };
   if (ParseDynamicSymbolsFromElfFile(art_lib_path, callback) != ElfStatus::NO_ERROR) {