#pragma once #include #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/Type.h" #include "llvm/IR/Verifier.h" #include "llvm/Pass.h" namespace vm { class lifters_t { // private default constructor... // used for singleton... lifters_t() { } using lifter_callback_t = std::function< void( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) >; static lifter_callback_t lconstq, lconstdwsxq, lconstwsxq, lconstbzxw, lconstbsxq, lconstwsxdw, lconstdw, lconstbsxdw; static lifter_callback_t addq, adddw, addw; static lifter_callback_t sregq, sregdw; static lifter_callback_t lregq, lregdw; static lifter_callback_t pushvsp; static lifter_callback_t readq, readdw; static lifter_callback_t nandq, nanddw; static lifter_callback_t shrq; static lifter_callback_t jmp; static lifter_callback_t lflagsq; static lifter_callback_t vmexit; std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, { vm::handler::LCONSTDW, &lconstdw }, { vm::handler::LCONSTDWSXQ, &lconstdwsxq }, { vm::handler::LCONSTWSXQ, &lconstwsxq }, { vm::handler::LCONSTBZXW, &lconstbzxw }, { vm::handler::LCONSTBSXQ, &lconstbsxq }, { vm::handler::LCONSTWSXDW, &lconstwsxdw }, { vm::handler::LCONSTBSXDW, &lconstbsxdw }, { vm::handler::ADDQ, &addq }, { vm::handler::ADDDW, &adddw }, { vm::handler::ADDW, &addw }, { vm::handler::SHRQ, &shrq }, { vm::handler::PUSHVSP, &pushvsp }, { vm::handler::SREGQ, &sregq }, { vm::handler::SREGDW, &sregdw }, { vm::handler::LREGQ, &lregq }, { vm::handler::LREGDW, &lregdw }, { vm::handler::READQ, &readq }, { vm::handler::READDW, &readdw }, { vm::handler::NANDQ, &nandq }, { vm::handler::NANDDW, &nanddw }, { vm::handler::LFLAGSQ, &lflagsq }, { vm::handler::JMP, &jmp }, { vm::handler::VMEXIT, &vmexit } }; static llvm::Value *and_flags( vm::devirt_t *rtn, std::uint8_t byte_size, llvm::Value *result ); static llvm::Value *add_flags( vm::devirt_t *rtn, std::uint8_t byte_size, llvm::Value *lhs, llvm::Value *rhs ); static llvm::Value *shr_flags( vm::devirt_t *rtn, std::uint8_t byte_size, llvm::Value *lhs, llvm::Value *rhs, llvm::Value *result ); public: static lifters_t *get_instance( void ) { static lifters_t obj; return &obj; } bool lift( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { if ( vinstr.mnemonic_t == vm::handler::INVALID || lifters.find( vinstr.mnemonic_t ) == lifters.end() ) return false; ( *( lifters[ vinstr.mnemonic_t ] ) )( rtn, vm_code_block, vinstr, ir_builder ); return true; } }; } // namespace vm