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 }