diff options
Diffstat (limited to 'tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r-- | tools/llvm-objdump/llvm-objdump.cpp | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 122ac83..9bc092e 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -31,6 +31,7 @@ #include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCModule.h" +#include "llvm/MC/MCModuleYAML.h" #include "llvm/MC/MCObjectDisassembler.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectSymbolizer.h" @@ -61,6 +62,7 @@ #include <algorithm> #include <cctype> #include <cstring> + using namespace llvm; using namespace object; @@ -139,6 +141,12 @@ static cl::opt<bool> CFG("cfg", cl::desc("Create a CFG for every function found in the object" " and write it to a graphviz file")); +// FIXME: Does it make sense to have a dedicated tool for yaml cfg output? +static cl::opt<std::string> +YAMLCFG("yaml-cfg", + cl::desc("Create a CFG and write it as a YAML MCModule."), + cl::value_desc("yaml output file")); + static StringRef ToolName; bool llvm::error(error_code ec) { @@ -178,6 +186,7 @@ static const Target *getTarget(const ObjectFile *Obj = NULL) { } // Write a graphviz file for the CFG inside an MCFunction. +// FIXME: Use GraphWriter static void emitDOTFile(const char *FileName, const MCFunction &f, MCInstPrinter *IP) { // Start a new dot file. @@ -333,7 +342,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { return; } - if (CFG) { + if (CFG || !YAMLCFG.empty()) { OwningPtr<MCObjectDisassembler> OD( new MCObjectDisassembler(*Obj, *DisAsm, *MIA)); OwningPtr<MCModule> Mod(OD->buildModule(/* withCFG */ true)); @@ -350,14 +359,25 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { } } } - for (MCModule::const_func_iterator FI = Mod->func_begin(), - FE = Mod->func_end(); - FI != FE; ++FI) { - static int filenum = 0; - emitDOTFile((Twine((*FI)->getName()) + "_" + - utostr(filenum) + ".dot").str().c_str(), - **FI, IP.get()); - ++filenum; + if (CFG) { + for (MCModule::const_func_iterator FI = Mod->func_begin(), + FE = Mod->func_end(); + FI != FE; ++FI) { + static int filenum = 0; + emitDOTFile((Twine((*FI)->getName()) + "_" + + utostr(filenum) + ".dot").str().c_str(), + **FI, IP.get()); + ++filenum; + } + } + if (!YAMLCFG.empty()) { + std::string Error; + raw_fd_ostream YAMLOut(YAMLCFG.c_str(), Error); + if (!Error.empty()) { + errs() << ToolName << ": warning: " << Error << '\n'; + return; + } + mcmodule2yaml(YAMLOut, *Mod, *MII, *MRI); } } @@ -750,6 +770,14 @@ static void PrintUnwindInfo(const ObjectFile *o) { } } +static void printPrivateFileHeader(const ObjectFile *o) { + if (o->isELF()) { + printELFFileHeader(o); + } else if (o->isCOFF()) { + printCOFFFileHeader(o); + } +} + static void DumpObject(const ObjectFile *o) { outs() << '\n'; outs() << o->getFileName() @@ -767,8 +795,8 @@ static void DumpObject(const ObjectFile *o) { PrintSymbolTable(o); if (UnwindInfo) PrintUnwindInfo(o); - if (PrivateHeaders && o->isELF()) - printELFFileHeader(o); + if (PrivateHeaders) + printPrivateFileHeader(o); } /// @brief Dump each object file in \a a; |