]> git.siccegge.de Git - frida/frida.git/commitdiff
Make LLVMDisassembler a template class
authorChristoph Egger <siccegge@faui49man12.informatik.uni-erlangen.de>
Wed, 14 Jan 2015 16:35:51 +0000 (17:35 +0100)
committerChristoph Egger <siccegge@faui49man12.informatik.uni-erlangen.de>
Wed, 14 Jan 2015 16:35:51 +0000 (17:35 +0100)
src/core/InformationManager.cxx
src/disassembler/llvm/LLVMBasicBlock.hxx
src/disassembler/llvm/LLVMDisassembler.cxx
src/disassembler/llvm/LLVMDisassembler.hxx
src/disassembler/llvm/include_llvm.hxx

index 6e9157263ef4eb8b22f2ea461ea76a4c209c4eb8..8f916ef6d2f5e24d3bf62778e39976aeeee70b3f 100644 (file)
@@ -1,9 +1,7 @@
 #include "InformationManager.hxx"
 #include "disassembler/llvm/LLVMDisassembler.hxx"
 
-#include <iostream>
-
 void InformationManager::reset(const std::string& filename) {
-       disassembler.reset(new LLVMDisassembler(filename, this));
+       disassembler.reset(createLLVMDisassembler(filename, this));
        disassembler.get()->start();
 }
index 6bc186de365858e6992a029840dd877c699af2b7..0949f70a4d87c50fac5fb611d249fd4ec0a7f569 100644 (file)
@@ -3,21 +3,20 @@
 
 #include "disassembler/BasicBlock.hxx"
 
