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