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