about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2019-01-02 16:22:43 +0100
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2019-01-11 07:21:49 +0100
commita424a91dba4342eaa616fcb2fc5a3659784a4565 (patch)
treec07145bd0ce96c0cdeae5ad1a2f80132347a2b0d
parentba8308d7762e45db47c01937c8334ffac29ac0ac (diff)
downloadmiasm-a424a91dba4342eaa616fcb2fc5a3659784a4565.tar.gz
miasm-a424a91dba4342eaa616fcb2fc5a3659784a4565.zip
MSP430: Explicit flags
-rw-r--r--miasm2/arch/msp430/ira.py12
-rw-r--r--miasm2/arch/msp430/sem.py252
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)))