diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/perfelfmap.cpp | 22 | ||||
-rw-r--r-- | app/perfelfmap.h | 16 | ||||
-rw-r--r-- | app/perfsymboltable.cpp | 3 | ||||
-rw-r--r-- | app/perfsymboltable.h | 6 |
4 files changed, 38 insertions, 9 deletions
diff --git a/app/perfelfmap.cpp b/app/perfelfmap.cpp index d5cf084..45776f0 100644 --- a/app/perfelfmap.cpp +++ b/app/perfelfmap.cpp @@ -31,9 +31,16 @@ QDebug operator<<(QDebug stream, const PerfElfMap::ElfInfo& info) << "originalFileName=" << info.originalFileName << ", " << "originalPath=" << info.originalPath << ", " << "addr=" << hex << info.addr<< ", " - << "len=" << hex << info.length << ", " - << "pgoff=" << hex << info.pgoff - << "}"; + << "len=" << info.length << ", " + << "pgoff=" << info.pgoff << ", " + << "baseAddr="; + + if (info.hasBaseAddr()) + stream << info.baseAddr; + else + stream << "n/a"; + + stream << "}" << dec; return stream.space(); } @@ -113,7 +120,14 @@ bool PerfElfMap::registerElf(quint64 addr, quint64 len, quint64 pgoff, for (auto it = removedElfs.rbegin(), end = removedElfs.rend(); it != end; ++it) m_elfs.remove(*it); - newElfs.push_back(ElfInfo(fullPath, addr, len, pgoff, originalFileName, originalPath)); + ElfInfo elf(fullPath, addr, len, pgoff, originalFileName, originalPath); + + if (!pgoff) + m_lastBase = elf; + else if (m_lastBase.originalPath == originalPath) + elf.baseAddr = m_lastBase.addr; + + newElfs.push_back(elf); for (const auto &elf : newElfs) { auto it = std::lower_bound(m_elfs.begin(), m_elfs.end(), diff --git a/app/perfelfmap.h b/app/perfelfmap.h index 2396046..e9262e4 100644 --- a/app/perfelfmap.h +++ b/app/perfelfmap.h @@ -22,11 +22,15 @@ #include <QFileInfo> #include <QVector> +#include <limits> class PerfElfMap { public: struct ElfInfo { + enum { + INVALID_BASE_ADDR = std::numeric_limits<quint64>::max() + }; explicit ElfInfo(const QFileInfo &localFile = QFileInfo(), quint64 addr = 0, quint64 length = 0, quint64 pgoff = 0, const QByteArray &originalFileName = {}, @@ -51,6 +55,11 @@ public: return localFile.isFile(); } + bool hasBaseAddr() const + { + return baseAddr != INVALID_BASE_ADDR; + } + bool operator==(const ElfInfo& rhs) const { return isFile() == rhs.isFile() @@ -59,7 +68,8 @@ public: && originalPath == rhs.originalPath && addr == rhs.addr && length == rhs.length - && pgoff == rhs.pgoff; + && pgoff == rhs.pgoff + && baseAddr == rhs.baseAddr; } QFileInfo localFile; @@ -68,7 +78,7 @@ public: quint64 addr; quint64 length; quint64 pgoff; - + quint64 baseAddr = INVALID_BASE_ADDR; quint64 dwflStart = 0; quint64 dwflEnd = 0; }; @@ -90,6 +100,8 @@ public: private: // elf sorted by start address QVector<ElfInfo> m_elfs; + // last registered elf with zero pgoff + ElfInfo m_lastBase; }; QT_BEGIN_NAMESPACE diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp index 136c8c6..50e6fbc 100644 --- a/app/perfsymboltable.cpp +++ b/app/perfsymboltable.cpp @@ -496,6 +496,9 @@ Dwfl_Module *PerfSymbolTable::module(quint64 addr, const PerfElfMap::ElfInfo &el if (!m_dwfl) return nullptr; + if (elf.pgoff && elf.hasBaseAddr()) + return module(addr, m_elfs.findElf(elf.baseAddr)); + Dwfl_Module *mod = dwfl_addrmodule(m_dwfl, addr); if (mod) { diff --git a/app/perfsymboltable.h b/app/perfsymboltable.h index c85edaa..b01268a 100644 --- a/app/perfsymboltable.h +++ b/app/perfsymboltable.h @@ -58,9 +58,6 @@ public: PerfElfMap::ElfInfo findElf(quint64 ip) const; - // Report an mmap to dwfl and parse it for symbols and inlines, or simply return it if dwfl has - // it already - Dwfl_Module *reportElf(const PerfElfMap::ElfInfo& elf); // Find the module for the given address and report it if needed Dwfl_Module *module(quint64 addr); Dwfl_Module *module(quint64 addr, const PerfElfMap::ElfInfo &elf); @@ -80,6 +77,9 @@ public: bool cacheIsDirty() const { return m_cacheIsDirty; } private: + // Report an mmap to dwfl and parse it for symbols and inlines, or simply return it if dwfl has + // it already + Dwfl_Module *reportElf(const PerfElfMap::ElfInfo& elf); QFileInfo findFile(const char *path, const QString &fileName, const QByteArray &buildId = QByteArray()) const; |