summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2020-06-12 18:03:10 +0200
committerMilian Wolff <milian.wolff@kdab.com>2020-06-15 08:24:49 +0000
commit9cdf95c8c81b7a1422da52099e8fb9544090fc5a (patch)
treefe0665c0ca51751c66c54ce00663068ca6cfe859
parent57989ee1b2d919698881dacb763338aedece030f (diff)
Allow address cache lookup for ElfInfo with pgoff / baseAddr
I have encountered cases where the ElfInfo we pass to the address cache is the pgoff-mmapped one. In that case, we need to take the baseAddr to compute the relative address, not the absolute address where the offsetted elf was mapped. In my case, the address was actually outside of the pgoff-mmapped one and within a different section apparently, which got handled properly by elfutils but our caching didn't handle this yet - we just asserted and failed. Change-Id: I2cd9d2cebbd60f00353ecbf413e020783374769e Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--app/perfaddresscache.cpp5
-rw-r--r--tests/auto/addresscache/tst_addresscache.cpp12
2 files changed, 15 insertions, 2 deletions
diff --git a/app/perfaddresscache.cpp b/app/perfaddresscache.cpp
index 27b646c..73db84d 100644
--- a/app/perfaddresscache.cpp
+++ b/app/perfaddresscache.cpp
@@ -23,9 +23,10 @@ namespace {
quint64 relativeAddress(const PerfElfMap::ElfInfo& elf, quint64 addr)
{
Q_ASSERT(elf.isValid());
- Q_ASSERT(elf.addr <= addr);
+ const auto elfAddr = elf.hasBaseAddr() ? elf.baseAddr : elf.addr;
+ Q_ASSERT(elfAddr <= addr);
Q_ASSERT((elf.addr + elf.length) > addr);
- return addr - elf.addr;
+ return addr - elfAddr;
}
}
diff --git a/tests/auto/addresscache/tst_addresscache.cpp b/tests/auto/addresscache/tst_addresscache.cpp
index 39a7860..5df3ae4 100644
--- a/tests/auto/addresscache/tst_addresscache.cpp
+++ b/tests/auto/addresscache/tst_addresscache.cpp
@@ -67,6 +67,10 @@ private slots:
PerfElfMap::ElfInfo info_a{{}, 0x100, 100, 0,
QByteArrayLiteral("libfoo_a.so"),
QByteArrayLiteral("/usr/lib/libfoo_a.so")};
+ PerfElfMap::ElfInfo info_a_offset{{}, 0x200, 100, 0x100,
+ QByteArrayLiteral("libfoo_a.so"),
+ QByteArrayLiteral("/usr/lib/libfoo_a.so")};
+ info_a_offset.baseAddr = info_a.addr;
PerfElfMap::ElfInfo info_b{{}, 0x100, 100, 0,
QByteArrayLiteral("libfoo_b.so"),
QByteArrayLiteral("/usr/lib/libfoo_b.so")};
@@ -74,6 +78,8 @@ private slots:
PerfAddressCache cache;
QVERIFY(!cache.findSymbol(info_a, 0x100).isValid());
+ QVERIFY(!cache.findSymbol(info_a_offset, 0x100).isValid());
+ QVERIFY(!cache.findSymbol(info_a_offset, 0x200).isValid());
QVERIFY(!cache.findSymbol(info_b, 0x100).isValid());
cache.cacheSymbol(info_a, 0x100, 10, "Foo");
@@ -83,8 +89,14 @@ private slots:
QCOMPARE(int(cached.offset), 0);
QCOMPARE(int(cached.size), 10);
QCOMPARE(cached.symname, "Foo");
+ const auto cached2 = cache.findSymbol(info_a_offset, addr);
+ QCOMPARE(cached2.isValid(), cached.isValid());
+ QCOMPARE(cached2.offset, cached.offset);
+ QCOMPARE(cached2.size, cached.size);
+ QCOMPARE(cached2.symname, cached.symname);
}
QVERIFY(!cache.findSymbol(info_a, 0x100 + 10).isValid());
+ QVERIFY(!cache.findSymbol(info_a_offset, 0x100 + 10).isValid());
QVERIFY(!cache.findSymbol(info_b, 0x100).isValid());
QVERIFY(!cache.findSymbol(info_b, 0x100 + 9).isValid());
}