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