src/main.cxx
src/gui/Mainwindow.cxx
src/gui/widgets/BasicBlockWidget.cxx
+ src/gui/widgets/CFGScene.cxx
src/gui/widgets/ScriptingDock.cxx
src/disassembler/Disassembler.cxx
src/disassembler/llvm/LLVMDisassembler.cxx
src/gui/qt.hxx
src/gui/Mainwindow.hxx
src/gui/widgets/BasicBlockWidget.hxx
+ src/gui/widgets/CFGScene.hxx
src/gui/widgets/ScriptingDock.hxx
src/disassembler/llvm/LLVMDisassembler.hxx
src/disassembler/Disassembler.hxx
#include "Mainwindow.hxx"
#include "qt.hxx"
#include "disassembler/llvm/LLVMDisassembler.hxx"
+#include "widgets/CFGScene.hxx"
#include <iostream>
#include <sstream>
BasicBlockWidget *
local__add_basic_block(BasicBlock * block, Disassembler * dis,
std::map<uint64_t, BasicBlockWidget*>& known_blocks,
- QGraphicsScene * scene, uint64_t starty, uint64_t startx) {
+ CFGScene * scene, uint64_t starty, uint64_t startx) {
decltype(known_blocks.begin()) old;
if ((old = known_blocks.find(block->getStartAddress())) != known_blocks.end())
scene->addItem(widget);
widget->setFlag(QGraphicsItem::ItemIsMovable, true);
- widget->moveBy(100*startx, 10*(block->getStartAddress() - starty));
+ widget->moveBy(100*startx, block->getStartAddress() - starty);
dis->printEachInstruction(block->getStartAddress(), block->getEndAddress(),
[&](uint8_t* bytes, size_t byte_count, const std::string& line) {
QTabWidget * w = new QTabWidget();
// CFG
- QGraphicsScene * scene = new QGraphicsScene;
+ CFGScene * scene = new CFGScene;
BasicBlock * block = disassembler->getBasicBlock(fun->getStartAddress());
#include "disassembler/BasicBlock.hxx"
#include <vector>
#include <cassert>
+#include <tuple>
class BasicBlockWidget : public QGraphicsItem
{
QRectF boundingRect() const {
qreal penWidth = 1;
-
-
- if (next[0]) {
- if (next[1]) {
- result |= QRectF(QPointF(x + dx/3, y+dy),
- mapFromScene(next[0]->getEntry()));
- } else {
- result |= QRectF(QPointF(x + dx/2, y+dy),
- mapFromScene(next[0]->getEntry()));
- }
- }
- if (next[1])
- result |= QRectF(QPointF(x + 2*dx/3, y+dy),
- mapFromScene(next[1]->getEntry()));
-
QRectF result(- penWidth / 2, - penWidth / 2,
width + penWidth, height + penWidth);
return result;
}
- void mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
+
+ void mouseMoveEvent(QGraphicsSceneMouseEvent * event) {
QGraphicsItem::mouseMoveEvent(event);
- std::for_each(previous.begin(), previous.end(),
- [&] (BasicBlockWidget * item) {
- item->update(boundingRect() | item->boundingRect());
- });
+ scene()->update();
}
QPointF getEntry() const {
return mapToScene(QPointF(width/2, 0));
}
+ std::tuple<QPointF, QPointF, QPointF> getExits() const {
+ return std::make_tuple(mapToScene(QPointF( width/3, height)),
+ mapToScene(QPointF( width/2, height)),
+ mapToScene(QPointF(2*width/3, height)));
+ }
+
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget) {
painter->fillRect(0, 0, width, height, QColor(0xcc, 0xcc, 0xff, 0xff));
painter->drawRect(0, 0, width, height);
painter->drawText(5, 15, name);
if (_widget.rowCount() != 0)
- _widget.render(painter);
-
- if (next[0]) {
- if (next[1]) {
- painter->setPen(QColor(0x00, 0xff, 0x00, 0xff));
- painter->drawLine(QPointF(x + dx/3, y+dy),
- mapFromScene(next[0]->getEntry()));
- } else {
- painter->setPen(QColor(0x00, 0x00, 0x00, 0xff));
- painter->drawLine(QPointF(x + dx/2, y+dy),
- mapFromScene(next[0]->getEntry()));
- }
- }
- painter->setPen(QColor(0xff, 0x00, 0x00, 0xff));
- if (next[1])
- painter->drawLine(QPointF(x + 2*dx/3, y+dy),
- mapFromScene(next[1]->getEntry()));
-
+ _widget.render(painter, QPoint(5, 20));
}
void addPrevious(BasicBlockWidget * widget) {
next[1] = right;
}
+ BasicBlockWidget ** getNext() {
+ return next;
+ }
+
private:
uint32_t width, height;
QTableWidget _widget;
--- /dev/null
+#include "CFGScene.hxx"
+
+void CFGScene::drawBackground(QPainter* painter, const QRectF & rect) {
+ QGraphicsScene::drawBackground(painter, rect);
+
+ spaceWidgets();
+
+ for (BasicBlockWidget * widget : widgets) {
+ QPointF kopf = widget->getEntry();
+ painter->setPen(QColor(0x00, 0xff, 0x00, 0xff));
+ painter->drawLine(kopf, kopf - QPointF(0, 20));
+
+ auto tails = widget->getExits();
+ auto next = widget->getNext();
+ if (NULL != next[0]) {
+ if (NULL != next[1]) {
+ painter->setPen(QColor(0xff, 0x00, 0x00, 0xff));
+ painter->drawLine(std::get<0>(tails), std::get<0>(tails) + QPointF(0, 20));
+ drawLine(painter, std::get<0>(tails) + QPointF(0, 20), next[1]->getEntry() - QPointF(0, 20));
+ painter->setPen(QColor(0x00, 0xff, 0x00, 0xff));
+ painter->drawLine(std::get<2>(tails), std::get<2>(tails) + QPointF(0, 20));
+ drawLine(painter, std::get<2>(tails) + QPointF(0, 20), next[0]->getEntry() - QPointF(0, 20));
+ } else {
+ painter->setPen(QColor(0x00, 0x00, 0x00, 0xff));
+ painter->drawLine(std::get<1>(tails), std::get<1>(tails) + QPointF(0, 20));
+ drawLine(painter, std::get<1>(tails) + QPointF(0, 20), next[0]->getEntry() - QPointF(0, 20));
+ }
+ }
+ }
+}
+
+void CFGScene::drawLine(QPainter* painter, QPointF from, QPointF to, bool left) {
+ if ((to - from).y() > 0) {
+ QPointF angle1(from + QPointF(0, (to - from).y())), angle2(to - QPointF(0, (to - from).y() / 2));
+ painter->drawLine(from, angle1);
+ painter->drawLine(angle1, to);
+ }
+}
+
+void CFGScene::spaceWidgets() {
+ bool changed = false;
+ do {
+ changed = false;
+ for (BasicBlockWidget * widget : widgets) {
+ QPointF out(std::get<0>(widget->getExits()));
+ BasicBlockWidget ** next = widget->getNext();
+
+ if (NULL != next[0]
+ && (next[0]->getEntry() - widget->getEntry()).y() > 0
+ && (next[0]->getEntry() - out).y() < 50) {
+ next[0]->moveBy(0, 1);
+ changed = true;
+ }
+ if (NULL != next[1]
+ && (next[1]->getEntry() - widget->getEntry()).y() > 0
+ && (next[1]->getEntry() - out).y() < 50) {
+ next[1]->moveBy(0, 1);
+ changed = true;
+ }
+ }
+ } while (changed);
+}
--- /dev/null
+#ifndef INCLUDE__CFGScene_hxx
+#define INCLUDE__CFGScene_hxx
+
+#include "gui/qt.hxx"
+#include "BasicBlockWidget.hxx"
+
+#include <vector>
+
+class CFGScene : public QGraphicsScene {
+public:
+ CFGScene(QWidget * parent = 0)
+ : QGraphicsScene(parent) {}
+
+ // Take special care when adding a BasicBlock to the scene as we
+ // need to draw arrows for it later on
+ void addItem(BasicBlockWidget* block) {
+ widgets.push_back(block);
+ QGraphicsScene::addItem(block);
+ }
+
+ virtual void drawBackground(QPainter* painter, const QRectF & rect);
+private:
+ std::vector<BasicBlockWidget*> widgets;
+
+ void drawLine(QPainter* painter, QPointF from, QPointF to, bool left = true);
+
+ void spaceWidgets();
+};
+
+#endif