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