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