From 9023eb3885faa52eb9729b61b401e5b131199c0d Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Fri, 8 Nov 2013 23:16:03 +0100 Subject: [PATCH] Update --- COPYING.NCSA | 29 ++++++++++ Makefile | 15 ++++-- src/Binary.cxx | 120 ++++++++++++++++++++++++++++++----------- src/Binary.hxx | 2 + src/gui/Mainwindow.cxx | 46 ++++++++++++++++ src/gui/Mainwindow.h++ | 23 ++++++++ src/include.hxx | 4 +- src/main.cxx | 12 +++-- 8 files changed, 212 insertions(+), 39 deletions(-) create mode 100644 COPYING.NCSA create mode 100644 src/gui/Mainwindow.cxx create mode 100644 src/gui/Mainwindow.h++ diff --git a/COPYING.NCSA b/COPYING.NCSA new file mode 100644 index 0000000..e1a7814 --- /dev/null +++ b/COPYING.NCSA @@ -0,0 +1,29 @@ +Copyright (c) University of Illinois at Urbana-Champaign. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. \ No newline at end of file diff --git a/Makefile b/Makefile index 3037d61..549ea3c 100644 --- a/Makefile +++ b/Makefile @@ -3,11 +3,11 @@ CXX = clang++ LD = clang++ -CXXFLAGS += `llvm-config-3.4 --cflags` -LDFLAGS ?= `llvm-config-3.4 --ldflags` -LIBS ?= `llvm-config-3.4 --libs` +CXXFLAGS += $(shell llvm-config-3.4 --cflags) $(shell pkg-config QtGui --cflags) -Isrc +LDFLAGS ?= $(shell llvm-config-3.4 --ldflags) +LIBS ?= $(shell llvm-config-3.4 --libs) $(shell pkg-config QtGui --libs) -objects = $(patsubst %.cxx,%.o,$(shell find src -name \*.cxx)) +objects = $(patsubst %.cxx,%.o,$(shell find src -name \*.cxx)) $(patsubst %.h++,%_moc.o,$(shell find src -name \*.h++)) qtlldb: $(objects) $(LD) -o qtlldb $(LDFLAGS) $^ $(LIBS) @@ -16,9 +16,16 @@ qtlldb: $(objects) $(CXX) -MM -o $*.make $(CXXFLAGS) $< $(CXX) -o $@ -c $(CXXFLAGS) $< +.cpp.o: + $(CXX) -MM -o $*.make $(CXXFLAGS) $< + $(CXX) -o $@ -c $(CXXFLAGS) $< + clean: rm $(objects) qtlldb +%_moc.cpp: %.h++ + moc $< -o $@ + include **/*.make .SUFFIXES: .cxx .o diff --git a/src/Binary.cxx b/src/Binary.cxx index 696947d..d57db4e 100644 --- a/src/Binary.cxx +++ b/src/Binary.cxx @@ -8,44 +8,44 @@ using namespace llvm; using namespace llvm::object; static bool error(error_code ec) { - if (!ec) return false; + if (!ec) return false; - outs() << "error reading file: " << ec.message() << ".\n"; - outs().flush(); - return true; + outs() << "error reading file: " << ec.message() << ".\n"; + outs().flush(); + return true; } static bool RelocAddressLess(RelocationRef a, RelocationRef b) { - uint64_t a_addr, b_addr; - if (error(a.getOffset(a_addr))) return false; - if (error(b.getOffset(b_addr))) return false; - return a_addr < b_addr; + uint64_t a_addr, b_addr; + if (error(a.getOffset(a_addr))) return false; + if (error(b.getOffset(b_addr))) return false; + return a_addr < b_addr; } static void DumpBytes(StringRef bytes) { - static const char hex_rep[] = "0123456789abcdef"; - // FIXME: The real way to do this is to figure out the longest instruction - // and align to that size before printing. I'll fix this when I get - // around to outputting relocations. - // 15 is the longest x86 instruction - // 3 is for the hex rep of a byte + a space. - // 1 is for the null terminator. - enum { OutputSize = (15 * 3) + 1 }; - char output[OutputSize]; - - assert(bytes.size() <= 15 - && "DumpBytes only supports instructions of up to 15 bytes"); - memset(output, ' ', sizeof(output)); - unsigned index = 0; - for (StringRef::iterator i = bytes.begin(), - e = bytes.end(); i != e; ++i) { - output[index] = hex_rep[(*i & 0xF0) >> 4]; - output[index + 1] = hex_rep[*i & 0xF]; - index += 3; - } - - output[sizeof(output) - 1] = 0; - outs() << output; + static const char hex_rep[] = "0123456789abcdef"; + // FIXME: The real way to do this is to figure out the longest instruction + // and align to that size before printing. I'll fix this when I get + // around to outputting relocations. + // 15 is the longest x86 instruction + // 3 is for the hex rep of a byte + a space. + // 1 is for the null terminator. + enum { OutputSize = (15 * 3) + 1 }; + char output[OutputSize]; + + assert(bytes.size() <= 15 + && "DumpBytes only supports instructions of up to 15 bytes"); + memset(output, ' ', sizeof(output)); + unsigned index = 0; + for (StringRef::iterator i = bytes.begin(), + e = bytes.end(); i != e; ++i) { + output[index] = hex_rep[(*i & 0xF0) >> 4]; + output[index + 1] = hex_rep[*i & 0xF]; + index += 3; + } + + output[sizeof(output) - 1] = 0; + outs() << output; } ::Binary::Binary(const std::string& filename) @@ -177,6 +177,9 @@ void ::Binary::disassemble_functions() { StringRef Name; if (error(si->getName(Name))) break; + + outs() << "\nXXX " << Name << "\n"; + Symbols.push_back(std::make_pair(Address, Name)); } } @@ -294,3 +297,58 @@ void ::Binary::disassemble_functions() { } } } + +void ::Binary::disassemble_cfg() { + for (MCModule::const_func_iterator FI = Mod->func_begin(), + FE = Mod->func_end(); + FI != FE; ++FI) { + static int filenum = 0; + std::string FileName = std::string("dot/") + (Twine((*FI)->getName()) + "_" + utostr(filenum) + ".dot").str(); + + std::cerr << FileName << std::endl; + + // Start a new dot file. + std::string Error; + raw_fd_ostream Out(FileName.c_str(), Error); + if (!Error.empty()) { + errs() << "llvm-objdump: warning: " << Error << '\n'; + return; + } + + Out << "digraph \"" << (*FI)->getName() << "\" {\n"; + Out << "graph [ rankdir = \"LR\" ];\n"; + for (MCFunction::const_iterator i = (*FI)->begin(), e = (*FI)->end(); i != e; ++i) { + // Only print blocks that have predecessors. + bool hasPreds = (*i)->pred_begin() != (*i)->pred_end(); + + if (!hasPreds && i != (*FI)->begin()) + continue; + + Out << '"' << (*i)->getInsts()->getBeginAddr() << "\" [ label=\""; + // Print instructions. + for (unsigned ii = 0, ie = (*i)->getInsts()->size(); ii != ie; + ++ii) { + if (ii != 0) // Not the first line, start a new row. + Out << '|'; + if (ii + 1 == ie) // Last line, add an end id. + Out << ""; + + // Escape special chars and print the instruction in mnemonic form. + std::string Str; + raw_string_ostream OS(Str); + IP->printInst(&(*i)->getInsts()->at(ii).Inst, OS, ""); + Out << DOT::EscapeString(OS.str()); + } + Out << "\" shape=\"record\" ];\n"; + + // Add edges. + for (MCBasicBlock::succ_const_iterator si = (*i)->succ_begin(), + se = (*i)->succ_end(); si != se; ++si) + Out << (*i)->getInsts()->getBeginAddr() << ":o -> " + << (*si)->getInsts()->getBeginAddr() << ":a\n"; + } + Out << "}\n"; + + ++filenum; + } +} diff --git a/src/Binary.hxx b/src/Binary.hxx index aa5460e..31d7485 100644 --- a/src/Binary.hxx +++ b/src/Binary.hxx @@ -29,4 +29,6 @@ public: void disassemble(); void disassemble_functions(); + + void disassemble_cfg(); }; diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx new file mode 100644 index 0000000..3e26227 --- /dev/null +++ b/src/gui/Mainwindow.cxx @@ -0,0 +1,46 @@ +#include "Mainwindow.h++" + +#include + +Mainwindow::Mainwindow() +{ + // openAction = new QAction(tr("&Open"), this); + // saveAction = new QAction(tr("&Save"), this); + exitAction = new QAction(tr("E&xit"), this); + + // connect(openAction, SIGNAL(triggered()), this, SLOT(open())); + // connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); + connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + + fileMenu = menuBar()->addMenu(tr("&File")); + // fileMenu->addAction(openAction); + // fileMenu->addAction(saveAction); + // fileMenu->addSeparator(); + fileMenu->addAction(exitAction); + + // + // setCentralWidget(textEdit); + + tabwidget = new QTabWidget; + setCentralWidget(tabwidget); + + textEdit = new QTextEdit; + tabwidget->addTab(textEdit, "edit"); + + setWindowTitle(tr("Notepad")); +} + +void Mainwindow::quit() +{ + QMessageBox messageBox; + messageBox.setWindowTitle(tr("Notepad")); + messageBox.setText(tr("Do you really want to quit?")); + messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + messageBox.setDefaultButton(QMessageBox::No); + if (messageBox.exec() == QMessageBox::Yes) + qApp->quit(); +} + +void Mainwindow::open() { + +} diff --git a/src/gui/Mainwindow.h++ b/src/gui/Mainwindow.h++ new file mode 100644 index 0000000..daf9d3d --- /dev/null +++ b/src/gui/Mainwindow.h++ @@ -0,0 +1,23 @@ +#include "include.hxx" + + +#include +#include +#include + + +class Mainwindow : public QMainWindow { + Q_OBJECT +private: + QTextEdit *textEdit; + QPushButton *quitButton; + QAction *exitAction; + QMenu *fileMenu; + QTabWidget * tabwidget; +private slots: + void quit(); + void open(); + +public: + Mainwindow(); +}; diff --git a/src/include.hxx b/src/include.hxx index afb4787..e0beeea 100644 --- a/src/include.hxx +++ b/src/include.hxx @@ -2,8 +2,9 @@ #define INCLUDE__include_hxx #include "llvm/ADT/OwningPtr.h" -#include +#include "llvm/ADT/Triple.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/Archive.h" @@ -26,5 +27,6 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/StringRefMemoryObject.h" +#include "llvm/Support/GraphWriter.h" #endif diff --git a/src/main.cxx b/src/main.cxx index ec76891..3a60a99 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -3,7 +3,11 @@ #include #include +#include +#include + #include "Binary.hxx" +#include "gui/Mainwindow.h++" using std::cout; using std::cin; @@ -16,8 +20,10 @@ int main(int argc, char** argv) llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); - Binary bin(argv[1]); - bin.disassemble(); + QApplication app(argc, argv); + + Mainwindow m; + m.show(); - bin.disassemble_functions(); + return app.exec(); } -- 2.39.2