Fill BasicBlockWidgets with actual assembly instructions
authorChristoph Egger <siccegge@cs.fau.de>
Tue, 27 May 2014 14:58:36 +0000 (16:58 +0200)
committerChristoph Egger <siccegge@cs.fau.de>
Tue, 27 May 2014 14:58:36 +0000 (16:58 +0200)
src/disassembler/Disassembler.hxx
src/disassembler/llvm/LLVMBasicBlock.hxx
src/disassembler/llvm/LLVMDisassembler.cxx
src/disassembler/llvm/LLVMDisassembler.hxx
src/gui/Mainwindow.cxx
src/gui/widgets/BasicBlockWidget.hxx

index 7ad4dc02623d834134b4f38e7f53abf8a17ee595..7bd3cdc4cfa3da85b34ff7fc66b1a47279a3bf5d 100644 (file)
@@ -15,10 +15,10 @@ public:
 
        void getSymbols();
        uint64_t entryAddress();
-
-       virtual void forEachFunction(std::function<void (uint64_t, Function*)> callback) = 0;
        virtual BasicBlock * getBasicBlock(uint64_t address) = 0;
 
+       virtual void forEachFunction(std::function<void (uint64_t, Function*)> callback) = 0;
+       virtual void printEachInstruction(uint64_t start, uint64_t end, std::function<void (const std::string&)> fun) = 0;
 protected:
     virtual bool isFunctionCall(uint64_t address) = 0;
     virtual bool isJump(uint64_t address) = 0;
index ede89d6f58564ade6a9a07c986fc388a9bb25f93..6bc186de365858e6992a029840dd877c699af2b7 100644 (file)
@@ -3,14 +3,20 @@
 
 #include "disassembler/BasicBlock.hxx"
 
