1 //===- DWARFLinkerUnit.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 LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERUNIT_H 10 #define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERUNIT_H 11 12 #include "DWARFLinkerGlobalData.h" 13 #include "IndexedValuesMap.h" 14 #include "OutputSections.h" 15 #include "llvm/CodeGen/DIE.h" 16 #include "llvm/DWARFLinker/Parallel/DWARFLinker.h" 17 #include "llvm/DWARFLinker/StringPool.h" 18 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 19 #include "llvm/Support/LEB128.h" 20 21 namespace llvm { 22 namespace dwarf_linker { 23 namespace parallel { 24 25 class DwarfUnit; 26 using MacroOffset2UnitMapTy = DenseMap<uint64_t, DwarfUnit *>; 27 28 /// Base class for all Dwarf units(Compile unit/Type table unit). 29 class DwarfUnit : public OutputSections { 30 public: 31 virtual ~DwarfUnit() {} 32 DwarfUnit(LinkingGlobalData &GlobalData, unsigned ID, 33 StringRef ClangModuleName) 34 : OutputSections(GlobalData), ID(ID), ClangModuleName(ClangModuleName), 35 OutUnitDIE(nullptr) {} 36 37 /// Unique id of the unit. 38 unsigned getUniqueID() const { return ID; } 39 40 /// Returns size of this(newly generated) compile unit. 41 uint64_t getUnitSize() const { return UnitSize; } 42 43 /// Returns this unit name. 44 StringRef getUnitName() const { return UnitName; } 45 46 /// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef. 47 StringRef getSysRoot() { return SysRoot; } 48 49 /// Return true if this compile unit is from Clang module. 50 bool isClangModule() const { return !ClangModuleName.empty(); } 51 52 /// Return Clang module name; 53 const std::string &getClangModuleName() const { return ClangModuleName; } 54 55 /// Return global data. 56 LinkingGlobalData &getGlobalData() { return GlobalData; } 57 58 /// Returns true if unit is inter-connected(it references/referenced by other 59 /// unit). 60 bool isInterconnectedCU() const { return IsInterconnectedCU; } 61 62 /// Mark this unit as inter-connected(it references/referenced by other unit). 63 void setInterconnectedCU() { IsInterconnectedCU = true; } 64 65 /// Adds \p Abbrev into unit`s abbreviation table. 66 void assignAbbrev(DIEAbbrev &Abbrev); 67 68 /// Returns abbreviations for this compile unit. 69 const std::vector<std::unique_ptr<DIEAbbrev>> &getAbbreviations() const { 70 return Abbreviations; 71 } 72 73 /// Returns output unit DIE. 74 DIE *getOutUnitDIE() { return OutUnitDIE; } 75 76 /// Set output unit DIE. 77 void setOutUnitDIE(DIE *UnitDie) { 78 OutUnitDIE = UnitDie; 79 80 if (OutUnitDIE != nullptr) 81 UnitSize = getDebugInfoHeaderSize() + OutUnitDIE->getSize(); 82 } 83 84 /// \defgroup Methods used to emit unit's debug info: 85 /// 86 /// @{ 87 /// Emit unit's abbreviations. 88 Error emitAbbreviations(); 89 90 /// Emit .debug_info section for unit DIEs. 91 Error emitDebugInfo(const Triple &TargetTriple); 92 93 /// Emit .debug_line section. 94 Error emitDebugLine(const Triple &TargetTriple, 95 const DWARFDebugLine::LineTable &OutLineTable); 96 97 /// Emit the .debug_str_offsets section for current unit. 98 Error emitDebugStringOffsetSection(); 99 /// @} 100 101 /// \defgroup Methods used for reporting warnings and errors: 102 /// 103 /// @{ 104 void warn(const Twine &Warning) { GlobalData.warn(Warning, getUnitName()); } 105 106 void error(const Twine &Err) { GlobalData.warn(Err, getUnitName()); } 107 /// @} 108 109 /// \defgroup Methods and data members used for building accelerator tables: 110 /// 111 /// @{ 112 113 enum class AccelType : uint8_t { None, Name, Namespace, ObjC, Type }; 114 115 /// This structure keeps fields which would be used for creating accelerator 116 /// table. 117 struct AccelInfo { 118 AccelInfo() { 119 AvoidForPubSections = false; 120 ObjcClassImplementation = false; 121 } 122 123 /// Name of the entry. 124 StringEntry *String = nullptr; 125 126 /// Output offset of the DIE this entry describes. 127 uint64_t OutOffset; 128 129 /// Hash of the fully qualified name. 130 uint32_t QualifiedNameHash = 0; 131 132 /// Tag of the DIE this entry describes. 133 dwarf::Tag Tag = dwarf::DW_TAG_null; 134 135 /// Type of this accelerator record. 136 AccelType Type = AccelType::None; 137 138 /// Avoid emitting this entry for pub sections. 139 bool AvoidForPubSections : 1; 140 141 /// Is this an ObjC class implementation? 142 bool ObjcClassImplementation : 1; 143 }; 144 145 /// Emit .debug_pubnames and .debug_pubtypes for \p Unit. 146 void emitPubAccelerators(); 147 148 /// Enumerates accelerator data. 149 virtual void 150 forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) = 0; 151 152 /// @} 153 154 /// Returns index(inside .debug_str_offsets) of specified string. 155 virtual uint64_t getDebugStrIndex(const StringEntry *String) { 156 return DebugStringIndexMap.getValueIndex(String); 157 } 158 159 protected: 160 /// Emit single abbreviation entry. 161 void emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev, 162 SectionDescriptor &AbbrevSection); 163 164 /// Emit single pubnames/pubtypes accelerator entry. 165 std::optional<uint64_t> 166 emitPubAcceleratorEntry(SectionDescriptor &OutSection, const AccelInfo &Info, 167 std::optional<uint64_t> LengthOffset); 168 169 /// Unique ID for the unit. 170 unsigned ID = 0; 171 172 /// The name of this unit. 173 std::string UnitName; 174 175 /// The DW_AT_LLVM_sysroot of this unit. 176 std::string SysRoot; 177 178 /// If this is a Clang module, this holds the module's name. 179 std::string ClangModuleName; 180 181 uint64_t UnitSize = 0; 182 183 /// true if current unit references_to/is_referenced by other unit. 184 std::atomic<bool> IsInterconnectedCU = {false}; 185 186 /// FoldingSet that uniques the abbreviations. 187 FoldingSet<DIEAbbrev> AbbreviationsSet; 188 189 /// Storage for the unique Abbreviations. 190 std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations; 191 192 /// Output unit DIE. 193 DIE *OutUnitDIE = nullptr; 194 195 /// Cache for file names for this unit. 196 using FileNamesCache = 197 DenseMap<uint64_t, std::pair<std::string, std::string>>; 198 FileNamesCache FileNames; 199 200 /// Maps a string into the index inside .debug_str_offsets section. 201 IndexedValuesMap<const StringEntry *> DebugStringIndexMap; 202 }; 203 204 inline bool isODRLanguage(uint16_t Language) { 205 switch (Language) { 206 case dwarf::DW_LANG_C_plus_plus: 207 case dwarf::DW_LANG_C_plus_plus_03: 208 case dwarf::DW_LANG_C_plus_plus_11: 209 case dwarf::DW_LANG_C_plus_plus_14: 210 case dwarf::DW_LANG_ObjC_plus_plus: 211 return true; 212 default: 213 return false; 214 }; 215 216 return false; 217 } 218 219 } // end of namespace parallel 220 } // end of namespace dwarf_linker 221 } // end of namespace llvm 222 223 #endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERUNIT_H 224