11db9f3b2SDimitry Andric //===- DwarfEmitterImpl.h ---------------------------------------*- C++ -*-===// 21db9f3b2SDimitry Andric // 31db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 51db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61db9f3b2SDimitry Andric // 71db9f3b2SDimitry Andric //===----------------------------------------------------------------------===// 81db9f3b2SDimitry Andric 91db9f3b2SDimitry Andric #ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DWARFEMITTERIMPL_H 101db9f3b2SDimitry Andric #define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFEMITTERIMPL_H 111db9f3b2SDimitry Andric 121db9f3b2SDimitry Andric #include "DWARFLinkerCompileUnit.h" 131db9f3b2SDimitry Andric #include "llvm/BinaryFormat/Swift.h" 141db9f3b2SDimitry Andric #include "llvm/CodeGen/AccelTable.h" 151db9f3b2SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 161db9f3b2SDimitry Andric #include "llvm/DWARFLinker/Parallel/DWARFLinker.h" 171db9f3b2SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 181db9f3b2SDimitry Andric #include "llvm/MC/MCContext.h" 191db9f3b2SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 201db9f3b2SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 211db9f3b2SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 221db9f3b2SDimitry Andric #include "llvm/MC/MCStreamer.h" 231db9f3b2SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 241db9f3b2SDimitry Andric #include "llvm/Target/TargetMachine.h" 251db9f3b2SDimitry Andric 261db9f3b2SDimitry Andric namespace llvm { 271db9f3b2SDimitry Andric 281db9f3b2SDimitry Andric /// User of DwarfEmitterImpl should call initialization code 291db9f3b2SDimitry Andric /// for AsmPrinter: 301db9f3b2SDimitry Andric /// 311db9f3b2SDimitry Andric /// InitializeAllTargetInfos(); 321db9f3b2SDimitry Andric /// InitializeAllTargetMCs(); 331db9f3b2SDimitry Andric /// InitializeAllTargets(); 341db9f3b2SDimitry Andric /// InitializeAllAsmPrinters(); 351db9f3b2SDimitry Andric 361db9f3b2SDimitry Andric template <typename DataT> class AccelTable; 371db9f3b2SDimitry Andric class MCCodeEmitter; 381db9f3b2SDimitry Andric 391db9f3b2SDimitry Andric namespace dwarf_linker { 401db9f3b2SDimitry Andric namespace parallel { 411db9f3b2SDimitry Andric 421db9f3b2SDimitry Andric using DebugNamesUnitsOffsets = std::vector<std::variant<MCSymbol *, uint64_t>>; 431db9f3b2SDimitry Andric using CompUnitIDToIdx = DenseMap<unsigned, unsigned>; 441db9f3b2SDimitry Andric 451db9f3b2SDimitry Andric /// This class emits DWARF data to the output stream. It emits already 461db9f3b2SDimitry Andric /// generated section data and specific data, which could not be generated 471db9f3b2SDimitry Andric /// by CompileUnit. 48*7a6dacacSDimitry Andric class DwarfEmitterImpl { 491db9f3b2SDimitry Andric public: DwarfEmitterImpl(DWARFLinker::OutputFileType OutFileType,raw_pwrite_stream & OutFile)501db9f3b2SDimitry Andric DwarfEmitterImpl(DWARFLinker::OutputFileType OutFileType, 511db9f3b2SDimitry Andric raw_pwrite_stream &OutFile) 521db9f3b2SDimitry Andric : OutFile(OutFile), OutFileType(OutFileType) {} 531db9f3b2SDimitry Andric 541db9f3b2SDimitry Andric /// Initialize AsmPrinter data. 551db9f3b2SDimitry Andric Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName); 561db9f3b2SDimitry Andric 571db9f3b2SDimitry Andric /// Returns triple of output stream. getTargetTriple()581db9f3b2SDimitry Andric const Triple &getTargetTriple() { return MC->getTargetTriple(); } 591db9f3b2SDimitry Andric 601db9f3b2SDimitry Andric /// Dump the file to the disk. finish()61*7a6dacacSDimitry Andric void finish() { MS->finish(); } 621db9f3b2SDimitry Andric 631db9f3b2SDimitry Andric /// Emit abbreviations. 641db9f3b2SDimitry Andric void emitAbbrevs(const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs, 651db9f3b2SDimitry Andric unsigned DwarfVersion); 661db9f3b2SDimitry Andric 671db9f3b2SDimitry Andric /// Emit compile unit header. 681db9f3b2SDimitry Andric void emitCompileUnitHeader(DwarfUnit &Unit); 691db9f3b2SDimitry Andric 701db9f3b2SDimitry Andric /// Emit DIE recursively. 711db9f3b2SDimitry Andric void emitDIE(DIE &Die); 721db9f3b2SDimitry Andric 731db9f3b2SDimitry Andric /// Returns size of generated .debug_info section. getDebugInfoSectionSize()741db9f3b2SDimitry Andric uint64_t getDebugInfoSectionSize() const { return DebugInfoSectionSize; } 751db9f3b2SDimitry Andric 761db9f3b2SDimitry Andric /// Emits .debug_names section according to the specified \p Table. 771db9f3b2SDimitry Andric void emitDebugNames(DWARF5AccelTable &Table, 781db9f3b2SDimitry Andric DebugNamesUnitsOffsets &CUOffsets, 791db9f3b2SDimitry Andric CompUnitIDToIdx &UnitIDToIdxMap); 801db9f3b2SDimitry Andric 811db9f3b2SDimitry Andric /// Emits .apple_names section according to the specified \p Table. 821db9f3b2SDimitry Andric void emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table); 831db9f3b2SDimitry Andric 841db9f3b2SDimitry Andric /// Emits .apple_namespaces section according to the specified \p Table. 851db9f3b2SDimitry Andric void emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table); 861db9f3b2SDimitry Andric 871db9f3b2SDimitry Andric /// Emits .apple_objc section according to the specified \p Table. 881db9f3b2SDimitry Andric void emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table); 891db9f3b2SDimitry Andric 901db9f3b2SDimitry Andric /// Emits .apple_types section according to the specified \p Table. 911db9f3b2SDimitry Andric void emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table); 921db9f3b2SDimitry Andric 931db9f3b2SDimitry Andric private: 941db9f3b2SDimitry Andric // Enumerate all string patches and write them into the destination section. 951db9f3b2SDimitry Andric // Order of patches is the same as in original input file. To avoid emitting 961db9f3b2SDimitry Andric // the same string twice we accumulate NextOffset value. Thus if string 971db9f3b2SDimitry Andric // offset smaller than NextOffset value then the patch is skipped (as that 981db9f3b2SDimitry Andric // string was emitted earlier). 991db9f3b2SDimitry Andric template <typename PatchTy> 1001db9f3b2SDimitry Andric void emitStringsImpl(ArrayList<PatchTy> &StringPatches, 1011db9f3b2SDimitry Andric const StringEntryToDwarfStringPoolEntryMap &Strings, 1021db9f3b2SDimitry Andric uint64_t &NextOffset, MCSection *OutSection); 1031db9f3b2SDimitry Andric 1041db9f3b2SDimitry Andric /// \defgroup MCObjects MC layer objects constructed by the streamer 1051db9f3b2SDimitry Andric /// @{ 1061db9f3b2SDimitry Andric std::unique_ptr<MCRegisterInfo> MRI; 1071db9f3b2SDimitry Andric std::unique_ptr<MCAsmInfo> MAI; 1081db9f3b2SDimitry Andric std::unique_ptr<MCObjectFileInfo> MOFI; 1091db9f3b2SDimitry Andric std::unique_ptr<MCContext> MC; 1101db9f3b2SDimitry Andric MCAsmBackend *MAB; // Owned by MCStreamer 1111db9f3b2SDimitry Andric std::unique_ptr<MCInstrInfo> MII; 1121db9f3b2SDimitry Andric std::unique_ptr<MCSubtargetInfo> MSTI; 1131db9f3b2SDimitry Andric MCInstPrinter *MIP; // Owned by AsmPrinter 1141db9f3b2SDimitry Andric MCCodeEmitter *MCE; // Owned by MCStreamer 1151db9f3b2SDimitry Andric MCStreamer *MS; // Owned by AsmPrinter 1161db9f3b2SDimitry Andric std::unique_ptr<TargetMachine> TM; 1171db9f3b2SDimitry Andric std::unique_ptr<AsmPrinter> Asm; 1181db9f3b2SDimitry Andric /// @} 1191db9f3b2SDimitry Andric 1201db9f3b2SDimitry Andric /// The output file we stream the linked Dwarf to. 1211db9f3b2SDimitry Andric raw_pwrite_stream &OutFile; 122*7a6dacacSDimitry Andric DWARFLinkerBase::OutputFileType OutFileType = 123*7a6dacacSDimitry Andric DWARFLinkerBase::OutputFileType::Object; 1241db9f3b2SDimitry Andric 1251db9f3b2SDimitry Andric uint64_t DebugInfoSectionSize = 0; 1261db9f3b2SDimitry Andric }; 1271db9f3b2SDimitry Andric 1281db9f3b2SDimitry Andric } // end of namespace parallel 1291db9f3b2SDimitry Andric } // end of namespace dwarf_linker 1301db9f3b2SDimitry Andric } // end of namespace llvm 1311db9f3b2SDimitry Andric 1321db9f3b2SDimitry Andric #endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFEMITTERIMPL_H 133