SymbolFile.h revision 360784
1//===-- SymbolFile.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_SymbolFile_h_
10#define liblldb_SymbolFile_h_
11
12#include "lldb/Core/PluginInterface.h"
13#include "lldb/Symbol/CompilerDecl.h"
14#include "lldb/Symbol/CompilerDeclContext.h"
15#include "lldb/Symbol/CompilerType.h"
16#include "lldb/Symbol/Function.h"
17#include "lldb/Symbol/SourceModule.h"
18#include "lldb/Symbol/Type.h"
19#include "lldb/Symbol/TypeList.h"
20#include "lldb/Symbol/TypeSystem.h"
21#include "lldb/lldb-private.h"
22#include "llvm/ADT/DenseSet.h"
23#include "llvm/Support/Errc.h"
24
25#include <mutex>
26
27#if defined(LLDB_CONFIGURATION_DEBUG)
28#define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock())
29#else
30#define ASSERT_MODULE_LOCK(expr) ((void)0)
31#endif
32
33namespace lldb_private {
34
35class SymbolFile : public PluginInterface {
36  /// LLVM RTTI support.
37  static char ID;
38
39public:
40  /// LLVM RTTI support.
41  /// \{
42  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
43  static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
44  /// \}
45
46  // Symbol file ability bits.
47  //
48  // Each symbol file can claim to support one or more symbol file abilities.
49  // These get returned from SymbolFile::GetAbilities(). These help us to
50  // determine which plug-in will be best to load the debug information found
51  // in files.
52  enum Abilities {
53    CompileUnits = (1u << 0),
54    LineTables = (1u << 1),
55    Functions = (1u << 2),
56    Blocks = (1u << 3),
57    GlobalVariables = (1u << 4),
58    LocalVariables = (1u << 5),
59    VariableTypes = (1u << 6),
60    kAllAbilities = ((1u << 7) - 1u)
61  };
62
63  static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp);
64
65  // Constructors and Destructors
66  SymbolFile(lldb::ObjectFileSP objfile_sp)
67      : m_objfile_sp(std::move(objfile_sp)), m_abilities(0),
68        m_calculated_abilities(false) {}
69
70  ~SymbolFile() override {}
71
72  /// Get a mask of what this symbol file supports for the object file
73  /// that it was constructed with.
74  ///
75  /// Each symbol file gets to respond with a mask of abilities that
76  /// it supports for each object file. This happens when we are
77  /// trying to figure out which symbol file plug-in will get used
78  /// for a given object file. The plug-in that responds with the
79  /// best mix of "SymbolFile::Abilities" bits set, will get chosen to
80  /// be the symbol file parser. This allows each plug-in to check for
81  /// sections that contain data a symbol file plug-in would need. For
82  /// example the DWARF plug-in requires DWARF sections in a file that
83  /// contain debug information. If the DWARF plug-in doesn't find
84  /// these sections, it won't respond with many ability bits set, and
85  /// we will probably fall back to the symbol table SymbolFile plug-in
86  /// which uses any information in the symbol table. Also, plug-ins
87  /// might check for some specific symbols in a symbol table in the
88  /// case where the symbol table contains debug information (STABS
89  /// and COFF). Not a lot of work should happen in these functions
90  /// as the plug-in might not get selected due to another plug-in
91  /// having more abilities. Any initialization work should be saved
92  /// for "void SymbolFile::InitializeObject()" which will get called
93  /// on the SymbolFile object with the best set of abilities.
94  ///
95  /// \return
96  ///     A uint32_t mask containing bits from the SymbolFile::Abilities
97  ///     enumeration. Any bits that are set represent an ability that
98  ///     this symbol plug-in can parse from the object file.
99  uint32_t GetAbilities() {
100    if (!m_calculated_abilities) {
101      m_abilities = CalculateAbilities();
102      m_calculated_abilities = true;
103    }
104
105    return m_abilities;
106  }
107
108  virtual uint32_t CalculateAbilities() = 0;
109
110  /// Symbols file subclasses should override this to return the Module that
111  /// owns the TypeSystem that this symbol file modifies type information in.
112  virtual std::recursive_mutex &GetModuleMutex() const;
113
114  /// Initialize the SymbolFile object.
115  ///
116  /// The SymbolFile object with the best set of abilities (detected
117  /// in "uint32_t SymbolFile::GetAbilities()) will have this function
118  /// called if it is chosen to parse an object file. More complete
119  /// initialization can happen in this function which will get called
120  /// prior to any other functions in the SymbolFile protocol.
121  virtual void InitializeObject() {}
122
123  // Compile Unit function calls
124  // Approach 1 - iterator
125  uint32_t GetNumCompileUnits();
126  lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx);
127
128  Symtab *GetSymtab();
129
130  virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0;
131  virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0;
132  virtual bool ParseLineTable(CompileUnit &comp_unit) = 0;
133  virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0;
134
135  /// Apply a lambda to each external lldb::Module referenced by this
136  /// \p comp_unit. Recursively also descends into the referenced external
137  /// modules of any encountered compilation unit.
138  ///
139  /// \param comp_unit
140  ///     When this SymbolFile consists of multiple auxilliary
141  ///     SymbolFiles, for example, a Darwin debug map that references
142  ///     multiple .o files, comp_unit helps choose the auxilliary
143  ///     file. In most other cases comp_unit's symbol file is
144  ///     identiacal with *this.
145  ///
146  /// \param[in] lambda
147  ///     The lambda that should be applied to every function. The lambda can
148  ///     return true if the iteration should be aborted earlier.
149  ///
150  /// \param visited_symbol_files
151  ///     A set of SymbolFiles that were already visited to avoid
152  ///     visiting one file more than once.
153  ///
154  /// \return
155  ///     If the lambda early-exited, this function returns true to
156  ///     propagate the early exit.
157  virtual bool ForEachExternalModule(
158      lldb_private::CompileUnit &comp_unit,
159      llvm::DenseSet<lldb_private::SymbolFile *> &visited_symbol_files,
160      llvm::function_ref<bool(Module &)> lambda) {
161    return false;
162  }
163  virtual bool ParseSupportFiles(CompileUnit &comp_unit,
164                                 FileSpecList &support_files) = 0;
165  virtual size_t ParseTypes(CompileUnit &comp_unit) = 0;
166  virtual bool ParseIsOptimized(CompileUnit &comp_unit) { return false; }
167
168  virtual bool
169  ParseImportedModules(const SymbolContext &sc,
170                       std::vector<SourceModule> &imported_modules) = 0;
171  virtual size_t ParseBlocksRecursive(Function &func) = 0;
172  virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0;
173  virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0;
174
175
176  /// The characteristics of an array type.
177  struct ArrayInfo {
178    int64_t first_index = 0;
179    llvm::SmallVector<uint64_t, 1> element_orders;
180    uint32_t byte_stride = 0;
181    uint32_t bit_stride = 0;
182  };
183  /// If \c type_uid points to an array type, return its characteristics.
184  /// To support variable-length array types, this function takes an
185  /// optional \p ExtecutionContext. If \c exe_ctx is non-null, the
186  /// dynamic characteristics for that context are returned.
187  virtual llvm::Optional<ArrayInfo>
188  GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,
189                            const lldb_private::ExecutionContext *exe_ctx) = 0;
190
191  virtual bool CompleteType(CompilerType &compiler_type) = 0;
192  virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {}
193  virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) {
194    return CompilerDecl();
195  }
196  virtual CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) {
197    return CompilerDeclContext();
198  }
199  virtual CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) {
200    return CompilerDeclContext();
201  }
202  virtual uint32_t ResolveSymbolContext(const Address &so_addr,
203                                        lldb::SymbolContextItem resolve_scope,
204                                        SymbolContext &sc) = 0;
205  virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec,
206                                        uint32_t line, bool check_inlines,
207                                        lldb::SymbolContextItem resolve_scope,
208                                        SymbolContextList &sc_list);
209
210  virtual void DumpClangAST(Stream &s) {}
211  virtual void
212  FindGlobalVariables(ConstString name,
213                      const CompilerDeclContext *parent_decl_ctx,
214                      uint32_t max_matches, VariableList &variables);
215  virtual void FindGlobalVariables(const RegularExpression &regex,
216                                   uint32_t max_matches,
217                                   VariableList &variables);
218  virtual void FindFunctions(ConstString name,
219                             const CompilerDeclContext *parent_decl_ctx,
220                             lldb::FunctionNameType name_type_mask,
221                             bool include_inlines, SymbolContextList &sc_list);
222  virtual void FindFunctions(const RegularExpression &regex,
223                             bool include_inlines, SymbolContextList &sc_list);
224  virtual void
225  FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
226            uint32_t max_matches,
227            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
228            TypeMap &types);
229
230  /// Find types specified by a CompilerContextPattern.
231  /// \param languages
232  ///     Only return results in these languages.
233  /// \param searched_symbol_files
234  ///     Prevents one file from being visited multiple times.
235  virtual void
236  FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
237            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
238            TypeMap &types);
239
240  virtual void
241  GetMangledNamesForFunction(const std::string &scope_qualified_name,
242                             std::vector<ConstString> &mangled_names);
243
244  virtual void GetTypes(lldb_private::SymbolContextScope *sc_scope,
245                        lldb::TypeClass type_mask,
246                        lldb_private::TypeList &type_list) = 0;
247
248  virtual void PreloadSymbols();
249
250  virtual llvm::Expected<lldb_private::TypeSystem &>
251  GetTypeSystemForLanguage(lldb::LanguageType language);
252
253  virtual CompilerDeclContext
254  FindNamespace(ConstString name,
255                const CompilerDeclContext *parent_decl_ctx) {
256    return CompilerDeclContext();
257  }
258
259  ObjectFile *GetObjectFile() { return m_objfile_sp.get(); }
260  const ObjectFile *GetObjectFile() const { return m_objfile_sp.get(); }
261  ObjectFile *GetMainObjectFile();
262
263  virtual std::vector<std::unique_ptr<CallEdge>>
264  ParseCallEdgesInFunction(UserID func_id) {
265    return {};
266  }
267
268  virtual void AddSymbols(Symtab &symtab) {}
269
270  /// Notify the SymbolFile that the file addresses in the Sections
271  /// for this module have been changed.
272  virtual void SectionFileAddressesChanged();
273
274  struct RegisterInfoResolver {
275    virtual ~RegisterInfoResolver(); // anchor
276
277    virtual const RegisterInfo *ResolveName(llvm::StringRef name) const = 0;
278    virtual const RegisterInfo *ResolveNumber(lldb::RegisterKind kind,
279                                              uint32_t number) const = 0;
280  };
281  virtual lldb::UnwindPlanSP
282  GetUnwindPlan(const Address &address, const RegisterInfoResolver &resolver) {
283    return nullptr;
284  }
285
286  /// Return the number of stack bytes taken up by the parameters to this
287  /// function.
288  virtual llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) {
289    return llvm::createStringError(make_error_code(llvm::errc::not_supported),
290                                   "Operation not supported.");
291  }
292
293  virtual void Dump(Stream &s);
294
295protected:
296  void AssertModuleLock();
297  virtual uint32_t CalculateNumCompileUnits() = 0;
298  virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;
299  virtual TypeList &GetTypeList() { return m_type_list; }
300
301  void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp);
302
303  lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in
304                                   // case it isn't the same as the module
305                                   // object file (debug symbols in a separate
306                                   // file)
307  llvm::Optional<std::vector<lldb::CompUnitSP>> m_compile_units;
308  TypeList m_type_list;
309  Symtab *m_symtab = nullptr;
310  uint32_t m_abilities;
311  bool m_calculated_abilities;
312
313private:
314  DISALLOW_COPY_AND_ASSIGN(SymbolFile);
315};
316
317} // namespace lldb_private
318
319#endif // liblldb_SymbolFile_h_
320