1//===- DwarfStreamer.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_DWARFLINKER_CLASSIC_DWARFSTREAMER_H
10#define LLVM_DWARFLINKER_CLASSIC_DWARFSTREAMER_H
11
12#include "DWARFLinker.h"
13#include "llvm/BinaryFormat/Swift.h"
14#include "llvm/CodeGen/AsmPrinter.h"
15#include "llvm/MC/MCAsmInfo.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCInstrInfo.h"
18#include "llvm/MC/MCObjectFileInfo.h"
19#include "llvm/MC/MCRegisterInfo.h"
20#include "llvm/MC/MCSubtargetInfo.h"
21#include "llvm/Target/TargetMachine.h"
22
23namespace llvm {
24template <typename DataT> class AccelTable;
25
26class MCCodeEmitter;
27class DWARFDebugMacro;
28
29namespace dwarf_linker {
30namespace classic {
31
32/// User of DwarfStreamer should call initialization code
33/// for AsmPrinter:
34///
35/// InitializeAllTargetInfos();
36/// InitializeAllTargetMCs();
37/// InitializeAllTargets();
38/// InitializeAllAsmPrinters();
39
40/// The Dwarf streaming logic.
41///
42/// All interactions with the MC layer that is used to build the debug
43/// information binary representation are handled in this class.
44class DwarfStreamer : public DwarfEmitter {
45public:
46 DwarfStreamer(DWARFLinkerBase::OutputFileType OutFileType,
47 raw_pwrite_stream &OutFile,
48 DWARFLinkerBase::MessageHandlerTy Warning)
49 : OutFile(OutFile), OutFileType(OutFileType), WarningHandler(Warning) {}
50 virtual ~DwarfStreamer() = default;
51
52 static Expected<std::unique_ptr<DwarfStreamer>> createStreamer(
53 const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType,
54 raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning);
55
56 Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
57
58 /// Dump the file to the disk.
59 void finish() override;
60
61 AsmPrinter &getAsmPrinter() const { return *Asm; }
62
63 /// Set the current output section to debug_info and change
64 /// the MC Dwarf version to \p DwarfVersion.
65 void switchToDebugInfoSection(unsigned DwarfVersion);
66
67 /// Emit the compilation unit header for \p Unit in the
68 /// debug_info section.
69 ///
70 /// As a side effect, this also switches the current Dwarf version
71 /// of the MC layer to the one of U.getOrigUnit().
72 void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override;
73
74 /// Recursively emit the DIE tree rooted at \p Die.
75 void emitDIE(DIE &Die) override;
76
77 /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
78 void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
79 unsigned DwarfVersion) override;
80
81 /// Emit contents of section SecName From Obj.
82 void emitSectionContents(StringRef SecData,
83 DebugSectionKind SecKind) override;
84
85 /// Emit the string table described by \p Pool into .debug_str table.
86 void emitStrings(const NonRelocatableStringpool &Pool) override;
87
88 /// Emit the debug string offset table described by \p StringOffsets into the
89 /// .debug_str_offsets table.
90 void emitStringOffsets(const SmallVector<uint64_t> &StringOffset,
91 uint16_t TargetDWARFVersion) override;
92
93 /// Emit the string table described by \p Pool into .debug_line_str table.
94 void emitLineStrings(const NonRelocatableStringpool &Pool) override;
95
96 /// Emit the swift_ast section stored in \p Buffer.
97 void emitSwiftAST(StringRef Buffer);
98
99 /// Emit the swift reflection section stored in \p Buffer.
100 void emitSwiftReflectionSection(
101 llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
102 StringRef Buffer, uint32_t Alignment, uint32_t Size);
103
104 /// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
105 MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override;
106
107 /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment.
108 void emitDwarfDebugRangeListFragment(const CompileUnit &Unit,
109 const AddressRanges &LinkedRanges,
110 PatchLocation Patch,
111 DebugDieValuePool &AddrPool) override;
112
113 /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer.
114 void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
115 MCSymbol *EndLabel) override;
116
117 /// Emit debug locations(.debug_loc, .debug_loclists) header.
118 MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) override;
119
120 /// Emit .debug_addr header.
121 MCSymbol *emitDwarfDebugAddrsHeader(const CompileUnit &Unit) override;
122
123 /// Emit the addresses described by \p Addrs into .debug_addr table.
124 void emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs,
125 uint8_t AddrSize) override;
126
127 /// Emit .debug_addr footer.
128 void emitDwarfDebugAddrsFooter(const CompileUnit &Unit,
129 MCSymbol *EndLabel) override;
130
131 /// Emit debug ranges(.debug_loc, .debug_loclists) fragment.
132 void emitDwarfDebugLocListFragment(
133 const CompileUnit &Unit,
134 const DWARFLocationExpressionsVector &LinkedLocationExpression,
135 PatchLocation Patch, DebugDieValuePool &AddrPool) override;
136
137 /// Emit debug ranges(.debug_loc, .debug_loclists) footer.
138 void emitDwarfDebugLocListFooter(const CompileUnit &Unit,
139 MCSymbol *EndLabel) override;
140
141 /// Emit .debug_aranges entries for \p Unit
142 void emitDwarfDebugArangesTable(const CompileUnit &Unit,
143 const AddressRanges &LinkedRanges) override;
144
145 uint64_t getRangesSectionSize() const override { return RangesSectionSize; }
146
147 uint64_t getRngListsSectionSize() const override {
148 return RngListsSectionSize;
149 }
150
151 /// Emit .debug_line table entry for specified \p LineTable
152 void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
153 const CompileUnit &Unit,
154 OffsetsStringPool &DebugStrPool,
155 OffsetsStringPool &DebugLineStrPool) override;
156
157 uint64_t getLineSectionSize() const override { return LineSectionSize; }
158
159 /// Emit the .debug_pubnames contribution for \p Unit.
160 void emitPubNamesForUnit(const CompileUnit &Unit) override;
161
162 /// Emit the .debug_pubtypes contribution for \p Unit.
163 void emitPubTypesForUnit(const CompileUnit &Unit) override;
164
165 /// Emit a CIE.
166 void emitCIE(StringRef CIEBytes) override;
167
168 /// Emit an FDE with data \p Bytes.
169 void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address,
170 StringRef Bytes) override;
171
172 /// Emit DWARF debug names.
173 void emitDebugNames(DWARF5AccelTable &Table) override;
174
175 /// Emit Apple namespaces accelerator table.
176 void emitAppleNamespaces(
177 AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
178
179 /// Emit Apple names accelerator table.
180 void
181 emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
182
183 /// Emit Apple Objective-C accelerator table.
184 void
185 emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
186
187 /// Emit Apple type accelerator table.
188 void
189 emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override;
190
191 uint64_t getFrameSectionSize() const override { return FrameSectionSize; }
192
193 uint64_t getDebugInfoSectionSize() const override {
194 return DebugInfoSectionSize;
195 }
196
197 uint64_t getDebugMacInfoSectionSize() const override {
198 return MacInfoSectionSize;
199 }
200
201 uint64_t getDebugMacroSectionSize() const override {
202 return MacroSectionSize;
203 }
204
205 uint64_t getLocListsSectionSize() const override {
206 return LocListsSectionSize;
207 }
208
209 uint64_t getDebugAddrSectionSize() const override { return AddrSectionSize; }
210
211 void emitMacroTables(DWARFContext *Context,
212 const Offset2UnitMap &UnitMacroMap,
213 OffsetsStringPool &StringPool) override;
214
215private:
216 inline void warn(const Twine &Warning, StringRef Context = "") {
217 if (WarningHandler)
218 WarningHandler(Warning, Context, nullptr);
219 }
220
221 MCSection *getMCSection(DebugSectionKind SecKind);
222
223 void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
224 const Offset2UnitMap &UnitMacroMap,
225 OffsetsStringPool &StringPool, uint64_t &OutOffset);
226
227 /// Emit piece of .debug_ranges for \p LinkedRanges.
228 void emitDwarfDebugRangesTableFragment(const CompileUnit &Unit,
229 const AddressRanges &LinkedRanges,
230 PatchLocation Patch);
231
232 /// Emit piece of .debug_rnglists for \p LinkedRanges.
233 void emitDwarfDebugRngListsTableFragment(const CompileUnit &Unit,
234 const AddressRanges &LinkedRanges,
235 PatchLocation Patch,
236 DebugDieValuePool &AddrPool);
237
238 /// Emit piece of .debug_loc for \p LinkedRanges.
239 void emitDwarfDebugLocTableFragment(
240 const CompileUnit &Unit,
241 const DWARFLocationExpressionsVector &LinkedLocationExpression,
242 PatchLocation Patch);
243
244 /// Emit piece of .debug_loclists for \p LinkedRanges.
245 void emitDwarfDebugLocListsTableFragment(
246 const CompileUnit &Unit,
247 const DWARFLocationExpressionsVector &LinkedLocationExpression,
248 PatchLocation Patch, DebugDieValuePool &AddrPool);
249
250 /// \defgroup Line table emission
251 /// @{
252 void emitLineTablePrologue(const DWARFDebugLine::Prologue &P,
253 OffsetsStringPool &DebugStrPool,
254 OffsetsStringPool &DebugLineStrPool);
255 void emitLineTableString(const DWARFDebugLine::Prologue &P,
256 const DWARFFormValue &String,
257 OffsetsStringPool &DebugStrPool,
258 OffsetsStringPool &DebugLineStrPool);
259 void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P,
260 OffsetsStringPool &DebugStrPool,
261 OffsetsStringPool &DebugLineStrPool);
262 void emitLineTablePrologueV2IncludeAndFileTable(
263 const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
264 OffsetsStringPool &DebugLineStrPool);
265 void emitLineTablePrologueV5IncludeAndFileTable(
266 const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
267 OffsetsStringPool &DebugLineStrPool);
268 void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable,
269 MCSymbol *LineEndSym, unsigned AddressByteSize);
270 void emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format,
271 uint64_t &SectionSize);
272 void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
273 dwarf::DwarfFormat Format, uint64_t &SectionSize);
274 /// @}
275
276 /// \defgroup MCObjects MC layer objects constructed by the streamer
277 /// @{
278 std::unique_ptr<MCRegisterInfo> MRI;
279 std::unique_ptr<MCAsmInfo> MAI;
280 std::unique_ptr<MCObjectFileInfo> MOFI;
281 std::unique_ptr<MCContext> MC;
282 MCAsmBackend *MAB; // Owned by MCStreamer
283 std::unique_ptr<MCInstrInfo> MII;
284 std::unique_ptr<MCSubtargetInfo> MSTI;
285 MCInstPrinter *MIP; // Owned by AsmPrinter
286 MCCodeEmitter *MCE; // Owned by MCStreamer
287 MCStreamer *MS; // Owned by AsmPrinter
288 std::unique_ptr<TargetMachine> TM;
289 std::unique_ptr<AsmPrinter> Asm;
290 /// @}
291
292 /// The output file we stream the linked Dwarf to.
293 raw_pwrite_stream &OutFile;
294 DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object;
295
296 uint64_t RangesSectionSize = 0;
297 uint64_t RngListsSectionSize = 0;
298 uint64_t LocSectionSize = 0;
299 uint64_t LocListsSectionSize = 0;
300 uint64_t LineSectionSize = 0;
301 uint64_t FrameSectionSize = 0;
302 uint64_t DebugInfoSectionSize = 0;
303 uint64_t MacInfoSectionSize = 0;
304 uint64_t MacroSectionSize = 0;
305 uint64_t AddrSectionSize = 0;
306 uint64_t StrOffsetSectionSize = 0;
307
308 /// Keep track of emitted CUs and their Unique ID.
309 struct EmittedUnit {
310 unsigned ID;
311 MCSymbol *LabelBegin;
312 };
313 std::vector<EmittedUnit> EmittedUnits;
314
315 /// Emit the pubnames or pubtypes section contribution for \p
316 /// Unit into \p Sec. The data is provided in \p Names.
317 void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
318 const CompileUnit &Unit,
319 const std::vector<CompileUnit::AccelInfo> &Names);
320
321 DWARFLinkerBase::MessageHandlerTy WarningHandler = nullptr;
322};
323
324} // end of namespace classic
325} // end of namespace dwarf_linker
326} // end of namespace llvm
327
328#endif // LLVM_DWARFLINKER_CLASSIC_DWARFSTREAMER_H
329

source code of llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h