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