Add interface to iterate over functions
authorChristoph Egger <siccegge@cs.fau.de>
Tue, 27 May 2014 12:34:51 +0000 (14:34 +0200)
committerChristoph Egger <siccegge@cs.fau.de>
Tue, 27 May 2014 12:34:51 +0000 (14:34 +0200)
src/disassembler/Disassembler.hxx
src/disassembler/Function.hxx
src/disassembler/llvm/LLVMDisassembler.cxx
src/disassembler/llvm/LLVMDisassembler.hxx
src/disassembler/llvm/LLVMFunction.hxx

index 14083262f5027ac7b22057c009d4dfb1feeb8ff0..b2576f70d3c5939f132374a7d5fbdff498162604 100644 (file)
@@ -5,6 +5,7 @@
 #include <functional>
 
 #include "disassembler/BasicBlock.hxx"
+#include "disassembler/Function.hxx"
 
 
 class Disassembler {
@@ -15,7 +16,8 @@ public:
        void getSymbols();
        uint64_t entryAddress();
 
-    virtual void forEachInstruction(const std::string& name, std::function<void (long, std::string, std::string)> callback) = 0;
+       virtual void forEachFunction(std::function<void (uint64_t, Function*)> callback) = 0;
+    // virtual void forEachInstruction(const std::string& name, std::function<void (long, std::string, std::string)> callback) = 0;
 
     // http://llvm.org/docs/doxygen/html/MCObjectDisassembler_8cpp_source.html +197
        BasicBlock * generateControlFlowGraph(const std::string& name);
index 6cad001dcf74c68ea2f0113c078487c767af7e68..ccca54c2198ec22b247ba27e264bac30e526908a 100644 (file)
@@ -5,19 +5,21 @@
 
 class Function {
 public:
-       Function(const std::string& name) {
-               this->name = name;
+       Function(const std::string& name, uint64_t start_address)
+               : name(name)
+               , start_address(start_address) {
+       }
+
+       uint64_t getStartAddress() const {
+               return start_address;
        }
 
        std::string getName() const {
                return name;
        }
-
-       BasicBlock * getEntry();
-
 private:
        std::string name;
-       BasicBlock * start;
+       uint64_t start_address;
 };
 
 #endif
index e1570758da27831e02d1ca63fe85fa326297bda1..3494b79bd8a370814d35eba28fec53db0e1543d6 100644 (file)
@@ -13,7 +13,6 @@ using namespace llvm::object;
  * ist sondern z.B. einfach nur Instruktionen oder ein Bootsektor oder
  * foo
  */
-
 LLVMDisassembler::LLVMDisassembler(const std::string& filename)
     : Disassembler(filename)
     , logger(log4cxx::Logger::getLogger("LLVMDisassembler"))
@@ -117,24 +116,29 @@ void LLVMDisassembler::disassemble() {
     std::stack<LLVMBasicBlock*> remaining_blocks;
     SectionRef text_section = sections[".text"];
 
-    std::for_each(symbols.begin(), symbols.end(),
-                  [&](std::pair<const std::string, SymbolRef> x) {
-                      uint64_t result;
-                      bool contains;
-                      SymbolRef::Type symbol_type;
+       for (auto x = symbols.begin(); x != symbols.end(); ++x) {
+               uint64_t result;
+               bool contains;
+               SymbolRef::Type symbol_type;
+
+/*
+ * TODO: If we jump into some Basic Block we need to split it there into two
+ */
 
-                      if (text_section.containsSymbol(x.second, contains) || !contains)
-                          return;
+               if (text_section.containsSymbol(x->second, contains) || !contains)
+                       continue;
 
-                      if (x.second.getType(symbol_type)
-                          || SymbolRef::ST_Function != symbol_type)
-                          return;
+               if (x->second.getType(symbol_type)
+                       || SymbolRef::ST_Function != symbol_type)
+                       continue;
 
-                      if (!x.second.getAddress(result)) {
-                          remaining_functions.push(new LLVMFunction(x.first, result));
-                          LOG4CXX_DEBUG(logger, "Disasembling " << x.first);
-                      }
-                  });
+               if (!x->second.getAddress(result)) {
+                       LLVMFunction * fun = new LLVMFunction(x->first, result);
+                       remaining_functions.push(fun);
+                       functions.insert(std::make_pair(result, fun));
+                       LOG4CXX_DEBUG(logger, "Disasembling " << x->first);
+               }
+       }
 
     StringRef bytes;
     text_section.getContents(bytes);
@@ -149,7 +153,9 @@ void LLVMDisassembler::disassemble() {
         // if ("_start" != current_function->getName())
         //  continue;
 
-        remaining_blocks.push(new LLVMBasicBlock(current_function->getStartAddress()));
+               LLVMBasicBlock * block = new LLVMBasicBlock(current_function->getStartAddress());
+        remaining_blocks.push(block);
+               blocks.insert(std::make_pair(block->getStartAddress(), block));
 
         while (remaining_blocks.size()) {
             LLVMBasicBlock * current_block = remaining_blocks.top();
@@ -187,14 +193,24 @@ void LLVMDisassembler::disassemble() {
                                                jmptarget += base_address;
                         if (!MIA->isIndirectBranch(inst)) {
                             if (MIA->isCall(inst)) {
-                                                               if (blocks.find(jmptarget) == blocks.end())
-                                                                       remaining_functions.push(new LLVMFunction("<Unnamed>", jmptarget));
+                                                               if (functions.find(jmptarget) == functions.end()) {
+                                                                       std::stringstream s;
+                                                                       s << "<Unnamed 0x" << std::hex << jmptarget << ">";
+                                                                       LLVMFunction * fun = new LLVMFunction(s.str(), jmptarget);
+                                                                       functions.insert(std::make_pair(jmptarget, fun));
+                                                                       remaining_functions.push(fun);
+                                                               }
                             } else {
-                                                               if (blocks.find(jmptarget) == blocks.end())
-                                remaining_blocks.push(new LLVMBasicBlock(jmptarget));
+                                                               if (blocks.find(jmptarget) == blocks.end()) {
+                                                                       LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget);
+                                                                       blocks.insert(std::make_pair(block->getStartAddress(), block));
+                                                                       remaining_blocks.push(block);
+                                                               }
                                 if (MIA->isConditionalBranch(inst)) {
                                                                        jmptarget = base_address + current_address + inst_size;
-                                                                       if (blocks.find(jmptarget) == blocks.end())
+                                                                       if (blocks.find(jmptarget) == blocks.end()) {
+                                                                               LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget);
+                                                                               blocks.insert(std::make_pair(block->getStartAddress(), block));
                                                                                remaining_blocks.push(new LLVMBasicBlock(jmptarget));
                                 }
                             }
@@ -207,8 +223,9 @@ void LLVMDisassembler::disassemble() {
 
                 if (inst_size == 0 || MIA->isTerminator(inst) || MIA->isBranch(inst)) {
                     current_block->setEndAddress(current_address + base_address);
-                                       blocks.insert(std::make_pair(current_block->getStartAddress(), current_block));
-                    LOG4CXX_DEBUG(logger, "Finished Block at " << current_block->getEndAddress());
+                    LOG4CXX_DEBUG(logger, "Finished Block at " << std::hex << 
+                                                                 current_block->getEndAddress());
+                                                                       }
                     break;
                 }
                 current_address += inst_size;
@@ -247,6 +264,15 @@ void LLVMDisassembler::readSections() {
 
 }
 
-BasicBlock * LLVMDisassembler::generateControlFlowGraph(uint64_t address) {
+void LLVMDisassembler::forEachFunction(std::function<void (uint64_t, Function*)> callback) {
+       std::for_each(functions.begin(), functions.end(),
+                                 [&](std::pair<uint64_t, LLVMFunction*> x) {
+                                         callback(x.first, x.second);
+                                 });
+}
+
+
+
+void LLVMDisassembler::generateControlFlowGraph(uint64_t address) {
 
 }
index 4f58a0eb8450078758d5dd6486138cc8d500afda..87dbefa2c9ed355349dcf892aac5a3a936614dae 100644 (file)
@@ -8,6 +8,8 @@
 #include "include_llvm.hxx"
 
 #include "disassembler/Disassembler.hxx"
+#include "disassembler/BasicBlock.hxx"
+#include "disassembler/Function.hxx"
 #include "disassembler/llvm/LLVMBasicBlock.hxx"
 
 
@@ -20,9 +22,7 @@ public:
        void getSymbols();
        uint64_t entryAddress();
 
-    void forEachInstruction(const std::string& name,
-                                                       std::function<void (long, std::string, std::string)> callback)
-               {}
+       void forEachFunction(std::function<void (uint64_t, Function*)> callback);
 
        BasicBlock * generateControlFlowGraph(const std::string& name);
        BasicBlock * generateControlFlowGraph(uint64_t address);
@@ -38,7 +38,8 @@ private:
        void readSections();
 
     log4cxx::LoggerPtr logger;
-       std::map<uint8_t, LLVMBasicBlock*> blocks;
+       std::map<uint64_t, LLVMBasicBlock*> blocks;
+       std::map<uint64_t, LLVMFunction*> functions;
 
     llvm::Triple triple;
     std::shared_ptr<llvm::object::Binary> binary;
index 0ac3ead70a1f0a9ff86efc522fd3a476dc481203..3bc813a79359511da101eac0488b24ab9dd3a209 100644 (file)
@@ -6,13 +6,8 @@
 class LLVMFunction : public Function {
 public:
        LLVMFunction(const std::string& name, uint64_t start_address)
-               :Function(name)
-               , start_address(start_address) {
-       }
-
-       uint64_t getStartAddress() const {return start_address;}
+               :Function(name, start_address) {}
 private:
-       uint64_t start_address;
 };
 
 #endif