]> git.siccegge.de Git - frida/frida.git/blobdiff - src/gui/widgets/BasicBlockWidget.cxx
Remove adjustSize() hack -- doesn't seem to be necessary any more
[frida/frida.git] / src / gui / widgets / BasicBlockWidget.cxx
index 6d615b41eed305861c6e4e20033ff564cf8f837f..eee78c4ea55d06b47e672afeb10367967b3e8a30 100644 (file)
@@ -1,4 +1,5 @@
 #include "BasicBlockWidget.hxx"
+#include "CFGScene.hxx"
 #include "gui/Mainwindow.hxx"
 #include "gui/dialogs/SimpleStringDialog.hxx"
 #include "core/BasicBlock.hxx"
@@ -15,8 +16,6 @@ public:
        CustomQGraphicsTextItem(const QString& text, BasicBlockWidget* parent)
                : QGraphicsTextItem(text, parent), parent(parent) {}
        void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
-
-       void adjustSize();
 private:
        void addComment(int row, bool global);
 
@@ -32,12 +31,15 @@ void CustomQGraphicsTextItem::addComment(int row, bool global) {
                if (global) {
                        comment = parent->block->getManager()->newGlobalComment(address);
                } else {
+                       /* TODO: 0x23 as we currently don't have the function here
+                        * and setting it to null will make the comment appear
+                        * global. Also means local comments are largely still
+                        * broken.
+                        */
                        comment = parent->block->getManager()->newLocalComment(address, (Function*)0x23);
                }
                comment->setText(dialog.result().toStdString());
                parent->block->getManager()->finishComment(comment);
-
-//             cell.firstCursorPosition().insertHtml(QString(";; ") + dialog.result());
        } else {
                LOG4CXX_DEBUG(parent->logger, "addComment aborted");
        }
@@ -51,13 +53,21 @@ void CustomQGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* e
        QMenu menu;
        bool ok;
        uint64_t address = c.selectedText().toLongLong(&ok, 16);
+       QTextTable* table = c.currentTable();
        if (ok) {
                QAction* act = menu.addAction(c.selectedText() + " is a Function");
                QObject::connect(act, &QAction::triggered,
-                                [=]() {parent->mainwindow->requestNewFunctionByAddress(address);});
+                                [=]() {
+                                        parent->mainwindow->requestNewFunctionByAddress(address);
+                                        if (NULL == table) return;
+                                        int row = table->cellAt(c).row();
+                                        uint64_t insAddress = parent->instructions[row].getAddress();
+                                        Comment* comment = parent->block->getManager()->newLocalComment(insAddress, (Function*)0x23);
+                                        comment->setText("#F<" + c.selectedText().toStdString() + ">");
+                                        parent->block->getManager()->finishComment(comment);
+                                });
        }
 
-       QTextTable* table = c.currentTable();
        if (NULL != table) {
                int row = table->cellAt(c).row();
                QAction* globalComment = menu.addAction("Add global Comment");
@@ -72,27 +82,16 @@ void CustomQGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* e
        menu.exec(event->screenPos());
 }
 
-void CustomQGraphicsTextItem::adjustSize() {
-       int width = 1000;
-       setTextWidth(width);
-       int height = boundingRect().height();
-       while (width > 250 && height == boundingRect().height()) {
-               setTextWidth(width -= 10);
-       }
-       width += 10;
-       if (width < 250) width = 250;
-       setTextWidth(width);
-}
-
 BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block,
                                    Mainwindow * mainwindow)
        : width(200), height(45), name(name)
-       , _table(NULL)
+       , currentColor(defaultColor), _table(NULL)
        , block(block), mainwindow(mainwindow)
        , logger(log4cxx::Logger::getLogger("gui.BasicBlockWidget." + name.toStdString())) {
        next[0] = NULL; next[1] = NULL;
 
-       block->getManager()->registerRenameFunctionEvent([=](RenameFunctionEvent* event) {updateFunctionName(event);});
+       QObject::connect(block->getManager(), &InformationManager::renameFunctionEvent,
+                        [=](RenameFunctionEvent* event) {updateFunctionName(event);});
 
        _widget.reset(new CustomQGraphicsTextItem("", this));
        _widget->setPos(5, 20);
@@ -106,11 +105,27 @@ BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block,
                                 if (str.startsWith("function:")) {
                                         QString address = str.remove("function:");
                                         mainwindow->switchMainPlaneToAddress(address.toInt(NULL, 16));
+                                } else if (str.startsWith("block:")) {
+                                        QString address = str.remove("block:");
+
+                                        /* next[0] is always the jumptarget. On a
+                                         * conditional jump, next[1] also
+                                         * contains the following instruction
+                                         *
+                                         * TODO: Verify we're switching to the
+                                         *       right block -- the target
+                                         *       address matches the next blocks
+                                         *       start address
+                                         */
+                                        LOG4CXX_TRACE(logger, "Highlighting block at Address " << address.toStdString()
+                                                      << " BasicBlockWidget " << std::hex << next[0]);
+                                        ((CFGScene*)this->scene())->highlightBlock(next[0]);
                                 }
                         });
        instructions = block->getInstructions();
        populateWidget();
