diff options
| author | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2019-01-02 16:22:43 +0100 |
|---|---|---|
| committer | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2019-01-11 07:21:49 +0100 |
| commit | a424a91dba4342eaa616fcb2fc5a3659784a4565 (patch) | |
| tree | c07145bd0ce96c0cdeae5ad1a2f80132347a2b0d | |
| parent | ba8308d7762e45db47c01937c8334ffac29ac0ac (diff) | |
| download | miasm-a424a91dba4342eaa616fcb2fc5a3659784a4565.tar.gz miasm-a424a91dba4342eaa616fcb2fc5a3659784a4565.zip | |
MSP430: Explicit flags
| -rw-r--r-- | miasm2/arch/msp430/ira.py | 12 | ||||
| -rw-r--r-- | miasm2/arch/msp430/sem.py | 252 |
2 files changed, 163 insertions, 101 deletions
diff --git a/miasm2/arch/msp430/ira.py b/miasm2/arch/msp430/ira.py index 2a850d82..5b19956e 100644 --- a/miasm2/arch/msp430/ira.py +++ b/miasm2/arch/msp430/ira.py @@ -2,7 +2,8 @@ from miasm2.ir.analysis import ira from miasm2.arch.msp430.sem import ir_msp430 - +from miasm2.ir.ir import AssignBlock +from miasm2.expression.expression import * class ir_a_msp430_base(ir_msp430, ira): @@ -10,6 +11,15 @@ class ir_a_msp430_base(ir_msp430, ira): ir_msp430.__init__(self, loc_db) self.ret_reg = self.arch.regs.R15 + def call_effects(self, addr, instr): + call_assignblk = AssignBlock( + [ + ExprAssign(self.ret_reg, ExprOp('call_func_ret', addr, self.sp, self.arch.regs.R15)), + ExprAssign(self.sp, ExprOp('call_func_stack', addr, self.sp)) + ], + instr + ) + return [call_assignblk], [] class ir_a_msp430(ir_a_msp430_base): diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py index 4736a51c..e0110d24 100644 --- a/miasm2/arch/msp430/sem.py +++ b/miasm2/arch/msp430/sem.py @@ -27,45 +27,67 @@ def reset_sr_res(): return [ExprAssign(res, ExprInt(0, 7))] -def update_flag_zf(a): - return [ExprAssign(zf, ExprCond(a, ExprInt(0, zf.size), ExprInt(1, zf.size)))] +def update_flag_cf_inv_zf(a): + return [ExprAssign(cf, ExprCond(a, ExprInt(1, 1), ExprInt(0, 1)))] -def update_flag_nf(a): - return [ExprAssign(nf, a.msb())] +def update_flag_zf_eq(a, b): + return [ExprAssign(zf, ExprOp("FLAG_EQ_CMP", a, b))] -def update_flag_pf(a): - return [ExprAssign(pf, ExprOp('parity', a & ExprInt(0xFF, a.size)))] +def update_flag_zf(a): + return [ExprAssign(zf, ExprOp("FLAG_EQ", a))] -def update_flag_cf_inv_zf(a): - return [ExprAssign(cf, ExprCond(a, ExprInt(1, cf.size), ExprInt(0, cf.size)))] +def update_flag_nf(arg): + return [ + ExprAssign( + nf, + ExprOp("FLAG_SIGN_SUB", arg, ExprInt(0, arg.size)) + ) + ] -def update_flag_zn_r(a): - e = [] - e += update_flag_zf(a) - e += update_flag_nf(a) - e += reset_sr_res() - return e +def update_flag_add_cf(op1, op2, res): + "Compute cf in @res = @op1 + @op2" + return [ExprAssign(cf, ExprOp("FLAG_ADD_CF", op1, op2))] -def update_flag_sub_cf(a, b, c): - return [ExprAssign(cf, - ((((a ^ b) ^ c) ^ ((a ^ c) & (a ^ b))).msb()) ^ ExprInt(1, 1))] +def update_flag_add_of(op1, op2, res): + "Compute of in @res = @op1 + @op2" + return [ExprAssign(of, ExprOp("FLAG_ADD_OF", op1, op2))] -def update_flag_add_cf(a, b, c): - return [ExprAssign(cf, (((a ^ b) ^ c) ^ ((a ^ c) & (~(a ^ b)))).msb())] +# checked: ok for sbb add because b & c before +cf +def update_flag_sub_cf(op1, op2, res): + "Compote CF in @op1 - @op2" + return [ExprAssign(cf, ExprOp("FLAG_SUB_CF", op1, op2) ^ ExprInt(1, 1))] -def update_flag_add_of(a, b, c): - return [ExprAssign(of, (((a ^ c) & (~(a ^ b)))).msb())] +def update_flag_sub_of(op1, op2, res): + "Compote OF in @res = @op1 - @op2" + return [ExprAssign(of, ExprOp("FLAG_SUB_OF", op1, op2))] -def update_flag_sub_of(a, b, c): - return [ExprAssign(of, (((a ^ c) & (a ^ b))).msb())] +def update_flag_arith_sub_zn(arg1, arg2): + """ + Compute znp flags for (arg1 - arg2) + """ + e = [] + e += update_flag_zf_eq(arg1, arg2) + e += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUB", arg1, arg2))] + return e + + +def update_flag_arith_add_zn(arg1, arg2): + """ + Compute zf and nf flags for (arg1 + arg2) + """ + e = [] + e += update_flag_zf_eq(arg1, -arg2) + e += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUB", arg1, -arg2))] + return e + def mng_autoinc(a, b, size): @@ -103,22 +125,31 @@ def mov_w(ir, instr, a, b): def and_b(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 8) - c = a[:8] & b[:8] - e.append(ExprAssign(b, c.zeroExtend(16))) - e += update_flag_zn_r(c) - e += update_flag_cf_inv_zf(c) + e, arg1, arg2 = mng_autoinc(a, b, 8) + arg1, arg2 = arg1[:8], arg2[:8] + res = arg1 & arg2 + e.append(ExprAssign(b, res.zeroExtend(16))) + + e += [ExprAssign(zf, ExprOp('FLAG_EQ_AND', arg1, arg2))] + e += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUB", res, ExprInt(0, res.size)))] + e += reset_sr_res() + e += update_flag_cf_inv_zf(res) e += [ExprAssign(of, ExprInt(0, 1))] + return e, [] def and_w(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 16) - c = a & b - e.append(ExprAssign(b, c)) - e += update_flag_zn_r(c) - e += update_flag_cf_inv_zf(c) + e, arg1, arg2 = mng_autoinc(a, b, 16) + res = arg1 & arg2 + e.append(ExprAssign(arg2, res)) + + e += [ExprAssign(zf, ExprOp('FLAG_EQ_AND', arg1, arg2))] + e += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUB", res, ExprInt(0, res.size)))] + e += reset_sr_res() + e += update_flag_cf_inv_zf(res) e += [ExprAssign(of, ExprInt(0, 1))] + return e, [] @@ -132,6 +163,12 @@ def bic_b(ir, instr, a, b): def bic_w(ir, instr, a, b): e, a, b = mng_autoinc(a, b, 16) + if b == SR: + # Special case + if a.is_int(1): + # cf + e.append(ExprAssign(cf, ExprInt(0, 1))) + return e, [] c = (a ^ ExprInt(0xffff, 16)) & b e.append(ExprAssign(b, c)) return e, [] @@ -145,30 +182,29 @@ def bis_w(ir, instr, a, b): def bit_w(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 16) - c = a & b - e += update_flag_zn_r(c) - e += update_flag_cf_inv_zf(c) - e.append(ExprAssign(of, ExprInt(0, 1))) - return e, [] + e, arg1, arg2 = mng_autoinc(a, b, 16) + res = arg1 & arg2 -""" -def sub_b(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 8) - c = b - a - e.append(ExprAssign(b, c)) - e += update_flag_zn_r(c) - e += update_flag_sub_cf(b, a, c) - return None, e, [] -""" + e += [ExprAssign(zf, ExprOp('FLAG_EQ_AND', arg1, arg2))] + e += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUB", res, ExprInt(0, res.size)))] + e += reset_sr_res() + e += update_flag_cf_inv_zf(res) + e += [ExprAssign(of, ExprInt(0, 1))] + + return e, [] def sub_w(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 16) - c = b - a - e.append(ExprAssign(b, c)) - e += update_flag_zn_r(c) - e += update_flag_sub_cf(b, a, c) + e, arg1, arg2 = mng_autoinc(a, b, 16) + res = arg2 - arg1 + + e.append(ExprAssign(b, res)) + + e += update_flag_arith_sub_zn(arg2, arg1) + e += update_flag_sub_cf(arg2, arg1, res) + e += update_flag_sub_of(arg2, arg1, res) + e += reset_sr_res() + # micrcorruption # e += update_flag_sub_of(a, b, c) # e += update_flag_sub_of(b, a, c) @@ -176,27 +212,33 @@ def sub_w(ir, instr, a, b): def add_b(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 8) - if isinstance(b, ExprMem): - b = ExprMem(b.arg, 8) + e, arg1, arg2 = mng_autoinc(a, b, 8) + if isinstance(arg2, ExprMem): + arg2 = ExprMem(arg2.arg, 8) else: - b = b[:8] - a = a[:8] - c = b + a - e.append(ExprAssign(b, c)) - e += update_flag_zn_r(c) - e += update_flag_add_cf(a, b, c) - e += update_flag_add_of(a, b, c) + arg2 = arg2[:8] + arg1 = arg1[:8] + res = arg2 + arg1 + e.append(ExprAssign(b, res)) + + e += update_flag_arith_add_zn(arg2, arg1) + e += update_flag_add_cf(arg2, arg1, res) + e += update_flag_add_of(arg2, arg1, res) + e += reset_sr_res() + return e, [] def add_w(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 16) - c = b + a - e.append(ExprAssign(b, c)) - e += update_flag_zn_r(c) - e += update_flag_add_cf(a, b, c) - e += update_flag_add_of(a, b, c) + e, arg1, arg2 = mng_autoinc(a, b, 16) + res = arg2 + arg1 + e.append(ExprAssign(b, res)) + + e += update_flag_arith_add_zn(arg2, arg1) + e += update_flag_add_cf(arg2, arg1, res) + e += update_flag_add_of(arg2, arg1, res) + e += reset_sr_res() + return e, [] @@ -206,7 +248,6 @@ def dadd_w(ir, instr, a, b): c = ExprOp("bcdadd", b, a) # +zeroExtend(cf, 16)) e.append(ExprAssign(b, c)) - # e += update_flag_zn_r(c) # micrcorruption e += update_flag_zf(a) @@ -220,12 +261,16 @@ def dadd_w(ir, instr, a, b): def xor_w(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 16) - c = b ^ a - e.append(ExprAssign(b, c)) - e += update_flag_zn_r(c) + e, arg1, arg2 = mng_autoinc(a, b, 16) + res = arg2 ^ arg1 + e.append(ExprAssign(b, res)) + + e += [ExprAssign(zf, ExprOp('FLAG_EQ_CMP', arg2, arg1))] + e += update_flag_nf(res) + e += reset_sr_res() e += update_flag_cf_inv_zf(c) - e.append(ExprAssign(of, b.msb() & a.msb())) + e.append(ExprAssign(of, arg2.msb() & arg1.msb())) + return e, [] @@ -257,20 +302,27 @@ def swpb(ir, instr, a): def cmp_w(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 16) - c = b - a - e += update_flag_zn_r(c) - e += update_flag_sub_cf(b, a, c) - e += update_flag_sub_of(b, a, c) + e, arg1, arg2 = mng_autoinc(a, b, 16) + res = arg2 - arg1 + + e += update_flag_arith_sub_zn(arg2, arg1) + e += update_flag_sub_cf(arg2, arg1, res) + e += update_flag_sub_of(arg2, arg1, res) + e += reset_sr_res() + return e, [] def cmp_b(ir, instr, a, b): - e, a, b = mng_autoinc(a, b, 8) - c = b[:8] - a[:8] - e += update_flag_zn_r(c) - e += update_flag_sub_cf(b[:8], a[:8], c) - e += update_flag_sub_of(b[:8], a[:8], c) + e, arg1, arg2 = mng_autoinc(a, b, 8) + arg1, arg2 = arg1[:8], arg2[:8] + res = arg2 - arg1 + + e += update_flag_arith_sub_zn(arg2, arg1) + e += update_flag_sub_cf(arg2, arg1, res) + e += update_flag_sub_of(arg2, arg1, res) + e += reset_sr_res() + return e, [] @@ -278,8 +330,8 @@ def jz(ir, instr, a): loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAssign(PC, ExprCond(zf, a, loc_next_expr))) - e.append(ExprAssign(ir.IRDst, ExprCond(zf, a, loc_next_expr))) + e.append(ExprAssign(PC, ExprCond(ExprOp("CC_EQ", zf), a, loc_next_expr))) + e.append(ExprAssign(ir.IRDst, ExprCond(ExprOp("CC_EQ", zf), a, loc_next_expr))) return e, [] @@ -287,8 +339,8 @@ def jnz(ir, instr, a): loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAssign(PC, ExprCond(zf, loc_next_expr, a))) - e.append(ExprAssign(ir.IRDst, ExprCond(zf, loc_next_expr, a))) + e.append(ExprAssign(PC, ExprCond(ExprOp("CC_EQ", zf), loc_next_expr, a))) + e.append(ExprAssign(ir.IRDst, ExprCond(ExprOp("CC_EQ", zf), loc_next_expr, a))) return e, [] @@ -296,8 +348,8 @@ def jl(ir, instr, a): loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAssign(PC, ExprCond(nf ^ of, a, loc_next_expr))) - e.append(ExprAssign(ir.IRDst, ExprCond(nf ^ of, a, loc_next_expr))) + e.append(ExprAssign(PC, ExprCond(ExprOp("CC_S<", nf, of), a, loc_next_expr))) + e.append(ExprAssign(ir.IRDst, ExprCond(ExprOp("CC_S<", nf, of), a, loc_next_expr))) return e, [] @@ -305,8 +357,8 @@ def jc(ir, instr, a): loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAssign(PC, ExprCond(cf, a, loc_next_expr))) - e.append(ExprAssign(ir.IRDst, ExprCond(cf, a, loc_next_expr))) + e.append(ExprAssign(PC, ExprCond(ExprOp("CC_U>=", cf ^ ExprInt(1, 1)), a, loc_next_expr))) + e.append(ExprAssign(ir.IRDst, ExprCond(ExprOp("CC_U>=", cf ^ ExprInt(1, 1)), a, loc_next_expr))) return e, [] @@ -314,8 +366,8 @@ def jnc(ir, instr, a): loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAssign(PC, ExprCond(cf, loc_next_expr, a))) - e.append(ExprAssign(ir.IRDst, ExprCond(cf, loc_next_expr, a))) + e.append(ExprAssign(PC, ExprCond(ExprOp("CC_U>=", cf ^ ExprInt(1, 1)), loc_next_expr, a))) + e.append(ExprAssign(ir.IRDst, ExprCond(ExprOp("CC_U>=", cf ^ ExprInt(1, 1)), loc_next_expr, a))) return e, [] @@ -323,8 +375,8 @@ def jge(ir, instr, a): loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 16) e = [] - e.append(ExprAssign(PC, ExprCond(nf ^ of, loc_next_expr, a))) - e.append(ExprAssign(ir.IRDst, ExprCond(nf ^ of, loc_next_expr, a))) + e.append(ExprAssign(PC, ExprCond(ExprOp("CC_S>=", nf, of), a, loc_next_expr))) + e.append(ExprAssign(ir.IRDst, ExprCond(ExprOp("CC_S>=", nf, of), a, loc_next_expr))) return e, [] @@ -340,7 +392,6 @@ def rrc_w(ir, instr, a): c = ExprCompose(a[1:16], cf) e.append(ExprAssign(a, c)) e.append(ExprAssign(cf, a[:1])) - # e += update_flag_zn_r(c) # micrcorruption e += update_flag_zf(a) @@ -357,7 +408,6 @@ def rra_w(ir, instr, a): e.append(ExprAssign(a, c)) # TODO: error in disasm microcorruption? # e.append(ExprAssign(cf, a[:1])) - # e += update_flag_zn_r(c) # micrcorruption e += update_flag_zf(a) @@ -373,7 +423,9 @@ def sxt(ir, instr, a): c = a[:8].signExtend(16) e.append(ExprAssign(a, c)) - e += update_flag_zn_r(c) + e += update_flag_zf(a) + e += update_flag_nf(a) + e += reset_sr_res() e += update_flag_cf_inv_zf(c) e.append(ExprAssign(of, ExprInt(0, 1))) |