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