static InstTransResult translate_CALL32m( NativeModulePtr natM, BasicBlock *& block, InstPtr ip, MCInst &inst) { InstTransResult ret; // is this an external call? if( ip->has_ext_call_target() ) { std::string s = ip->get_ext_call_target()->getSymbolName(); ret = doCallPCExtern(block, s); // not external call, but some weird way of calling local function? } else if( ip->has_call_tgt() ) { ret = doCallPC(ip, block, ip->get_call_tgt(0)); } // is this referencing global data? else if( ip->is_data_offset() ) { doCallM<32>(block, ip, STD_GLOBAL_OP(0)); ret = ContinueBlock; // is this a simple address computation? } else { doCallM<32>(block, ip, ADDR(0)); ret = ContinueBlock; } return ret; }
static InstTransResult translate_MOVoa (NativeModulePtr natM, BasicBlock *& block, InstPtr ip, MCInst &inst) { InstTransResult ret; Function *F = block->getParent(); // loading functions only available if its a 32-bit offset if( ip->has_external_ref() && width == 32) { Value *addrInt = getValueForExternal<32>(F->getParent(), ip, block); TASSERT(addrInt != 0, "Could not get external data reference"); R_WRITE<width>(block, X86::EAX, addrInt); return ContinueBlock; //ret = doRMMov<32>(ip, block, addrInt, MCOperand::CreateReg(X86::EAX)) ; } else if( ip->has_call_tgt() && width == 32 ) { Value *callback_fn = makeCallbackForLocalFunction( block->getParent()->getParent(), ip->get_call_tgt(0) ); Value *addrInt = new PtrToIntInst( callback_fn, llvm::Type::getInt32Ty(block->getContext()), "", block); ret = doRMMov<32>(ip, block, addrInt, MCOperand::CreateReg(X86::EAX)) ; } else if( ip->is_data_offset() ) { ret = doRMMov<width>(ip, block, GLOBAL_DATA_OFFSET(block, natM, ip), MCOperand::CreateReg(X86::EAX) ); } else { Value *addrv = CONST_V<width>(block, OP(0).getImm()); ret = doRMMov<width>(ip, block, addrv, MCOperand::CreateReg(X86::EAX)) ; } return ret ; }
static InstTransResult translate_LEA64_32r(NativeModulePtr natM, BasicBlock *&block, InstPtr ip, MCInst &inst) { InstTransResult ret; Function *F = block->getParent(); if( ip->has_call_tgt() ) { Value *callback_fn = archMakeCallbackForLocalFunction( block->getParent()->getParent(), ip->get_call_tgt(0)); Value *addrInt = new PtrToIntInst( callback_fn, llvm::Type::getInt32Ty(block->getContext()), "", block); ret = doLeaV<32>(block, OP(0), addrInt); } else if( ip->is_data_offset() ) { ret = doLea<32>(ip, block, STD_GLOBAL_OP(1), OP(0)); } else { ret = doLea<32>(ip, block, ADDR(1), OP(0)); } return ret; }
static InstTransResult translate_CALLpcrel32(NativeModulePtr natM, BasicBlock *& block, InstPtr ip, MCInst &inst) { InstTransResult ret; if( ip->has_ext_call_target() ) { std::string s = ip->get_ext_call_target()->getSymbolName(); ret = doCallPCExtern(block, s); } else if (ip->has_call_tgt() ) { int64_t off = (int64_t) ip->get_call_tgt(0); ret = doCallPC(ip, block, off); } else { int64_t off = (int64_t) OP(0).getImm(); ret = doCallPC(ip, block, ip->get_loc()+ip->get_len()+off); } return ret; }
static InstTransResult translate_MOV32ri(NativeModulePtr natM, BasicBlock *& block, InstPtr ip, MCInst &inst) { InstTransResult ret; Function *F = block->getParent(); if( ip->has_call_tgt() ) { Value *callback_fn = makeCallbackForLocalFunction( block->getParent()->getParent(), ip->get_call_tgt(0) ); Value *addrInt = new PtrToIntInst( callback_fn, llvm::Type::getInt32Ty(block->getContext()), "", block); ret = doRIMovV<32>(ip, block, addrInt, OP(0) ); } else if( ip->is_data_offset() ) { ret = doRIMovV<32>(ip, block, GLOBAL_DATA_OFFSET(block, natM, ip), OP(0) ); } else { ret = doRIMov<32>(ip, block, OP(1), OP(0)) ; } return ret ; }
//GENERIC_TRANSLATION_32MI(MOV32mi, // doMIMov<32>(ip, block, ADDR(0), OP(5)), // doMIMov<32>(ip, block, STD_GLOBAL_OP(0), OP(5)), // doMIMovV<32>(ip, block, ADDR_NOREF(0), GLOBAL_DATA_OFFSET(block, natM, ip)) // ) // static InstTransResult translate_MOV32mi(NativeModulePtr natM, BasicBlock *&block, InstPtr ip, MCInst &inst) { InstTransResult ret; Function *F = block->getParent(); if( ip->has_call_tgt() ) { Value *callback_fn = makeCallbackForLocalFunction( block->getParent()->getParent(), ip->get_call_tgt(0) ); Value *addrInt = new PtrToIntInst( callback_fn, llvm::Type::getInt32Ty(block->getContext()), "", block); ret = doMIMovV<32>(ip, block, ADDR(0), addrInt); } else if( ip->is_data_offset() ) { if( ip->get_reloc_offset() < OP(5).getOffset() ) { doMIMov<32>(ip, block, STD_GLOBAL_OP(0), OP(5)); } else { doMIMovV<32>(ip, block, ADDR_NOREF(0), GLOBAL_DATA_OFFSET(block, natM, ip)); } ret = ContinueBlock; } else { ret = doMIMov<32>(ip, block, ADDR(0), OP(5)); } return ret; }