SymbolFile.h revision 353358
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/lldb-private.h"
20
21#include "llvm/ADT/DenseSet.h"
22
23#include <mutex>
24
25#if defined(LLDB_CONFIGURATION_DEBUG)
26#define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock())
27#else
28#define ASSERT_MODULE_LOCK(expr) ((void)0)
29#endif
30
31namespace lldb_private {
32
33class SymbolFile : public PluginInterface {
34public:
35  // Symbol file ability bits.
36  //
37  // Each symbol file can claim to support one or more symbol file abilities.
38  // These get returned from SymbolFile::GetAbilities(). These help us to
39  // determine which plug-in will be best to load the debug information found
40  // in files.
41  enum Abilities {
42    CompileUnits = (1u << 0),
43    LineTables = (1u << 1),
44    Functions = (1u << 2),
45    Blocks = (1u << 3),
46    GlobalVariables = (1u << 4),
47    LocalVariables = (1u << 5),
48    VariableTypes = (1u << 6),
49    kAllAbilities = ((1u << 7) - 1u)
50  };
51
52  static SymbolFile *FindPlugin(ObjectFile *obj_file);
53
54  // Constructors and Destructors
55  SymbolFile(ObjectFile *obj_file)
56      : m_obj_file(obj_file), m_abilities(0), m_calculated_abilities(false) {}
57
58  ~SymbolFile() override {}
59
60  /// Get a mask of what this symbol file supports for the object file
61  /// that it was constructed with.
62  ///
63  /// Each symbol file gets to respond with a mask of abilities that
64  /// it supports for each object file. This happens when we are
65  /// trying to figure out which symbol file plug-in will get used
66  /// for a given object file. The plug-in that responds with the
67  /// best mix of "SymbolFile::Abilities" bits set, will get chosen to
68  /// be the symbol file parser. This allows each plug-in to check for
69  /// sections that contain data a symbol file plug-in would need. For
70  /// example the DWARF plug-in requires DWARF sections in a file that
71  /// contain debug information. If the DWARF plug-in doesn't find
72  /// these sections, it won't respond with many ability bits set, and
73  /// we will probably fall back to the symbol table SymbolFile plug-in
74  /// which uses any information in the symbol table. Also, plug-ins
75  /// might check for some specific symbols in a symbol table in the
76  /// case where the symbol table contains debug information (STABS
77  /// and COFF). Not a lot of work should happen in these functions
78  /// as the plug-in might not get selected due to another plug-in
79  /// having more abilities. Any initialization work should be saved
80  /// for "void SymbolFile::InitializeObject()" which will get called
81  /// on the SymbolFile object with the best set of abilities.
82  ///
83  /// \return
84  ///     A uint32_t mask containing bits from the SymbolFile::Abilities
85  ///     enumeration. Any bits that are set represent an ability that
86  ///     this symbol plug-in can parse from the object file.
87  uint32_t GetAbilities() {
88    if (!m_calculated_abilities) {
89      m_abilities = CalculateAbilities();
90      m_calculated_abilities = true;
91    }
92
93    return m_abilities;
94  }
95
96  virtual uint32_t CalculateAbilities() = 0;
97
98  /// Symbols file subclasses should override this to return the Module that
99  /// owns the TypeSystem that this symbol file modifies type information in.
100  virtual std::recursive_mutex &GetModuleMutex() const;
101
102  /// Initialize the SymbolFile object.
103  ///
104  /// The SymbolFile object with the best set of abilities (detected
105  /// in "uint32_t SymbolFile::GetAbilities()) will have this function
106  /// called if it is chosen to parse an object file. More complete
107  /// initialization can happen in this function which will get called
108  /// prior to any other functions in the SymbolFile protocol.
109  virtual void InitializeObject() {}
110
111  // Compile Unit function calls
112  // Approach 1 - iterator
113  virtual uint32_t GetNumCompileUnits() = 0;
114  virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0;
115
116  virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0;
117  virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0;
118  virtual bool ParseLineTable(CompileUnit &comp_unit) = 0;
119  virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0;
120  virtual bool ParseSupportFiles(CompileUnit &comp_unit,
121                                 FileSpecList &support_files) = 0;
122  virtual size_t ParseTypes(CompileUnit &comp_unit) = 0;
123  virtual bool ParseIsOptimized(CompileUnit &comp_unit) { return false; }
124
125  virtual bool
126  ParseImportedModules(const SymbolContext &sc,
127                       std::vector<SourceModule> &imported_modules) = 0;
128  virtual size_t ParseBlocksRecursive(Function &func) = 0;
129  virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0;
130  virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0;
131
132
133  /// The characteristics of an array type.
134  struct ArrayInfo {
135    int64_t first_index = 0;
136    llvm::SmallVector<uint64_t, 1> element_orders;
137    uint32_t byte_stride = 0;
138    uint32_t bit_stride = 0;
139  };
140  /// If \c type_uid points to an array type, return its characteristics.
141  /// To support variable-length array types, this function takes an
142  /// optional \p ExtecutionContext. If \c exe_ctx is non-null, the
143  /// dynamic characteristics for that context are returned.
144  virtual llvm::Optional<ArrayInfo>
145  GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,
146                            const lldb_private::ExecutionContext *exe_ctx) = 0;
147
148  virtual bool CompleteType(CompilerType &compiler_type) = 0;
149  virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {}
150  virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) {
151    return CompilerDecl();
152  }
153  virtual CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) {
154    return CompilerDeclContext();
155  }
156  virtual CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) {
157    return CompilerDeclContext();
158  }
159  virtual uint32_t ResolveSymbolContext(const Address &so_addr,
160                                        lldb::SymbolContextItem resolve_scope,
161                                        SymbolContext &sc) = 0;
162  virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec,
163                                        uint32_t line, bool check_inlines,
164                                        lldb::SymbolContextItem resolve_scope,
165                                        SymbolContextList &sc_list);
166
167  virtual void DumpClangAST(Stream &s) {}
168  virtual uint32_t
169  FindGlobalVariables(ConstString name,
170                      const CompilerDeclContext *parent_decl_ctx,
171                      uint32_t max_matches, VariableList &variables);
172  virtual uint32_t FindGlobalVariables(const RegularExpression &regex,
173                                       uint32_t max_matches,
174                                       VariableList &variables);
175  virtual uint32_t FindFunctions(ConstString name,
176                                 const CompilerDeclContext *parent_decl_ctx,
177                                 lldb::FunctionNameType name_type_mask,
178                                 bool include_inlines, bool append,
179                                 SymbolContextList &sc_list);
180  virtual uint32_t FindFunctions(const RegularExpression &regex,
181                                 bool include_inlines, bool append,
182                                 SymbolContextList &sc_list);
183  virtual uint32_t
184  FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
185            bool append, uint32_t max_matches,
186            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
187            TypeMap &types);
188  virtual size_t FindTypes(const std::vector<CompilerContext> &context,
189                           bool append, TypeMap &types);
190
191  virtual void
192  GetMangledNamesForFunction(const std::string &scope_qualified_name,
193                             std::vector<ConstString> &mangled_names);
194  //  virtual uint32_t        FindTypes (const SymbolContext& sc, const
195  //  RegularExpression& regex, bool append, uint32_t max_matches, TypeList&
196  //  types) = 0;
197  virtual TypeList *GetTypeList();
198  virtual size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
199                          lldb::TypeClass type_mask,
200                          lldb_private::TypeList &type_list) = 0;
201
202  virtual void PreloadSymbols();
203
204  virtual lldb_private::TypeSystem *
205  GetTypeSystemForLanguage(lldb::LanguageType language);
206
207  virtual CompilerDeclContext
208  FindNamespace(ConstString name,
209                const CompilerDeclContext *parent_decl_ctx) {
210    return CompilerDeclContext();
211  }
212
213  ObjectFile *GetObjectFile() { return m_obj_file; }
214  const ObjectFile *GetObjectFile() const { return m_obj_file; }
215
216  virtual std::vector<CallEdge> ParseCallEdgesInFunction(UserID func_id) {
217    return {};
218  }
219
220  virtual void AddSymbols(Symtab &symtab) {}
221
222  /// Notify the SymbolFile that the file addresses in the Sections
223  /// for this module have been changed.
224  virtual void SectionFileAddressesChanged() {}
225
226  struct RegisterInfoResolver {
227    virtual ~RegisterInfoResolver(); // anchor
228
229    virtual const RegisterInfo *ResolveName(llvm::StringRef name) const = 0;
230    virtual const RegisterInfo *ResolveNumber(lldb::RegisterKind kind,
231                                              uint32_t number) const = 0;
232  };
233  virtual lldb::UnwindPlanSP
234  GetUnwindPlan(const Address &address, const RegisterInfoResolver &resolver) {
235    return nullptr;
236  }
237
238  virtual void Dump(Stream &s) {}
239
240protected:
241  void AssertModuleLock();
242
243  ObjectFile *m_obj_file; // The object file that symbols can be extracted from.
244  uint32_t m_abilities;
245  bool m_calculated_abilities;
246
247private:
248  DISALLOW_COPY_AND_ASSIGN(SymbolFile);
249};
250
251} // namespace lldb_private
252
253#endif // liblldb_SymbolFile_h_
254