diff --git a/tools/dsymutil/DwarfStreamer.h b/include/llvm/DWARFLinker/DWARFStreamer.h similarity index 81% rename from tools/dsymutil/DwarfStreamer.h rename to include/llvm/DWARFLinker/DWARFStreamer.h index 1084a28532a..de58f5dedf2 100644 --- a/tools/dsymutil/DwarfStreamer.h +++ b/include/llvm/DWARFLinker/DWARFStreamer.h @@ -1,4 +1,4 @@ -//===- tools/dsymutil/DwarfStreamer.h - Dwarf Streamer ----------*- C++ -*-===// +//===- DwarfStreamer.h ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,37 +6,35 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H -#define LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H +#ifndef LLVM_DWARFLINKER_DWARFSTREAMER_H +#define LLVM_DWARFLINKER_DWARFSTREAMER_H -#include "DebugMap.h" -#include "LinkUtils.h" #include "llvm/CodeGen/AccelTable.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/NonRelocatableStringpool.h" #include "llvm/DWARFLinker/DWARFLinker.h" -#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h" -#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" -#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" -#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectFileInfo.h" -#include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCSection.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCTargetOptions.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" namespace llvm { -namespace dsymutil { + +enum class OutputFileType { + Object, + Assembly, +}; + +/// User of DwarfStreamer should call initialization code +/// for AsmPrinter: +/// +/// InitializeAllTargetInfos(); +/// InitializeAllTargetMCs(); +/// InitializeAllTargets(); +/// InitializeAllAsmPrinters(); + +class MCCodeEmitter; /// The Dwarf streaming logic. /// @@ -44,13 +42,16 @@ namespace dsymutil { /// information binary representation are handled in this class. class DwarfStreamer : public DwarfEmitter { public: - DwarfStreamer(raw_fd_ostream &OutFile, LinkOptions Options) - : OutFile(OutFile), Options(std::move(Options)) {} + DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile, + std::function Translator, + bool Minimize, messageHandler Error, messageHandler Warning) + : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), + Minimize(Minimize), ErrorHandler(Error), WarningHandler(Warning) {} bool init(Triple TheTriple); /// Dump the file to the disk. - bool finish(const DebugMap &, SymbolMapTranslator &T); + void finish(); AsmPrinter &getAsmPrinter() const { return *Asm; } @@ -158,6 +159,16 @@ public: } private: + inline void error(const Twine &Error, StringRef Context = "") { + if (ErrorHandler) + ErrorHandler(Error, Context, nullptr); + } + + inline void warn(const Twine &Warning, StringRef Context = "") { + if (WarningHandler) + WarningHandler(Warning, Context, nullptr); + } + /// \defgroup MCObjects MC layer objects constructed by the streamer /// @{ std::unique_ptr MRI; @@ -174,10 +185,11 @@ private: std::unique_ptr Asm; /// @} - /// The file we stream the linked Dwarf to. - raw_fd_ostream &OutFile; - - LinkOptions Options; + /// The output file we stream the linked Dwarf to. + raw_pwrite_stream &OutFile; + OutputFileType OutFileType = OutputFileType::Object; + std::function Translator; + bool Minimize = true; uint64_t RangesSectionSize = 0; uint64_t LocSectionSize = 0; @@ -197,9 +209,11 @@ private: void emitPubSectionForUnit(MCSection *Sec, StringRef Name, const CompileUnit &Unit, const std::vector &Names); + + messageHandler ErrorHandler = nullptr; + messageHandler WarningHandler = nullptr; }; -} // end namespace dsymutil } // end namespace llvm -#endif // LLVM_TOOLS_DSYMUTIL_DWARFSTREAMER_H +#endif // LLVM_DWARFLINKER_DWARFSTREAMER_H diff --git a/lib/DWARFLinker/CMakeLists.txt b/lib/DWARFLinker/CMakeLists.txt index f8c61336640..724ed7613ae 100644 --- a/lib/DWARFLinker/CMakeLists.txt +++ b/lib/DWARFLinker/CMakeLists.txt @@ -2,6 +2,7 @@ add_llvm_component_library(LLVMDWARFLinker DWARFLinkerCompileUnit.cpp DWARFLinkerDeclContext.cpp DWARFLinker.cpp + DWARFStreamer.cpp DEPENDS intrinsics_gen diff --git a/tools/dsymutil/DwarfStreamer.cpp b/lib/DWARFLinker/DWARFStreamer.cpp similarity index 97% rename from tools/dsymutil/DwarfStreamer.cpp rename to lib/DWARFLinker/DWARFStreamer.cpp index c53d5d566e4..5b38b584dcb 100644 --- a/tools/dsymutil/DwarfStreamer.cpp +++ b/lib/DWARFLinker/DWARFStreamer.cpp @@ -1,4 +1,4 @@ -//===- tools/dsymutil/DwarfStreamer.cpp - Dwarf Streamer ------------------===// +//===- DwarfStreamer.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,25 +6,29 @@ // //===----------------------------------------------------------------------===// -#include "DwarfStreamer.h" -#include "LinkUtils.h" -#include "MachOUtils.h" +#include "llvm/DWARFLinker/DWARFStreamer.h" #include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/NonRelocatableStringpool.h" #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/TargetRegistry.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" namespace llvm { static mc::RegisterMCTargetOptionsFlags MOF; -namespace dsymutil { - bool DwarfStreamer::init(Triple TheTriple) { std::string ErrorStr; std::string TripleName; @@ -34,18 +38,19 @@ bool DwarfStreamer::init(Triple TheTriple) { const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); if (!TheTarget) - return error(ErrorStr, Context); + return error(ErrorStr, Context), false; TripleName = TheTriple.getTriple(); // Create all the MC Objects. MRI.reset(TheTarget->createMCRegInfo(TripleName)); if (!MRI) - return error(Twine("no register info for target ") + TripleName, Context); + return error(Twine("no register info for target ") + TripleName, Context), + false; MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags(); MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); if (!MAI) - return error("no asm info for target " + TripleName, Context); + return error("no asm info for target " + TripleName, Context), false; MOFI.reset(new MCObjectFileInfo); MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get())); @@ -53,21 +58,21 @@ bool DwarfStreamer::init(Triple TheTriple) { MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); if (!MSTI) - return error("no subtarget info for target " + TripleName, Context); + return error("no subtarget info for target " + TripleName, Context), false; MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions); if (!MAB) - return error("no asm backend for target " + TripleName, Context); + return error("no asm backend for target " + TripleName, Context), false; MII.reset(TheTarget->createMCInstrInfo()); if (!MII) - return error("no instr info info for target " + TripleName, Context); + return error("no instr info info for target " + TripleName, Context), false; MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC); if (!MCE) - return error("no code emitter for target " + TripleName, Context); + return error("no code emitter for target " + TripleName, Context), false; - switch (Options.FileType) { + switch (OutFileType) { case OutputFileType::Assembly: { MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(), *MAI, *MII, *MRI); @@ -88,17 +93,17 @@ bool DwarfStreamer::init(Triple TheTriple) { } if (!MS) - return error("no object streamer for target " + TripleName, Context); + return error("no object streamer for target " + TripleName, Context), false; // Finally create the AsmPrinter we'll use to emit the DIEs. TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(), None)); if (!TM) - return error("no target machine for target " + TripleName, Context); + return error("no target machine for target " + TripleName, Context), false; Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr(MS))); if (!Asm) - return error("no asm printer for target " + TripleName, Context); + return error("no asm printer for target " + TripleName, Context), false; RangesSectionSize = 0; LocSectionSize = 0; @@ -109,15 +114,7 @@ bool DwarfStreamer::init(Triple TheTriple) { return true; } -bool DwarfStreamer::finish(const DebugMap &DM, SymbolMapTranslator &T) { - bool Result = true; - if (DM.getTriple().isOSDarwin() && !DM.getBinaryPath().empty() && - Options.FileType == OutputFileType::Object) - Result = MachOUtils::generateDsymCompanion(DM, T, *MS, OutFile); - else - MS->Finish(); - return Result; -} +void DwarfStreamer::finish() { MS->Finish(); } void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) { MS->SwitchSection(MOFI->getDwarfInfoSection()); @@ -660,7 +657,7 @@ void DwarfStreamer::translateLineTable(DataExtractor Data, uint64_t Offset) { if (Dir[0] == 0) break; - StringRef Translated = Options.Translator(Dir); + StringRef Translated = Translator(Dir); Asm->OutStreamer->emitBytes(Translated); Asm->emitInt8(0); LineSectionSize += Translated.size() + 1; @@ -672,7 +669,7 @@ void DwarfStreamer::translateLineTable(DataExtractor Data, uint64_t Offset) { if (File[0] == 0) break; - StringRef Translated = Options.Translator(File); + StringRef Translated = Translator(File); Asm->OutStreamer->emitBytes(Translated); Asm->emitInt8(0); LineSectionSize += Translated.size() + 1; @@ -740,7 +737,7 @@ void DwarfStreamer::emitPubSectionForUnit( /// Emit .debug_pubnames for \p Unit. void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) { - if (Options.Minimize) + if (Minimize) return; emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(), "names", Unit, Unit.getPubnames()); @@ -748,7 +745,7 @@ void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) { /// Emit .debug_pubtypes for \p Unit. void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) { - if (Options.Minimize) + if (Minimize) return; emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(), "types", Unit, Unit.getPubtypes()); @@ -776,5 +773,4 @@ void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize, FrameSectionSize += FDEBytes.size() + 8 + AddrSize; } -} // namespace dsymutil } // namespace llvm diff --git a/tools/dsymutil/CMakeLists.txt b/tools/dsymutil/CMakeLists.txt index dc31b86b2fc..a42e1a98080 100644 --- a/tools/dsymutil/CMakeLists.txt +++ b/tools/dsymutil/CMakeLists.txt @@ -24,7 +24,6 @@ add_llvm_tool(dsymutil CFBundle.cpp DebugMap.cpp DwarfLinkerForBinary.cpp - DwarfStreamer.cpp MachODebugMapParser.cpp MachOUtils.cpp SymbolMap.cpp diff --git a/tools/dsymutil/DwarfLinkerForBinary.cpp b/tools/dsymutil/DwarfLinkerForBinary.cpp index c1c247d1baa..4e99e5f8de0 100644 --- a/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -9,7 +9,6 @@ #include "DwarfLinkerForBinary.h" #include "BinaryHolder.h" #include "DebugMap.h" -#include "DwarfStreamer.h" #include "MachOUtils.h" #include "dsymutil.h" #include "llvm/ADT/ArrayRef.h" @@ -163,7 +162,14 @@ bool DwarfLinkerForBinary::createStreamer(const Triple &TheTriple, if (Options.NoOutput) return true; - Streamer = std::make_unique(OutFile, Options); + Streamer = std::make_unique( + Options.FileType, OutFile, Options.Translator, Options.Minimize, + [&](const Twine &Error, StringRef Context, const DWARFDie *) { + error(Error, Context); + }, + [&](const Twine &Warning, StringRef Context, const DWARFDie *) { + warn(Warning, Context); + }); return Streamer->init(TheTriple); } @@ -318,7 +324,7 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) { reportWarning(Warning, Context, DIE); }); GeneralLinker.setErrorHandler( - [&](const Twine &Error, StringRef Context, const DWARFDie *DIE) { + [&](const Twine &Error, StringRef Context, const DWARFDie *) { error(Error, Context); }); GeneralLinker.setObjFileLoader( @@ -442,7 +448,14 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) { return error(toString(std::move(E))); } - return Streamer->finish(Map, Options.Translator); + if (Map.getTriple().isOSDarwin() && !Map.getBinaryPath().empty() && + Options.FileType == OutputFileType::Object) + return MachOUtils::generateDsymCompanion( + Map, Options.Translator, *Streamer->getAsmPrinter().OutStreamer, + OutFile); + + Streamer->finish(); + return true; } static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) { diff --git a/tools/dsymutil/DwarfLinkerForBinary.h b/tools/dsymutil/DwarfLinkerForBinary.h index 9b7d9c5b55f..7cabacbb993 100644 --- a/tools/dsymutil/DwarfLinkerForBinary.h +++ b/tools/dsymutil/DwarfLinkerForBinary.h @@ -11,11 +11,11 @@ #include "BinaryHolder.h" #include "DebugMap.h" -#include "DwarfStreamer.h" #include "LinkUtils.h" #include "llvm/DWARFLinker/DWARFLinker.h" #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h" #include "llvm/DWARFLinker/DWARFLinkerDeclContext.h" +#include "llvm/DWARFLinker/DWARFStreamer.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Remarks/RemarkFormat.h" #include "llvm/Remarks/RemarkLinker.h" diff --git a/tools/dsymutil/LinkUtils.h b/tools/dsymutil/LinkUtils.h index 0339f4485e7..c630be328fa 100644 --- a/tools/dsymutil/LinkUtils.h +++ b/tools/dsymutil/LinkUtils.h @@ -16,16 +16,12 @@ #include "llvm/Support/WithColor.h" #include "llvm/DWARFLinker/DWARFLinker.h" +#include "llvm/DWARFLinker/DWARFStreamer.h" #include namespace llvm { namespace dsymutil { -enum class OutputFileType { - Object, - Assembly, -}; - struct LinkOptions { /// Verbosity bool Verbose = false;