-class LLVMDisassembler;
+class Disassembler;
 
 class LLVMBasicBlock : public BasicBlock {
 public:
-       LLVMBasicBlock(uint64_t start_address, LLVMDisassembler * disassembler) {
+       LLVMBasicBlock(uint64_t start_address, Disassembler * disassembler) {
                setStartAddress(start_address);
        }
 
-       LLVMDisassembler * getDisassembler() {
+       Disassembler * getDisassembler() {
                return disassembler;
        }
 
 private:
-       LLVMDisassembler * disassembler;
+       Disassembler * disassembler;
 };
 
-
 #endif
index 6a25e9abad87e756a9d77c77876f72be90aa96fc..1f92ab04410624c1a3ede4957234e2ad21cb0671 100644 (file)
@@ -9,12 +9,42 @@ using namespace llvm;
 using namespace llvm::object;
 using std::error_code;
 
+/*
+ *
+ */
+Disassembler * createLLVMDisassembler(const std::string& filename, InformationManager* manager) {
+       std::unique_ptr<Binary> o;
+       o.reset(createBinary(filename).get());
+       const Binary * op = o.get();
+
+       // ELFType<endian, maxalign, 64bit>
+       if (const ELF32LEObjectFile * _ = dyn_cast<ELF32LEObjectFile>(op)) {
+#pragma unused(_)
+               return new LLVMDisassembler<ELFType<support::little, 2, false>>(filename, manager);
+       }
+       if (const ELF64LEObjectFile * _ = dyn_cast<ELF64LEObjectFile>(op)) {
+#pragma unused(_)
+               return new LLVMDisassembler<ELFType<support::little, 2, true>>(filename, manager);
+       }
+       if (const ELF32BEObjectFile * _ = dyn_cast<ELF32BEObjectFile>(op)) {
+#pragma unused(_)
+               return new LLVMDisassembler<ELFType<support::big, 2, false>>(filename, manager);
+       }
+       if (const ELF64BEObjectFile * _ = dyn_cast<ELF64BEObjectFile>(op)) {
+#pragma unused(_)
+               return new LLVMDisassembler<ELFType<support::big, 2, true>>(filename, manager);
+       }
+
+       return NULL;
+}
+
 /*
  * TODO: fallback code falls die Datei kein ELF/PE/COFF/MacO/.. binary
  * ist sondern z.B. einfach nur Instruktionen oder ein Bootsektor oder
  * foo
  */
-LLVMDisassembler::LLVMDisassembler(const std::string& filename,
+template <typename ELFT>
+LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
                                    InformationManager* manager)
        : Disassembler(filename, manager)
        , logger(log4cxx::Logger::getLogger("LLVMDisassembler"))
@@ -115,13 +145,15 @@ LLVMDisassembler::LLVMDisassembler(const std::string& filename,
        Mod.reset(OD->buildModule(false));
 }
 
-void LLVMDisassembler::start() {
+template <typename ELFT>
+void LLVMDisassembler<ELFT>::start() {
        readSymbols();
        readSections();
        disassemble();
 }
 
-LLVMDisassembler::~LLVMDisassembler() {
+template <typename ELFT>
+LLVMDisassembler<ELFT>::~LLVMDisassembler() {
        std::for_each(functions.begin(), functions.end(),
                      [](std::pair<uint64_t,LLVMFunction*> it) {
                              delete it.second;
@@ -132,7 +164,8 @@ LLVMDisassembler::~LLVMDisassembler() {
                      });
 }
 
-Function* LLVMDisassembler::disassembleFunctionAt(uint64_t address, const std::string& name) {
+template <typename ELFT>
+Function* LLVMDisassembler<ELFT>::disassembleFunctionAt(uint64_t address, const std::string& name) {
        SectionRef text_section = sections[".text"];
        uint64_t base_address, size;
        text_section.getAddress(base_address);
@@ -162,7 +195,8 @@ Function* LLVMDisassembler::disassembleFunctionAt(uint64_t address, const std::s
        return function;
 }
 
-void LLVMDisassembler::disassembleFunction(LLVMFunction* function) {
+template <typename ELFT>
+void LLVMDisassembler<ELFT>::disassembleFunction(LLVMFunction* function) {
        std::stack<LLVMBasicBlock*> remaining_blocks;
        SectionRef text_section = sections[".text"];
        StringRef bytes;
@@ -248,7 +282,8 @@ void LLVMDisassembler::disassembleFunction(LLVMFunction* function) {
        manager->signal_new_function(function);
 }
 
-void LLVMDisassembler::disassemble() {
+template <typename ELFT>
+void LLVMDisassembler<ELFT>::disassemble() {
        SectionRef text_section = sections[".text"];
        std::vector<LLVMFunction*> remaining_functions;
 
@@ -305,7 +340,8 @@ void LLVMDisassembler::disassemble() {
        }
 }
 
-void LLVMDisassembler::splitBlocks(LLVMFunction* function) {
+template <typename ELFT>
+void LLVMDisassembler<ELFT>::splitBlocks(LLVMFunction* function) {
        SectionRef text_section = sections[".text"];
        StringRef bytes;
        text_section.getContents(bytes);
@@ -353,7 +389,8 @@ void LLVMDisassembler::splitBlocks(LLVMFunction* function) {
        }
 }
 
-void LLVMDisassembler::readSymbols() {
+template <typename ELFT>
+void LLVMDisassembler<ELFT>::readSymbols() {
        error_code ec;
        symbol_iterator si(o->symbol_begin()), se(o->symbol_end());
        for (; si != se; ++si) {
@@ -367,7 +404,8 @@ void LLVMDisassembler::readSymbols() {
        }
 }
 
-void LLVMDisassembler::readSections() {
+template <typename ELFT>
+void LLVMDisassembler<ELFT>::readSections() {
        error_code ec;
        section_iterator i(o->section_begin()), e(o->section_end());
        for (; i != e; ++i) {
@@ -382,14 +420,16 @@ void LLVMDisassembler::readSections() {
 
 }
 
-void LLVMDisassembler::forEachFunction(std::function<void (uint64_t, Function*)> callback) {
+template <typename ELFT>
+void LLVMDisassembler<ELFT>::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::printEachInstruction(uint64_t start, uint64_t end,
+template <typename ELFT>
+void LLVMDisassembler<ELFT>::printEachInstruction(uint64_t start, uint64_t end,
                                             std::function<void (uint8_t*, size_t,
                                                                 const std::string&)> fun) {
        SectionRef text_section = sections[".text"];
index b0ab082502a4483d3062b412e36b83e6787001a9..5c54f3945fe89a4ed8798e8b99717334b5da6678 100644 (file)
@@ -14,6 +14,9 @@
 #include "disassembler/llvm/LLVMFunction.hxx"
 
 
+Disassembler * createLLVMDisassembler(const std::string& filename, InformationManager* manager);
+
+template <typename ELFT>
 class LLVMDisassembler
        : public Disassembler {
 public:
index 0ab21a34399bd8c337da3b9a7f31f2acd0233609..8e5babdb2ee923776e2541f945ac8dd26bcf9a7c 100644 (file)
@@ -7,6 +7,7 @@
 #include <llvm/ADT/STLExtras.h>
 #include <llvm/ADT/StringExtras.h>
 #include <llvm/MC/MCAsmInfo.h>
+#include <llvm/Object/ELFObjectFile.h>
 #include <llvm/Object/ObjectFile.h>
 #include <llvm/Object/Archive.h>
 #include <llvm/MC/MCAsmInfo.h>