xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
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 
23 namespace llvm {
24 template <typename DataT> class AccelTable;
25 
26 class MCCodeEmitter;
27 class DWARFDebugMacro;
28 
29 namespace dwarf_linker {
30 namespace 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.
44 class DwarfStreamer : public DwarfEmitter {
45 public:
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 
215 private:
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