]> git.siccegge.de Git - frida/frida.git/commitdiff
Restructure InformationManager
authorChristoph Egger <Christoph.Egger@fau.de>
Mon, 16 Mar 2015 15:40:18 +0000 (16:40 +0100)
committerChristoph Egger <Christoph.Egger@fau.de>
Mon, 16 Mar 2015 15:50:54 +0000 (16:50 +0100)
  - Signals now all use Event objects to communicate information and all
    share a common sane interface
  - Organize signals consistently and grup by signal name
  - Dynamic and local functions are now handled almost the same
  - Changes all over the place to fix users for these changes
  - proper iterator access for the maps so one can actually iterate over
    all functions (for example a script)
  - ignore these iterators where they would be most usefuill (scripting)
    untill I figure out how to make SWIG compile them properly

CMakeLists.txt
src/bindings/guile/frida.i
src/core/Comment.hxx
src/core/Function.cxx
src/core/Function.hxx
src/core/InformationManager.cxx
src/core/InformationManager.hxx
src/disassembler/llvm/LLVMDisassembler.cxx
src/gui/Mainwindow.cxx
src/gui/widgets/BasicBlockWidget.cxx

index 2c178ba0333846bf9a146bf73e54437a5033a6e7..51f9689ee3f673fb785d80b8410e126aa690508b 100644 (file)
@@ -48,6 +48,7 @@ SWIG_LINK_LIBRARIES(frida-guile ${GUILE_LDFLAGS})
 SET(frida_SOURCES
   src/core/InformationManager.cxx
   src/core/BasicBlock.cxx
+  src/core/Comment.cxx
   src/core/Function.cxx
   src/gui/Mainwindow.cxx
   src/gui/widgets/BasicBlockWidget.cxx
index 03069b9d8cf404ab17192077e7e61e5d72deab60..c8b80b6cbc8b4a7ee618a82a069365aecc3c0666 100644 (file)
@@ -6,6 +6,13 @@
 %include <stdint.i>
 %include <std_string.i>
 %include <std_map.i>
+%include <stl.i>
+
+ // noone knows how to get these working
+%ignore beginFunctions();
+%ignore endFunctions();
+%ignore beginBasicBlocks();
+%ignore endBasicBlocks();
 
 %{
 #include "core/Function.hxx"
@@ -17,7 +24,9 @@
 %}
 
 namespace std {
-       %template(map_uint64t_BasicBlock) map<unsigned long long, BasicBlock*>;
+       %template(BasicBlockMap) map<unsigned long, BasicBlock*>;
+       %template(FunctionMap) map<unsigned long, Function*>;
+       %template(InterpreterMap) map<std::string, Interpreter*>;
 }
 
 %inline %{
index e151f5a09b0f796de028883d6b3231610bfafbdb..b07f13ae1a81c8310ae3ab93104ff933529d9f0c 100644 (file)
@@ -4,18 +4,24 @@
 #include <string>
 
 class Function;
+class InformationManager;
 
 class Comment {
 public:
        bool isLocal() const {return location == NULL;}
 
+       void setText(const std::string& text);
+       uint64_t getAddress();
 private:
-       Comment(uint64_t address);
-       Comment(uint64_t address, Function* location);
+       Comment(uint64_t address, InformationManager* manager);
+       Comment(uint64_t address, Function* location, InformationManager* manager);
 
        uint64_t address;
        Function* location;
+       InformationManager* manager;
        std::string text;
+
+       friend class InformationManager;
 };
 
 #endif /* INCLUDE__Comment_hxx */
index c4dc9854d9853a48816a0c4cb20bb284afb6eca5..e31bce4a88481ea8952eb16dd384bf637cabfa92 100644 (file)
@@ -4,8 +4,9 @@
 #include "InformationManager.hxx"
 #include "gui/qt.hxx"
 
-Function::Function(uint64_t start_address, InformationManager* manager)
+Function::Function(uint64_t start_address, bool dynamic, InformationManager* manager)
        : start_address(start_address)
+       , dynamic(dynamic)
        , manager(manager) {}
 
 
index 75b38c2cd34877fe0349b80eae21b5dc57976fbb..ab8c0c9193c937c2e3d83501d5daa38555b97d06 100644 (file)
@@ -9,17 +9,14 @@ class QXmlStreamWriter;
 
 class Function {
 public:
-       uint64_t getStartAddress() const {
-               return start_address;
-       }
+       uint64_t getStartAddress() const { return start_address; }
 
-       std::string getName() const
-               { return name; }
+       std::string getName() const { return name; }
        void setName(const std::string& new_name);
 
-       InformationManager* getManager() const {
-               return manager;
-       }
+       InformationManager* getManager() const { return manager; }
+
+       bool isDynamic() const { return dynamic; }
 
        void addBasicBlock(BasicBlock* block) {
                _blocks.insert(std::make_pair(block->getStartAddress(), block));
@@ -33,10 +30,11 @@ public:
        static Function* deserialize(QXmlStreamReader& stream, InformationManager* manager);
 
 private:
-       Function(uint64_t start_address, InformationManager* manager);
+       Function(uint64_t start_address, bool dynamic, InformationManager* manager);
 
        std::string name;
        uint64_t start_address;
+       bool dynamic;
        InformationManager * manager;
        std::map<uint64_t, BasicBlock*> _blocks;
 
index 5a70dee6a54041951a4461723a85f40714caf518..e1571892349336ab5d0cc94f1d64104d64428d68 100644 (file)
@@ -4,6 +4,7 @@
 #include "core/Function.hxx"
 #include "core/BasicBlock.hxx"
 #include "core/Comment.hxx"
+#include "core/events/NewFunctionEvent.hxx"
 
 #include "gui/qt.hxx"
 #include <quazip/quazip.h>
@@ -119,10 +120,6 @@ void InformationManager::save(const std::string& filename) {
        zip.close();
 }
 
-void InformationManager::signal_new_function(Function* fun) {
-}
-
-
 
 /* *******************************
  * Accessors for the Functions map
@@ -189,7 +186,13 @@ std::map<std::string, Interpreter*>::const_iterator InformationManager::endInter
  */
 
 Function* InformationManager::newFunction(uint64_t address) {
-       Function* fun = new Function(address, this);
+       Function* fun = new Function(address, false, this);
+       functions.insert(std::make_pair(address, fun));
+       return fun;
+}
+
+Function* InformationManager::newDynamicFunction(uint64_t address) {
+       Function* fun = new Function(address, true, this);
        functions.insert(std::make_pair(address, fun));
        return fun;
 }
@@ -201,11 +204,15 @@ BasicBlock* InformationManager::newBasicBlock(uint64_t address) {
 }
 
 Comment* InformationManager::newGlobalComment(uint64_t address) {
-       return NULL;
+       Comment* comment = new Comment(address, this);
+       comments.insert(std::make_pair(address, comment));
+       return comment;
 }
 
 Comment* InformationManager::newLocalComment(uint64_t address, Function* f) {
-       return NULL;
+       Comment* comment = new Comment(address, this);
+       comments.insert(std::make_pair(address, comment));
+       return comment;
 }
 
 void InformationManager::finishFunction(Function* fun) {
@@ -214,10 +221,11 @@ void InformationManager::finishFunction(Function* fun) {
                BasicBlock* bl = b.second;
                blocks.insert(std::make_pair(bl->getStartAddress(), bl));
        }
-       new_function_signal(fun);
+       NewFunctionEvent event(fun->getStartAddress(), fun);
+       dispatch(&event);
 }
 
-void InformationManager::finishBasicBlock(BasicBlock* b) {
+void InformationManager::finishBasicBlock(BasicBlock*) {
 }
 
 void InformationManager::finnishComment(Comment* c) {
@@ -234,5 +242,12 @@ void InformationManager::deleteBasicBlock(BasicBlock* b) {
 }
 
 void InformationManager::deleteComment(Comment* c) {
+       auto range = comments.equal_range(c->getAddress());
+       for (auto it = range.first; it != range.second; ++it) {
+               if (it->second == c) {
+                       comments.erase(it);
+                       break;
+               }
+       }
        delete c;
 }
index 610ece50da253f51820e9af3679ed934008808cb..bb37a1e9a69ee9965b82a031b4e8d7bb9853d3f8 100644 (file)
@@ -17,11 +17,15 @@ class BasicBlock;
 class Comment;
 
 class RenameFunctionEvent;
+class NewFunctionEvent;
+class ChangeCommentEvent;
 
 class QString;
 class QTemporaryFile;
 class QPluginLoader;
 
+using boost::signals2::connection;
+
 class InformationManager {
 public:
        InformationManager();
@@ -31,32 +35,32 @@ public:
        void load(const std::string& filename);
        void save(const std::string& filename);
 
-       void signal_new_function(Function* f);
-       void signal_new_dyn_symbol(const std::string& f)
-               { new_dyn_symbol_signal(f); }
-
-       boost::signals2::connection
-       connect_new_function_signal(std::function<void(Function*)> f)
-               { return new_function_signal.connect(f); }
-
-       boost::signals2::connection
-       connect_new_dyn_symbol_signal(std::function<void(const std::string& name)> f)
-               { return new_dyn_symbol_signal.connect(f); }
-
-       boost::signals2::connection
-       connect_reset_signal(std::function<void ()> f)
-               { return reset_signal.connect(f); }
-
-       boost::signals2::connection
-       connect_rename_function_signal(std::function<void (RenameFunctionEvent*)> f)
-               { return rename_function_signal.connect(f); }
-
        Disassembler* getDisassembler()
                { return disassembler.get(); }
 
+       // Rename Function
+       typedef std::function<void (RenameFunctionEvent*)> RenameFunctionHandler;
+       connection registerRenameFunctionEvent(RenameFunctionHandler h)
+               { return renameFunctionSignal.connect(h); }
        void dispatch(RenameFunctionEvent* event)
-               { rename_function_signal(event); }
-
+               { renameFunctionSignal(event); }
+
+       // New Function
+       typedef std::function<void (NewFunctionEvent*)> NewFunctionHandler;
+       connection registerNewFunctionEvent(NewFunctionHandler h)
+               { return newFunctionSignal.connect(h); }
+       void dispatch(NewFunctionEvent* event)
+               { newFunctionSignal(event); }
+
+       // Change Comment
+       typedef std::function<void (ChangeCommentEvent*)> ChangeCommentHandler;
+       connection registerChangeCommentEvent(ChangeCommentHandler h)
+               { return changeCommentSignal.connect(h); }
+       void dispatch(ChangeCommentEvent* event)
+               { changeCommentSignal(event); }
+
+       connection connect_reset_signal(std::function<void ()> f)
+               { return reset_signal.connect(f); }
 
        Function* getFunction(uint64_t address);
        bool hasFunctions() const {return functions.size() != 0;}
@@ -68,7 +72,6 @@ public:
        std::map<uint64_t, BasicBlock*>::const_iterator beginBasicBlocks();
        std::map<uint64_t, BasicBlock*>::const_iterator endBasicBlocks();
 
-
        Interpreter* getInterpreter(const std::string& name);
        bool hasInterpreters() const {return interpreters.size() != 0;}
        std::map<std::string, Interpreter*>::const_iterator beginInterpreters();
@@ -95,6 +98,7 @@ public:
         * thingsmay happen.
         */
        Function* newFunction(uint64_t address);
+       Function* newDynamicFunction(uint64_t address);
        BasicBlock* newBasicBlock(uint64_t address);
        Comment* newGlobalComment(uint64_t address);
        Comment* newLocalComment(uint64_t address, Function* f);
@@ -106,14 +110,19 @@ public:
        void deleteComment(Comment* c);
 
 private:
+       boost::signals2::signal<void (RenameFunctionEvent*)> renameFunctionSignal;
+       boost::signals2::signal<void (NewFunctionEvent*)> newFunctionSignal;
+       boost::signals2::signal<void (ChangeCommentEvent*)> changeCommentSignal;
+
        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;
-       boost::signals2::signal<void (RenameFunctionEvent*)> rename_function_signal;
+
        std::unique_ptr<Disassembler> disassembler;
+
        std::map<std::string, Interpreter*> interpreters;
        std::map<uint64_t, Function*> functions;
        std::map<uint64_t, BasicBlock*> blocks;
+       std::multimap<uint64_t, Comment*> comments;
+
        std::string filename;
        std::unique_ptr<QTemporaryFile> tmpfile;
        std::vector<QPluginLoader*> plugins;
index 21766bb344cb708a473188f577659d03723bd1c5..58d122ab4d51472715c5288c99e7e846080f429a 100644 (file)
@@ -475,7 +475,11 @@ void LLVMDisassembler<ELFT>::readDynamicSymbols() {
                        // TODO: Error handling
                        std::string symbolname = *(elffile->getSymbolName(it));
                        std::string symbolversion = *(elffile->getSymbolVersion(nullptr, &*it, is_default));
-                       manager->signal_new_dyn_symbol(symbolname + (is_default? "@@" : "@") + symbolversion);
+                       // TODO: actually get the symbol address from relocations
+                       Function* f = manager->newDynamicFunction(0);
+                       f->setName(symbolname + (is_default? "@@" : "@") + symbolversion);
+                       manager->finishFunction(f);
+
                        LOG4CXX_DEBUG(logger, "Adding dynamic Symbol " << symbolname << (is_default? "@@" : "@") << symbolversion);
                }
        }
index 859311032c79c45a49e1721d97ab32b1c67e61a6..33e48bc694dc19981a1dc7e889bcf36c4a3e98d1 100644 (file)
@@ -6,6 +6,7 @@
 #include "core/BasicBlock.hxx"
 #include "core/InformationManager.hxx"
 #include "core/events/RenameFunctionEvent.hxx"
+#include "core/events/NewFunctionEvent.hxx"
 
 #include "widgets/FridaDock.hxx"
 #include "widgets/LogDock.hxx"
@@ -87,12 +88,16 @@ Mainwindow::Mainwindow(InformationManager* mgr)
        QTreeWidgetItem * external = new QTreeWidgetItem(listWidget, QStringList("External Functions"));
        external->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
        external->setBackground(0, QBrush(QColor(0xff, 0xdd, 0xdd)));
-       mgr->connect_new_function_signal([&] (Function* fun) {addFunction(fun);});
-       mgr->connect_new_dyn_symbol_signal([=] (const std::string& name) {
-                       auto item = new QTreeWidgetItem(external, QStringList(name.c_str()));
-                       item->setBackground(0, QBrush(QColor(0xff, 0xdd, 0xdd)));
+       mgr->registerNewFunctionEvent([=] (NewFunctionEvent* event) {
+                       std::string name = event->function->getName();
+                       if (event->function->isDynamic()) {
+                               auto item = new QTreeWidgetItem(external, QStringList(name.c_str()));
+                               item->setBackground(0, QBrush(QColor(0xff, 0xdd, 0xdd)));
+                       } else {
+                               addFunction(event->function);
+                       }
                });
-       mgr->connect_rename_function_signal([&](RenameFunctionEvent* event) {
+       mgr->registerRenameFunctionEvent([&](RenameFunctionEvent* event) {
                        if (objects_list_by_address.find(event->address) == objects_list_by_address.end())
                                return;
                        auto item = objects_list_by_address[event->address];
index 4889cb43fdded1d58332f8e2d61497549b5e031e..128b9fb5401d0e4b3977057af4d5ffe5212e8315 100644 (file)
@@ -68,7 +68,7 @@ BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block,
        , logger(log4cxx::Logger::getLogger("gui.BasicBlockWidget." + name.toStdString())) {
        next[0] = NULL; next[1] = NULL;
 
-       block->getManager()->connect_rename_function_signal([=](RenameFunctionEvent* event) {updateFunctionName(event);});
+       block->getManager()->registerRenameFunctionEvent([=](RenameFunctionEvent* event) {updateFunctionName(event);});
 
        _widget.reset(new CustomQGraphicsTextItem("", this));
        _widget->setPos(5, 20);