Add basic save support (Infrastructure)
authorChristoph Egger <Christoph.Egger@fau.de>
Thu, 19 Feb 2015 15:51:41 +0000 (16:51 +0100)
committerChristoph Egger <Christoph.Egger@fau.de>
Thu, 19 Feb 2015 16:02:08 +0000 (17:02 +0100)
This is some start on save infrastructure. To complete save/load we now
need to add all relevant information to the save() function and the
implement load(). Also fileformat is not really setteled by now.

src/core/InformationManager.cxx
src/core/InformationManager.hxx
src/disassembler/BasicBlock.hxx
src/gui/Mainwindow.cxx
src/gui/Mainwindow.hxx
src/gui/qt.hxx

index f0b6e1e444c78491a0c33018fabb6c5a54c47b5b..0907cf9d2d7f7eeb5a191781c4345e1fc3e5a72c 100644 (file)
@@ -1,8 +1,49 @@
 #include "InformationManager.hxx"
 #include "disassembler/llvm/LLVMDisassembler.hxx"
+#include "gui/qt.hxx"
+#include "quazip/quazip.h"
+#include "quazip/quazipfile.h"
 
 void InformationManager::reset(const std::string& filename) {
        disassembler.reset(createLLVMDisassembler(filename, this));
        if (disassembler.get() != NULL)
                disassembler.get()->start();
 }
+
+void InformationManager::save(const QString& filename) {
+       QuaZip zip(filename);
+       zip.open(QuaZip::mdCreate);
+       zip.setComment("FRIDA 0.0");
+       QuaZipFile outZipFile(&zip);
+
+       for (Function* fun : functions) {
+               QuaZipNewInfo zipinfo(fun->getName().c_str());
+               zipinfo.setPermissions(static_cast<QFile::Permissions>(0x6444));
+               outZipFile.open(QIODevice::WriteOnly, zipinfo);
+               QXmlStreamWriter stream(&outZipFile);
+               stream.setAutoFormatting(true);
+               stream.setAutoFormattingIndent(-1);
+               stream.writeStartDocument();
+               stream.writeStartElement("function");
+               stream.writeAttribute("name", fun->getName().c_str());
+               stream.writeAttribute("entry", QString::number(fun->getStartAddress(), 16));
+
+               for (auto& blockentry : fun->blocks()) {
+                       stream.writeStartElement("block");
+                       stream.writeAttribute("id", blockentry.second->getName().c_str());
+                       stream.writeTextElement("start", QString::number(blockentry.second->getStartAddress(), 16));
+                       stream.writeTextElement("end", QString::number(blockentry.second->getEndAddress(), 16));
+                       if (0 != blockentry.second->getNextBlock(0))
+                               stream.writeTextElement("next", QString::number(blockentry.second->getNextBlock(0), 16));
+                       if (0 != blockentry.second->getNextBlock(1))
+                               stream.writeTextElement("next", QString::number(blockentry.second->getNextBlock(1), 16));
+                       stream.writeEndElement(); // "block"
+               }
+
+               stream.writeEndElement(); // "function"
+               stream.writeEndDocument();
+               outZipFile.close();
+       }
+
+       zip.close();
+}
index 9285d5fdd92658e3196ec7b340110b40d7bf4e5b..4e1b3187a52a081e5453aa9beb661af872170d55 100644 (file)
@@ -4,51 +4,44 @@
 #include <boost/signals2.hpp>
 #include <functional>
 #include <string>
+#include <set>
 
 class Disassembler;
 class Function;
 
+class QString;
+
 class InformationManager {
 public:
-       boost::signals2::connection
-       connect_new_function_signal(std::function<void(Function*)> f) {
-               return new_function_signal.connect(f);
-       }
-
-       void signal_new_function(Function* f) {
-               new_function_signal(f);
-       }
+       void reset(const std::string& filename);
+       void save(const QString& filename);
 
        boost::signals2::connection
-       connect_new_dyn_symbol_signal(std::function<void(const std::string& name)> f) {
-               return new_dyn_symbol_signal.connect(f);
-       }
+       connect_new_function_signal(std::function<void(Function*)> f)
+               { return new_function_signal.connect(f); }
 
-       void signal_new_dyn_symbol(const std::string& f) {
-               new_dyn_symbol_signal(f);
-       }
+       void signal_new_function(Function* f)
+               { functions.insert(f); new_function_signal(f); }
 
        boost::signals2::connection
-       connect_reset_signal(std::function<void ()> f) {
-               return reset_signal.connect(f);
-       }
+       connect_new_dyn_symbol_signal(std::function<void(const std::string& name)> f)
+               { return new_dyn_symbol_signal.connect(f); }
 
-       // boost::signals2::connection
-       // connect_information_added_signal(uint64_t begin, uint64_t end,
-       //                                  std::function<void (uint64_t)>) {
+       void signal_new_dyn_symbol(const std::string& f)
+               { new_dyn_symbol_signal(f);     }
 
-       // }
-
-       Disassembler* getDisassembler() {
-               return disassembler.get();
-       }
+       boost::signals2::connection
+       connect_reset_signal(std::function<void ()> f)
+               { return reset_signal.connect(f); }
 
-       void reset(const std::string& filename);
+       Disassembler* getDisassembler()
+               { return disassembler.get(); }
 private:
        boost::signals2::signal<void ()> reset_signal;
        boost::signals2::signal<void (Function*)> new_function_signal;
        boost::signals2::signal<void (const std::string& name)> new_dyn_symbol_signal;
        std::unique_ptr<Disassembler> disassembler;
+       std::set<Function*> functions;
 };
 
 #endif /* INCLUDE__InformationManager_hxx */
