예제 #1
0
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);
    }
}
예제 #2
0
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;
    }

}