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