diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2011-07-20 19:37:35 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2011-07-20 19:37:35 +0000 |
commit | 685a2501b20baf688f6cc087f4b92bbafcd8028e (patch) | |
tree | 3f0fca76506239b383567c664fbc53c820cebabd /tools/llvm-objdump/llvm-objdump.cpp | |
parent | a4d0bd84f7bdc78784e44b623ded448988022e4b (diff) |
Sketch out an CFG reconstruction mode for llvm-objdump.
- Not great yet, but it's a start.
- Requires an object file with a symbol table. (I really want to fix this, but it'll need a whole new algorithm)
- ELF and COFF won't work at the moment due to libObject shortcomings.
To try it out run
$ llvm-objdump -d --cfg foo.o
This will create a graphviz file for every symbol in the object file's text section containing a CFG.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135608 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r-- | tools/llvm-objdump/llvm-objdump.cpp | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 8f6e9df275..21df7ccd9d 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -13,6 +13,7 @@ // //===----------------------------------------------------------------------===// +#include "MCFunction.h" #include "llvm/Object/ObjectFile.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Triple.h" @@ -21,6 +22,8 @@ #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Format.h" @@ -52,6 +55,10 @@ namespace { Disassembled("d", cl::desc("Alias for --disassemble"), cl::aliasopt(Disassemble)); + cl::opt<bool> + CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and" + "write it to a graphviz file")); + cl::opt<std::string> TripleName("triple", cl::desc("Target triple to disassemble for, " "see -version for available targets")); @@ -156,6 +163,7 @@ static void DisassembleInput(const StringRef &Filename) { // GetTarget prints out stuff. return; } + const MCInstrInfo *InstrInfo = TheTarget->createMCInstrInfo(); outs() << '\n'; outs() << Filename @@ -233,15 +241,14 @@ static void DisassembleInput(const StringRef &Filename) { uint64_t End = si == se-1 ? SectSize : Symbols[si + 1].first - 1; outs() << '\n' << Symbols[si].second << ":\n"; - for (Index = Start; Index < End; Index += Size) { - MCInst Inst; - #ifndef NDEBUG raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); #else raw_ostream &DebugOut = nulls(); #endif + for (Index = Start; Index < End; Index += Size) { + MCInst Inst; if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut)) { uint64_t addr; if (error(i->getAddress(addr))) break; @@ -255,6 +262,36 @@ static void DisassembleInput(const StringRef &Filename) { Size = 1; // skip illegible bytes } } + + if (CFG) { + MCFunction f = + MCFunction::createFunctionFromMC(Symbols[si].second, DisAsm.get(), + memoryObject, Start, End, InstrInfo, + DebugOut); + + // Start a new dot file. + std::string Error; + raw_fd_ostream Out((f.getName().str() + ".dot").c_str(), Error); + + Out << "digraph " << f.getName() << " {\n"; + Out << "graph [ rankdir = \"LR\" ];\n"; + for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) { + Out << '"' << (uintptr_t)&i->second << "\" [ label=\"<a>"; + // Print instructions. + for (unsigned ii = 0, ie = i->second.getInsts().size(); ii != ie; + ++ii) { + IP->printInst(&i->second.getInsts()[ii].Inst, Out); + Out << '|'; + } + Out << "<o>\" shape=\"record\" ];\n"; + + // Add edges. + for (MCBasicBlock::succ_iterator si = i->second.succ_begin(), + se = i->second.succ_end(); si != se; ++si) + Out << (uintptr_t)&i->second << ":o -> " << (uintptr_t)*si <<":a\n"; + } + Out << "}\n"; + } } } } @@ -271,6 +308,7 @@ int main(int argc, char **argv) { llvm::InitializeAllTargets(); llvm::InitializeAllMCAsmInfos(); llvm::InitializeAllMCCodeGenInfos(); + llvm::InitializeAllMCInstrInfos(); llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); |