1 //===-- DebugNamesDWARFIndex.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 LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H 10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H 11 12 #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" 13 #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" 14 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" 15 #include "lldb/Utility/ConstString.h" 16 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" 17 #include <optional> 18 19 namespace lldb_private::plugin { 20 namespace dwarf { 21 class DebugNamesDWARFIndex : public DWARFIndex { 22 public: 23 static llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> 24 Create(Module &module, DWARFDataExtractor debug_names, 25 DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf); 26 Preload()27 void Preload() override { m_fallback.Preload(); } 28 29 void 30 GetGlobalVariables(ConstString basename, 31 llvm::function_ref<bool(DWARFDIE die)> callback) override; 32 void 33 GetGlobalVariables(const RegularExpression ®ex, 34 llvm::function_ref<bool(DWARFDIE die)> callback) override; 35 void 36 GetGlobalVariables(DWARFUnit &cu, 37 llvm::function_ref<bool(DWARFDIE die)> callback) override; 38 void GetObjCMethods(ConstString class_name,llvm::function_ref<bool (DWARFDIE die)> callback)39 GetObjCMethods(ConstString class_name, 40 llvm::function_ref<bool(DWARFDIE die)> callback) override {} 41 void GetCompleteObjCClass( 42 ConstString class_name, bool must_be_implementation, 43 llvm::function_ref<bool(DWARFDIE die)> callback) override; 44 45 /// Uses DWARF5's IDX_parent fields, when available, to speed up this query. 46 void GetFullyQualifiedType( 47 const DWARFDeclContext &context, 48 llvm::function_ref<bool(DWARFDIE die)> callback) override; 49 void GetTypes(ConstString name, 50 llvm::function_ref<bool(DWARFDIE die)> callback) override; 51 void GetTypes(const DWARFDeclContext &context, 52 llvm::function_ref<bool(DWARFDIE die)> callback) override; 53 void GetNamespaces(ConstString name, 54 llvm::function_ref<bool(DWARFDIE die)> callback) override; 55 void GetFunctions(const Module::LookupInfo &lookup_info, 56 SymbolFileDWARF &dwarf, 57 const CompilerDeclContext &parent_decl_ctx, 58 llvm::function_ref<bool(DWARFDIE die)> callback) override; 59 void GetFunctions(const RegularExpression ®ex, 60 llvm::function_ref<bool(DWARFDIE die)> callback) override; 61 62 void Dump(Stream &s) override; 63 64 private: DebugNamesDWARFIndex(Module & module,std::unique_ptr<llvm::DWARFDebugNames> debug_names_up,DWARFDataExtractor debug_names_data,DWARFDataExtractor debug_str_data,SymbolFileDWARF & dwarf)65 DebugNamesDWARFIndex(Module &module, 66 std::unique_ptr<llvm::DWARFDebugNames> debug_names_up, 67 DWARFDataExtractor debug_names_data, 68 DWARFDataExtractor debug_str_data, 69 SymbolFileDWARF &dwarf) 70 : DWARFIndex(module), m_debug_info(dwarf.DebugInfo()), 71 m_debug_names_data(debug_names_data), m_debug_str_data(debug_str_data), 72 m_debug_names_up(std::move(debug_names_up)), 73 m_fallback(module, dwarf, GetUnits(*m_debug_names_up), 74 GetTypeUnitSignatures(*m_debug_names_up)) {} 75 76 DWARFDebugInfo &m_debug_info; 77 78 // LLVM DWARFDebugNames will hold a non-owning reference to this data, so keep 79 // track of the ownership here. 80 DWARFDataExtractor m_debug_names_data; 81 DWARFDataExtractor m_debug_str_data; 82 83 using DebugNames = llvm::DWARFDebugNames; 84 std::unique_ptr<DebugNames> m_debug_names_up; 85 ManualDWARFIndex m_fallback; 86 87 DWARFUnit *GetNonSkeletonUnit(const DebugNames::Entry &entry) const; 88 DWARFDIE GetDIE(const DebugNames::Entry &entry) const; 89 90 /// Checks if an entry is a foreign TU and fetch the type unit. 91 /// 92 /// This function checks if the DebugNames::Entry refers to a foreign TU and 93 /// returns an optional with a value of the \a entry is a foreign type unit 94 /// entry. A valid pointer will be returned if this entry is from a .dwo file 95 /// or if it is from a .dwp file and it matches the type unit's originating 96 /// .dwo file by verifying that the DW_TAG_type_unit DIE has a DW_AT_dwo_name 97 /// that matches the DWO name from the originating skeleton compile unit. 98 /// 99 /// \param[in] entry 100 /// The accelerator table entry to check. 101 /// 102 /// \returns 103 /// A std::optional that has a value if this entry represents a foreign type 104 /// unit. If the pointer is valid, then we were able to find and match the 105 /// entry to the type unit in the .dwo or .dwp file. The returned value can 106 /// have a valid, yet contain NULL in the following cases: 107 /// - we were not able to load the .dwo file (missing or DWO ID mismatch) 108 /// - we were able to load the .dwp file, but the type units DWO name 109 /// doesn't match the originating skeleton compile unit's entry 110 /// Returns std::nullopt if this entry is not a foreign type unit entry. 111 std::optional<DWARFTypeUnit *> 112 GetForeignTypeUnit(const DebugNames::Entry &entry) const; 113 114 bool ProcessEntry(const DebugNames::Entry &entry, 115 llvm::function_ref<bool(DWARFDIE die)> callback); 116 117 /// Returns true if `parent_entries` have identical names to `parent_names`. 118 bool SameParentChain(llvm::ArrayRef<llvm::StringRef> parent_names, 119 llvm::ArrayRef<DebugNames::Entry> parent_entries) const; 120 121 static void MaybeLogLookupError(llvm::Error error, 122 const DebugNames::NameIndex &ni, 123 llvm::StringRef name); 124 125 static llvm::DenseSet<dw_offset_t> GetUnits(const DebugNames &debug_names); 126 static llvm::DenseSet<uint64_t> 127 GetTypeUnitSignatures(const DebugNames &debug_names); 128 }; 129 130 } // namespace dwarf 131 } // namespace lldb_private::plugin 132 133 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H 134