Symtab.h 9.2 KB

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