summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/perfelfmap.cpp22
-rw-r--r--app/perfelfmap.h16
-rw-r--r--app/perfsymboltable.cpp3
-rw-r--r--app/perfsymboltable.h6
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;