From: Jonas Devlieghere Date: Mon, 9 Jul 2018 16:58:48 +0000 (+0000) Subject: [dsymutil] Add support for outputting assembly X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=82dee6aca8755abb3cd2383ce9b46db722d52b21;p=platform%2Fupstream%2Fllvm.git [dsymutil] Add support for outputting assembly When implementing the DWARF accelerator tables in dsymutil I ran into an assertion in the assembler. Debugging these kind of issues is a lot easier when looking at the assembly instead of debugging the assembler itself. Since it's only a matter of creating an AsmStreamer instead of a MCObjectStreamer it made sense to turn this into a (hidden) dsymutil feature. Differential revision: https://reviews.llvm.org/D49079 llvm-svn: 336561 --- diff --git a/llvm/test/tools/dsymutil/X86/assembly-output.test b/llvm/test/tools/dsymutil/X86/assembly-output.test new file mode 100644 index 0000000..892f08a --- /dev/null +++ b/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 diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index 4e3457d..f21873f 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -208,7 +208,7 @@ bool DwarfLinker::createStreamer(const Triple &TheTriple, if (Options.NoOutput) return true; - Streamer = llvm::make_unique(OutFile); + Streamer = llvm::make_unique(OutFile, Options); return Streamer->init(TheTriple); } @@ -2411,7 +2411,7 @@ bool DwarfLinker::link(const DebugMap &Map) { 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, diff --git a/llvm/tools/dsymutil/DwarfStreamer.cpp b/llvm/tools/dsymutil/DwarfStreamer.cpp index 5bf2382..79442f3 100644 --- a/llvm/tools/dsymutil/DwarfStreamer.cpp +++ b/llvm/tools/dsymutil/DwarfStreamer.cpp @@ -69,8 +69,8 @@ bool DwarfStreamer::init(Triple TheTriple) { 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 @@ bool DwarfStreamer::init(Triple TheTriple) { 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::init(Triple TheTriple) { 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 @@ static void emitSectionContents(const object::ObjectFile &Obj, 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); diff --git a/llvm/tools/dsymutil/DwarfStreamer.h b/llvm/tools/dsymutil/DwarfStreamer.h index 574f36c..d54985e 100644 --- a/llvm/tools/dsymutil/DwarfStreamer.h +++ b/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 @@ public: 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 @@ private: 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 @@ private: /// The file we stream the linked Dwarf to. raw_fd_ostream &OutFile; + LinkOptions Options; + uint32_t RangesSectionSize; uint32_t LocSectionSize; uint32_t LineSectionSize; diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h index 7f43d11..1362896 100644 --- a/llvm/tools/dsymutil/LinkUtils.h +++ b/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 @@ struct LinkOptions { /// Number of threads. unsigned Threads = 1; + // Output file type. + OutputFileType FileType = OutputFileType::Object; + /// -oso-prepend-path std::string PrependPath; diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 2e633fc..5fb3a4b 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -66,6 +66,11 @@ static opt OsoPrependPath( desc("Specify a directory to prepend to the paths of object files."), value_desc("path"), cat(DsymCategory)); +static opt Assembly( + "S", + desc("Output textual assembly instead of a binary dSYM companion file."), + 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 +327,9 @@ static Expected getOptions() { 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