]> git.siccegge.de Git - frida/frida.git/blobdiff - src/disassembler/llvm/LLVMDisassembler.cxx
Forward-port to LLVM 3.5 release
[frida/frida.git] / src / disassembler / llvm / LLVMDisassembler.cxx
index e96f0baae1cc32c271b344cc822e53612d177dba..c2b0527f1f33b2a158c8505776d034e6cbad4e20 100644 (file)
@@ -7,6 +7,7 @@
 
 using namespace llvm;
 using namespace llvm::object;
+using std::error_code;
 
 /*
  * TODO: fallback code falls die Datei kein ELF/PE/COFF/MacO/.. binary
@@ -72,22 +73,25 @@ LLVMDisassembler::LLVMDisassembler(const std::string& filename)
         return;
     }
 
-    DisAsm.reset(target->createMCDisassembler(*STI));
+    MOFI.reset(new MCObjectFileInfo);
+    MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
+
+    DisAsm.reset(target->createMCDisassembler(*STI, Ctx));
     if (!DisAsm) {
         LOG4CXX_ERROR(logger, "no disassembler for target " << tripleName);
         return;
     }
-
-    MOFI.reset(new MCObjectFileInfo);
-    Ctx.reset(new MCContext(AsmInfo.get(), MRI.get(), MOFI.get()));
     RelInfo.reset(
-        target->createMCRelocationInfo(tripleName, *Ctx.get()));
+        target->createMCRelocationInfo(tripleName, Ctx));
     if (RelInfo) {
         Symzer.reset(
-            MCObjectSymbolizer::createObjectSymbolizer(*Ctx.get(), RelInfo, o));
+            MCObjectSymbolizer::createObjectSymbolizer(Ctx, std::move(RelInfo), o));
         if (Symzer)
-            DisAsm->setSymbolizer(Symzer);
+            DisAsm->setSymbolizer(std::move(Symzer));
     }
+    RelInfo.release();
+    Symzer.release();
+
 
     MIA.reset(target->createMCInstrAnalysis(MII.get()));
 
@@ -101,7 +105,7 @@ LLVMDisassembler::LLVMDisassembler(const std::string& filename)
     IP->setPrintImmHex(llvm::HexStyle::C);
     IP->setPrintImmHex(true);
 
-    OwningPtr<MCObjectDisassembler> OD(
+    std::unique_ptr<MCObjectDisassembler> OD(
         new MCObjectDisassembler(*o, *DisAsm, *MIA));
     Mod.reset(OD->buildModule(false));
 
@@ -193,18 +197,18 @@ void LLVMDisassembler::disassemble() {
                                     remaining_functions.push(fun);
                                 }
                             } else {
+                                                               current_block->setNextBlock(0, jmptarget);
                                 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;
+                                                                       current_block->setNextBlock(1, jmptarget);
                                     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,7 +239,7 @@ void LLVMDisassembler::disassemble() {
                uint64_t base_address;
                text_section.getAddress(base_address);
                uint64_t current_address = current_block->getStartAddress() - base_address;
-               while(current_block->getEndAddress() - base_address != current_address) {
+               while(current_block->getEndAddress() - base_address > current_address) {
                        MCInst inst;
                        std::string buf;
                        llvm::raw_string_ostream s(buf);
@@ -245,14 +249,17 @@ void LLVMDisassembler::disassemble() {
                                auto other = blocks.find(current_address + inst_size + base_address);
 
                                if (other != blocks.end()) {
-                                       LOG4CXX_DEBUG(logger, "Shortening block starting at "
-                                                                 << std::hex
-                                                                 << current_block->getStartAddress()
-                                                                 << " now ending at "
-                                                                 << other->first);
-                                       current_block->setEndAddress(current_address + inst_size + base_address);
-                                       current_block->setNextBlock(0, other->first);
-                                       current_block->setNextBlock(1, 0);
+                                       uint64_t endaddress = current_address + inst_size + base_address;
+                                       if (endaddress != current_block->getEndAddress()) {
+                                               LOG4CXX_DEBUG(logger, "Shortening block starting at "
+                                                                         << std::hex
+                                                                         << current_block->getStartAddress()
+                                                                         << " now ending at "
+                                                                         << other->first);
+                                               current_block->setEndAddress(endaddress);
+                                               current_block->setNextBlock(0, other->first);
+                                               current_block->setNextBlock(1, 0);
+                                       }
                                }
                        } else {
                                inst_size = 1;
@@ -321,7 +328,14 @@ void LLVMDisassembler::printEachInstruction(uint64_t start, uint64_t end,
             uint8_t bytes[inst_size+2];
             ref.readBytes(current_address, inst_size, bytes);
 
-            IP->printInst(&inst, s, "");
+                       uint64_t jmptarget;
+                       if (MIA->evaluateBranch(inst, current_address, inst_size, jmptarget)) {
+                               std::stringstream stream;
+                               stream << std::hex << (base_address + jmptarget);
+                               IP->printInst(&inst, s, stream.str());
+                       } else
+                               IP->printInst(&inst, s, "");
+
                        fun(bytes, inst_size, s.str());
         } else {
                        LOG4CXX_WARN(logger, "Invalid byte at" << std::hex << current_address + base_address);