]> git.siccegge.de Git - frida/frida.git/blobdiff - src/core/Function.cxx
Add support for deserializing functions
[frida/frida.git] / src / core / Function.cxx
index e9bb173374301703bf0ef3e0c4a928dee0ad79ea..781940ce71ddef42c7243ed63096f5d3155da590 100644 (file)
@@ -1,15 +1,12 @@
 #include "Function.hxx"
+#include "BasicBlock.hxx"
 #include "core/events/RenameFunctionEvent.hxx"
 #include "InformationManager.hxx"
+#include "gui/qt.hxx"
 
-#include <iostream>
-
-Function::Function(const std::string& name, uint64_t start_address,
-                   InformationManager* manager)
+Function::Function(uint64_t start_address, InformationManager* manager)
        : start_address(start_address)
-       , manager(manager) {
-       setName(name);
-}
+       , manager(manager) {}
 
 
 void Function::setName(const std::string& new_name) {
@@ -18,3 +15,41 @@ void Function::setName(const std::string& new_name) {
        manager->dispatch(&event);
 }
 
+void Function::serialize(QXmlStreamWriter& stream) {
+       stream.writeStartElement("function");
+       stream.writeAttribute("name", getName().c_str());
+       stream.writeAttribute("entry", QString::number(getStartAddress(), 16));
+
+       for (auto& blockentry : blocks()) {
+               blockentry.second->serialize(stream);
+       }
+
+       stream.writeEndElement(); // "function"
+}
+
+Function* Function::deserialize(QXmlStreamReader& stream, InformationManager* manager) {
+       Q_ASSERT(stream.name() == "function");
+
+       QString name = stream.attributes().value("name").toString();
+       uint64_t entry = stream.attributes().value("entry").toULongLong(NULL, 16);
+       Function* fun = manager->newFunction(entry);
+
+       while (QXmlStreamReader::NoToken != stream.readNext()) {
+               while (QXmlStreamReader::Characters == stream.tokenType() &&
+                      stream.isWhitespace())
+                       stream.readNext();
+               if (QXmlStreamReader::EndElement == stream.tokenType())
+                       break;
+
+               if (stream.name() == "block") {
+                       BasicBlock* block = BasicBlock::deserialize(stream, manager);
+                       fun->addBasicBlock(block);
+               } else {
+                       return NULL;
+               }
+       }
+
+       manager->finishFunction(fun);
+       fun->setName(name.toStdString());
+       return fun;
+}