Add doc repo as submodule
[frida/frida.git] / src / core / Function.cxx
1 #include "Function.hxx"
2 #include "BasicBlock.hxx"
3 #include "core/events/RenameFunctionEvent.hxx"
4 #include "InformationManager.hxx"
5 #include "qt.hxx"
6
7 Function::Function(uint64_t start_address, bool dynamic, InformationManager* manager)
8 : start_address(start_address)
9 , dynamic(dynamic)
10 , manager(manager) {}
11
12
13 void Function::setName(const std::string& new_name) {
14 name = new_name;
15 RenameFunctionEvent event(new_name, this, start_address);
16 emit manager->renameFunctionEvent(&event);
17 }
18
19 void Function::serialize(QXmlStreamWriter& stream) {
20 stream.writeStartElement("function");
21 stream.writeAttribute("name", getName().c_str());
22 stream.writeAttribute("entry", QString::number(getStartAddress(), 16));
23 stream.writeAttribute("dynamic", dynamic? "yes" : "no");
24
25 for (auto& blockentry : blocks()) {
26 blockentry.second->serialize(stream);
27 }
28
29 stream.writeEndElement(); // "function"
30 }
31
32 Function* Function::deserialize(QXmlStreamReader& stream, InformationManager* manager) {
33 Q_ASSERT(stream.name() == "function");
34
35 QString name = stream.attributes().value("name").toString();
36 bool dynamic = stream.attributes().value("dynamic").toString() == "yes";
37 uint64_t entry = stream.attributes().value("entry").toULongLong(NULL, 16);
38 Function* fun = manager->newFunction(entry);
39
40 while (QXmlStreamReader::NoToken != stream.readNext()) {
41 while (QXmlStreamReader::Characters == stream.tokenType() &&
42 stream.isWhitespace())
43 stream.readNext();
44 if (QXmlStreamReader::EndElement == stream.tokenType())
45 break;
46
47 if (stream.name() == "block") {
48 BasicBlock* block = BasicBlock::deserialize(stream, manager);
49 fun->addBasicBlock(block);
50 } else {
51 return NULL;
52 }
53 }
54
55 fun->name = name.toStdString();
56 fun->dynamic = dynamic;
57 manager->finishFunction(fun);
58
59 return fun;
60 }