X-Git-Url: https://git.siccegge.de//index.cgi?p=frida%2Ffrida.git;a=blobdiff_plain;f=src%2Fgui%2Fwidgets%2FBasicBlockWidget.cxx;h=eee78c4ea55d06b47e672afeb10367967b3e8a30;hp=6d615b41eed305861c6e4e20033ff564cf8f837f;hb=9ec8606194f7996edf21615ac34007e1391eb80f;hpb=dfee3a7d828b09c19ab3c03db17be627b952dcd7 diff --git a/src/gui/widgets/BasicBlockWidget.cxx b/src/gui/widgets/BasicBlockWidget.cxx index 6d615b4..eee78c4 100644 --- a/src/gui/widgets/BasicBlockWidget.cxx +++ b/src/gui/widgets/BasicBlockWidget.cxx @@ -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 += "
"; - comments += QString(c->getText().c_str()).toHtmlEscaped(); + comments << QString(c->getText().c_str()).toHtmlEscaped(); } - return (comments == "" ? "" : ";; ") + comments.trimmed(); + return (comments.empty() ? "" : ";; ") + comments.join("
").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);