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