core/x86/instr.c
/* Given a cbr, change the opcode (and potentially branch hint
 * prefixes) to that of the inverted branch condition.
 */
Given a cbr, change the opcode (and potentially branch hint
prefixes) to that of the inverted branch condition.
Given a cbr change the opcode ( and potentially branch hint prefixes ) to that of the inverted branch condition .
void
instr_invert_cbr(instr_t *instr)
{
    int opc = instr_get_opcode(instr);
    CLIENT_ASSERT(instr_is_cbr(instr), "instr_invert_cbr: instr not a cbr");
    if (instr_is_cti_short_rewrite(instr, NULL)) {
        if (instr_get_raw_byte(instr, 1) == 2) {
            CLIENT_ASSERT(instr_get_raw_byte(instr, 3) == 5,
                          "instr_invert_cbr: cti_short_rewrite is corrupted");
            instr_set_raw_byte(instr, 1, (byte)7); 
            instr_set_raw_byte(instr, 3, (byte)0); 
        } else {
            CLIENT_ASSERT(instr_get_raw_byte(instr, 1) == 7 &&
                          instr_get_raw_byte(instr, 3) == 0,
                          "instr_invert_cbr: cti_short_rewrite is corrupted");
            instr_set_raw_byte(instr, 1, (byte)2);
            instr_set_raw_byte(instr, 3, (byte)5);
        }
    } else if ((opc >= OP_jo && opc <= OP_jnle) ||
               (opc >= OP_jo_short && opc <= OP_jnle_short)) {
        switch (opc) {
        case OP_jb:   opc = OP_jnb; break;
        case OP_jnb:  opc = OP_jb; break;
        case OP_jbe:  opc = OP_jnbe; break;
        case OP_jnbe: opc = OP_jbe; break;
        case OP_jl:   opc = OP_jnl; break;
        case OP_jnl:  opc = OP_jl; break;
        case OP_jle:  opc = OP_jnle; break;
        case OP_jnle: opc = OP_jle; break;
        case OP_jo:   opc = OP_jno; break;
        case OP_jno:  opc = OP_jo; break;
        case OP_jp:   opc = OP_jnp; break;
        case OP_jnp:  opc = OP_jp; break;
        case OP_js:   opc = OP_jns; break;
        case OP_jns:  opc = OP_js; break;
        case OP_jz:   opc = OP_jnz; break;
        case OP_jnz:  opc = OP_jz; break;
        case OP_jb_short:   opc = OP_jnb_short; break;
        case OP_jnb_short:  opc = OP_jb_short; break;
        case OP_jbe_short:  opc = OP_jnbe_short; break;
        case OP_jnbe_short: opc = OP_jbe_short; break;
        case OP_jl_short:   opc = OP_jnl_short; break;
        case OP_jnl_short:  opc = OP_jl_short; break;
        case OP_jle_short:  opc = OP_jnle_short; break;
        case OP_jnle_short: opc = OP_jle_short; break;
        case OP_jo_short:   opc = OP_jno_short; break;
        case OP_jno_short:  opc = OP_jo_short; break;
        case OP_jp_short:   opc = OP_jnp_short; break;
        case OP_jnp_short:  opc = OP_jp_short; break;
        case OP_js_short:   opc = OP_jns_short; break;
        case OP_jns_short:  opc = OP_js_short; break;
        case OP_jz_short:   opc = OP_jnz_short; break;
        case OP_jnz_short:  opc = OP_jz_short; break;
        default: CLIENT_ASSERT(false, "instr_invert_cbr: unknown opcode"); break;
        }
        instr_set_opcode(instr, opc);
        if (TEST(PREFIX_JCC_TAKEN, instr_get_prefixes(instr))) {
            instr->prefixes &= ~PREFIX_JCC_TAKEN;
            instr->prefixes |= PREFIX_JCC_NOT_TAKEN;
        } else if (TEST(PREFIX_JCC_NOT_TAKEN, instr_get_prefixes(instr))) {
            instr->prefixes &= ~PREFIX_JCC_NOT_TAKEN;
            instr->prefixes |= PREFIX_JCC_TAKEN;
        }
    } else
        CLIENT_ASSERT(false, "instr_invert_cbr: unknown opcode");
}
void instr_invert_cbr ( instr_t * instr ) { int opc = instr_get_opcode ( instr ) ; CLIENT_ASSERT ( instr_is_cbr ( instr ) , " " ) ; if ( instr_is_cti_short_rewrite ( instr , NULL ) ) { if ( instr_get_raw_byte ( instr , 1 ) == 2 ) { CLIENT_ASSERT ( instr_get_raw_byte ( instr , 3 ) == 5 , " " ) ; instr_set_raw_byte ( instr , 1 , ( byte ) 7 ) ; instr_set_raw_byte ( instr , 3 , ( byte ) 0 ) ; } else { CLIENT_ASSERT ( instr_get_raw_byte ( instr , 1 ) == 7 && instr_get_raw_byte ( instr , 3 ) == 0 , " " ) ; instr_set_raw_byte ( instr , 1 , ( byte ) 2 ) ; instr_set_raw_byte ( instr , 3 , ( byte ) 5 ) ; } } else if ( ( opc >= OP_jo && opc <= OP_jnle ) || ( opc >= OP_jo_short && opc <= OP_jnle_short ) ) { switch ( opc ) { case OP_jb : opc = OP_jnb ; break ; case OP_jnb : opc = OP_jb ; break ; case OP_jbe : opc = OP_jnbe ; break ; case OP_jnbe : opc = OP_jbe ; break ; case OP_jl : opc = OP_jnl ; break ; case OP_jnl : opc = OP_jl ; break ; case OP_jle : opc = OP_jnle ; break ; case OP_jnle : opc = OP_jle ; break ; case OP_jo : opc = OP_jno ; break ; case OP_jno : opc = OP_jo ; break ; case OP_jp : opc = OP_jnp ; break ; case OP_jnp : opc = OP_jp ; break ; case OP_js : opc = OP_jns ; break ; case OP_jns : opc = OP_js ; break ; case OP_jz : opc = OP_jnz ; break ; case OP_jnz : opc = OP_jz ; break ; case OP_jb_short : opc = OP_jnb_short ; break ; case OP_jnb_short : opc = OP_jb_short ; break ; case OP_jbe_short : opc = OP_jnbe_short ; break ; case OP_jnbe_short : opc = OP_jbe_short ; break ; case OP_jl_short : opc = OP_jnl_short ; break ; case OP_jnl_short : opc = OP_jl_short ; break ; case OP_jle_short : opc = OP_jnle_short ; break ; case OP_jnle_short : opc = OP_jle_short ; break ; case OP_jo_short : opc = OP_jno_short ; break ; case OP_jno_short : opc = OP_jo_short ; break ; case OP_jp_short : opc = OP_jnp_short ; break ; case OP_jnp_short : opc = OP_jp_short ; break ; case OP_js_short : opc = OP_jns_short ; break ; case OP_jns_short : opc = OP_js_short ; break ; case OP_jz_short : opc = OP_jnz_short ; break ; case OP_jnz_short : opc = OP_jz_short ; break ; default : CLIENT_ASSERT ( false , " " ) ; break ; } instr_set_opcode ( instr , opc ) ; if ( TEST ( PREFIX_JCC_TAKEN , instr_get_prefixes ( instr ) ) ) { instr -> prefixes &= ~ PREFIX_JCC_TAKEN ; instr -> prefixes |= PREFIX_JCC_NOT_TAKEN ; } else if ( TEST ( PREFIX_JCC_NOT_TAKEN , instr_get_prefixes ( instr ) ) ) { instr -> prefixes &= ~ PREFIX_JCC_NOT_TAKEN ; instr -> prefixes |= PREFIX_JCC_TAKEN ; } } else CLIENT_ASSERT ( false , " " ) ; }
Given a cbr, change the opcode (and potentially branch hint
 prefixes) to that of the inverted branch condition.
Given a cbr change the opcode ( and potentially branch hint prefixes ) to that of the inverted branch condition .
/* these all look like this:
                     jcxz cx_zero
                     jmp-short cx_nonzero
            cx_zero: jmp foo
            cx_nonzero:
         */ /* swap targets of the short jumps: */ /* target cx_nonzero */ /* target next instr, cx_zero */ /* with inverted logic we don't need jmp-short but we keep it in
             * case we get inverted again */ /* re-invert */ /* reverse any branch hint */