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
19namespace lldb_private {
20
21class Symtab {
22public:
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;
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 &regex,
93 lldb::SymbolType symbol_type,
94 std::vector<uint32_t> &indexes);
95 uint32_t AppendSymbolIndexesMatchingRegExAndType(
96 const RegularExpression &regex, 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 &regex, 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
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
140 ObjectFile *GetObjectFile() { return m_objfile; }
141
142protected:
143 typedef std::vector<Symbol> collection;
144 typedef collection::iterator iterator;
145 typedef collection::const_iterator const_iterator;
146 class FileRangeToIndexMapCompare {
147 public:
148 FileRangeToIndexMapCompare(const Symtab &symtab) : m_symtab(symtab) {}
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?
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
184private:
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