xref: /freebsd-src/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.h (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
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