summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2018-10-23 21:48:29 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-05-03 12:44:21 +0000
commitf6daea1a9b3afdcb7c5ae61eeac2ac20e8c88135 (patch)
treed61d8656ddff579ab78d54b872d0f2544b3f25ad
parenta69e6a514390640b6a1d06372f5e3dcc5de9d165 (diff)
Try to guess offset base address before reporting elf to dwfl
When we record perf data files with `--call-graph [fp,lbr]`, we only see mmap events for the executable code segments. These are usually offset. Without the non-offset mmap event, we would not report anything to dwfl so far. Now, we guess the base address and use that before reporting the elf to dwfl. This seems to work, but could fail once a gap would exist at the start. Change-Id: I9d837e8bed650d6574e84401da67beeddaf7ff57 Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
-rw-r--r--app/perfsymboltable.cpp11
1 files changed, 3 insertions, 8 deletions
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp
index 9f81a62..212cf01 100644
--- a/app/perfsymboltable.cpp
+++ b/app/perfsymboltable.cpp
@@ -466,15 +466,10 @@ Dwfl_Module *PerfSymbolTable::reportElf(const PerfElfMap::ElfInfo& info)
if (!info.isValid() || !info.isFile())
return nullptr;
- if (info.pgoff > 0) {
- reportError(m_pid, info, "Cannot report file fragments");
- return nullptr;
- }
-
dwfl_report_begin_add(m_dwfl);
Dwfl_Module *ret = dwfl_report_elf(
m_dwfl, info.originalFileName.constData(),
- info.localFile.absoluteFilePath().toLocal8Bit().constData(), -1, info.addr,
+ info.localFile.absoluteFilePath().toLocal8Bit().constData(), -1, info.addr - info.pgoff,
false);
if (!ret) {
reportError(m_pid, info, dwfl_errmsg(dwfl_errno()));
@@ -515,7 +510,7 @@ Dwfl_Module *PerfSymbolTable::module(quint64 addr, const PerfElfMap::ElfInfo &el
// by dwfl. If that is the case, then we would invalidate the cache and
// re-report the library again - essentially recreating the current state
// for no gain, except wasting time
- mod = dwfl_addrmodule(m_dwfl, elf.addr);
+ mod = dwfl_addrmodule(m_dwfl, elf.addr - elf.pgoff);
}
if (mod) {
@@ -525,7 +520,7 @@ Dwfl_Module *PerfSymbolTable::module(quint64 addr, const PerfElfMap::ElfInfo &el
Dwarf_Addr mod_start = 0;
dwfl_module_info(mod, nullptr, &mod_start, nullptr, nullptr, nullptr, nullptr,
nullptr);
- if (elf.addr == mod_start)
+ if (elf.addr - elf.pgoff == mod_start)
return mod;
}
return reportElf(elf);