-       block->getManager()->registerChangeCommentEvent([=](ChangeCommentEvent* e) {changeCommentHandler(e);});
+       QObject::connect(block->getManager(), &InformationManager::changeCommentEvent,
+                        [=](ChangeCommentEvent* e) {changeCommentHandler(e);});
 }
 
 void BasicBlockWidget::updateFunctionName(RenameFunctionEvent *event) {
@@ -124,7 +139,15 @@ void BasicBlockWidget::updateFunctionName(RenameFunctionEvent *event) {
                        if (isLink)
                        {
                                if (search == format.anchorHref()) {
-                                       LOG4CXX_DEBUG(logger, i.fragment().text().toStdString() << " ---> " << format.anchorHref().toStdString());
+                                       LOG4CXX_DEBUG(logger, i.fragment().text().toStdString() << " ---> "
+                                                     << format.anchorHref().toStdString());
+
+                                       /* This should select the function name. It stars
+                                        * by selecting the whole link fragment from back
+                                        * to front and then moves one word to the back
+                                        * again deselecting whatever mnemonic is used for
+                                        * the call instruction.
+                                        */
                                        QTextCursor c(b);
                                        c.setPosition(i.fragment().position());
                                        c.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, i.fragment().length());
@@ -133,7 +156,7 @@ void BasicBlockWidget::updateFunctionName(RenameFunctionEvent *event) {
                                        c.insertText(event->new_name.c_str());
 
                                        QGraphicsTextItem* item = _widget.get();
-                                       ((CustomQGraphicsTextItem*)item)->adjustSize();
+                                       item->adjustSize();
                                }
                        }
                }
@@ -162,13 +185,14 @@ void BasicBlockWidget::changeCommentHandler(ChangeCommentEvent* event) {
                cursor.removeSelectedText();
                cursor.insertHtml(formatComments(&*inst_it));
                QGraphicsTextItem* item = _widget.get();
-               ((CustomQGraphicsTextItem*)item)->adjustSize();
+               item->adjustSize();
        }
 }
 
 void BasicBlockWidget::populateWidget() {
        int row;
        QTextTableFormat format;
+       QTextDocument* document = new QTextDocument();
        format.setBorderStyle(QTextFrameFormat::BorderStyle_None);
        format.setBorder(0);
 
@@ -178,7 +202,7 @@ void BasicBlockWidget::populateWidget() {
                        _table->appendRows(1);
                } else {
                        row = 0;
-                       _table = _widget->textCursor().insertTable(1, 3, format);
+                       _table = QTextCursor(document).insertTable(1, 3, format);
                }
                QString bytestring;
                for (uint8_t byte : inst.getBytes()) {
@@ -209,16 +233,16 @@ void BasicBlockWidget::populateWidget() {
                _table->cellAt(row, 2).firstCursorPosition().insertHtml(formatComments(&inst));
        }
        QGraphicsTextItem* item = _widget.get();
-       ((CustomQGraphicsTextItem*)item)->adjustSize();
+       item->setDocument(document);
+       item->adjustSize();
 }
 
 QString BasicBlockWidget::formatComments(Instruction* inst) {
-       QString comments;
+       QStringList comments;
        for (Comment* c: inst->comments()) {
-               comments += "<br />";
-               comments += QString(c->getText().c_str()).toHtmlEscaped();
+               comments << QString(c->getText().c_str()).toHtmlEscaped();
        }
-       return (comments == "" ? "" : ";; ") + comments.trimmed();
+       return (comments.empty() ? "" : ";; ") + comments.join("<br />").trimmed();
 }
 
 void BasicBlockWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem*,
@@ -227,7 +251,7 @@ void BasicBlockWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem*,
        height = 25 + _widget->boundingRect().height();
        if (width < 250) width = 250;
 
-       painter->fillRect(0, 0, width, height, QColor(0xcc, 0xcc, 0xff, 0xff));
+       painter->fillRect(0, 0, width, height, currentColor);
        painter->setPen(QColor(0x00, 0x00, 0xff, 0xff));
        painter->drawRect(0, 0, width, height);
        painter->drawText(5, 15, name);