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 ®ex, 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 ®ex, 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