static InstTransResult translate_JMP32r(NativeModulePtr natM, BasicBlock *&block, InstPtr ip, MCInst &inst) { const MCOperand &tgtOp = inst.getOperand(0); TASSERT(inst.getNumOperands() == 1, ""); TASSERT(tgtOp.isReg(), ""); //read the register Value *fromReg = R_READ<32>(block, tgtOp.getReg()); if (ip->has_jump_table()) { // this is a jump table that got converted // into a table in the data section llvm::dbgs() << __FUNCTION__ << ": jump table via register: " << to_string<VA>(ip->get_loc(), std::hex) << "\n"; BasicBlock *defaultb = nullptr; doJumpTableViaSwitchReg(block, ip, fromReg, defaultb); TASSERT(defaultb != nullptr, "Default block has to exit"); // fallback to doing do_call_value doCallV(defaultb, ip, fromReg); return doRet(defaultb); } else { // translate the JMP32r as a call/ret llvm::dbgs() << __FUNCTION__ << ": regular jump via register: " << to_string<VA>(ip->get_loc(), std::hex) << "\n"; doCallV(block, ip, fromReg); return doRet(block); } }
static InstTransResult translate_JMP32m(NativeModulePtr natM, BasicBlock *& block, InstPtr ip, MCInst &inst) { InstTransResult ret; // translate JMP mem32 API calls // as a call <api>, ret; if( ip->has_ext_call_target() ) { std::string s = ip->get_ext_call_target()->getSymbolName(); ret = doCallPCExtern(block, s, true); if (ret != EndBlock) { return doRet(block); } else { // noreturn api calls don't need to fix stack return ret; } } else if (ip->has_jump_table() && ip->is_data_offset()) { // this is a jump table that got converted // into a table in the data section doJumpTableViaData(natM, block, ip, inst); // return a "ret", since the jmp is simulated // as a call/ret pair return doRet(block); } else if(ip->has_jump_table()) { // this is a conformant jump table // emit an llvm switch doJumpTableViaSwitch(natM, block, ip, inst); return EndBlock; } else { std::string msg("NIY: JMP32m only supported for external API calls and jump tables: "); msg += to_string<VA>(ip->get_loc(), std::hex); throw TErr(__LINE__, __FILE__, msg.c_str()); return EndBlock; } }