X-Git-Url: https://git.siccegge.de//index.cgi?p=frida%2Ffrida.git;a=blobdiff_plain;f=src%2Fgui%2Fwidgets%2FFunctionWidget.cxx;h=20d586df6eff9aff69d1921fcd4334c8af937520;hp=e4c1c0b5c2a2bbbd5f3a7da113f0af92c57955c1;hb=ae7b9847b80153121fbc1f87e4fdc1dd0e94f4cc;hpb=adb0e762792c23674633b8513f4106b82aa38d15 diff --git a/src/gui/widgets/FunctionWidget.cxx b/src/gui/widgets/FunctionWidget.cxx index e4c1c0b..20d586d 100644 --- a/src/gui/widgets/FunctionWidget.cxx +++ b/src/gui/widgets/FunctionWidget.cxx @@ -1 +1,116 @@ #include "FunctionWidget.hxx" + +#include "core/Function.hxx" +#include "core/BasicBlock.hxx" +#include "core/InformationManager.hxx" + +#include "gui/widgets/CFGScene.hxx" +#include "gui/Mainwindow.hxx" + +namespace { + BasicBlockWidget * + local__add_basic_block(BasicBlock * block, + Mainwindow * mainwindow, InformationManager * manager, + std::map& known_blocks, + CFGScene * scene, uint64_t starty, uint64_t startx); +} + +FunctionWidget::FunctionWidget(Function* function, Mainwindow* mainwindow) + : function(function) + , mainwindow(mainwindow) + , logger(log4cxx::Logger::getLogger("Mainwindow")) { + + // CFG + CFGScene * scene = new CFGScene; + InformationManager* manager = function->getManager(); + + BasicBlock * block = manager->getBasicBlock(function->getStartAddress()); + LOG4CXX_DEBUG(logger, "Building widget for functionction " << function->getName()); + for (auto i : function->blocks()) { + LOG4CXX_DEBUG(logger, "Functionction contains Block " << i.second->getName()); + } + + uint64_t start_address(std::numeric_limits::max()); + for (auto b : function->blocks()) { + if (b.first < start_address) + start_address = b.first; + } + + std::map _blocks; + local__add_basic_block(block, mainwindow, + manager, _blocks, scene, start_address, 100); + + QGraphicsView * view = new QGraphicsView(scene); + addTab(view, "CFG"); + + // Listing + QTableWidget * t = new QTableWidget(); + t->setColumnCount(3); + t->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + + addTab(t, "Listing"); +} + + + + +namespace { + BasicBlockWidget * + local__add_basic_block(BasicBlock * block, + Mainwindow * mainwindow, InformationManager * manager, + std::map& known_blocks, + CFGScene * scene, uint64_t starty, uint64_t startx) { + + decltype(known_blocks.begin()) old; + if ((old = known_blocks.find(block->getStartAddress())) != known_blocks.end()) + return old->second; + + std::stringstream s; + s << "BLOCK_" << std::hex << block->getStartAddress() + << "_" << block->getEndAddress(); + BasicBlockWidget * widget = new BasicBlockWidget(s.str().c_str(), + block, mainwindow); + + known_blocks.insert(std::make_pair(block->getStartAddress(), widget)); + + scene->addItem(widget); + widget->setFlag(QGraphicsItem::ItemIsMovable, true); + widget->moveBy(100*startx, block->getStartAddress() - starty); + + manager->getDisassembler() + ->printEachInstruction(block->getStartAddress(), + block->getEndAddress(), + [&](uint8_t* bytes, + size_t byte_count, + const std::string& line, + const std::string& ref) { + widget->addItem(bytes, byte_count, + line.c_str() + 1, // remove \t + ref.c_str()); + }); + + BasicBlockWidget *tmp, *nextl(NULL), *nextr(NULL); + BasicBlock * tmpblock; + if (block->getNextBlock(0) != 0) { + int xshift = 0; + if (block->getNextBlock(1) != 0) + xshift = 1; + tmpblock = manager->getBasicBlock(block->getNextBlock(0)); + tmp = local__add_basic_block(tmpblock, mainwindow, manager, + known_blocks, + scene, starty, startx+xshift); + nextl = tmp; + tmp->addPrevious(widget); + } + if (block->getNextBlock(1) != 0) { + tmpblock = manager->getBasicBlock(block->getNextBlock(1)); + tmp = local__add_basic_block(tmpblock, mainwindow, manager, + known_blocks, + scene, starty, startx-1); + nextr = tmp; + tmp->addPrevious(widget); + } + widget->addNext(nextl, nextr); + return widget; + } +}