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 enum class OutputFileType { 27 Object, 28 Assembly, 29 }; 30 31 /// User of DwarfStreamer should call initialization code 32 /// for AsmPrinter: 33 /// 34 /// InitializeAllTargetInfos(); 35 /// InitializeAllTargetMCs(); 36 /// InitializeAllTargets(); 37 /// InitializeAllAsmPrinters(); 38 39 class MCCodeEmitter; 40 class DWARFDebugMacro; 41 42 /// The Dwarf streaming logic. 43 /// 44 /// All interactions with the MC layer that is used to build the debug 45 /// information binary representation are handled in this class. 46 class DwarfStreamer : public DwarfEmitter { 47 public: DwarfStreamer(OutputFileType OutFileType,raw_pwrite_stream & OutFile,std::function<StringRef (StringRef Input)> Translator,messageHandler Error,messageHandler Warning)48 DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile, 49 std::function<StringRef(StringRef Input)> Translator, 50 messageHandler Error, messageHandler Warning) 51 : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), 52 ErrorHandler(Error), WarningHandler(Warning) {} 53 54 bool init(Triple TheTriple, StringRef Swift5ReflectionSegmentName); 55 56 /// Dump the file to the disk. 57 void finish(); 58 getAsmPrinter()59 AsmPrinter &getAsmPrinter() const { 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 DIE containing warnings. 80 void emitPaperTrailWarningsDie(DIE &Die) override; 81 82 /// Emit contents of section SecName From Obj. 83 void emitSectionContents(StringRef SecData, StringRef SecName) override; 84 85 /// Emit the string table described by \p Pool. 86 void emitStrings(const NonRelocatableStringpool &Pool) override; 87 88 /// Emit the swift_ast section stored in \p Buffer. 89 void emitSwiftAST(StringRef Buffer); 90 91 /// Emit the swift reflection section stored in \p Buffer. 92 void emitSwiftReflectionSection( 93 llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind, 94 StringRef Buffer, uint32_t Alignment, uint32_t Size); 95 96 /// Emit piece of .debug_ranges for \p Ranges. 97 virtual void 98 emitDwarfDebugRangesTableFragment(const CompileUnit &Unit, 99 const AddressRanges &LinkedRanges) override; 100 101 /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true, 102 /// also emit the debug_ranges entries for the DW_TAG_compile_unit's 103 /// DW_AT_ranges attribute. 104 void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection) override; 105 getRangesSectionSize()106 uint64_t getRangesSectionSize() const override { return RangesSectionSize; } 107 108 /// Emit the debug_loc contribution for \p Unit by copying the entries from 109 /// \p Dwarf and offsetting them. Update the location attributes to point to 110 /// the new entries. 111 void emitLocationsForUnit( 112 const CompileUnit &Unit, DWARFContext &Dwarf, 113 std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr) 114 override; 115 116 /// Emit the line table described in \p Rows into the debug_line section. 117 void emitLineTableForUnit(MCDwarfLineTableParams Params, 118 StringRef PrologueBytes, unsigned MinInstLength, 119 std::vector<DWARFDebugLine::Row> &Rows, 120 unsigned AdddressSize) override; 121 122 /// Copy the debug_line over to the updated binary while unobfuscating the 123 /// file names and directories. 124 void translateLineTable(DataExtractor LineData, uint64_t Offset) override; 125 getLineSectionSize()126 uint64_t getLineSectionSize() const override { return LineSectionSize; } 127 128 /// Emit the .debug_pubnames contribution for \p Unit. 129 void emitPubNamesForUnit(const CompileUnit &Unit) override; 130 131 /// Emit the .debug_pubtypes contribution for \p Unit. 132 void emitPubTypesForUnit(const CompileUnit &Unit) override; 133 134 /// Emit a CIE. 135 void emitCIE(StringRef CIEBytes) override; 136 137 /// Emit an FDE with data \p Bytes. 138 void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address, 139 StringRef Bytes) override; 140 141 /// Emit DWARF debug names. 142 void emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) override; 143 144 /// Emit Apple namespaces accelerator table. 145 void emitAppleNamespaces( 146 AccelTable<AppleAccelTableStaticOffsetData> &Table) override; 147 148 /// Emit Apple names accelerator table. 149 void 150 emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override; 151 152 /// Emit Apple Objective-C accelerator table. 153 void 154 emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override; 155 156 /// Emit Apple type accelerator table. 157 void 158 emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override; 159 getFrameSectionSize()160 uint64_t getFrameSectionSize() const override { return FrameSectionSize; } 161 getDebugInfoSectionSize()162 uint64_t getDebugInfoSectionSize() const override { 163 return DebugInfoSectionSize; 164 } 165 getDebugMacInfoSectionSize()166 uint64_t getDebugMacInfoSectionSize() const override { 167 return MacInfoSectionSize; 168 } 169 getDebugMacroSectionSize()170 uint64_t getDebugMacroSectionSize() const override { 171 return MacroSectionSize; 172 } 173 174 void emitMacroTables(DWARFContext *Context, 175 const Offset2UnitMap &UnitMacroMap, 176 OffsetsStringPool &StringPool) override; 177 178 private: 179 inline void error(const Twine &Error, StringRef Context = "") { 180 if (ErrorHandler) 181 ErrorHandler(Error, Context, nullptr); 182 } 183 184 inline void warn(const Twine &Warning, StringRef Context = "") { 185 if (WarningHandler) 186 WarningHandler(Warning, Context, nullptr); 187 } 188 189 void emitMacroTableImpl(const DWARFDebugMacro *MacroTable, 190 const Offset2UnitMap &UnitMacroMap, 191 OffsetsStringPool &StringPool, uint64_t &OutOffset); 192 void emitDwarfDebugArangesTable(const CompileUnit &Unit, 193 const AddressRanges &LinkedRanges); 194 195 /// \defgroup MCObjects MC layer objects constructed by the streamer 196 /// @{ 197 std::unique_ptr<MCRegisterInfo> MRI; 198 std::unique_ptr<MCAsmInfo> MAI; 199 std::unique_ptr<MCObjectFileInfo> MOFI; 200 std::unique_ptr<MCContext> MC; 201 MCAsmBackend *MAB; // Owned by MCStreamer 202 std::unique_ptr<MCInstrInfo> MII; 203 std::unique_ptr<MCSubtargetInfo> MSTI; 204 MCInstPrinter *MIP; // Owned by AsmPrinter 205 MCCodeEmitter *MCE; // Owned by MCStreamer 206 MCStreamer *MS; // Owned by AsmPrinter 207 std::unique_ptr<TargetMachine> TM; 208 std::unique_ptr<AsmPrinter> Asm; 209 /// @} 210 211 /// The output file we stream the linked Dwarf to. 212 raw_pwrite_stream &OutFile; 213 OutputFileType OutFileType = OutputFileType::Object; 214 std::function<StringRef(StringRef Input)> Translator; 215 216 uint64_t RangesSectionSize = 0; 217 uint64_t LocSectionSize = 0; 218 uint64_t LineSectionSize = 0; 219 uint64_t FrameSectionSize = 0; 220 uint64_t DebugInfoSectionSize = 0; 221 uint64_t MacInfoSectionSize = 0; 222 uint64_t MacroSectionSize = 0; 223 224 /// Keep track of emitted CUs and their Unique ID. 225 struct EmittedUnit { 226 unsigned ID; 227 MCSymbol *LabelBegin; 228 }; 229 std::vector<EmittedUnit> EmittedUnits; 230 231 /// Emit the pubnames or pubtypes section contribution for \p 232 /// Unit into \p Sec. The data is provided in \p Names. 233 void emitPubSectionForUnit(MCSection *Sec, StringRef Name, 234 const CompileUnit &Unit, 235 const std::vector<CompileUnit::AccelInfo> &Names); 236 237 messageHandler ErrorHandler = nullptr; 238 messageHandler WarningHandler = nullptr; 239 }; 240 241 } // end namespace llvm 242 243 #endif // LLVM_DWARFLINKER_DWARFSTREAMER_H 244