From 9f53c415cf1554e2d9cc040d3d646ec22fe281f6 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Tue, 3 Mar 2015 18:30:25 +0100 Subject: [PATCH] Add support for deserializing functions Includes a first testcase --- CMakeLists.txt | 1 + src/core/Function.cxx | 28 ++++++++++++++++++++++++++++ src/core/Function.hxx | 2 ++ src/core/tests/FunctionTest.cxx | 26 ++++++++++++++++++++++++++ testdata/core/Function/valid.xml | 23 +++++++++++++++++++++++ 5 files changed, 80 insertions(+) create mode 100644 src/core/tests/FunctionTest.cxx create mode 100644 testdata/core/Function/valid.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index 7657461..5d16516 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,7 @@ TARGET_LINK_LIBRARIES(frida ${QT_LIBRARIES} ${LLVM_LDFLAGS} -lLLVM-3.5 ${LLVM_SY set(fridatest_SOURCES src/test.cxx src/core/tests/BasicBlockTest.cxx + src/core/tests/FunctionTest.cxx ${frida_SOURCES} ) diff --git a/src/core/Function.cxx b/src/core/Function.cxx index 1df4d1d..781940c 100644 --- a/src/core/Function.cxx +++ b/src/core/Function.cxx @@ -1,4 +1,5 @@ #include "Function.hxx" +#include "BasicBlock.hxx" #include "core/events/RenameFunctionEvent.hxx" #include "InformationManager.hxx" #include "gui/qt.hxx" @@ -25,3 +26,30 @@ void Function::serialize(QXmlStreamWriter& 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; +} diff --git a/src/core/Function.hxx b/src/core/Function.hxx index d567c28..75b38c2 100644 --- a/src/core/Function.hxx +++ b/src/core/Function.hxx @@ -30,6 +30,8 @@ public: } void serialize(QXmlStreamWriter& stream); + static Function* deserialize(QXmlStreamReader& stream, InformationManager* manager); + private: Function(uint64_t start_address, InformationManager* manager); diff --git a/src/core/tests/FunctionTest.cxx b/src/core/tests/FunctionTest.cxx new file mode 100644 index 0000000..5357bb9 --- /dev/null +++ b/src/core/tests/FunctionTest.cxx @@ -0,0 +1,26 @@ +#include + +#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()); +} + diff --git a/testdata/core/Function/valid.xml b/testdata/core/Function/valid.xml new file mode 100644 index 0000000..a0f2bc0 --- /dev/null +++ b/testdata/core/Function/valid.xml @@ -0,0 +1,23 @@ + + + 403e10 + 403e48 + 403e66 + 403e48 + + + 403e48 + 403e50 + 403e50 + + + 403e50 + 403e66 + 403e50 + 403e66 + + + 403e66 + 403e75 + + -- 2.39.5