mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-07 12:30:57 +00:00
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336561 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
798b3ef0fc
commit
a5d860c471
3
test/tools/dsymutil/X86/assembly-output.test
Normal file
3
test/tools/dsymutil/X86/assembly-output.test
Normal file
@ -0,0 +1,3 @@
|
||||
RUN: dsymutil -S -f -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 -o - | FileCheck %s
|
||||
|
||||
CHECK: .section __DWARF
|
@ -208,7 +208,7 @@ bool DwarfLinker::createStreamer(const Triple &TheTriple,
|
||||
if (Options.NoOutput)
|
||||
return true;
|
||||
|
||||
Streamer = llvm::make_unique<DwarfStreamer>(OutFile);
|
||||
Streamer = llvm::make_unique<DwarfStreamer>(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,
|
||||
|
@ -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<MCAsmBackend>(MAB),
|
||||
MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(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<formatted_raw_ostream>(OutFile), true, true, MIP,
|
||||
std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB),
|
||||
true);
|
||||
break;
|
||||
}
|
||||
case OutputFileType::Object: {
|
||||
MS = TheTarget->createMCObjectStreamer(
|
||||
TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
|
||||
MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(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);
|
||||
|
||||
|
@ -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<MCInstrInfo> MII;
|
||||
std::unique_ptr<MCSubtargetInfo> MSTI;
|
||||
MCInstPrinter *MIP; // Owned by AsmPrinter
|
||||
MCCodeEmitter *MCE; // Owned by MCStreamer
|
||||
MCStreamer *MS; // Owned by AsmPrinter
|
||||
std::unique_ptr<TargetMachine> 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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -66,6 +66,11 @@ static opt<std::string> OsoPrependPath(
|
||||
desc("Specify a directory to prepend to the paths of object files."),
|
||||
value_desc("path"), cat(DsymCategory));
|
||||
|
||||
static opt<bool> Assembly(
|
||||
"S",
|
||||
desc("Output textual assembly instead of a binary dSYM companion file."),
|
||||
init(false), cat(DsymCategory), cl::Hidden);
|
||||
|
||||
static opt<bool> DumpStab(
|
||||
"symtab",
|
||||
desc("Dumps the symbol table found in executable or object file(s) and\n"
|
||||
@ -322,6 +327,9 @@ static Expected<LinkOptions> 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
|
||||
|
Loading…
Reference in New Issue
Block a user