1 //===-- Symtab.h ------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SYMBOL_SYMTAB_H 10 #define LLDB_SYMBOL_SYMTAB_H 11 12 #include "lldb/Core/UniqueCStringMap.h" 13 #include "lldb/Symbol/Symbol.h" 14 #include "lldb/Utility/RangeMap.h" 15 #include "lldb/lldb-private.h" 16 #include <mutex> 17 #include <vector> 18 19 namespace lldb_private { 20 21 class Symtab { 22 public: 23 typedef std::vector<uint32_t> IndexCollection; 24 typedef UniqueCStringMap<uint32_t> NameToIndexMap; 25 26 enum Debug { 27 eDebugNo, // Not a debug symbol 28 eDebugYes, // A debug symbol 29 eDebugAny 30 }; 31 32 enum Visibility { eVisibilityAny, eVisibilityExtern, eVisibilityPrivate }; 33 34 Symtab(ObjectFile *objfile); 35 ~Symtab(); 36 37 void PreloadSymbols(); 38 void Reserve(size_t count); 39 Symbol *Resize(size_t count); 40 uint32_t AddSymbol(const Symbol &symbol); 41 size_t GetNumSymbols() const; 42 void SectionFileAddressesChanged(); 43 void 44 Dump(Stream *s, Target *target, SortOrder sort_type, 45 Mangled::NamePreference name_preference = Mangled::ePreferDemangled); 46 void Dump(Stream *s, Target *target, std::vector<uint32_t> &indexes, 47 Mangled::NamePreference name_preference = 48 Mangled::ePreferDemangled) const; 49 uint32_t GetIndexForSymbol(const Symbol *symbol) const; GetMutex()50 std::recursive_mutex &GetMutex() { return m_mutex; } 51 Symbol *FindSymbolByID(lldb::user_id_t uid) const; 52 Symbol *SymbolAtIndex(size_t idx); 53 const Symbol *SymbolAtIndex(size_t idx) const; 54 Symbol *FindSymbolWithType(lldb::SymbolType symbol_type, 55 Debug symbol_debug_type, 56 Visibility symbol_visibility, uint32_t &start_idx); 57 /// Get the parent symbol for the given symbol. 58 /// 59 /// Many symbols in symbol tables are scoped by other symbols that 60 /// contain one or more symbol. This function will look for such a 61 /// containing symbol and return it if there is one. 62 const Symbol *GetParent(Symbol *symbol) const; 63 uint32_t AppendSymbolIndexesWithType(lldb::SymbolType symbol_type, 64 std::vector<uint32_t> &indexes, 65 uint32_t start_idx = 0, 66 uint32_t end_index = UINT32_MAX) const; 67 uint32_t AppendSymbolIndexesWithTypeAndFlagsValue( 68 lldb::SymbolType symbol_type, uint32_t flags_value, 69 std::vector<uint32_t> &indexes, uint32_t start_idx = 0, 70 uint32_t end_index = UINT32_MAX) const; 71 uint32_t AppendSymbolIndexesWithType(lldb::SymbolType symbol_type, 72 Debug symbol_debug_type, 73 Visibility symbol_visibility, 74 std::vector<uint32_t> &matches, 75 uint32_t start_idx = 0, 76 uint32_t end_index = UINT32_MAX) const; 77 uint32_t AppendSymbolIndexesWithName(ConstString symbol_name, 78 std::vector<uint32_t> &matches); 79 uint32_t AppendSymbolIndexesWithName(ConstString symbol_name, 80 Debug symbol_debug_type, 81 Visibility symbol_visibility, 82 std::vector<uint32_t> &matches); 83 uint32_t AppendSymbolIndexesWithNameAndType(ConstString symbol_name, 84 lldb::SymbolType symbol_type, 85 std::vector<uint32_t> &matches); 86 uint32_t AppendSymbolIndexesWithNameAndType(ConstString symbol_name, 87 lldb::SymbolType symbol_type, 88 Debug symbol_debug_type, 89 Visibility symbol_visibility, 90 std::vector<uint32_t> &matches); 91 uint32_t 92 AppendSymbolIndexesMatchingRegExAndType(const RegularExpression ®ex, 93 lldb::SymbolType symbol_type, 94 std::vector<uint32_t> &indexes); 95 uint32_t AppendSymbolIndexesMatchingRegExAndType( 96 const RegularExpression ®ex, lldb::SymbolType symbol_type, 97 Debug symbol_debug_type, Visibility symbol_visibility, 98 std::vector<uint32_t> &indexes); 99 void FindAllSymbolsWithNameAndType(ConstString name, 100 lldb::SymbolType symbol_type, 101 std::vector<uint32_t> &symbol_indexes); 102 void FindAllSymbolsWithNameAndType(ConstString name, 103 lldb::SymbolType symbol_type, 104 Debug symbol_debug_type, 105 Visibility symbol_visibility, 106 std::vector<uint32_t> &symbol_indexes); 107 void FindAllSymbolsMatchingRexExAndType( 108 const RegularExpression ®ex, lldb::SymbolType symbol_type, 109 Debug symbol_debug_type, Visibility symbol_visibility, 110 std::vector<uint32_t> &symbol_indexes); 111 Symbol *FindFirstSymbolWithNameAndType(ConstString name, 112 lldb::SymbolType symbol_type, 113 Debug symbol_debug_type, 114 Visibility symbol_visibility); 115 Symbol *FindSymbolAtFileAddress(lldb::addr_t file_addr); 116 Symbol *FindSymbolContainingFileAddress(lldb::addr_t file_addr); 117 void ForEachSymbolContainingFileAddress( 118 lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback); 119 void FindFunctionSymbols(ConstString name, uint32_t name_type_mask, 120 SymbolContextList &sc_list); 121 void CalculateSymbolSizes(); 122 123 void SortSymbolIndexesByValue(std::vector<uint32_t> &indexes, 124 bool remove_duplicates) const; 125 126 static void DumpSymbolHeader(Stream *s); 127 Finalize()128 void Finalize() { 129 // Shrink to fit the symbols so we don't waste memory 130 if (m_symbols.capacity() > m_symbols.size()) { 131 collection new_symbols(m_symbols.begin(), m_symbols.end()); 132 m_symbols.swap(new_symbols); 133 } 134 } 135 136 void AppendSymbolNamesToMap(const IndexCollection &indexes, 137 bool add_demangled, bool add_mangled, 138 NameToIndexMap &name_to_index_map) const; 139 GetObjectFile()140 ObjectFile *GetObjectFile() { return m_objfile; } 141 142 protected: 143 typedef std::vector<Symbol> collection; 144 typedef collection::iterator iterator; 145 typedef collection::const_iterator const_iterator; 146 class FileRangeToIndexMapCompare { 147 public: FileRangeToIndexMapCompare(const Symtab & symtab)148 FileRangeToIndexMapCompare(const Symtab &symtab) : m_symtab(symtab) {} operator()149 bool operator()(const uint32_t a_data, const uint32_t b_data) const { 150 return rank(a_data) > rank(b_data); 151 } 152 153 private: 154 // How much preferred is this symbol? rank(const uint32_t data)155 int rank(const uint32_t data) const { 156 const Symbol &symbol = *m_symtab.SymbolAtIndex(data); 157 if (symbol.IsExternal()) 158 return 3; 159 if (symbol.IsWeak()) 160 return 2; 161 if (symbol.IsDebug()) 162 return 0; 163 return 1; 164 } 165 const Symtab &m_symtab; 166 }; 167 typedef RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t, 0, 168 FileRangeToIndexMapCompare> 169 FileRangeToIndexMap; 170 void InitNameIndexes(); 171 void InitAddressIndexes(); 172 173 ObjectFile *m_objfile; 174 collection m_symbols; 175 FileRangeToIndexMap m_file_addr_to_index; 176 UniqueCStringMap<uint32_t> m_name_to_index; 177 UniqueCStringMap<uint32_t> m_basename_to_index; 178 UniqueCStringMap<uint32_t> m_method_to_index; 179 UniqueCStringMap<uint32_t> m_selector_to_index; 180 mutable std::recursive_mutex 181 m_mutex; // Provide thread safety for this symbol table 182 bool m_file_addr_to_index_computed : 1, m_name_indexes_computed : 1; 183 184 private: CheckSymbolAtIndex(size_t idx,Debug symbol_debug_type,Visibility symbol_visibility)185 bool CheckSymbolAtIndex(size_t idx, Debug symbol_debug_type, 186 Visibility symbol_visibility) const { 187 switch (symbol_debug_type) { 188 case eDebugNo: 189 if (m_symbols[idx].IsDebug()) 190 return false; 191 break; 192 193 case eDebugYes: 194 if (!m_symbols[idx].IsDebug()) 195 return false; 196 break; 197 198 case eDebugAny: 199 break; 200 } 201 202 switch (symbol_visibility) { 203 case eVisibilityAny: 204 return true; 205 206 case eVisibilityExtern: 207 return m_symbols[idx].IsExternal(); 208 209 case eVisibilityPrivate: 210 return !m_symbols[idx].IsExternal(); 211 } 212 return false; 213 } 214 215 void SymbolIndicesToSymbolContextList(std::vector<uint32_t> &symbol_indexes, 216 SymbolContextList &sc_list); 217 218 void RegisterMangledNameEntry( 219 uint32_t value, std::set<const char *> &class_contexts, 220 std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog, 221 RichManglingContext &rmc); 222 223 void RegisterBacklogEntry(const NameToIndexMap::Entry &entry, 224 const char *decl_context, 225 const std::set<const char *> &class_contexts); 226 227 Symtab(const Symtab &) = delete; 228 const Symtab &operator=(const Symtab &) = delete; 229 }; 230 231 } // namespace lldb_private 232 233 #endif // LLDB_SYMBOL_SYMTAB_H 234