--- /dev/null
+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
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)
$(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
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)
StringRef Name;
if (error(si->getName(Name))) break;
+
+ outs() << "\nXXX " << Name << "\n";
+
Symbols.push_back(std::make_pair(Address, Name));
}
}
}
}
}
+
+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=\"<a>";
+ // 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 << "<o>";
+
+ // 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;
+ }
+}
void disassemble();
void disassemble_functions();
+
+ void disassemble_cfg();
};
--- /dev/null
+#include "Mainwindow.h++"
+
+#include <QtGui>
+
+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() {
+
+}
--- /dev/null
+#include "include.hxx"
+
+
+#include <QTextEdit>
+#include <QPushButton>
+#include <QMainWindow>
+
+
+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();
+};
#define INCLUDE__include_hxx
#include "llvm/ADT/OwningPtr.h"
-#include <llvm/ADT/Triple.h>
+#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"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/StringRefMemoryObject.h"
+#include "llvm/Support/GraphWriter.h"
#endif
#include <iostream>
#include <climits>
+#include <QApplication>
+#include <QTextEdit>
+
#include "Binary.hxx"
+#include "gui/Mainwindow.h++"
using std::cout;
using std::cin;
llvm::InitializeAllAsmParsers();
llvm::InitializeAllDisassemblers();
- Binary bin(argv[1]);
- bin.disassemble();
+ QApplication app(argc, argv);
+
+ Mainwindow m;
+ m.show();
- bin.disassemble_functions();
+ return app.exec();
}