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
26namespace llvm {
27
28/// User of DwarfEmitterImpl should call initialization code
29/// for AsmPrinter:
30///
31/// InitializeAllTargetInfos();
32/// InitializeAllTargetMCs();
33/// InitializeAllTargets();
34/// InitializeAllAsmPrinters();
35
36template <typename DataT> class AccelTable;
37class MCCodeEmitter;
38
39namespace dwarf_linker {
40namespace parallel {
41
42using DebugNamesUnitsOffsets = std::vector<std::variant<MCSymbol *, uint64_t>>;
43using 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.
48class DwarfEmitterImpl {
49public:
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() { MS->finish(); }
62
63 /// Emit abbreviations.
64 void emitAbbrevs(const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
65 unsigned DwarfVersion);
66
67 /// Emit compile unit header.
68 void emitCompileUnitHeader(DwarfUnit &Unit);
69
70 /// Emit DIE recursively.
71 void emitDIE(DIE &Die);
72
73 /// Returns size of generated .debug_info section.
74 uint64_t getDebugInfoSectionSize() const { return DebugInfoSectionSize; }
75
76 /// Emits .debug_names section according to the specified \p Table.
77 void emitDebugNames(DWARF5AccelTable &Table,
78 DebugNamesUnitsOffsets &CUOffsets,
79 CompUnitIDToIdx &UnitIDToIdxMap);
80
81 /// Emits .apple_names section according to the specified \p Table.
82 void emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table);
83
84 /// Emits .apple_namespaces section according to the specified \p Table.
85 void emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table);
86
87 /// Emits .apple_objc section according to the specified \p Table.
88 void emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table);
89
90 /// Emits .apple_types section according to the specified \p Table.
91 void emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table);
92
93private:
94 // Enumerate all string patches and write them into the destination section.
95 // Order of patches is the same as in original input file. To avoid emitting
96 // the same string twice we accumulate NextOffset value. Thus if string
97 // offset smaller than NextOffset value then the patch is skipped (as that
98 // string was emitted earlier).
99 template <typename PatchTy>
100 void emitStringsImpl(ArrayList<PatchTy> &StringPatches,
101 const StringEntryToDwarfStringPoolEntryMap &Strings,
102 uint64_t &NextOffset, MCSection *OutSection);
103
104 /// \defgroup MCObjects MC layer objects constructed by the streamer
105 /// @{
106 std::unique_ptr<MCRegisterInfo> MRI;
107 std::unique_ptr<MCAsmInfo> MAI;
108 std::unique_ptr<MCObjectFileInfo> MOFI;
109 std::unique_ptr<MCContext> MC;
110 MCAsmBackend *MAB; // Owned by MCStreamer
111 std::unique_ptr<MCInstrInfo> MII;
112 std::unique_ptr<MCSubtargetInfo> MSTI;
113 MCInstPrinter *MIP; // Owned by AsmPrinter
114 MCCodeEmitter *MCE; // Owned by MCStreamer
115 MCStreamer *MS; // Owned by AsmPrinter
116 std::unique_ptr<TargetMachine> TM;
117 std::unique_ptr<AsmPrinter> Asm;
118 /// @}
119
120 /// The output file we stream the linked Dwarf to.
121 raw_pwrite_stream &OutFile;
122 DWARFLinkerBase::OutputFileType OutFileType =
123 DWARFLinkerBase::OutputFileType::Object;
124
125 uint64_t DebugInfoSectionSize = 0;
126};
127
128} // end of namespace parallel
129} // end of namespace dwarf_linker
130} // end of namespace llvm
131
132#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFEMITTERIMPL_H
133