1 //===- DwarfStreamer.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_DWARFLINKER_DWARFSTREAMER_H 10 #define LLVM_DWARFLINKER_DWARFSTREAMER_H 11 12 #include "llvm/BinaryFormat/Swift.h" 13 #include "llvm/CodeGen/AsmPrinter.h" 14 #include "llvm/DWARFLinker/DWARFLinker.h" 15 #include "llvm/MC/MCAsmInfo.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCInstrInfo.h" 18 #include "llvm/MC/MCObjectFileInfo.h" 19 #include "llvm/MC/MCRegisterInfo.h" 20 #include "llvm/MC/MCSubtargetInfo.h" 21 #include "llvm/Target/TargetMachine.h" 22 23 namespace llvm { 24 template <typename DataT> class AccelTable; 25 26 /// User of DwarfStreamer should call initialization code 27 /// for AsmPrinter: 28 /// 29 /// InitializeAllTargetInfos(); 30 /// InitializeAllTargetMCs(); 31 /// InitializeAllTargets(); 32 /// InitializeAllAsmPrinters(); 33 34 class MCCodeEmitter; 35 class DWARFDebugMacro; 36 37 /// The Dwarf streaming logic. 38 /// 39 /// All interactions with the MC layer that is used to build the debug 40 /// information binary representation are handled in this class. 41 class DwarfStreamer : public DwarfEmitter { 42 public: DwarfStreamer(DWARFLinker::OutputFileType OutFileType,raw_pwrite_stream & OutFile,std::function<StringRef (StringRef Input)> Translator,DWARFLinker::messageHandler Warning)43 DwarfStreamer(DWARFLinker::OutputFileType OutFileType, 44 raw_pwrite_stream &OutFile, 45 std::function<StringRef(StringRef Input)> Translator, 46 DWARFLinker::messageHandler Warning) 47 : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), 48 WarningHandler(Warning) {} 49 50 Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName); 51 52 /// Dump the file to the disk. 53 void finish() override; 54 getAsmPrinter()55 AsmPrinter &getAsmPrinter() const override { return *Asm; } 56 57 /// Set the current output section to debug_info and change 58 /// the MC Dwarf version to \p DwarfVersion. 59 void switchToDebugInfoSection(unsigned DwarfVersion); 60 61 /// Emit the compilation unit header for \p Unit in the 62 /// debug_info section. 63 /// 64 /// As a side effect, this also switches the current Dwarf version 65 /// of the MC layer to the one of U.getOrigUnit(). 66 void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override; 67 68 /// Recursively emit the DIE tree rooted at \p Die. 69 void emitDIE(DIE &Die) override; 70 71 /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section. 72 void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, 73 unsigned DwarfVersion) override; 74 75 /// Emit contents of section SecName From Obj. 76 void emitSectionContents(StringRef SecData, StringRef SecName) override; 77 78 /// Emit the string table described by \p Pool into .debug_str table. 79 void emitStrings(const NonRelocatableStringpool &Pool) override; 80 81 /// Emit the debug string offset table described by \p StringOffsets into the 82 /// .debug_str_offsets table. 83 void emitStringOffsets(const SmallVector<uint64_t> &StringOffset, 84 uint16_t TargetDWARFVersion) override; 85 86 /// Emit the string table described by \p Pool into .debug_line_str table. 87 void emitLineStrings(const NonRelocatableStringpool &Pool) override; 88 89 /// Emit the swift_ast section stored in \p Buffer. 90 void emitSwiftAST(StringRef Buffer) override; 91 92 /// Emit the swift reflection section stored in \p Buffer. 93 void emitSwiftReflectionSection( 94 llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind, 95 StringRef Buffer, uint32_t Alignment, uint32_t Size) override; 96 97 /// Emit debug ranges(.debug_ranges, .debug_rnglists) header. 98 MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override; 99 100 /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment. 101 void emitDwarfDebugRangeListFragment(const CompileUnit &Unit, 102 const AddressRanges &LinkedRanges, 103 PatchLocation Patch, 104 DebugDieValuePool &AddrPool) override; 105 106 /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer. 107 void emitDwarfDebugRangeListFooter(const CompileUnit &Unit, 108 MCSymbol *EndLabel) override; 109 110 /// Emit debug locations(.debug_loc, .debug_loclists) header. 111 MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) override; 112 113 /// Emit .debug_addr header. 114 MCSymbol *emitDwarfDebugAddrsHeader(const CompileUnit &Unit) override; 115 116 /// Emit the addresses described by \p Addrs into .debug_addr table. 117 void emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs, 118 uint8_t AddrSize) override; 119 120 /// Emit .debug_addr footer. 121 void emitDwarfDebugAddrsFooter(const CompileUnit &Unit, 122 MCSymbol *EndLabel) override; 123 124 /// Emit debug ranges(.debug_loc, .debug_loclists) fragment. 125 void emitDwarfDebugLocListFragment( 126 const CompileUnit &Unit, 127 const DWARFLocationExpressionsVector &LinkedLocationExpression, 128 PatchLocation Patch, DebugDieValuePool &AddrPool) override; 129 130 /// Emit debug ranges(.debug_loc, .debug_loclists) footer. 131 void emitDwarfDebugLocListFooter(const CompileUnit &Unit, 132 MCSymbol *EndLabel) override; 133 134 /// Emit .debug_aranges entries for \p Unit 135 void emitDwarfDebugArangesTable(const CompileUnit &Unit, 136 const AddressRanges &LinkedRanges) override; 137 getRangesSectionSize()138 uint64_t getRangesSectionSize() const override { return RangesSectionSize; } 139 getRngListsSectionSize()140 uint64_t getRngListsSectionSize() const override { 141 return RngListsSectionSize; 142 } 143 144 /// Emit .debug_line table entry for specified \p LineTable 145 void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable, 146 const CompileUnit &Unit, 147 OffsetsStringPool &DebugStrPool, 148 OffsetsStringPool &DebugLineStrPool) override; 149 getLineSectionSize()150 uint64_t getLineSectionSize() const override { return LineSectionSize; } 151 152 /// Emit the .debug_pubnames contribution for \p Unit. 153 void emitPubNamesForUnit(const CompileUnit &Unit) override; 154 155 /// Emit the .debug_pubtypes contribution for \p Unit. 156 void emitPubTypesForUnit(const CompileUnit &Unit) override; 157 158 /// Emit a CIE. 159 void emitCIE(StringRef CIEBytes) override; 160 161 /// Emit an FDE with data \p Bytes. 162 void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address, 163 StringRef Bytes) override; 164 165 /// Emit DWARF debug names. 166 void emitDebugNames(DWARF5AccelTable &Table) override; 167 168 /// Emit Apple namespaces accelerator table. 169 void emitAppleNamespaces( 170 AccelTable<AppleAccelTableStaticOffsetData> &Table) override; 171 172 /// Emit Apple names accelerator table. 173 void 174 emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override; 175 176 /// Emit Apple Objective-C accelerator table. 177 void 178 emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override; 179 180 /// Emit Apple type accelerator table. 181 void 182 emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override; 183 getFrameSectionSize()184 uint64_t getFrameSectionSize() const override { return FrameSectionSize; } 185 getDebugInfoSectionSize()186 uint64_t getDebugInfoSectionSize() const override { 187 return DebugInfoSectionSize; 188 } 189 getDebugMacInfoSectionSize()190 uint64_t getDebugMacInfoSectionSize() const override { 191 return MacInfoSectionSize; 192 } 193 getDebugMacroSectionSize()194 uint64_t getDebugMacroSectionSize() const override { 195 return MacroSectionSize; 196 } 197 getLocListsSectionSize()198 uint64_t getLocListsSectionSize() const override { 199 return LocListsSectionSize; 200 } 201 getDebugAddrSectionSize()202 uint64_t getDebugAddrSectionSize() const override { return AddrSectionSize; } 203 204 void emitMacroTables(DWARFContext *Context, 205 const Offset2UnitMap &UnitMacroMap, 206 OffsetsStringPool &StringPool) override; 207 208 private: 209 inline void warn(const Twine &Warning, StringRef Context = "") { 210 if (WarningHandler) 211 WarningHandler(Warning, Context, nullptr); 212 } 213 214 void emitMacroTableImpl(const DWARFDebugMacro *MacroTable, 215 const Offset2UnitMap &UnitMacroMap, 216 OffsetsStringPool &StringPool, uint64_t &OutOffset); 217 218 /// Emit piece of .debug_ranges for \p LinkedRanges. 219 void emitDwarfDebugRangesTableFragment(const CompileUnit &Unit, 220 const AddressRanges &LinkedRanges, 221 PatchLocation Patch); 222 223 /// Emit piece of .debug_rnglists for \p LinkedRanges. 224 void emitDwarfDebugRngListsTableFragment(const CompileUnit &Unit, 225 const AddressRanges &LinkedRanges, 226 PatchLocation Patch, 227 DebugDieValuePool &AddrPool); 228 229 /// Emit piece of .debug_loc for \p LinkedRanges. 230 void emitDwarfDebugLocTableFragment( 231 const CompileUnit &Unit, 232 const DWARFLocationExpressionsVector &LinkedLocationExpression, 233 PatchLocation Patch); 234 235 /// Emit piece of .debug_loclists for \p LinkedRanges. 236 void emitDwarfDebugLocListsTableFragment( 237 const CompileUnit &Unit, 238 const DWARFLocationExpressionsVector &LinkedLocationExpression, 239 PatchLocation Patch, DebugDieValuePool &AddrPool); 240 241 /// \defgroup Line table emission 242 /// @{ 243 void emitLineTablePrologue(const DWARFDebugLine::Prologue &P, 244 OffsetsStringPool &DebugStrPool, 245 OffsetsStringPool &DebugLineStrPool); 246 void emitLineTableString(const DWARFDebugLine::Prologue &P, 247 const DWARFFormValue &String, 248 OffsetsStringPool &DebugStrPool, 249 OffsetsStringPool &DebugLineStrPool); 250 void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P, 251 OffsetsStringPool &DebugStrPool, 252 OffsetsStringPool &DebugLineStrPool); 253 void emitLineTablePrologueV2IncludeAndFileTable( 254 const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool, 255 OffsetsStringPool &DebugLineStrPool); 256 void emitLineTablePrologueV5IncludeAndFileTable( 257 const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool, 258 OffsetsStringPool &DebugLineStrPool); 259 void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable, 260 MCSymbol *LineEndSym, unsigned AddressByteSize); 261 void emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format, 262 uint64_t &SectionSize); 263 void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 264 dwarf::DwarfFormat Format, uint64_t &SectionSize); 265 /// @} 266 267 /// \defgroup MCObjects MC layer objects constructed by the streamer 268 /// @{ 269 std::unique_ptr<MCRegisterInfo> MRI; 270 std::unique_ptr<MCAsmInfo> MAI; 271 std::unique_ptr<MCObjectFileInfo> MOFI; 272 std::unique_ptr<MCContext> MC; 273 MCAsmBackend *MAB; // Owned by MCStreamer 274 std::unique_ptr<MCInstrInfo> MII; 275 std::unique_ptr<MCSubtargetInfo> MSTI; 276 MCInstPrinter *MIP; // Owned by AsmPrinter 277 MCCodeEmitter *MCE; // Owned by MCStreamer 278 MCStreamer *MS; // Owned by AsmPrinter 279 std::unique_ptr<TargetMachine> TM; 280 std::unique_ptr<AsmPrinter> Asm; 281 /// @} 282 283 /// The output file we stream the linked Dwarf to. 284 raw_pwrite_stream &OutFile; 285 DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object; 286 std::function<StringRef(StringRef Input)> Translator; 287 288 uint64_t RangesSectionSize = 0; 289 uint64_t RngListsSectionSize = 0; 290 uint64_t LocSectionSize = 0; 291 uint64_t LocListsSectionSize = 0; 292 uint64_t LineSectionSize = 0; 293 uint64_t FrameSectionSize = 0; 294 uint64_t DebugInfoSectionSize = 0; 295 uint64_t MacInfoSectionSize = 0; 296 uint64_t MacroSectionSize = 0; 297 uint64_t AddrSectionSize = 0; 298 uint64_t StrOffsetSectionSize = 0; 299 300 /// Keep track of emitted CUs and their Unique ID. 301 struct EmittedUnit { 302 unsigned ID; 303 MCSymbol *LabelBegin; 304 }; 305 std::vector<EmittedUnit> EmittedUnits; 306 307 /// Emit the pubnames or pubtypes section contribution for \p 308 /// Unit into \p Sec. The data is provided in \p Names. 309 void emitPubSectionForUnit(MCSection *Sec, StringRef Name, 310 const CompileUnit &Unit, 311 const std::vector<CompileUnit::AccelInfo> &Names); 312 313 DWARFLinker::messageHandler WarningHandler = nullptr; 314 }; 315 316 } // end namespace llvm 317 318 #endif // LLVM_DWARFLINKER_DWARFSTREAMER_H 319