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