133965Sjdp//===-- SymbolFileDWARFDebugMap.h ------------------------------*- C++ -*-===//
2218822Sdim//
3218822Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
433965Sjdp// See https://llvm.org/LICENSE.txt for license information.
533965Sjdp// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6130561Sobrien//
733965Sjdp//===----------------------------------------------------------------------===//
8130561Sobrien
9130561Sobrien#ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
10130561Sobrien#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
11130561Sobrien
1233965Sjdp#include "lldb/Symbol/SymbolFile.h"
13130561Sobrien#include "lldb/Utility/RangeMap.h"
14130561Sobrien#include "llvm/Support/Chrono.h"
15130561Sobrien#include <bitset>
16130561Sobrien#include <map>
1733965Sjdp#include <vector>
18130561Sobrien
19130561Sobrien#include "UniqueDWARFASTType.h"
20218822Sdim
2133965Sjdpclass SymbolFileDWARF;
2233965Sjdpclass DWARFDebugAranges;
2333965Sjdpclass DWARFDeclContext;
2433965Sjdp
2533965Sjdpclass SymbolFileDWARFDebugMap : public lldb_private::SymbolFile {
2633965Sjdp  /// LLVM RTTI support.
2777298Sobrien  static char ID;
2833965Sjdp
2933965Sjdppublic:
3033965Sjdp  /// LLVM RTTI support.
3133965Sjdp  /// \{
3233965Sjdp  bool isA(const void *ClassID) const override {
3333965Sjdp    return ClassID == &ID || SymbolFile::isA(ClassID);
3433965Sjdp  }
3533965Sjdp  static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
3633965Sjdp  /// \}
3733965Sjdp
3833965Sjdp  // Static Functions
3933965Sjdp  static void Initialize();
4033965Sjdp
41218822Sdim  static void Terminate();
42218822Sdim
4333965Sjdp  static lldb_private::ConstString GetPluginNameStatic();
4433965Sjdp
45218822Sdim  static const char *GetPluginDescriptionStatic();
4633965Sjdp
4733965Sjdp  static lldb_private::SymbolFile *
4833965Sjdp  CreateInstance(lldb::ObjectFileSP objfile_sp);
4933965Sjdp
5033965Sjdp  // Constructors and Destructors
5133965Sjdp  SymbolFileDWARFDebugMap(lldb::ObjectFileSP objfile_sp);
5233965Sjdp  ~SymbolFileDWARFDebugMap() override;
5333965Sjdp
5433965Sjdp  uint32_t CalculateAbilities() override;
5533965Sjdp  void InitializeObject() override;
5633965Sjdp
57130561Sobrien  // Compile Unit function calls
5833965Sjdp  lldb::LanguageType
5933965Sjdp  ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
6033965Sjdp
6133965Sjdp  size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
6233965Sjdp
6333965Sjdp  bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
6433965Sjdp
6533965Sjdp  bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
6633965Sjdp
6733965Sjdp  bool ForEachExternalModule(
6833965Sjdp      lldb_private::CompileUnit &, llvm::DenseSet<lldb_private::SymbolFile *> &,
6933965Sjdp      llvm::function_ref<bool(lldb_private::Module &)>) override;
7033965Sjdp
7133965Sjdp  bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
72130561Sobrien                         lldb_private::FileSpecList &support_files) override;
7377298Sobrien
7433965Sjdp  bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
7533965Sjdp
7633965Sjdp  size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
7733965Sjdp
7833965Sjdp  bool ParseImportedModules(
7933965Sjdp      const lldb_private::SymbolContext &sc,
8033965Sjdp      std::vector<lldb_private::SourceModule> &imported_modules) override;
8133965Sjdp  size_t ParseBlocksRecursive(lldb_private::Function &func) override;
8233965Sjdp  size_t
8333965Sjdp  ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
8433965Sjdp
8533965Sjdp  lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
8633965Sjdp  llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
8733965Sjdp      lldb::user_id_t type_uid,
8833965Sjdp      const lldb_private::ExecutionContext *exe_ctx) override;
8933965Sjdp
90130561Sobrien  lldb_private::CompilerDeclContext
91130561Sobrien  GetDeclContextForUID(lldb::user_id_t uid) override;
9233965Sjdp  lldb_private::CompilerDeclContext
9333965Sjdp  GetDeclContextContainingUID(lldb::user_id_t uid) override;
9433965Sjdp  void
9533965Sjdp  ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
9633965Sjdp
9733965Sjdp  bool CompleteType(lldb_private::CompilerType &compiler_type) override;
9833965Sjdp  uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
9933965Sjdp                                lldb::SymbolContextItem resolve_scope,
10033965Sjdp                                lldb_private::SymbolContext &sc) override;
101130561Sobrien  uint32_t
102130561Sobrien  ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
10333965Sjdp                       bool check_inlines,
10433965Sjdp                       lldb::SymbolContextItem resolve_scope,
105130561Sobrien                       lldb_private::SymbolContextList &sc_list) override;
10633965Sjdp  void
10733965Sjdp  FindGlobalVariables(lldb_private::ConstString name,
10833965Sjdp                      const lldb_private::CompilerDeclContext *parent_decl_ctx,
10933965Sjdp                      uint32_t max_matches,
11033965Sjdp                      lldb_private::VariableList &variables) override;
11133965Sjdp  void FindGlobalVariables(const lldb_private::RegularExpression &regex,
11233965Sjdp                           uint32_t max_matches,
11377298Sobrien                           lldb_private::VariableList &variables) override;
11433965Sjdp  void FindFunctions(lldb_private::ConstString name,
11533965Sjdp                     const lldb_private::CompilerDeclContext *parent_decl_ctx,
116130561Sobrien                     lldb::FunctionNameType name_type_mask,
117130561Sobrien                     bool include_inlines,
11833965Sjdp                     lldb_private::SymbolContextList &sc_list) override;
11960484Sobrien  void FindFunctions(const lldb_private::RegularExpression &regex,
120130561Sobrien                     bool include_inlines,
121130561Sobrien                     lldb_private::SymbolContextList &sc_list) override;
122130561Sobrien  void
12333965Sjdp  FindTypes(lldb_private::ConstString name,
12489857Sobrien            const lldb_private::CompilerDeclContext *parent_decl_ctx,
12533965Sjdp            uint32_t max_matches,
12689857Sobrien            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
12789857Sobrien            lldb_private::TypeMap &types) override;
12877298Sobrien  void
12977298Sobrien  FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> context,
130130561Sobrien            lldb_private::LanguageSet languages,
13177298Sobrien            llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
13233965Sjdp            lldb_private::TypeMap &types) override;
13333965Sjdp  lldb_private::CompilerDeclContext FindNamespace(
134130561Sobrien      lldb_private::ConstString name,
13533965Sjdp      const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
13677298Sobrien  void GetTypes(lldb_private::SymbolContextScope *sc_scope,
13733965Sjdp                lldb::TypeClass type_mask,
13833965Sjdp                lldb_private::TypeList &type_list) override;
13933965Sjdp  std::vector<std::unique_ptr<lldb_private::CallEdge>>
14089857Sobrien  ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
14177298Sobrien
14233965Sjdp  void DumpClangAST(lldb_private::Stream &s) override;
14333965Sjdp
14489857Sobrien  // PluginInterface protocol
14589857Sobrien  lldb_private::ConstString GetPluginName() override;
14689857Sobrien
147130561Sobrien  uint32_t GetPluginVersion() override;
148130561Sobrien
14933965Sjdpprotected:
150130561Sobrien  enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
15133965Sjdp
15277298Sobrien  friend class DebugMapModule;
15333965Sjdp  friend class DWARFASTParserClang;
15489857Sobrien  friend class DWARFCompileUnit;
15533965Sjdp  friend class SymbolFileDWARF;
15677298Sobrien  struct OSOInfo {
15733965Sjdp    lldb::ModuleSP module_sp;
15833965Sjdp
15933965Sjdp    OSOInfo() : module_sp() {}
16077298Sobrien  };
16177298Sobrien
16289857Sobrien  typedef std::shared_ptr<OSOInfo> OSOInfoSP;
163130561Sobrien
164130561Sobrien  typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t,
165130561Sobrien                                        lldb::addr_t>
166130561Sobrien      FileRangeMap;
167130561Sobrien
16833965Sjdp  // Class specific types
16977298Sobrien  struct CompileUnitInfo {
17077298Sobrien    lldb_private::FileSpec so_file;
17177298Sobrien    lldb_private::ConstString oso_path;
17277298Sobrien    llvm::sys::TimePoint<> oso_mod_time;
17377298Sobrien    OSOInfoSP oso_sp;
17477298Sobrien    lldb::CompUnitSP compile_unit_sp;
17577298Sobrien    uint32_t first_symbol_index;
17677298Sobrien    uint32_t last_symbol_index;
17777298Sobrien    uint32_t first_symbol_id;
178218822Sdim    uint32_t last_symbol_id;
179218822Sdim    FileRangeMap file_range_map;
180218822Sdim    bool file_range_map_valid;
181218822Sdim
182218822Sdim    CompileUnitInfo()
183218822Sdim        : so_file(), oso_path(), oso_mod_time(), oso_sp(), compile_unit_sp(),
184218822Sdim          first_symbol_index(UINT32_MAX), last_symbol_index(UINT32_MAX),
185218822Sdim          first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX),
186130561Sobrien          file_range_map(), file_range_map_valid(false) {}
18777298Sobrien
18877298Sobrien    const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
18977298Sobrien  };
19077298Sobrien
19177298Sobrien  // Protected Member Functions
19277298Sobrien  void InitOSO();
19377298Sobrien
19477298Sobrien  uint32_t CalculateNumCompileUnits() override;
19577298Sobrien  lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
19677298Sobrien
19777298Sobrien  static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
19877298Sobrien    return (uint32_t)((uid >> 32ull) - 1ull);
19977298Sobrien  }
20077298Sobrien
20177298Sobrien  static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file);
20277298Sobrien
20377298Sobrien  bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec);
20477298Sobrien
20577298Sobrien  CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc);
20677298Sobrien  CompileUnitInfo *GetCompUnitInfo(const lldb_private::CompileUnit &comp_unit);
20777298Sobrien
20877298Sobrien  size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module,
20977298Sobrien                                   std::vector<CompileUnitInfo *> &cu_infos);
21077298Sobrien
211130561Sobrien  lldb_private::Module *
21277298Sobrien  GetModuleByCompUnitInfo(CompileUnitInfo *comp_unit_info);
21333965Sjdp
21460484Sobrien  lldb_private::Module *GetModuleByOSOIndex(uint32_t oso_idx);
21577298Sobrien
21677298Sobrien  lldb_private::ObjectFile *
21777298Sobrien  GetObjectFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
21889857Sobrien
21960484Sobrien  lldb_private::ObjectFile *GetObjectFileByOSOIndex(uint32_t oso_idx);
220218822Sdim
221218822Sdim  uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info);
222218822Sdim
22377298Sobrien  SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc);
22477298Sobrien  SymbolFileDWARF *GetSymbolFile(const lldb_private::CompileUnit &comp_unit);
225130561Sobrien
22677298Sobrien  SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
22789857Sobrien
228130561Sobrien  SymbolFileDWARF *GetSymbolFileByOSOIndex(uint32_t oso_idx);
229130561Sobrien
230130561Sobrien  // If closure returns "false", iteration continues.  If it returns
231130561Sobrien  // "true", iteration terminates.
232130561Sobrien  void ForEachSymbolFile(std::function<bool(SymbolFileDWARF *)> closure) {
23333965Sjdp    for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size();
23477298Sobrien         oso_idx < num_oso_idxs; ++oso_idx) {
23577298Sobrien      if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) {
23677298Sobrien        if (closure(oso_dwarf))
23777298Sobrien          return;
23877298Sobrien      }
23933965Sjdp    }
24077298Sobrien  }
24133965Sjdp
24277298Sobrien  CompileUnitInfo *GetCompileUnitInfoForSymbolWithIndex(uint32_t symbol_idx,
243130561Sobrien                                                        uint32_t *oso_idx_ptr);
244130561Sobrien
24577298Sobrien  CompileUnitInfo *GetCompileUnitInfoForSymbolWithID(lldb::user_id_t symbol_id,
24677298Sobrien                                                     uint32_t *oso_idx_ptr);
24777298Sobrien
24877298Sobrien  static int
24977298Sobrien  SymbolContainsSymbolWithIndex(uint32_t *symbol_idx_ptr,
25077298Sobrien                                const CompileUnitInfo *comp_unit_info);
25177298Sobrien
25277298Sobrien  static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr,
25377298Sobrien                                        const CompileUnitInfo *comp_unit_info);
25477298Sobrien
25589857Sobrien  void PrivateFindGlobalVariables(
25689857Sobrien      lldb_private::ConstString name,
257130561Sobrien      const lldb_private::CompilerDeclContext *parent_decl_ctx,
25889857Sobrien      const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
25989857Sobrien      lldb_private::VariableList &variables);
26033965Sjdp
26189857Sobrien  void SetCompileUnit(SymbolFileDWARF *oso_dwarf,
26289857Sobrien                      const lldb::CompUnitSP &cu_sp);
26377298Sobrien
26489857Sobrien  lldb::CompUnitSP GetCompileUnit(SymbolFileDWARF *oso_dwarf);
26589857Sobrien
26689857Sobrien  CompileUnitInfo *GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf);
26789857Sobrien
26889857Sobrien  lldb::TypeSP
26989857Sobrien  FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
270130561Sobrien
27189857Sobrien  bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso);
27289857Sobrien
27389857Sobrien  lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
27489857Sobrien      const DWARFDIE &die, lldb_private::ConstString type_name,
27577298Sobrien      bool must_be_implementation);
27677298Sobrien
27777298Sobrien  UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() {
27889857Sobrien    return m_unique_ast_type_map;
27977298Sobrien  }
28077298Sobrien
281130561Sobrien  // OSOEntry
28277298Sobrien  class OSOEntry {
28377298Sobrien  public:
28477298Sobrien    OSOEntry()
28589857Sobrien        : m_exe_sym_idx(UINT32_MAX), m_oso_file_addr(LLDB_INVALID_ADDRESS) {}
28689857Sobrien
28789857Sobrien    OSOEntry(uint32_t exe_sym_idx, lldb::addr_t oso_file_addr)
28889857Sobrien        : m_exe_sym_idx(exe_sym_idx), m_oso_file_addr(oso_file_addr) {}
289130561Sobrien
29089857Sobrien    uint32_t GetExeSymbolIndex() const { return m_exe_sym_idx; }
29189857Sobrien
29289857Sobrien    bool operator<(const OSOEntry &rhs) const {
29389857Sobrien      return m_exe_sym_idx < rhs.m_exe_sym_idx;
29489857Sobrien    }
29589857Sobrien
29689857Sobrien    lldb::addr_t GetOSOFileAddress() const { return m_oso_file_addr; }
297130561Sobrien
29889857Sobrien    void SetOSOFileAddress(lldb::addr_t oso_file_addr) {
299130561Sobrien      m_oso_file_addr = oso_file_addr;
300130561Sobrien    }
301130561Sobrien
302130561Sobrien  protected:
303130561Sobrien    uint32_t m_exe_sym_idx;
304130561Sobrien    lldb::addr_t m_oso_file_addr;
305130561Sobrien  };
306130561Sobrien
307130561Sobrien  typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry>
308130561Sobrien      DebugMap;
309130561Sobrien
310130561Sobrien  // Member Variables
311130561Sobrien  std::bitset<kNumFlags> m_flags;
312130561Sobrien  std::vector<CompileUnitInfo> m_compile_unit_infos;
313130561Sobrien  std::vector<uint32_t> m_func_indexes; // Sorted by address
314130561Sobrien  std::vector<uint32_t> m_glob_indexes;
315130561Sobrien  std::map<std::pair<lldb_private::ConstString, llvm::sys::TimePoint<>>,
316130561Sobrien           OSOInfoSP>
317130561Sobrien      m_oso_map;
318130561Sobrien  UniqueDWARFASTTypeMap m_unique_ast_type_map;
319130561Sobrien  lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
32089857Sobrien  DebugMap m_debug_map;
321130561Sobrien
322130561Sobrien  // When an object file from the debug map gets parsed in
32389857Sobrien  // SymbolFileDWARF, it needs to tell the debug map about the object
32489857Sobrien  // files addresses by calling this function once for each N_FUN,
32589857Sobrien  // N_GSYM and N_STSYM and after all entries in the debug map have
32689857Sobrien  // been matched up, FinalizeOSOFileRanges() should be called.
32777298Sobrien  bool AddOSOFileRange(CompileUnitInfo *cu_info, lldb::addr_t exe_file_addr,
32877298Sobrien                       lldb::addr_t exe_byte_size, lldb::addr_t oso_file_addr,
32977298Sobrien                       lldb::addr_t oso_byte_size);
33077298Sobrien
33177298Sobrien  // Called after calling AddOSOFileRange() for each object file debug
33233965Sjdp  // map entry to finalize the info for the unlinked compile unit.
33377298Sobrien  void FinalizeOSOFileRanges(CompileUnitInfo *cu_info);
334218822Sdim
335218822Sdim  /// Convert \a addr from a .o file address, to an executable address.
336218822Sdim  ///
337218822Sdim  /// \param[in] addr
338218822Sdim  ///     A section offset address from a .o file
339218822Sdim  ///
340218822Sdim  /// \return
341218822Sdim  ///     Returns true if \a addr was converted to be an executable
342130561Sobrien  ///     section/offset address, false otherwise.
34333965Sjdp  bool LinkOSOAddress(lldb_private::Address &addr);
34433965Sjdp
34577298Sobrien  /// Convert a .o file "file address" to an executable "file address".
34677298Sobrien  ///
34733965Sjdp  /// \param[in] oso_symfile
34833965Sjdp  ///     The DWARF symbol file that contains \a oso_file_addr
34933965Sjdp  ///
35033965Sjdp  /// \param[in] oso_file_addr
35177298Sobrien  ///     A .o file "file address" to convert.
35233965Sjdp  ///
35333965Sjdp  /// \return
35433965Sjdp  ///     LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
35533965Sjdp  ///     linked executable, otherwise a valid "file address" from the
35689857Sobrien  ///     linked executable that contains the debug map.
35789857Sobrien  lldb::addr_t LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
35877298Sobrien                                  lldb::addr_t oso_file_addr);
35989857Sobrien
36089857Sobrien  /// Given a line table full of lines with "file addresses" that are
361130561Sobrien  /// for a .o file represented by \a oso_symfile, link a new line table
36289857Sobrien  /// and return it.
363130561Sobrien  ///
364130561Sobrien  /// \param[in] oso_symfile
365130561Sobrien  ///     The DWARF symbol file that produced the \a line_table
366130561Sobrien  ///
367130561Sobrien  /// \param[in] line_table
368130561Sobrien  ///     A pointer to the line table.
369130561Sobrien  ///
37089857Sobrien  /// \return
37189857Sobrien  ///     Returns a valid line table full of linked addresses, or NULL
37289857Sobrien  ///     if none of the line table addresses exist in the main
373130561Sobrien  ///     executable.
37433965Sjdp  lldb_private::LineTable *
37533965Sjdp  LinkOSOLineTable(SymbolFileDWARF *oso_symfile,
37633965Sjdp                   lldb_private::LineTable *line_table);
37733965Sjdp
37833965Sjdp  size_t AddOSOARanges(SymbolFileDWARF *dwarf2Data,
37933965Sjdp                       DWARFDebugAranges *debug_aranges);
38033965Sjdp};
381130561Sobrien
38233965Sjdp#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
38333965Sjdp