diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2020-06-12 18:03:10 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2020-06-15 08:24:49 +0000 |
commit | 9cdf95c8c81b7a1422da52099e8fb9544090fc5a (patch) | |
tree | fe0665c0ca51751c66c54ce00663068ca6cfe859 | |
parent | 57989ee1b2d919698881dacb763338aedece030f (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.cpp | 5 | ||||
-rw-r--r-- | tests/auto/addresscache/tst_addresscache.cpp | 12 |
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()); } |