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