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/CodeGen/AccelTable.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/Target/TargetMachine.h"
21 
22 namespace llvm {
23 
24 enum class OutputFileType {
25   Object,
26   Assembly,
27 };
28 
29 ///   User of DwarfStreamer should call initialization code
30 ///   for AsmPrinter:
31 ///
32 ///   InitializeAllTargetInfos();
33 ///   InitializeAllTargetMCs();
34 ///   InitializeAllTargets();
35 ///   InitializeAllAsmPrinters();
36 
37 class MCCodeEmitter;
38 
39 /// The Dwarf streaming logic.
40 ///
41 /// All interactions with the MC layer that is used to build the debug
42 /// information binary representation are handled in this class.
43 class DwarfStreamer : public DwarfEmitter {
44 public:
DwarfStreamer(OutputFileType OutFileType,raw_pwrite_stream & OutFile,std::function<StringRef (StringRef Input)> Translator,bool Minimize,messageHandler Error,messageHandler Warning)45   DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile,
46                 std::function<StringRef(StringRef Input)> Translator,
47                 bool Minimize, messageHandler Error, messageHandler Warning)
48       : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
49         Minimize(Minimize), ErrorHandler(Error), WarningHandler(Warning) {}
50 
51   bool init(Triple TheTriple);
52 
53   /// Dump the file to the disk.
54   void finish();
55 
getAsmPrinter()56   AsmPrinter &getAsmPrinter() const { return *Asm; }
57 
58   /// Set the current output section to debug_info and change
59   /// the MC Dwarf version to \p DwarfVersion.
60   void switchToDebugInfoSection(unsigned DwarfVersion);
61 
62   /// Emit the compilation unit header for \p Unit in the
63   /// debug_info section.
64   ///
65   /// As a side effect, this also switches the current Dwarf version
66   /// of the MC layer to the one of U.getOrigUnit().
67   void emitCompileUnitHeader(CompileUnit &Unit) override;
68 
69   /// Recursively emit the DIE tree rooted at \p Die.
70   void emitDIE(DIE &Die) override;
71 
72   /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
73   void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
74                    unsigned DwarfVersion) override;
75 
76   /// Emit DIE containing warnings.
77   void emitPaperTrailWarningsDie(DIE &Die) 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.
83   void emitStrings(const NonRelocatableStringpool &Pool) override;
84 
85   /// Emit the swift_ast section stored in \p Buffer.
86   void emitSwiftAST(StringRef Buffer);
87 
88   /// Emit debug_ranges for \p FuncRange by translating the
89   /// original \p Entries.
90   void emitRangesEntries(
91       int64_t UnitPcOffset, uint64_t OrigLowPc,
92       const FunctionIntervals::const_iterator &FuncRange,
93       const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
94       unsigned AddressSize) override;
95 
96   /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
97   /// also emit the debug_ranges entries for the DW_TAG_compile_unit's
98   /// DW_AT_ranges attribute.
99   void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection) override;
100 
getRangesSectionSize()101   uint64_t getRangesSectionSize() const override { return RangesSectionSize; }
102 
103   /// Emit the debug_loc contribution for \p Unit by copying the entries from
104   /// \p Dwarf and offsetting them. Update the location attributes to point to
105   /// the new entries.
106   void emitLocationsForUnit(
107       const CompileUnit &Unit, DWARFContext &Dwarf,
108       std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr)
109       override;
110 
111   /// Emit the line table described in \p Rows into the debug_line section.
112   void emitLineTableForUnit(MCDwarfLineTableParams Params,
113                             StringRef PrologueBytes, unsigned MinInstLength,
114                             std::vector<DWARFDebugLine::Row> &Rows,
115                             unsigned AdddressSize) override;
116 
117   /// Copy the debug_line over to the updated binary while unobfuscating the
118   /// file names and directories.
119   void translateLineTable(DataExtractor LineData, uint64_t Offset) override;
120 
getLineSectionSize()121   uint64_t getLineSectionSize() const override { return LineSectionSize; }
122 
123   /// Emit the .debug_pubnames contribution for \p Unit.
124   void emitPubNamesForUnit(const CompileUnit &Unit) override;
125 
126   /// Emit the .debug_pubtypes contribution for \p Unit.
127   void emitPubTypesForUnit(const CompileUnit &Unit) override;
128 
129   /// Emit a CIE.
130   void emitCIE(StringRef CIEBytes) override;
131 
132   /// Emit an FDE with data \p Bytes.
133   void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
134                StringRef Bytes) override;
135 
136   /// Emit DWARF debug names.
137   void emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) override;
138 
139   /// Emit Apple namespaces accelerator table.
140   void emitAppleNamespaces(
141       AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
142 
143   /// Emit Apple names accelerator table.
144   void
145   emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
146 
147   /// Emit Apple Objective-C accelerator table.
148   void
149   emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
150 
151   /// Emit Apple type accelerator table.
152   void
153   emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override;
154 
getFrameSectionSize()155   uint64_t getFrameSectionSize() const override { return FrameSectionSize; }
156 
getDebugInfoSectionSize()157   uint64_t getDebugInfoSectionSize() const override {
158     return DebugInfoSectionSize;
159   }
160 
161 private:
162   inline void error(const Twine &Error, StringRef Context = "") {
163     if (ErrorHandler)
164       ErrorHandler(Error, Context, nullptr);
165   }
166 
167   inline void warn(const Twine &Warning, StringRef Context = "") {
168     if (WarningHandler)
169       WarningHandler(Warning, Context, nullptr);
170   }
171 
172   /// \defgroup MCObjects MC layer objects constructed by the streamer
173   /// @{
174   std::unique_ptr<MCRegisterInfo> MRI;
175   std::unique_ptr<MCAsmInfo> MAI;
176   std::unique_ptr<MCObjectFileInfo> MOFI;
177   std::unique_ptr<MCContext> MC;
178   MCAsmBackend *MAB; // Owned by MCStreamer
179   std::unique_ptr<MCInstrInfo> MII;
180   std::unique_ptr<MCSubtargetInfo> MSTI;
181   MCInstPrinter *MIP; // Owned by AsmPrinter
182   MCCodeEmitter *MCE; // Owned by MCStreamer
183   MCStreamer *MS;     // Owned by AsmPrinter
184   std::unique_ptr<TargetMachine> TM;
185   std::unique_ptr<AsmPrinter> Asm;
186   /// @}
187 
188   /// The output file we stream the linked Dwarf to.
189   raw_pwrite_stream &OutFile;
190   OutputFileType OutFileType = OutputFileType::Object;
191   std::function<StringRef(StringRef Input)> Translator;
192   bool Minimize = true;
193 
194   uint64_t RangesSectionSize = 0;
195   uint64_t LocSectionSize = 0;
196   uint64_t LineSectionSize = 0;
197   uint64_t FrameSectionSize = 0;
198   uint64_t DebugInfoSectionSize = 0;
199 
200   /// Keep track of emitted CUs and their Unique ID.
201   struct EmittedUnit {
202     unsigned ID;
203     MCSymbol *LabelBegin;
204   };
205   std::vector<EmittedUnit> EmittedUnits;
206 
207   /// Emit the pubnames or pubtypes section contribution for \p
208   /// Unit into \p Sec. The data is provided in \p Names.
209   void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
210                              const CompileUnit &Unit,
211                              const std::vector<CompileUnit::AccelInfo> &Names);
212 
213   messageHandler ErrorHandler = nullptr;
214   messageHandler WarningHandler = nullptr;
215 };
216 
217 } // end namespace llvm
218 
219 #endif // LLVM_DWARFLINKER_DWARFSTREAMER_H
220