summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/perfelfmap.cpp12
-rw-r--r--app/perfelfmap.h5
-rw-r--r--app/perfsymboltable.cpp6
-rw-r--r--tests/auto/elfmap/tst_elfmap.cpp28
4 files changed, 33 insertions, 18 deletions
diff --git a/app/perfelfmap.cpp b/app/perfelfmap.cpp
index 54e9e1e..5fad1ee 100644
--- a/app/perfelfmap.cpp
+++ b/app/perfelfmap.cpp
@@ -121,10 +121,14 @@ void PerfElfMap::registerElf(quint64 addr, quint64 len, quint64 pgoff,
ElfInfo elf(fullPath, addr, len, pgoff, originalFileName, originalPath);
- if (!pgoff)
- m_lastBase = elf;
- else if (m_lastBase.originalPath == originalPath)
- elf.baseAddr = m_lastBase.addr;
+ if (elf.isFile()) {
+ if (m_lastBase.originalPath == originalPath && elf.addr > m_lastBase.addr)
+ elf.baseAddr = m_lastBase.addr;
+ else if (!pgoff)
+ m_lastBase = elf;
+ else
+ m_lastBase = ElfInfo();
+ }
newElfs.push_back(elf);
diff --git a/app/perfelfmap.h b/app/perfelfmap.h
index 9480f61..cb8c8fd 100644
--- a/app/perfelfmap.h
+++ b/app/perfelfmap.h
@@ -73,6 +73,11 @@ public:
&& baseAddr == rhs.baseAddr;
}
+ bool operator!=(const ElfInfo& rhs) const
+ {
+ return !operator==(rhs);
+ }
+
QFileInfo localFile;
QByteArray originalFileName;
QByteArray originalPath;
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp
index 8383b47..bedee81 100644
--- a/app/perfsymboltable.cpp
+++ b/app/perfsymboltable.cpp
@@ -549,9 +549,9 @@ Dwfl_Module *PerfSymbolTable::module(quint64 addr, const PerfElfMap::ElfInfo &el
if (!m_dwfl)
return nullptr;
- if (elf.pgoff && elf.hasBaseAddr()) {
+ if (elf.hasBaseAddr() && elf.baseAddr != elf.addr) {
const auto base = m_elfs.findElf(elf.baseAddr);
- if (base.addr == elf.baseAddr && !base.pgoff && elf.originalPath == base.originalPath)
+ if (base.addr == elf.baseAddr && !base.pgoff && elf.originalPath == base.originalPath && elf.addr != base.addr)
return module(addr, base);
qWarning() << "stale base mapping referenced:" << elf << base << dec << m_pid << hex << addr;
}
@@ -909,7 +909,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel,
if (elf.isValid()) {
binaryId = m_unwind->resolveString(elf.originalFileName);
binaryPathId = m_unwind->resolveString(elf.originalPath);
- elfStart = elf.addr;
+ elfStart = elf.hasBaseAddr() ? elf.baseAddr : elf.addr;
}
Dwfl_Module *mod = module(ip, elf);
diff --git a/tests/auto/elfmap/tst_elfmap.cpp b/tests/auto/elfmap/tst_elfmap.cpp
index c961b58..a255930 100644
--- a/tests/auto/elfmap/tst_elfmap.cpp
+++ b/tests/auto/elfmap/tst_elfmap.cpp
@@ -48,7 +48,7 @@ private slots:
PerfElfMap map;
QVERIFY(map.isEmpty());
- const PerfElfMap::ElfInfo first({}, 100, 10, 0);
+ const PerfElfMap::ElfInfo first({}, 100, 10, 0, "foo", "/foo");
QVERIFY(registerElf(&map, first).isEmpty());
QVERIFY(!map.isEmpty());
@@ -59,7 +59,7 @@ private slots:
QCOMPARE(map.findElf(109), first);
QCOMPARE(map.findElf(110), invalid);
- const PerfElfMap::ElfInfo second({}, 0, 10, 0);
+ const PerfElfMap::ElfInfo second({}, 0, 10, 0, "bar", "/bar");
QVERIFY(registerElf(&map, second).isEmpty());
QCOMPARE(map.findElf(0), second);
@@ -99,8 +99,10 @@ private slots:
QVERIFY(registerElf(&map, first).isEmpty());
QCOMPARE(map.findElf(110), first);
- const PerfElfMap::ElfInfo second(file1, 105, 20, 0);
+ PerfElfMap::ElfInfo second(file1, 105, 20, 0);
QCOMPARE(registerElf(&map, second), QVector<PerfElfMap::ElfInfo>{first});
+ if (firstIsFile)
+ second.baseAddr = first.addr;
QCOMPARE(map.findElf(110), second);
const PerfElfMap::ElfInfo fragment1(file1, 95, 10, 0);
@@ -156,41 +158,45 @@ private slots:
void testExtendMapping()
{
+ QTemporaryFile file;
+ QVERIFY(file.open());
+ const auto fileInfo = QFileInfo(file.fileName());
+
PerfElfMap map;
- const PerfElfMap::ElfInfo first({}, 0, 5000, 0, "lalala.so", "/tmp/lalala.so");
+ const PerfElfMap::ElfInfo first(fileInfo, 0, 5000, 0);
registerElf(&map, first);
QCOMPARE(map.findElf(100), first);
// fully contained in the first mapping
- const PerfElfMap::ElfInfo second({}, 20, 500, 20, "lalala.so", "/tmp/lalala.so");
+ const PerfElfMap::ElfInfo second(fileInfo, 20, 500, 20);
registerElf(&map, second);
QCOMPARE(map.findElf(100), first);
// extend the first mapping
- const PerfElfMap::ElfInfo third({}, 2000, 8000, 2000, "lalala.so", "/tmp/lalala.so");
+ const PerfElfMap::ElfInfo third(fileInfo, 2000, 8000, 2000);
registerElf(&map, third);
- const PerfElfMap::ElfInfo extended({}, 0, 10000, 0, "lalala.so", "/tmp/lalala.so");
+ const PerfElfMap::ElfInfo extended(fileInfo, 0, 10000, 0);
QCOMPARE(map.findElf(100), extended);
QCOMPARE(map.findElf(2200), extended);
// this has a gap, so don't extend directly
- PerfElfMap::ElfInfo fourth({}, 12000, 100, 100, "lalala.so", "/tmp/lalala.so");
+ PerfElfMap::ElfInfo fourth(fileInfo, 12000, 100, 100);
registerElf(&map, fourth);
QVERIFY(!fourth.hasBaseAddr());
fourth.baseAddr = 0;
QVERIFY(fourth.hasBaseAddr());
QCOMPARE(map.findElf(12000), fourth);
- PerfElfMap::ElfInfo fifth({}, 2000, 500, 3000, "lalala.so", "/tmp/lalala.so");
+ PerfElfMap::ElfInfo fifth(fileInfo, 2000, 500, 3000);
QVERIFY(!fifth.hasBaseAddr()); // base addr will be set on registering based on first mmap.
registerElf(&map, fifth);
fifth.baseAddr = 0;
QCOMPARE(map.findElf(2200), fifth);
- const PerfElfMap::ElfInfo remainder1({}, 0, 2000, 0, "lalala.so", "/tmp/lalala.so");
+ const PerfElfMap::ElfInfo remainder1(fileInfo, 0, 2000, 0);
QCOMPARE(map.findElf(100), remainder1);
- const PerfElfMap::ElfInfo remainder2({}, 2500, 7500, 2500, "lalala.so", "/tmp/lalala.so");
+ const PerfElfMap::ElfInfo remainder2(fileInfo, 2500, 7500, 2500);
QCOMPARE(map.findElf(3000), remainder2);
}