index 6d623d0f84116535962de5cd30c5ff14299fb55b..b3e5a89d819cfbd74c5b375919eba6dcccd7e09a 100644 (file)
@@ -2,6 +2,8 @@
 #define INCLUDE__BasicBlock_hxx
 
 #include <cassert>
+#include <string>
+#include <sstream>
 
 class BasicBlock {
 public:
@@ -36,6 +38,12 @@ public:
                end_address = address;
        }
 
+       std::string getName() {
+               std::stringstream s;
+               s << "BLOCK_" << std::hex << start_address << '_' << end_address;
+               return s.str();
+       }
+
 private:
        uint64_t start_address;
        uint64_t end_address;
index 18dcc8bef99f180c7a193962a2ac674709b9de75..03910a1be4801334ade968cbb237f6cd8cfe4d46 100644 (file)
@@ -20,18 +20,19 @@ Mainwindow::Mainwindow(InformationManager* mgr)
        : manager(mgr)
        , logger(log4cxx::Logger::getLogger("Mainwindow")) {
        openAction = new QAction(tr("&Open"), this);
-       // saveAction = new QAction(tr("&Save"), this);
+       saveAction = new QAction(tr("&Save"), this);
        exitAction = new QAction(tr("E&xit"), this);
 
        connect(openAction, SIGNAL(triggered()),
                this, SLOT(open()));
-       // connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
+       connect(saveAction, SIGNAL(triggered()),
+               this, SLOT(save()));
        connect(exitAction, SIGNAL(triggered()),
                qApp, SLOT(quit()));
 
        fileMenu = menuBar()->addMenu(tr("&File"));
        fileMenu->addAction(openAction);
-       // fileMenu->addAction(saveAction);
+       fileMenu->addAction(saveAction);
        fileMenu->addSeparator();
        fileMenu->addAction(exitAction);
 
@@ -94,6 +95,11 @@ void Mainwindow::open() {
        manager->reset(fileName.toStdString());
 }
 
+void Mainwindow::save() {
+       QString filename = QFileDialog::getSaveFileName(this, tr("Save File"), "", tr("Frida Archives (*.frida)"));
+       manager->save(filename);
+}
+
 void Mainwindow::switchMainPlaneToAddress(uint64_t address) {
        if (objects_list_by_address.find(address) != objects_list_by_address.end()) {
                LOG4CXX_DEBUG(logger, "Switching to function " << std::hex << address);
index 7084e2fec3c6995adb2256d7d208b4db4b6c08f2..0962efd7e1a554798efa6d2e30346a527113d50e 100644 (file)
@@ -39,6 +39,7 @@ private:
 
        QAction *exitAction;
        QAction *openAction;
+       QAction *saveAction;
 
        std::map<uint64_t, BasicBlockWidget*> blocks;
        std::map<QListWidgetItem*, QWidget*> objects_list;
@@ -53,6 +54,7 @@ public Q_SLOTS:
 private Q_SLOTS:
        void quit();
        void open();
+       void save();
        void switchMainPlane(int);
        void showListContextMenu(const QPoint&);
        void requestNewFunction();
index 97a1d280071d72ba55ba4c72d2511bf848829b43..ae4ef2c51fd46876c95533160c9e65e97b87e215 100644 (file)
@@ -25,5 +25,7 @@
 #include <QtGui>
 #include <QMenu>
 #include <QShortcut>
+#include <QXmlStreamWriter>
+#include <QXmlStreamReader>
 
 #endif /* INCLUDE__qt_hxx_ */