SymbolFileDWARFDebugMap.h revision 360784
1//===-- SymbolFileDWARFDebugMap.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 SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
10#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
11
12#include "lldb/Symbol/SymbolFile.h"
13#include "lldb/Utility/RangeMap.h"
14#include "llvm/Support/Chrono.h"
15#include <bitset>
16#include <map>
17#include <vector>
18
19#include "UniqueDWARFASTType.h"
20
21class SymbolFileDWARF;
22class DWARFDebugAranges;
23class DWARFDeclContext;
24
25class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile {
26  /// LLVM RTTI support.
27  static char ID;
28
29public:
30  /// LLVM RTTI support.
31  /// \{
32  bool isA(const void *ClassID) const override {
33    return ClassID == &ID || SymbolFile::isA(ClassID);
34  }
35  static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
36  /// \}
37
38  // Static Functions
39  static void Initialize();
40
41  static void Terminate();
42
43  static lldb_private::ConstString GetPluginNameStatic();
44
45  static const char *GetPluginDescriptionStatic();
46
47  static lldb_private::SymbolFile *
48  CreateInstance(lldb::ObjectFileSP objfile_sp);
49
50  // Constructors and Destructors
51  SymbolFileDWARFDebugMap(lldb::ObjectFileSP objfile_sp);
52  ~SymbolFileDWARFDebugMap() override;
53
54  uint32_t CalculateAbilities() override;
55  void InitializeObject() override;
56
57  // Compile Unit function calls
58  lldb::LanguageType
59  ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
60
61  size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
62
63  bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
64
65  bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
66
67  bool ForEachExternalModule(
68      lldb_private::CompileUnit &, llvm::DenseSet<lldb_private::SymbolFile *> &,
69      llvm::function_ref<bool(lldb_private::Module &)>) override;
70
71  bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
72                         lldb_private::FileSpecList &support_files) override;
73
74  bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
75
76  size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
77
78  bool ParseImportedModules(
79      const lldb_private::SymbolContext &sc,
80      std::vector<lldb_private::SourceModule> &imported_modules) override;
81  size_t ParseBlocksRecursive(lldb_private::Function &func) override;
82  size_t
83  ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
84
85  lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
86  llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
87      lldb::user_id_t type_uid,
88      const lldb_private::ExecutionContext *exe_ctx) override;
89
90  lldb_private::CompilerDeclContext
91  GetDeclContextForUID(lldb::user_id_t uid) override;
92  lldb_private::CompilerDeclContext
93  GetDeclContextContainingUID(lldb::user_id_t uid) override;
94  void
95  ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
96
97  bool CompleteType(lldb_private::CompilerType &compiler_type) override;
98  uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
99                                lldb::SymbolContextItem resolve_scope,
100                                lldb_private::SymbolContext &sc) override;
101  uint32_t
102  ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
103                       bool check_inlines,
104                       lldb::SymbolContextItem resolve_scope,
105                       lldb_private::SymbolContextList &sc_list) override;
106  void
107  FindGlobalVariables(lldb_private::ConstString name,
108                      const lldb_private::CompilerDeclContext *parent_decl_ctx,
109                      uint32_t max_matches,
110                      lldb_private::VariableList &variables) override;
111  void FindGlobalVariables(const lldb_private::RegularExpression &regex,
112                           uint32_t max_matches,
113                           lldb_private::VariableList &variables) override;
114  void FindFunctions(lldb_private::ConstString name,
115                     const lldb_private::CompilerDeclContext *parent_decl_ctx,
116                     lldb::FunctionNameType name_type_mask,
117                     bool include_inlines,
118                     lldb_private::SymbolContextList &sc_list) override;
119  void FindFunctions(const lldb_private::RegularExpression &regex,
120                     bool include_inlines,
121                     lldb_private::SymbolContextList &sc_list) override;
122  void
123  FindTypes(lldb_private::ConstString name,
124            const lldb_private::CompilerDeclContext *parent_decl_ctx,
125            uint32_t max_matches,
126            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
127            lldb_private::TypeMap &types) override;
128  void
129  FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> context,
130            lldb_private::LanguageSet languages,
131            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
132            lldb_private::TypeMap &types) override;
133  lldb_private::CompilerDeclContext FindNamespace(
134      lldb_private::ConstString name,
135      const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
136  void GetTypes(lldb_private::SymbolContextScope *sc_scope,
137                lldb::TypeClass type_mask,
138                lldb_private::TypeList &type_list) override;
139  std::vector<std::unique_ptr<lldb_private::CallEdge>>
140  ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
141
142  void DumpClangAST(lldb_private::Stream &s) override;
143
144  // PluginInterface protocol
145  lldb_private::ConstString GetPluginName() override;
146
147  uint32_t GetPluginVersion() override;
148
149protected:
150  enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
151
152  friend class DebugMapModule;
153  friend class DWARFASTParserClang;
154  friend class DWARFCompileUnit;
155  friend class SymbolFileDWARF;
156  struct OSOInfo {
157    lldb::ModuleSP module_sp;
158
159    OSOInfo() : module_sp() {}
160  };
161
162  typedef std::shared_ptr<OSOInfo> OSOInfoSP;
163
164  typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t,
165                                        lldb::addr_t>
166      FileRangeMap;
167
168  // Class specific types
169  struct CompileUnitInfo {
170    lldb_private::FileSpec so_file;
171    lldb_private::ConstString oso_path;
172    llvm::sys::TimePoint<> oso_mod_time;
173    OSOInfoSP oso_sp;
174    lldb::CompUnitSP compile_unit_sp;
175    uint32_t first_symbol_index;
176    uint32_t last_symbol_index;
177    uint32_t first_symbol_id;
178    uint32_t last_symbol_id;
179    FileRangeMap file_range_map;
180    bool file_range_map_valid;
181
182    CompileUnitInfo()
183        : so_file(), oso_path(), oso_mod_time(), oso_sp(), compile_unit_sp(),
184          first_symbol_index(UINT32_MAX), last_symbol_index(UINT32_MAX),
185          first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX),
186          file_range_map(), file_range_map_valid(false) {}
187
188    const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
189  };
190
191  // Protected Member Functions
192  void InitOSO();
193
194  uint32_t CalculateNumCompileUnits() override;
195  lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
196
197  static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
198    return (uint32_t)((uid >> 32ull) - 1ull);
199  }
200
201  static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file);
202
203  bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec);
204
205  CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc);
206  CompileUnitInfo *GetCompUnitInfo(const lldb_private::CompileUnit &comp_unit);
207
208  size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module,
209                                   std::vector<CompileUnitInfo *> &cu_infos);
210
211  lldb_private::Module *
212  GetModuleByCompUnitInfo(CompileUnitInfo *comp_unit_info);
213
214  lldb_private::Module *GetModuleByOSOIndex(uint32_t oso_idx);
215
216  lldb_private::ObjectFile *
217  GetObjectFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
218
219  lldb_private::ObjectFile *GetObjectFileByOSOIndex(uint32_t oso_idx);
220
221  uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info);
222
223  SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc);
224  SymbolFileDWARF *GetSymbolFile(const lldb_private::CompileUnit &comp_unit);
225
226  SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
227
228  SymbolFileDWARF *GetSymbolFileByOSOIndex(uint32_t oso_idx);
229
230  // If closure returns "false", iteration continues.  If it returns
231  // "true", iteration terminates.
232  void ForEachSymbolFile(std::function<bool(SymbolFileDWARF *)> closure) {
233    for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size();
234         oso_idx < num_oso_idxs; ++oso_idx) {
235      if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) {
236        if (closure(oso_dwarf))
237          return;
238      }
239    }
240  }
241
242  CompileUnitInfo *GetCompileUnitInfoForSymbolWithIndex(uint32_t symbol_idx,
243                                                        uint32_t *oso_idx_ptr);
244
245  CompileUnitInfo *GetCompileUnitInfoForSymbolWithID(lldb::user_id_t symbol_id,
246                                                     uint32_t *oso_idx_ptr);
247
248  static int
249  SymbolContainsSymbolWithIndex(uint32_t *symbol_idx_ptr,
250                                const CompileUnitInfo *comp_unit_info);
251
252  static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr,
253                                        const CompileUnitInfo *comp_unit_info);
254
255  void PrivateFindGlobalVariables(
256      lldb_private::ConstString name,
257      const lldb_private::CompilerDeclContext *parent_decl_ctx,
258      const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
259      lldb_private::VariableList &variables);
260
261  void SetCompileUnit(SymbolFileDWARF *oso_dwarf,
262                      const lldb::CompUnitSP &cu_sp);
263
264  lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf);
265
266  CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf);
267
268  lldb::TypeSP
269  FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
270
271  bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso);
272
273  lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
274      const DWARFDIE &die, lldb_private::ConstString type_name,
275      bool must_be_implementation);
276
277  UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() {
278    return m_unique_ast_type_map;
279  }
280
281  // OSOEntry
282  class OSOEntry {
283  public:
284    OSOEntry()
285        : m_exe_sym_idx(UINT32_MAX), m_oso_file_addr(LLDB_INVALID_ADDRESS) {}
286
287    OSOEntry(uint32_t exe_sym_idx, lldb::addr_t oso_file_addr)
288        : m_exe_sym_idx(exe_sym_idx), m_oso_file_addr(oso_file_addr) {}
289
290    uint32_t GetExeSymbolIndex() const { return m_exe_sym_idx; }
291
292    bool operator<(const OSOEntry &rhs) const {
293      return m_exe_sym_idx < rhs.m_exe_sym_idx;
294    }
295
296    lldb::addr_t GetOSOFileAddress() const { return m_oso_file_addr; }
297
298    void SetOSOFileAddress(lldb::addr_t oso_file_addr) {
299      m_oso_file_addr = oso_file_addr;
300    }
301
302  protected:
303    uint32_t m_exe_sym_idx;
304    lldb::addr_t m_oso_file_addr;
305  };
306
307  typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry>
308      DebugMap;
309
310  // Member Variables
311  std::bitset<kNumFlags> m_flags;
312  std::vector<CompileUnitInfo> m_compile_unit_infos;
313  std::vector<uint32_t> m_func_indexes; // Sorted by address
314  std::vector<uint32_t> m_glob_indexes;
315  std::map<std::pair<lldb_private::ConstString, llvm::sys::TimePoint<>>,
316           OSOInfoSP>
317      m_oso_map;
318  UniqueDWARFASTTypeMap m_unique_ast_type_map;
319  lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
320  DebugMap m_debug_map;
321
322  // When an object file from the debug map gets parsed in
323  // SymbolFileDWARF, it needs to tell the debug map about the object
324  // files addresses by calling this function once for each N_FUN,
325  // N_GSYM and N_STSYM and after all entries in the debug map have
326  // been matched up, FinalizeOSOFileRanges() should be called.
327  bool AddOSOFileRange(CompileUnitInfo *cu_info, lldb::addr_t exe_file_addr,
328                       lldb::addr_t exe_byte_size, lldb::addr_t oso_file_addr,
329                       lldb::addr_t oso_byte_size);
330
331  // Called after calling AddOSOFileRange() for each object file debug
332  // map entry to finalize the info for the unlinked compile unit.
333  void FinalizeOSOFileRanges(CompileUnitInfo *cu_info);
334
335  /// Convert \a addr from a .o file address, to an executable address.
336  ///
337  /// \param[in] addr
338  ///     A section offset address from a .o file
339  ///
340  /// \return
341  ///     Returns true if \a addr was converted to be an executable
342  ///     section/offset address, false otherwise.
343  bool LinkOSOAddress(lldb_private::Address &addr);
344
345  /// Convert a .o file "file address" to an executable "file address".
346  ///
347  /// \param[in] oso_symfile
348  ///     The DWARF symbol file that contains \a oso_file_addr
349  ///
350  /// \param[in] oso_file_addr
351  ///     A .o file "file address" to convert.
352  ///
353  /// \return
354  ///     LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
355  ///     linked executable, otherwise a valid "file address" from the
356  ///     linked executable that contains the debug map.
357  lldb::addr_t LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
358                                  lldb::addr_t oso_file_addr);
359
360  /// Given a line table full of lines with "file addresses" that are
361  /// for a .o file represented by \a oso_symfile, link a new line table
362  /// and return it.
363  ///
364  /// \param[in] oso_symfile
365  ///     The DWARF symbol file that produced the \a line_table
366  ///
367  /// \param[in] line_table
368  ///     A pointer to the line table.
369  ///
370  /// \return
371  ///     Returns a valid line table full of linked addresses, or NULL
372  ///     if none of the line table addresses exist in the main
373  ///     executable.
374  lldb_private::LineTable *
375  LinkOSOLineTable(SymbolFileDWARF *oso_symfile,
376                   lldb_private::LineTable *line_table);
377
378  size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data,
379                       DWARFDebugAranges *debug_aranges);
380};
381
382#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
383