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