diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2018-10-23 21:48:29 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-05-03 12:44:21 +0000 |
commit | f6daea1a9b3afdcb7c5ae61eeac2ac20e8c88135 (patch) | |
tree | d61d8656ddff579ab78d54b872d0f2544b3f25ad | |
parent | a69e6a514390640b6a1d06372f5e3dcc5de9d165 (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.cpp | 11 |
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); |