+class LLVMDisassembler;
+
 class LLVMBasicBlock : public BasicBlock {
 public:
-       LLVMBasicBlock(uint64_t start_address) {
+       LLVMBasicBlock(uint64_t start_address, LLVMDisassembler * disassembler) {
                setStartAddress(start_address);
        }
 
+       LLVMDisassembler * getDisassembler() {
+               return disassembler;
+       }
 
 private:
+       LLVMDisassembler * disassembler;
 };
 
 
index a8c2867f50784255a27246bb10be5db9312d2e87..6e76c91bc27c8121f7088460401ae3c20d4faf47 100644 (file)
@@ -111,14 +111,14 @@ LLVMDisassembler::LLVMDisassembler(const std::string& filename)
 }
 
 LLVMDisassembler::~LLVMDisassembler() {
-       std::for_each(functions.begin(), functions.end(),
-                                 [](std::pair<uint64_t,LLVMFunction*> it) {
-                                         delete it.second;
-                                 });
-       std::for_each(blocks.begin(), blocks.end(),
-                                 [](std::pair<uint64_t, LLVMBasicBlock*> it) {
-                                         delete it.second;
-                                 });
+    std::for_each(functions.begin(), functions.end(),
+                  [](std::pair<uint64_t,LLVMFunction*> it) {
+                      delete it.second;
+                  });
+    std::for_each(blocks.begin(), blocks.end(),
+                  [](std::pair<uint64_t, LLVMBasicBlock*> it) {
+                      delete it.second;
+                  });
 }
 
 /*
@@ -129,26 +129,26 @@ void LLVMDisassembler::disassemble() {
     std::stack<LLVMBasicBlock*> remaining_blocks;
     SectionRef text_section = sections[".text"];
 
-       for (auto x = symbols.begin(); x != symbols.end(); ++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;
 
 
-               if (text_section.containsSymbol(x->second, contains) || !contains)
-                       continue;
+        if (text_section.containsSymbol(x->second, contains) || !contains)
+            continue;
 
-               if (x->second.getType(symbol_type)
-                       || SymbolRef::ST_Function != symbol_type)
-                       continue;
+        if (x->second.getType(symbol_type)
+            || SymbolRef::ST_Function != symbol_type)
+            continue;
 
-               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);
-               }
-       }
+        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);
@@ -163,9 +163,9 @@ void LLVMDisassembler::disassemble() {
         // if ("_start" != current_function->getName())
         //  continue;
 
-               LLVMBasicBlock * block = new LLVMBasicBlock(current_function->getStartAddress());
+        LLVMBasicBlock * block = new LLVMBasicBlock(current_function->getStartAddress(), this);
         remaining_blocks.push(block);
-               blocks.insert(std::make_pair(block->getStartAddress(), block));
+        blocks.insert(std::make_pair(block->getStartAddress(), block));
 
         while (remaining_blocks.size()) {
             LLVMBasicBlock * current_block = remaining_blocks.top();
@@ -200,31 +200,31 @@ void LLVMDisassembler::disassemble() {
 
                     uint64_t jmptarget;
                     if (MIA->evaluateBranch(inst, current_address, inst_size, jmptarget)) {
-                                               jmptarget += base_address;
+                        jmptarget += base_address;
                         if (!MIA->isIndirectBranch(inst)) {
                             if (MIA->isCall(inst)) {
-                                                               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);
-                                                               }
+                                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()) {
-                                                                       LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget);
-                                                                       blocks.insert(std::make_pair(block->getStartAddress(), block));
-                                                                       current_block->setNextBlock(0, block->getStartAddress());
-                                                                       remaining_blocks.push(block);
-                                                               }
+                                if (blocks.find(jmptarget) == blocks.end()) {
+                                    LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this);
+                                    blocks.insert(std::make_pair(block->getStartAddress(), block));
+                                    current_block->setNextBlock(0, block->getStartAddress());
+                                    remaining_blocks.push(block);
+                                }
                                 if (MIA->isConditionalBranch(inst)) {
-                                                                       jmptarget = base_address + current_address + inst_size;
-                                                                       if (blocks.find(jmptarget) == blocks.end()) {
-                                                                               LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget);
-                                                                               blocks.insert(std::make_pair(block->getStartAddress(), block));
-                                                                               current_block->setNextBlock(1, block->getStartAddress());
-                                                                               remaining_blocks.push(new LLVMBasicBlock(jmptarget));
-                                                                       }
+                                    jmptarget = base_address + current_address + inst_size;
+                                    if (blocks.find(jmptarget) == blocks.end()) {
+                                        LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this);
+                                        blocks.insert(std::make_pair(block->getStartAddress(), block));
+                                        current_block->setNextBlock(1, block->getStartAddress());
+                                        remaining_blocks.push(block);
+                                    }
                                 }
                             }
                         }
@@ -235,9 +235,9 @@ void LLVMDisassembler::disassemble() {
 
 
                 if (inst_size == 0 || MIA->isTerminator(inst) || MIA->isBranch(inst)) {
-                    current_block->setEndAddress(current_address + base_address);
-                    LOG4CXX_DEBUG(logger, "Finished Block at " << std::hex << 
-                                                                 current_block->getEndAddress());
+                    current_block->setEndAddress(current_address + base_address + inst_size);
+                    LOG4CXX_DEBUG(logger, "Finished Block at " << std::hex <<
+                                  current_block->getEndAddress());
                     break;
                 }
                 current_address += inst_size;
@@ -277,8 +277,46 @@ void LLVMDisassembler::readSections() {
 }
 
 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);
-                                 });
+    std::for_each(functions.begin(), functions.end(),
+                  [&](std::pair<uint64_t, LLVMFunction*> x) {
+                      callback(x.first, x.second);
+                  });
+}
+
+void LLVMDisassembler::printEachInstruction(uint64_t start, uint64_t end, std::function<void (const std::string&)> fun) {
+    SectionRef text_section = sections[".text"];
+    uint64_t base_address;
+    text_section.getAddress(base_address);
+    uint64_t current_address = start - base_address;
+
+    StringRef bytes;
+    text_section.getContents(bytes);
+    StringRefMemoryObject ref(bytes);
+
+    while (current_address < end - base_address) {
+        uint64_t inst_size;
+        MCInst inst;
+               std::string buf;
+               llvm::raw_string_ostream s(buf);
+
+        if(llvm::MCDisassembler::Success ==
+           DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) {
+
+            uint8_t bytes[inst_size+2];
+            ref.readBytes(current_address, inst_size, bytes);
+            for(uint8_t* cur = bytes; cur < bytes + inst_size; ++cur) {
+                s.write_hex(*cur);
+                s << ' ';
+            }
+            s << '\t';
+
+            IP->printInst(&inst, s, "");
+                       fun(s.str());
+        } else {
+                       fun("Invalid Byte");
+                       inst_size = 1;
+               }
+
+               current_address += inst_size;
+    }
 }
index 848b20e4a7cff206c66c7ba4e78ef5f16e1be39f..8c93a450610d4f0f2b8925be02fd976b04ceff14 100644 (file)
@@ -24,6 +24,8 @@ public:
        uint64_t entryAddress();
 
        void forEachFunction(std::function<void (uint64_t, Function*)> callback);
+       void printEachInstruction(uint64_t start, uint64_t end, std::function<void (const std::string&)> fun);
+
        BasicBlock * getBasicBlock(uint64_t address) {
                return blocks[address];
        }
index 5e47b25871227bc791e9354021f49d2e5d0a7466..1c8ae0bb2225b49e2132b8cb9dcc188c2c2fcb25 100644 (file)
@@ -78,6 +78,11 @@ namespace {
                widget->setFlag(QGraphicsItem::ItemIsMovable, true);
                widget->moveBy(100*startx, 10*(block->getStartAddress() - starty));
 
+               dis->printEachInstruction(block->getStartAddress(), block->getEndAddress(),
+                                                                 [&](const std::string& line) {
+                                                                         widget->addItem(line.c_str());
+                                                                 });
+
                if (block->getNextBlock(0) != 0)
                        local__add_basic_block(dis->getBasicBlock(block->getNextBlock(0)), dis, scene, starty, startx+1);
                if (block->getNextBlock(1) != 0)
index effb5880665a9c4eeaed5baa2105ed7c4a7e9c39..ec443f36806a61481448acecaeb36c3bc8fb3064 100644 (file)
@@ -7,13 +7,13 @@ public:
                : x(-5), y(-20)
                , dx(250), dy(270)
                , name(name) {
-        _widget.addItem("THIS");
-        _widget.addItem("IS");
-        _widget.addItem("A");
-        _widget.addItem("TEST");
                _widget.resize(dx-20, dy-20);
     }
 
+       void addItem(const QString& line) {
+               _widget.addItem(line);
+       }
+
     QRectF boundingRect() const
     {
         qreal penWidth = 1;