set(fridatest_SOURCES
src/test.cxx
src/core/tests/BasicBlockTest.cxx
+ src/core/tests/FunctionTest.cxx
${frida_SOURCES}
)
#include "Function.hxx"
+#include "BasicBlock.hxx"
#include "core/events/RenameFunctionEvent.hxx"
#include "InformationManager.hxx"
#include "gui/qt.hxx"
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;
+}
}
void serialize(QXmlStreamWriter& stream);
+ static Function* deserialize(QXmlStreamReader& stream, InformationManager* manager);
+
private:
Function(uint64_t start_address, InformationManager* manager);
--- /dev/null
+#include <gtest/gtest.h>
+
+#include "gui/qt.hxx"
+#include "core/InformationManager.hxx"
+#include "core/BasicBlock.hxx"
+#include "core/Function.hxx"
+
+TEST(FunctionTest, deserializeValidInstance) {
+ QFile file("testdata/core/Function/valid.xml");
+ InformationManager manager;
+ file.open(QFile::ReadOnly | QFile::Text);
+ QXmlStreamReader reader(&file);
+
+ reader.readNextStartElement();
+ Function* fun = Function::deserialize(reader, &manager);
+
+ ASSERT_NE((void*)NULL, (void*)fun);
+ EXPECT_STREQ("main", fun->getName().c_str());
+ EXPECT_EQ(0x403e10, fun->getStartAddress());
+
+ EXPECT_STREQ("BLOCK_403e10_403e48", fun->blocks().find(0x403e10)->second->getName().c_str());
+ EXPECT_STREQ("BLOCK_403e48_403e50", fun->blocks().find(0x403e48)->second->getName().c_str());
+ EXPECT_STREQ("BLOCK_403e50_403e66", fun->blocks().find(0x403e50)->second->getName().c_str());
+ EXPECT_STREQ("BLOCK_403e66_403e75", fun->blocks().find(0x403e66)->second->getName().c_str());
+}
+
--- /dev/null
+<function name="main" entry="403e10">
+ <block id="BLOCK_403e10_403e48">
+ <start>403e10</start>
+ <end>403e48</end>
+ <next>403e66</next>
+ <next>403e48</next>
+ </block>
+ <block id="BLOCK_403e48_403e50">
+ <start>403e48</start>
+ <end>403e50</end>
+ <next>403e50</next>
+ </block>
+ <block id="BLOCK_403e50_403e66">
+ <start>403e50</start>
+ <end>403e66</end>
+ <next>403e50</next>
+ <next>403e66</next>
+ </block>
+ <block id="BLOCK_403e66_403e75">
+ <start>403e66</start>
+ <end>403e75</end>
+ </block>
+</function>