]> git.siccegge.de Git - frida/frida.git/blobdiff - src/disassembler/llvm/LLVMDisassembler.cxx
Make LLVMDisassembler a template class
[frida/frida.git] / src / disassembler / llvm / LLVMDisassembler.cxx
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"];