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