]> git.siccegge.de Git - frida/frida.git/blob - src/gui/widgets/FunctionWidget.cxx
Add doc repo as submodule
[frida/frida.git] / src / gui / widgets / FunctionWidget.cxx
1 #include "FunctionWidget.hxx"
2
3 #include "core/Function.hxx"
4 #include "core/BasicBlock.hxx"
5 #include "core/InformationManager.hxx"
6
7 #include "gui/widgets/CFGScene.hxx"
8 #include "gui/Mainwindow.hxx"
9
10 namespace {
11 BasicBlockWidget *
12 local__add_basic_block(BasicBlock * block,
13 Mainwindow * mainwindow, InformationManager * manager,
14 std::map<uint64_t, BasicBlockWidget*>& known_blocks,
15 CFGScene * scene, uint64_t starty, uint64_t startx);
16 }
17
18 FunctionWidget::FunctionWidget(Function* function, Mainwindow* mainwindow)
19 : function(function)
20 , mainwindow(mainwindow)
21 , layouted(false)
22 , logger(log4cxx::Logger::getLogger("gui.Mainwindow")) {
23
24 }
25
26 void FunctionWidget::showEvent(QShowEvent* event) {
27 if (!layouted) {
28 CFGScene * scene = new CFGScene;
29 InformationManager* manager = function->getManager();
30
31 BasicBlock * block = manager->getBasicBlock(function->getStartAddress());
32 LOG4CXX_DEBUG(logger, "Building widget for functionction " << function->getName());
33 for (auto i : function->blocks()) {
34 LOG4CXX_DEBUG(logger, "Functionction contains Block " << i.second->getName());
35 }
36
37 uint64_t start_address(std::numeric_limits<uint64_t>::max());
38 for (auto b : function->blocks()) {
39 if (b.first < start_address)
40 start_address = b.first;
41 }
42
43 std::map<uint64_t, BasicBlockWidget*> _blocks;
44 BasicBlockWidget* firstblock = local__add_basic_block(block, mainwindow,
45 manager, _blocks, scene, 3*start_address, 100);
46
47 QGraphicsView * view = new QGraphicsView(scene);
48 view->setDragMode(QGraphicsView::ScrollHandDrag);
49 addTab(view, "CFG");
50
51 // Listing
52 QTableWidget * t = new QTableWidget();
53 t->setColumnCount(3);
54 t->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
55
56 addTab(t, "Listing");
57 view->ensureVisible(firstblock);
58 layouted = true;
59 }
60 }
61
62 namespace {
63 BasicBlockWidget *
64 local__add_basic_block(BasicBlock * block,
65 Mainwindow * mainwindow, InformationManager * manager,
66 std::map<uint64_t, BasicBlockWidget*>& known_blocks,
67 CFGScene * scene, uint64_t starty, uint64_t startx) {
68
69 decltype(known_blocks.begin()) old;
70 if (!block) return NULL;
71 if ((old = known_blocks.find(block->getStartAddress())) != known_blocks.end())
72 return old->second;
73
74 std::stringstream s;
75 s << "BLOCK_" << std::hex << block->getStartAddress()
76 << "_" << block->getEndAddress();
77 BasicBlockWidget * widget = new BasicBlockWidget(s.str().c_str(),
78 block, mainwindow);
79
80 known_blocks.insert(std::make_pair(block->getStartAddress(), widget));
81
82 scene->addItem(widget);
83 widget->setFlag(QGraphicsItem::ItemIsMovable, true);
84 widget->moveBy(100*startx, 3*block->getStartAddress() - starty);
85
86 BasicBlockWidget *tmp, *nextl(NULL), *nextr(NULL);
87 BasicBlock * tmpblock;
88 if (block->getNextBlock(0) != 0) {
89 int xshift = 0;
90 if (block->getNextBlock(1) != 0)
91 xshift = 1;
92 tmpblock = manager->getBasicBlock(block->getNextBlock(0));
93 tmp = local__add_basic_block(tmpblock, mainwindow, manager,
94 known_blocks,
95 scene, starty, startx+xshift);
96 nextl = tmp;
97 tmp->addPrevious(widget);
98 }
99 if (block->getNextBlock(1) != 0) {
100 tmpblock = manager->getBasicBlock(block->getNextBlock(1));
101 tmp = local__add_basic_block(tmpblock, mainwindow, manager,
102 known_blocks,
103 scene, starty, startx-1);
104 nextr = tmp;
105 tmp->addPrevious(widget);
106 }
107 widget->addNext(nextl, nextr);
108 return widget;
109 }
110 }