core/x86/interp.c
/* Walk up from the bb->instr and verify that the preceding instructions
 * match the pattern that we expect to precede a sysenter. */
Walk up from the bb->instr and verify that the preceding instructions
match the pattern that we expect to precede a sysenter.
Walk up from the bb - > instr and verify that the preceding instructions match the pattern that we expect to precede a sysenter .
static instr_t *
bb_verify_sysenter_pattern(dcontext_t *dcontext, build_bb_t *bb)
{
    instr_t *instr = instr_get_prev_expanded(dcontext, bb->ilist, bb->instr);
    if (!(instr != NULL && instr_get_opcode(instr) == OP_mov_ld &&
          instr_num_srcs(instr) == 1 && instr_num_dsts(instr) == 1 &&
          opnd_is_reg(instr_get_dst(instr, 0)) &&
          opnd_get_reg(instr_get_dst(instr, 0)) == REG_XDX &&
          opnd_is_reg(instr_get_src(instr, 0)) &&
          opnd_get_reg(instr_get_src(instr, 0)) == REG_XSP)) {
        BBPRINT(bb, 3, "bb_verify_sysenter_pattern -- mov didn't match\n");
        return NULL;
    }
    instr = instr_get_prev_expanded(dcontext, bb->ilist, instr);
    if (!(instr != NULL && TEST(INSTR_IND_CALL_DIRECT, instr->flags) &&
          instr_is_call_indirect(instr) &&
          opnd_is_reg(instr_get_src(instr, 1)) &&
          opnd_get_reg(instr_get_src(instr, 1)) == REG_XSP &&
          ((opnd_is_near_base_disp(instr_get_src(instr, 0)) &&
            opnd_get_base(instr_get_src(instr, 0)) == REG_XDX &&
            opnd_get_disp(instr_get_src(instr, 0)) == 0) ||
           (opnd_is_reg(instr_get_src(instr, 0)) &&
            opnd_get_reg(instr_get_src(instr, 0)) == REG_XDX)))) {
        BBPRINT(bb, 3, "bb_verify_sysenter_pattern -- call didn't match\n");
        return NULL;
    }
    return instr;
}
static instr_t * bb_verify_sysenter_pattern ( dcontext_t * dcontext , build_bb_t * bb ) { instr_t * instr = instr_get_prev_expanded ( dcontext , bb -> ilist , bb -> instr ) ; if ( ! ( instr != NULL && instr_get_opcode ( instr ) == OP_mov_ld && instr_num_srcs ( instr ) == 1 && instr_num_dsts ( instr ) == 1 && opnd_is_reg ( instr_get_dst ( instr , 0 ) ) && opnd_get_reg ( instr_get_dst ( instr , 0 ) ) == REG_XDX && opnd_is_reg ( instr_get_src ( instr , 0 ) ) && opnd_get_reg ( instr_get_src ( instr , 0 ) ) == REG_XSP ) ) { BBPRINT ( bb , 3 , " \n " ) ; return NULL ; } instr = instr_get_prev_expanded ( dcontext , bb -> ilist , instr ) ; if ( ! ( instr != NULL && TEST ( INSTR_IND_CALL_DIRECT , instr -> flags ) && instr_is_call_indirect ( instr ) && opnd_is_reg ( instr_get_src ( instr , 1 ) ) && opnd_get_reg ( instr_get_src ( instr , 1 ) ) == REG_XSP && ( ( opnd_is_near_base_disp ( instr_get_src ( instr , 0 ) ) && opnd_get_base ( instr_get_src ( instr , 0 ) ) == REG_XDX && opnd_get_disp ( instr_get_src ( instr , 0 ) ) == 0 ) || ( opnd_is_reg ( instr_get_src ( instr , 0 ) ) && opnd_get_reg ( instr_get_src ( instr , 0 ) ) == REG_XDX ) ) ) ) { BBPRINT ( bb , 3 , " \n " ) ; return NULL ; } return instr ; }
Walk up from the bb->instr and verify that the preceding instructions
 match the pattern that we expect to precede a sysenter.
Walk up from the bb - > instr and verify that the preceding instructions match the pattern that we expect to precede a sysenter .
/* Walk back up 2 instructions and verify that there's a
     * "call (%xdx); mov %xsp -> %xdx" or "call %xdx; mov %xsp -> %xdx"
     * just prior to the sysenter.
     * We use "xsp" and "xdx" to be ready for x64 sysenter though we don't
     * expect to see it.
     */ /* FIXME Relax the pattern matching on the "mov; call" pair so that small
     * changes in the register dataflow and call construct are tolerated. */ /* Did we find a "mov %xsp -> %xdx"? */ /* Did we find a "call (%xdx) or "call %xdx" that's already marked
     * for ind->direct call conversion? */ /* The 2nd src operand should always be %xsp. */ /* Match 'call (%xdx)' for post-SP2. */ /* Match 'call %xdx' for pre-SP2. */