Add doc repo as submodule
[frida/frida.git] / src / core / BasicBlock.cxx
1 #include "BasicBlock.hxx"
2 #include "qt.hxx"
3 #include "core/InformationManager.hxx"
4
5 #include <cassert>
6 #include <iostream>
7
8 void BasicBlock::serialize(QXmlStreamWriter& stream) {
9 stream.writeStartElement("block");
10 stream.writeAttribute("id", getName().c_str());
11 stream.writeTextElement("start", QString::number(getStartAddress(), 16));
12 stream.writeTextElement("end", QString::number(getEndAddress(), 16));
13 if (0 != getNextBlock(0))
14 stream.writeTextElement("next", QString::number(getNextBlock(0), 16));
15 if (0 != getNextBlock(1))
16 stream.writeTextElement("next", QString::number(getNextBlock(1), 16));
17 stream.writeEndElement(); // "block"
18 }
19
20 BasicBlock* BasicBlock::deserialize(QXmlStreamReader& stream, InformationManager* manager) {
21 Q_ASSERT(stream.name() == "block");
22
23 QString name = stream.attributes().value("id").toString();
24 uint64_t start_address(0), end_address(0), next_blocks[2] = {0, 0};
25 BasicBlock* block;
26
27
28 while (QXmlStreamReader::NoToken != stream.readNext()) {
29 while (QXmlStreamReader::Characters == stream.tokenType() &&
30 stream.isWhitespace())
31 stream.readNext();
32 if (QXmlStreamReader::EndElement == stream.tokenType())
33 break;
34
35 if(QXmlStreamReader::StartElement != stream.tokenType())
36 return NULL;
37
38 if (stream.name() == "start") {
39 stream.readNext();
40 if (QXmlStreamReader::Characters != stream.tokenType())
41 return NULL;
42
43 start_address = stream.text().toULongLong(NULL, 16);
44 stream.readNext();
45
46 if(QXmlStreamReader::EndElement != stream.tokenType())
47 return NULL;
48 }
49 if (stream.name() == "end") {
50 stream.readNext();
51 if (QXmlStreamReader::Characters != stream.tokenType())
52 return NULL;
53
54 end_address = stream.text().toULongLong(NULL, 16);
55 stream.readNext();
56
57 if(QXmlStreamReader::EndElement != stream.tokenType())
58 return NULL;
59 }
60 if (stream.name() == "next") {
61 stream.readNext();
62 if (QXmlStreamReader::Characters != stream.tokenType())
63 return NULL;
64
65 uint64_t newblock = stream.text().toULongLong(NULL, 16);
66 stream.readNext();
67
68 if (next_blocks[0] == 0) {
69 next_blocks[0] = newblock;
70 } else {
71 if (0 != next_blocks[1])
72 return NULL;
73 next_blocks[1] = newblock;
74 }
75
76 if(QXmlStreamReader::EndElement != stream.tokenType())
77 return NULL;
78 }
79 }
80
81 block = manager->newBasicBlock(start_address);
82 block->end_address = end_address;
83 block->next_blocks[0] = next_blocks[0];
84 block->next_blocks[1] = next_blocks[1];
85
86 assert(stream.name() == "block");
87 assert(block->getName() == name.toStdString());
88
89 manager->finishBasicBlock(block);
90 return block;
91 }
92
93 std::vector<Instruction> BasicBlock::getInstructions() const {
94 return manager->getDisassembler()->getInstructions(this);
95 }