diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h --- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -21,6 +21,11 @@ enum class DwarfLinkerClient { Dsymutil, LLD, General }; +enum class OutputFileType { + Object, + Assembly, +}; + /// The kind of accelerator tables we should emit. enum class AccelTableKind { Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc. diff --git a/llvm/tools/dsymutil/DwarfStreamer.h b/llvm/include/llvm/DWARFLinker/DWARFStreamer.h rename from llvm/tools/dsymutil/DwarfStreamer.h rename to llvm/include/llvm/DWARFLinker/DWARFStreamer.h --- a/llvm/tools/dsymutil/DwarfStreamer.h +++ b/llvm/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,11 +6,9 @@ // //===----------------------------------------------------------------------===// -#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" @@ -36,7 +34,14 @@ #include "llvm/Target/TargetOptions.h" namespace llvm { -namespace dsymutil { + +/// User of DwarfStreamer should call initialization code +/// for AsmPrinter: +/// +/// InitializeAllTargetInfos(); +/// InitializeAllTargetMCs(); +/// InitializeAllTargets(); +/// InitializeAllAsmPrinters(); /// The Dwarf streaming logic. /// @@ -44,13 +49,16 @@ /// 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 +166,16 @@ } 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 +192,11 @@ 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 +216,11 @@ 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/llvm/lib/DWARFLinker/CMakeLists.txt b/llvm/lib/DWARFLinker/CMakeLists.txt --- a/llvm/lib/DWARFLinker/CMakeLists.txt +++ b/llvm/lib/DWARFLinker/CMakeLists.txt @@ -2,6 +2,7 @@ DWARFLinkerCompileUnit.cpp DWARFLinkerDeclContext.cpp DWARFLinker.cpp + DWARFStreamer.cpp DEPENDS intrinsics_gen diff --git a/llvm/tools/dsymutil/DwarfStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp rename from llvm/tools/dsymutil/DwarfStreamer.cpp rename to llvm/lib/DWARFLinker/DWARFStreamer.cpp --- a/llvm/tools/dsymutil/DwarfStreamer.cpp +++ b/llvm/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,9 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "DwarfStreamer.h" -#include "LinkUtils.h" -#include "MachOUtils.h" +#include "llvm/DWARFLinker/DWARFStreamer.h" #include "llvm/ADT/Triple.h" #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" @@ -23,8 +21,6 @@ static mc::RegisterMCTargetOptionsFlags MOF; -namespace dsymutil { - bool DwarfStreamer::init(Triple TheTriple) { std::string ErrorStr; std::string TripleName; @@ -34,18 +30,19 @@ 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 +50,21 @@ 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 +85,17 @@ } 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 +106,7 @@ 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 +649,7 @@ 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 +661,7 @@ 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 +729,7 @@ /// 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 +737,7 @@ /// 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 +765,4 @@ FrameSectionSize += FDEBytes.size() + 8 + AddrSize; } -} // namespace dsymutil } // namespace llvm diff --git a/llvm/lib/DWARFLinker/LLVMBuild.txt b/llvm/lib/DWARFLinker/LLVMBuild.txt --- a/llvm/lib/DWARFLinker/LLVMBuild.txt +++ b/llvm/lib/DWARFLinker/LLVMBuild.txt @@ -18,4 +18,4 @@ type = Library name = DWARFLinker parent = Libraries -required_libraries = DebugInfoDWARF AsmPrinter CodeGen MC Object Support +required_libraries = DebugInfoDWARF AsmPrinter CodeGen MC Object Support diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt --- a/llvm/tools/dsymutil/CMakeLists.txt +++ b/llvm/tools/dsymutil/CMakeLists.txt @@ -24,7 +24,6 @@ CFBundle.cpp DebugMap.cpp DwarfLinkerForBinary.cpp - DwarfStreamer.cpp MachODebugMapParser.cpp MachOUtils.cpp SymbolMap.cpp diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.h b/llvm/tools/dsymutil/DwarfLinkerForBinary.h --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.h +++ b/llvm/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/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/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 @@ 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 @@ 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,13 @@ 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); + else + return Streamer->finish(), true; } static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) { diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h --- a/llvm/tools/dsymutil/LinkUtils.h +++ b/llvm/tools/dsymutil/LinkUtils.h @@ -21,11 +21,6 @@ namespace llvm { namespace dsymutil { -enum class OutputFileType { - Object, - Assembly, -}; - struct LinkOptions { /// Verbosity bool Verbose = false;