Index: llvm/test/tools/dsymutil/X86/assembly-output.test =================================================================== --- /dev/null +++ llvm/test/tools/dsymutil/X86/assembly-output.test @@ -0,0 +1,3 @@ +RUN: dsymutil -S -f -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 -o - | FileCheck %s + +CHECK: .section __DWARF Index: llvm/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/tools/dsymutil/DwarfLinker.cpp +++ llvm/tools/dsymutil/DwarfLinker.cpp @@ -208,7 +208,7 @@ if (Options.NoOutput) return true; - Streamer = llvm::make_unique(OutFile); + Streamer = llvm::make_unique(OutFile, Options); return Streamer->init(TheTriple); } @@ -2411,7 +2411,7 @@ if (LLVM_UNLIKELY(Options.Update)) { for (auto &CurrentUnit : LinkContext.CompileUnits) CurrentUnit->markEverythingAsKept(); - Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile, Options); + Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile); } else { for (auto &CurrentUnit : LinkContext.CompileUnits) lookForDIEsToKeep(LinkContext.RelocMgr, LinkContext.Ranges, Index: llvm/tools/dsymutil/DwarfStreamer.h =================================================================== --- llvm/tools/dsymutil/DwarfStreamer.h +++ llvm/tools/dsymutil/DwarfStreamer.h @@ -9,6 +9,7 @@ #include "CompileUnit.h" #include "DebugMap.h" +#include "LinkUtils.h" #include "NonRelocatableStringpool.h" #include "llvm/CodeGen/AccelTable.h" #include "llvm/CodeGen/AsmPrinter.h" @@ -36,15 +37,15 @@ namespace llvm { namespace dsymutil { -struct LinkOptions; - /// The Dwarf streaming logic. /// /// All interactions with the MC layer that is used to build the debug /// information binary representation are handled in this class. class DwarfStreamer { public: - DwarfStreamer(raw_fd_ostream &OutFile) : OutFile(OutFile) {} + DwarfStreamer(raw_fd_ostream &OutFile, LinkOptions Options) + : OutFile(OutFile), Options(std::move(Options)) {} + bool init(Triple TheTriple); /// Dump the file to the disk. @@ -103,7 +104,7 @@ unsigned AdddressSize); /// Copy over the debug sections that are not modified when updating. - void copyInvariantDebugSection(const object::ObjectFile &Obj, LinkOptions &); + void copyInvariantDebugSection(const object::ObjectFile &Obj); uint32_t getLineSectionSize() const { return LineSectionSize; } @@ -144,6 +145,7 @@ MCAsmBackend *MAB; // Owned by MCStreamer std::unique_ptr MII; std::unique_ptr MSTI; + MCInstPrinter *MIP; // Owned by AsmPrinter MCCodeEmitter *MCE; // Owned by MCStreamer MCStreamer *MS; // Owned by AsmPrinter std::unique_ptr TM; @@ -153,6 +155,8 @@ /// The file we stream the linked Dwarf to. raw_fd_ostream &OutFile; + LinkOptions Options; + uint32_t RangesSectionSize; uint32_t LocSectionSize; uint32_t LineSectionSize; Index: llvm/tools/dsymutil/DwarfStreamer.cpp =================================================================== --- llvm/tools/dsymutil/DwarfStreamer.cpp +++ llvm/tools/dsymutil/DwarfStreamer.cpp @@ -69,8 +69,8 @@ if (!MSTI) return error("no subtarget info for target " + TripleName, Context); - MCTargetOptions Options; - MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, Options); + MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); + MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions); if (!MAB) return error("no asm backend for target " + TripleName, Context); @@ -82,12 +82,26 @@ if (!MCE) return error("no code emitter for target " + TripleName, Context); - MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); - MS = TheTarget->createMCObjectStreamer( - TheTriple, *MC, std::unique_ptr(MAB), - MAB->createObjectWriter(OutFile), std::unique_ptr(MCE), - *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, - /*DWARFMustBeAtTheEnd*/ false); + switch (Options.FileType) { + case OutputFileType::Assembly: { + MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(), + *MAI, *MII, *MRI); + MS = TheTarget->createAsmStreamer( + *MC, llvm::make_unique(OutFile), true, true, MIP, + std::unique_ptr(MCE), std::unique_ptr(MAB), + true); + break; + } + case OutputFileType::Object: { + MS = TheTarget->createMCObjectStreamer( + TheTriple, *MC, std::unique_ptr(MAB), + MAB->createObjectWriter(OutFile), std::unique_ptr(MCE), + *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, + /*DWARFMustBeAtTheEnd*/ false); + break; + } + } + if (!MS) return error("no object streamer for target " + TripleName, Context); @@ -111,7 +125,8 @@ bool DwarfStreamer::finish(const DebugMap &DM) { bool Result = true; - if (DM.getTriple().isOSDarwin() && !DM.getBinaryPath().empty()) + if (DM.getTriple().isOSDarwin() && !DM.getBinaryPath().empty() && + Options.FileType == OutputFileType::Object) Result = MachOUtils::generateDsymCompanion(DM, *MS, OutFile); else MS->Finish(); @@ -545,8 +560,7 @@ MS->EmitBytes(Contents); } -void DwarfStreamer::copyInvariantDebugSection(const object::ObjectFile &Obj, - LinkOptions &Options) { +void DwarfStreamer::copyInvariantDebugSection(const object::ObjectFile &Obj) { MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection()); emitSectionContents(Obj, "debug_line", MS); Index: llvm/tools/dsymutil/LinkUtils.h =================================================================== --- llvm/tools/dsymutil/LinkUtils.h +++ llvm/tools/dsymutil/LinkUtils.h @@ -17,6 +17,11 @@ namespace llvm { namespace dsymutil { +enum class OutputFileType { + Object, + Assembly, +}; + struct LinkOptions { /// Verbosity bool Verbose = false; @@ -39,6 +44,9 @@ /// Number of threads. unsigned Threads = 1; + // Output file type. + OutputFileType FileType = OutputFileType::Object; + /// -oso-prepend-path std::string PrependPath; Index: llvm/tools/dsymutil/dsymutil.cpp =================================================================== --- llvm/tools/dsymutil/dsymutil.cpp +++ llvm/tools/dsymutil/dsymutil.cpp @@ -66,6 +66,10 @@ desc("Specify a directory to prepend to the paths of object files."), value_desc("path"), cat(DsymCategory)); +static opt + Assembly("S", desc("Output assembly instead of dSYM companion object."), + init(false), cat(DsymCategory), cl::Hidden); + static opt DumpStab( "symtab", desc("Dumps the symbol table found in executable or object file(s) and\n" @@ -322,6 +326,9 @@ Options.NoTimestamp = NoTimestamp; Options.PrependPath = OsoPrependPath; + if (Assembly) + Options.FileType = OutputFileType::Assembly; + if (Options.Update && std::find(InputFiles.begin(), InputFiles.end(), "-") != InputFiles.end()) { // FIXME: We cannot use stdin for an update because stdin will be