]> git.siccegge.de Git - frida/frida.git/blobdiff - src/disassembler/llvm/LLVMDisassembler.cxx
Properly fail if no appropriate Disassembler can be constructed
[frida/frida.git] / src / disassembler / llvm / LLVMDisassembler.cxx
index e673c371650027021455b63f64b94e422dcc7a5d..66605d31bec388e64ef4ce97effeb8aa14feb089 100644 (file)
@@ -3,6 +3,7 @@
 #include "core/InformationManager.hxx"
 #include "core/Function.hxx"
 #include "core/BasicBlock.hxx"
+#include "core/Exception.hxx"
 #include <boost/algorithm/string.hpp>
 
 #include <stack>
@@ -47,26 +48,29 @@ Disassembler * createLLVMDisassembler(const std::string& filename, InformationMa
        foo.second.release();
 #endif
 
-       // ELFType<endian, maxalign, 64bit>
-       if (ELF32LEObjectFile * object = dyn_cast<ELF32LEObjectFile>(op)) {
-               return new LLVMDisassembler<ELFType<support::little, 2, false>>(filename, manager, object);
-       }
-       if (ELF64LEObjectFile * object = dyn_cast<ELF64LEObjectFile>(op)) {
-               return new LLVMDisassembler<ELFType<support::little, 2, true>>(filename, manager, object);
-       }
-       if (ELF32BEObjectFile * object = dyn_cast<ELF32BEObjectFile>(op)) {
-               return new LLVMDisassembler<ELFType<support::big, 2, false>>(filename, manager, object);
-       }
-       if (ELF64BEObjectFile * object = dyn_cast<ELF64BEObjectFile>(op)) {
-               return new LLVMDisassembler<ELFType<support::big, 2, true>>(filename, manager, object);
-       }
-       if (COFFObjectFile * object = dyn_cast<COFFObjectFile>(op)) {
-               return new LLVMDisassembler<COFFT>(filename, manager, object);
-       }
-       if (MachOObjectFile * object = dyn_cast<MachOObjectFile>(op)) {
-               return new LLVMDisassembler<MACHOT>(filename, manager, object);
+       try {
+               // ELFType<endian, maxalign, 64bit>
+               if (ELF32LEObjectFile * object = dyn_cast<ELF32LEObjectFile>(op)) {
+                       return new LLVMDisassembler<ELFType<support::little, 2, false>>(filename, manager, object);
+               }
+               if (ELF64LEObjectFile * object = dyn_cast<ELF64LEObjectFile>(op)) {
+                       return new LLVMDisassembler<ELFType<support::little, 2, true>>(filename, manager, object);
+               }
+               if (ELF32BEObjectFile * object = dyn_cast<ELF32BEObjectFile>(op)) {
+                       return new LLVMDisassembler<ELFType<support::big, 2, false>>(filename, manager, object);
+               }
+               if (ELF64BEObjectFile * object = dyn_cast<ELF64BEObjectFile>(op)) {
+                       return new LLVMDisassembler<ELFType<support::big, 2, true>>(filename, manager, object);
+               }
+               if (COFFObjectFile * object = dyn_cast<COFFObjectFile>(op)) {
+                       return new LLVMDisassembler<COFFT>(filename, manager, object);
+               }
+               if (MachOObjectFile * object = dyn_cast<MachOObjectFile>(op)) {
+                       return new LLVMDisassembler<MACHOT>(filename, manager, object);
+               }
+       } catch (BinaryNotSupported& e) {
+               return NULL;
        }
-
        return NULL;
 }
 
@@ -122,7 +126,8 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
        target = TargetRegistry::lookupTarget("", triple, es);
        if (!target) {
                LOG4CXX_ERROR(logger, es);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        LOG4CXX_INFO(logger, "Target " << target->getName());
@@ -130,26 +135,30 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
        MRI.reset(target->createMCRegInfo(tripleName));
        if (!MRI) {
                LOG4CXX_ERROR(logger, "no register info for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        // Set up disassembler.
        AsmInfo.reset(target->createMCAsmInfo(*MRI, tripleName));
        if (!AsmInfo) {
                LOG4CXX_ERROR(logger, "no assembly info for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        STI.reset(target->createMCSubtargetInfo(tripleName, "", ""));
        if (!STI) {
                LOG4CXX_ERROR(logger, "no subtarget info for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        MII.reset(target->createMCInstrInfo());
        if (!MII) {
                LOG4CXX_ERROR(logger, "no instruction info for target " << tripleName);
-               return;
+                               BinaryNotSupported e;
+               throw e;
        }
 
        MOFI.reset(new MCObjectFileInfo);
@@ -158,7 +167,8 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
        DisAsm.reset(target->createMCDisassembler(*STI, Ctx));
        if (!DisAsm) {
                LOG4CXX_ERROR(logger, "no disassembler for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
        RelInfo.reset(
                target->createMCRelocationInfo(tripleName, Ctx));
@@ -174,14 +184,16 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
        MIA.reset(target->createMCInstrAnalysis(MII.get()));
        if (!MIA) {
                LOG4CXX_ERROR(logger, "no instruction analysis for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
        IP.reset(target->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
        if (!IP) {
                LOG4CXX_ERROR(logger, "no instruction printer for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        IP->setPrintImmHex(llvm::HexStyle::C);