File indexing completed on 2024-05-05 05:44:16
0001 /* 0002 symbolcache.cpp 0003 0004 SPDX-FileCopyrightText: 2022 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com> 0005 SPDX-FileContributor: Milian Wolff <milian.wolff@kdab.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "symbolcache.h" 0011 0012 #include "dwarfdiecache.h" 0013 0014 #include <algorithm> 0015 0016 static bool operator<(const SymbolCache::SymbolCacheEntry& lhs, const SymbolCache::SymbolCacheEntry& rhs) 0017 { 0018 return lhs.offset < rhs.offset; 0019 } 0020 0021 static bool operator==(const SymbolCache::SymbolCacheEntry& lhs, const SymbolCache::SymbolCacheEntry& rhs) 0022 { 0023 return lhs.offset == rhs.offset && lhs.size == rhs.size; 0024 } 0025 0026 static bool operator<(const SymbolCache::SymbolCacheEntry& lhs, uint64_t addr) 0027 { 0028 return lhs.offset < addr; 0029 } 0030 0031 bool SymbolCache::hasSymbols(const std::string& filePath) const 0032 { 0033 return m_symbolCache.contains(filePath); 0034 } 0035 0036 SymbolCache::SymbolCacheEntry SymbolCache::findSymbol(const std::string& filePath, uint64_t relAddr) 0037 { 0038 auto& symbols = m_symbolCache[filePath]; 0039 auto it = std::lower_bound(symbols.begin(), symbols.end(), relAddr); 0040 0041 // demangle symbols on demand instead of demangling all symbols directly 0042 // hopefully most of the symbols we won't ever encounter after all 0043 auto lazyDemangle = [](SymbolCache::SymbolCacheEntry& entry) { 0044 if (!entry.demangled) { 0045 entry.symname = demangle(entry.symname); 0046 entry.demangled = true; 0047 } 0048 return entry; 0049 }; 0050 0051 if (it != symbols.end() && it->offset == relAddr) 0052 return lazyDemangle(*it); 0053 if (it == symbols.begin()) 0054 return {}; 0055 0056 --it; 0057 0058 if (it->offset <= relAddr && (it->offset + it->size > relAddr || (it->size == 0))) { 0059 return lazyDemangle(*it); 0060 } 0061 return {}; 0062 } 0063 0064 void SymbolCache::setSymbols(const std::string& filePath, Symbols symbols) 0065 { 0066 /* 0067 * use stable_sort to produce results that are comparable to what addr2line would 0068 * return when we have entries like this in the symtab: 0069 * 0070 * 000000000045a130 l F .text 0000000000000033 .hidden __memmove_avx_unaligned 0071 * 000000000045a180 l F .text 00000000000003d8 .hidden __memmove_avx_unaligned_erms 0072 * 000000000045a180 l F .text 00000000000003d8 .hidden __memcpy_avx_unaligned_erms 0073 * 000000000045a130 l F .text 0000000000000033 .hidden __memcpy_avx_unaligned 0074 * 0075 * here, addr2line would always find the first entry. we want to do the same 0076 */ 0077 0078 std::stable_sort(symbols.begin(), symbols.end()); 0079 symbols.erase(std::unique(symbols.begin(), symbols.end()), symbols.end()); 0080 m_symbolCache[filePath] = std::move(symbols); 0081 }