xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
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::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 
218 private:
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