]> git.siccegge.de Git - frida/frida.git/blob - src/gui/widgets/FunctionWidget.cxx
ba96e5d4af18fe3732de18e9c9e9ef6a0f9e8b3c
[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 , logger(log4cxx::Logger::getLogger("gui.Mainwindow")) {
22
23 // CFG
24 CFGScene * scene = new CFGScene;
25 InformationManager* manager = function->getManager();
26
27 BasicBlock * block = manager->getBasicBlock(function->getStartAddress());
28 LOG4CXX_DEBUG(logger, "Building widget for functionction " << function->getName());
29 for (auto i : function->blocks()) {
30 LOG4CXX_DEBUG(logger, "Functionction contains Block " << i.second->getName());
31 }
32
33 uint64_t start_address(std::numeric_limits<uint64_t>::max());
34 for (auto b : function->blocks()) {
35 if (b.first < start_address)
36 start_address = b.first;
37 }
38
39 std::map<uint64_t, BasicBlockWidget*> _blocks;
40 local__add_basic_block(block, mainwindow,
41 manager, _blocks, scene, start_address, 100);
42
43 QGraphicsView * view = new QGraphicsView(scene);
44 addTab(view, "CFG");
45
46 // Listing
47 QTableWidget * t = new QTableWidget();
48 t->setColumnCount(3);
49 t->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
50
51 addTab(t, "Listing");
52 }
53
54
55
56
57 namespace {
58 BasicBlockWidget *
59 local__add_basic_block(BasicBlock * block,
60 Mainwindow * mainwindow, InformationManager * manager,
61 std::map<uint64_t, BasicBlockWidget*>& known_blocks,
62 CFGScene * scene, uint64_t starty, uint64_t startx) {
63
64 decltype(known_blocks.begin()) old;
65 if ((old = known_blocks.find(block->getStartAddress())) != known_blocks.end())
66 return old->second;
67
68 std::stringstream s;
69 s << "BLOCK_" << std::hex << block->getStartAddress()
70 << "_" << block->getEndAddress();
71 BasicBlockWidget * widget = new BasicBlockWidget(s.str().c_str(),
72 block, mainwindow);
73
74 known_blocks.insert(std::make_pair(block->getStartAddress(), widget));
75
76 scene->addItem(widget);
77 widget->setFlag(QGraphicsItem::ItemIsMovable, true);
78 widget->moveBy(100*startx, block->getStartAddress() - starty);
79
80 manager->getDisassembler()
81 ->printEachInstruction(block->getStartAddress(),
82 block->getEndAddress(),
83 [&](uint8_t* bytes,
84 size_t byte_count,
85 const std::string& line,
86 const std::string& ref) {
87 widget->addItem(bytes, byte_count,
88 line.c_str() + 1, // remove \t
89 ref.c_str());
90 });
91
92 BasicBlockWidget *tmp, *nextl(NULL), *nextr(NULL);
93 BasicBlock * tmpblock;
94 if (block->getNextBlock(0) != 0) {
95 int xshift = 0;
96 if (block->getNextBlock(1) != 0)
97 xshift = 1;
98 tmpblock = manager->getBasicBlock(block->getNextBlock(0));
99 tmp = local__add_basic_block(tmpblock, mainwindow, manager,
100 known_blocks,
101 scene, starty, startx+xshift);
102 nextl = tmp;
103 tmp->addPrevious(widget);
104 }
105 if (block->getNextBlock(1) != 0) {
106 tmpblock = manager->getBasicBlock(block->getNextBlock(1));
107 tmp = local__add_basic_block(tmpblock, mainwindow, manager,
108 known_blocks,
109 scene, starty, startx-1);
110 nextr = tmp;
111 tmp->addPrevious(widget);
112 }
113 widget->addNext(nextl, nextr);
114 return widget;
115 }
116 }