1 //===- DwarfEmitterImpl.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_LIB_DWARFLINKER_PARALLEL_DWARFEMITTERIMPL_H 10 #define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFEMITTERIMPL_H 11 12 #include "DWARFLinkerCompileUnit.h" 13 #include "llvm/BinaryFormat/Swift.h" 14 #include "llvm/CodeGen/AccelTable.h" 15 #include "llvm/CodeGen/AsmPrinter.h" 16 #include "llvm/DWARFLinker/Parallel/DWARFLinker.h" 17 #include "llvm/MC/MCAsmInfo.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCInstrInfo.h" 20 #include "llvm/MC/MCObjectFileInfo.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/MC/MCStreamer.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 #include "llvm/Target/TargetMachine.h" 25 26 namespace llvm { 27 28 /// User of DwarfEmitterImpl should call initialization code 29 /// for AsmPrinter: 30 /// 31 /// InitializeAllTargetInfos(); 32 /// InitializeAllTargetMCs(); 33 /// InitializeAllTargets(); 34 /// InitializeAllAsmPrinters(); 35 36 template <typename DataT> class AccelTable; 37 class MCCodeEmitter; 38 39 namespace dwarf_linker { 40 namespace parallel { 41 42 using DebugNamesUnitsOffsets = std::vector<std::variant<MCSymbol *, uint64_t>>; 43 using CompUnitIDToIdx = DenseMap<unsigned, unsigned>; 44 45 /// This class emits DWARF data to the output stream. It emits already 46 /// generated section data and specific data, which could not be generated 47 /// by CompileUnit. 48 class DwarfEmitterImpl : public ExtraDwarfEmitter { 49 public: 50 DwarfEmitterImpl(DWARFLinker::OutputFileType OutFileType, 51 raw_pwrite_stream &OutFile) 52 : OutFile(OutFile), OutFileType(OutFileType) {} 53 54 /// Initialize AsmPrinter data. 55 Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName); 56 57 /// Returns triple of output stream. 58 const Triple &getTargetTriple() { return MC->getTargetTriple(); } 59 60 /// Dump the file to the disk. 61 void finish() override { MS->finish(); } 62 63 /// Returns AsmPrinter. 64 AsmPrinter &getAsmPrinter() const override { return *Asm; } 65 66 /// Emit the swift_ast section stored in \p Buffer. 67 void emitSwiftAST(StringRef Buffer) override; 68 69 /// Emit the swift reflection section stored in \p Buffer. 70 void emitSwiftReflectionSection( 71 llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind, 72 StringRef Buffer, uint32_t Alignment, uint32_t) override; 73 74 /// Emit specified section data. 75 void emitSectionContents(StringRef SecData, StringRef SecName) override; 76 77 /// Emit abbreviations. 78 void emitAbbrevs(const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs, 79 unsigned DwarfVersion); 80 81 /// Emit compile unit header. 82 void emitCompileUnitHeader(DwarfUnit &Unit); 83 84 /// Emit DIE recursively. 85 void emitDIE(DIE &Die); 86 87 /// Returns size of generated .debug_info section. 88 uint64_t getDebugInfoSectionSize() const { return DebugInfoSectionSize; } 89 90 /// Emits .debug_names section according to the specified \p Table. 91 void emitDebugNames(DWARF5AccelTable &Table, 92 DebugNamesUnitsOffsets &CUOffsets, 93 CompUnitIDToIdx &UnitIDToIdxMap); 94 95 /// Emits .apple_names section according to the specified \p Table. 96 void emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table); 97 98 /// Emits .apple_namespaces section according to the specified \p Table. 99 void emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table); 100 101 /// Emits .apple_objc section according to the specified \p Table. 102 void emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table); 103 104 /// Emits .apple_types section according to the specified \p Table. 105 void emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table); 106 107 private: 108 // Enumerate all string patches and write them into the destination section. 109 // Order of patches is the same as in original input file. To avoid emitting 110 // the same string twice we accumulate NextOffset value. Thus if string 111 // offset smaller than NextOffset value then the patch is skipped (as that 112 // string was emitted earlier). 113 template <typename PatchTy> 114 void emitStringsImpl(ArrayList<PatchTy> &StringPatches, 115 const StringEntryToDwarfStringPoolEntryMap &Strings, 116 uint64_t &NextOffset, MCSection *OutSection); 117 118 MCSection *switchSection(StringRef SecName); 119 120 /// \defgroup MCObjects MC layer objects constructed by the streamer 121 /// @{ 122 std::unique_ptr<MCRegisterInfo> MRI; 123 std::unique_ptr<MCAsmInfo> MAI; 124 std::unique_ptr<MCObjectFileInfo> MOFI; 125 std::unique_ptr<MCContext> MC; 126 MCAsmBackend *MAB; // Owned by MCStreamer 127 std::unique_ptr<MCInstrInfo> MII; 128 std::unique_ptr<MCSubtargetInfo> MSTI; 129 MCInstPrinter *MIP; // Owned by AsmPrinter 130 MCCodeEmitter *MCE; // Owned by MCStreamer 131 MCStreamer *MS; // Owned by AsmPrinter 132 std::unique_ptr<TargetMachine> TM; 133 std::unique_ptr<AsmPrinter> Asm; 134 /// @} 135 136 /// The output file we stream the linked Dwarf to. 137 raw_pwrite_stream &OutFile; 138 DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object; 139 140 uint64_t DebugInfoSectionSize = 0; 141 }; 142 143 } // end of namespace parallel 144 } // end of namespace dwarf_linker 145 } // end of namespace llvm 146 147 #endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFEMITTERIMPL_H 148