diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2022-05-28 22:28:37 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2022-06-08 20:18:20 +0000 |
commit | 443bd9ba86615f319fecd3fbb47f1c2413ae373c (patch) | |
tree | ac280fdd1a6130f31fe65133ddca5cdb111a0f17 | |
parent | 10c8a4e0ce9134f2d5cabb162b3b6d1f287ce8b7 (diff) |
Move code to extract symbol cache into perfaddresscache
This makes the code more easily reusable and moves code that
belongs together logically into the same file.
Change-Id: Icce3a1ce4dc05f3a7cd9333fa7c88bd3a1b118ec
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | app/perfaddresscache.cpp | 17 | ||||
-rw-r--r-- | app/perfaddresscache.h | 18 | ||||
-rw-r--r-- | app/perfsymboltable.cpp | 35 |
3 files changed, 38 insertions, 32 deletions
diff --git a/app/perfaddresscache.cpp b/app/perfaddresscache.cpp index 825c2cd..278ea2f 100644 --- a/app/perfaddresscache.cpp +++ b/app/perfaddresscache.cpp @@ -120,3 +120,20 @@ void PerfAddressCache::setSymbolCache(const QByteArray &filePath, SymbolCache ca cache.erase(std::unique(cache.begin(), cache.end()), cache.end()); m_symbolCache[filePath] = cache; } + +PerfAddressCache::SymbolCache PerfAddressCache::extractSymbols(Dwfl_Module *module, quint64 elfStart, bool isArmArch) +{ + PerfAddressCache::SymbolCache cache; + + const auto numSymbols = dwfl_module_getsymtab(module); + for (int i = 0; i < numSymbols; ++i) { + GElf_Sym sym; + GElf_Addr symAddr; + const auto symbol = dwfl_module_getsym_info(module, i, &sym, &symAddr, nullptr, nullptr, nullptr); + if (symbol) { + const quint64 start = alignedAddress(sym.st_value, isArmArch); + cache.append({symAddr - elfStart, start, sym.st_size, symbol}); + } + } + return cache; +} diff --git a/app/perfaddresscache.h b/app/perfaddresscache.h index 055ac3e..fd978bd 100644 --- a/app/perfaddresscache.h +++ b/app/perfaddresscache.h @@ -25,9 +25,23 @@ #include "perfelfmap.h" +#include <libdwfl.h> + class PerfAddressCache { public: + static quint64 symbolAddress(quint64 addr, bool isArmArch) + { + // For dwfl API call we need the raw pointer into symtab, so we need to adjust ip. + return (!isArmArch || (addr & 1)) ? addr : addr + 1; + } + + static quint64 alignedAddress(quint64 addr, bool isArmArch) + { + // Adjust addr back. The symtab entries are 1 off for all practical purposes. + return (isArmArch && (addr & 1)) ? addr - 1 : addr; + } + struct AddressCacheEntry { AddressCacheEntry(int locationId = -1, bool isInterworking = false) @@ -73,6 +87,10 @@ public: /// find the symbol that encompasses @p relAddr in @p filePath /// if the found symbol wasn't yet demangled, it will be demangled now SymbolCacheEntry findSymbol(const QByteArray &filePath, quint64 relAddr); + + /// extract all symbols in @p module into a structure suitable to be passed to @p setSymbols + static SymbolCache extractSymbols(Dwfl_Module *module, quint64 elfStart, bool isArmArch); + private: QHash<QByteArray, OffsetAddressCache> m_cache; QHash<QByteArray, SymbolCache> m_symbolCache; diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp index ac8ae11..f025670 100644 --- a/app/perfsymboltable.cpp +++ b/app/perfsymboltable.cpp @@ -611,35 +611,6 @@ static QByteArray fakeSymbolFromSection(Dwfl_Module *mod, Dwarf_Addr addr) return sym; } -static quint64 symbolAddress(quint64 addr, bool isArmArch) -{ - // For dwfl API call we need the raw pointer into symtab, so we need to adjust ip. - return (!isArmArch || (addr & 1)) ? addr : addr + 1; -} - -static quint64 alignedAddress(quint64 addr, bool isArmArch) -{ - // Adjust addr back. The symtab entries are 1 off for all practical purposes. - return (isArmArch && (addr & 1)) ? addr - 1 : addr; -} - -static PerfAddressCache::SymbolCache cacheSymbols(Dwfl_Module *module, quint64 elfStart, bool isArmArch) -{ - PerfAddressCache::SymbolCache cache; - - const auto numSymbols = dwfl_module_getsymtab(module); - for (int i = 0; i < numSymbols; ++i) { - GElf_Sym sym; - GElf_Addr symAddr; - const auto symbol = dwfl_module_getsym_info(module, i, &sym, &symAddr, nullptr, nullptr, nullptr); - if (symbol) { - const quint64 start = alignedAddress(sym.st_value, isArmArch); - cache.append({symAddr - elfStart, start, sym.st_size, symbol}); - } - } - return cache; -} - int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel, bool *isInterworking) { @@ -666,7 +637,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel, Dwfl_Module *mod = module(ip, elf); const bool isArmArch = (m_unwind->architecture() == PerfRegisterInfo::ARCH_ARM); - PerfUnwind::Location addressLocation(symbolAddress(ip, isArmArch), 0, -1, m_pid); + PerfUnwind::Location addressLocation(PerfAddressCache::symbolAddress(ip, isArmArch), 0, -1, m_pid); PerfUnwind::Location functionLocation(addressLocation); QByteArray symname; @@ -680,7 +651,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel, // cache all symbols in a sorted lookup table and demangle them on-demand // note that the symbols within the symtab aren't necessarily sorted, // which makes searching repeatedly via dwfl_module_addrinfo potentially very slow - addressCache->setSymbolCache(elf.originalPath, cacheSymbols(mod, elfStart, isArmArch)); + addressCache->setSymbolCache(elf.originalPath, PerfAddressCache::extractSymbols(mod, elfStart, isArmArch)); } auto cachedAddrInfo = addressCache->findSymbol(elf.originalPath, addressLocation.address - elfStart); @@ -689,7 +660,7 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel, symname = cachedAddrInfo.symname; start = cachedAddrInfo.value; size = cachedAddrInfo.size; - relAddr = alignedAddress(start + off, isArmArch); + relAddr = PerfAddressCache::alignedAddress(start + off, isArmArch); Dwarf_Addr bias = 0; functionLocation.address -= off; // in case we don't find anything better |