about summary refs log tree commit diff stats
path: root/miasm2/arch/mips32/sem.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/arch/mips32/sem.py')
-rw-r--r--miasm2/arch/mips32/sem.py471
1 files changed, 471 insertions, 0 deletions
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
new file mode 100644
index 00000000..1913a117
--- /dev/null
+++ b/miasm2/arch/mips32/sem.py
@@ -0,0 +1,471 @@
+from miasm2.expression.expression import *
+from miasm2.ir.ir import ir, irbloc
+from miasm2.arch.mips32.arch import mn_mips32l, mn_mips32b
+from miasm2.arch.mips32.regs import *
+
+def addiu(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b+c))
+    return None, e, []
+
+def lw(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(a, b))
+    return None, e, []
+
+def sw(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(b, a))
+    return None, e, []
+
+def jalr(ir, instr, a, b):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    e.append(ExprAff(PC, a))
+    e.append(ExprAff(b, n))
+    return a, e, []
+
+def bal(ir, instr, a):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    e.append(ExprAff(PC, a))
+    e.append(ExprAff(RA, n))
+    return a, e, []
+
+def l_b(ir, instr, a):
+    e = []
+    e.append(ExprAff(PC, a))
+    return a, e, []
+
+def lbu(ir, instr, a, b):
+    e = []
+    b = ExprMem(b.arg, 8)
+    e.append(ExprAff(a, b.zeroExtend(32)))
+    return None, e, []
+
+def lhu(ir, instr, a, b):
+    e = []
+    b = ExprMem(b.arg, 16)
+    e.append(ExprAff(a, b.zeroExtend(32)))
+    return None, e, []
+
+def beq(ir, instr, a, b, c):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    dst_o = ExprCond(a-b, c, n)
+    e = [ExprAff(PC, dst_o)]
+    return dst_o, e, []
+
+def bgez(ir, instr, a, b):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    dst_o = ExprCond(a.msb(), n, b)
+    e = [ExprAff(PC, dst_o)]
+    return dst_o, e, []
+
+def bne(ir, instr, a, b, c):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    dst_o = ExprCond(a-b, n, c)
+    e = [ExprAff(PC, dst_o)]
+    return dst_o, e, []
+
+def lui(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(a, ExprCompose([(ExprInt16(0), 0, 16),
+                                     (b[:16], 16, 32)])))
+    return None, e, []
+
+def nop(ir, instr):
+    return None, [], []
+
+def j(ir, instr, a):
+    e = []
+    e.append(ExprAff(PC, a))
+    return a, e, []
+
+def l_or(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b|c))
+    return None, e, []
+
+def nor(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, (b|c)^ExprInt32(0xFFFFFFFF)))
+    return None, e, []
+
+def l_and(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b&c))
+    return None, e, []
+
+def ext(ir, instr, a, b, c, d):
+    e = []
+    pos = int(c.arg)
+    size = int(d.arg)
+    e.append(ExprAff(a, b[pos:pos+size].zeroExtend(32)))
+    return None, e, []
+
+def mul(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, ExprOp('imul', b, c)))
+    return None, e, []
+
+def sltu(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, (b-c).msb().zeroExtend(32)))
+    return None, e, []
+
+def slt(ir, instr, a, b, c):
+    e = []
+    #nf - of
+    # TODO CHECK
+    f = (b-c).msb() ^ (((a ^ c) & (~(a ^ b)))).msb()
+    e.append(ExprAff(a, f.zeroExtend(32)))
+    return None, e, []
+
+def l_sub(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b-c))
+    return None, e, []
+
+def sb(ir, instr, a, b):
+    e = []
+    b = ExprMem(b.arg, 8)
+    e.append(ExprAff(b, a[:8]))
+    return None, e, []
+
+def sh(ir, instr, a, b):
+    e = []
+    b = ExprMem(b.arg, 16)
+    e.append(ExprAff(b, a[:16]))
+    return None, e, []
+
+def movn(ir, instr, a, b, c):
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do = []
+    e_do.append(ExprAff(a, b))
+
+    return ExprCond(c, lbl_do, lbl_skip), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+
+def srl(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b >> c))
+    return None, e, []
+
+def sra(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, ExprOp('a>>', b, c)))
+    return None, e, []
+
+def srav(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, ExprOp('a>>', b, c&ExprInt32(0x1F))))
+    return None, e, []
+
+def sll(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b<<c))
+    return None, e, []
+
+def srlv(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b >> (c & ExprInt32(0x1F))))
+    return None, e, []
+
+def sllv(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b << (c & ExprInt32(0x1F))))
+    return None, e, []
+
+def l_xor(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b^c))
+    return None, e, []
+
+def seb(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(a, b[:8].signExtend(32)))
+    return None, e, []
+
+def bltz(ir, instr, a, b):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    dst_o = ExprCond(a.msb(), b, n)
+    e = [ExprAff(PC, dst_o)]
+    return dst_o, e, []
+
+def blez(ir, instr, a, b):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    cond = ExprCond(a, ExprInt1(1), ExprInt1(0)) | a.msb()
+    dst_o = ExprCond(cond, b, n)
+    e = [ExprAff(PC, dst_o)]
+    return dst_o, e, []
+
+def bgtz(ir, instr, a, b):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    cond = ExprCond(a, ExprInt1(1), ExprInt1(0)) | a.msb()
+    dst_o = ExprCond(cond, n, b)
+    e = [ExprAff(PC, dst_o)]
+    return dst_o, e, []
+
+def wsbh(ir, instr, a, b):
+    e = [ExprAff(a, ExprCompose([(b[8:16],  0, 8)   ,
+                                 (b[0:8]  , 8, 16)  ,
+                                 (b[24:32], 16, 24),
+                                 (b[16:24], 24, 32)]))]
+    return None, e, []
+
+def rotr(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, ExprOp('>>>', b, c)))
+    return None, e, []
+
+def add_d(ir, instr, a, b, c):
+    # XXX TODO check
+    e = []
+    e.append(ExprAff(a, ExprOp('fadd', b, c)))
+    return None, e, []
+
+def sub_d(ir, instr, a, b, c):
+    # XXX TODO check
+    e = []
+    e.append(ExprAff(a, ExprOp('fsub', b, c)))
+    return None, e, []
+
+def div_d(ir, instr, a, b, c):
+    # XXX TODO check
+    e = []
+    e.append(ExprAff(a, ExprOp('fdiv', b, c)))
+    return None, e, []
+
+def mul_d(ir, instr, a, b, c):
+    # XXX TODO check
+    e = []
+    e.append(ExprAff(a, ExprOp('fmul', b, c)))
+    return None, e, []
+
+def mov_d(ir, instr, a, b):
+    # XXX TODO check
+    e = []
+    e.append(ExprAff(a, b))
+    return None, e, []
+
+def mfc0(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(a, b))
+    return None, e, []
+
+def mfc1(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(a, b))
+    return None, e, []
+
+def mtc0(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(b, a))
+    return None, e, []
+
+def mtc1(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(b, a))
+    return None, e, []
+
+def tlbwi(ir, instr):
+    # TODO XXX
+    e = []
+    return None, e, []
+
+def tlbp(ir, instr):
+    # TODO XXX
+    e = []
+    return None, e, []
+
+def ins(ir, instr, a, b, c, d):
+    e = []
+    pos = int(c.arg)
+    l = int(d.arg)
+
+    my_slices = []
+    if pos != 0:
+        my_slices.append((a[:pos], 0, pos))
+    if l != 0:
+        my_slices.append((b[:l], pos, pos+l))
+    if pos + l != 32:
+        my_slices.append((a[pos+l:], pos+l, 32))
+    r = ExprCompose(my_slices)
+    e.append(ExprAff(a, r))
+    return None, e, []
+
+
+def lwc1(ir, instr, a, b):
+    e = []
+    src = ExprOp('mem_%.2d_to_single' % b.size, b)
+    e.append(ExprAff(a, src))
+    return None, e, []
+
+def swc1(ir, instr, a, b):
+    e = []
+    src = ExprOp('single_to_mem_%.2d' % a.size, a)
+    e.append(ExprAff(b, src))
+    return None, e, []
+
+def c_lt_d(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, ExprOp('fcomp_lt', b, c)))
+    return None, e, []
+
+def c_eq_d(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, ExprOp('fcomp_eq', b, c)))
+    return None, e, []
+
+def c_le_d(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, ExprOp('fcomp_le', b, c)))
+    return None, e, []
+
+def bc1t(ir, instr, a, b):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    dst_o = ExprCond(a, b, n)
+    e = [ExprAff(PC, dst_o)]
+    return dst_o, e, []
+
+def bc1f(ir, instr, a, b):
+    e = []
+    n = ExprId(ir.get_next_break_label(instr))
+    dst_o = ExprCond(a, n, b)
+    e = [ExprAff(PC, dst_o)]
+    return dst_o, e, []
+
+def cvt_d_w(ir, instr, a, b):
+    e = []
+    # TODO XXX
+    e.append(ExprAff(a, ExprOp('flt_d_w', b)))
+    return None, e, []
+
+def mult(ir, instr, a, b):
+    e = []
+    size = a.size
+    r = a.signExtend(size * 2) * b.signExtend(size * 2)
+
+    e.append(ExprAff(R_LO, r[:32]))
+    e.append(ExprAff(R_HI, r[32:]))
+    return None, e, []
+
+def mfhi(ir, instr, a):
+    e = []
+    e.append(ExprAff(a, R_HI))
+    return None, e, []
+
+def mflo(ir, instr, a):
+    e = []
+    e.append(ExprAff(a, R_LO))
+    return None, e, []
+
+
+mnemo_func = {
+    "addiu": addiu,
+    "addu": addiu,
+    "lw" : lw,
+    "sw" : sw,
+    "sh" : sh,
+    "sb" : sb,
+    "jalr" : jalr,
+    "bal" : bal,
+    "b" : l_b,
+    "lbu" : lbu,
+    "lhu" : lhu,
+    "beq" : beq,
+    "bgez" : bgez,
+    "bltz" : bltz,
+    "bgtz" : bgtz,
+    "bne" : bne,
+    "lui" : lui,
+    "nop" : nop,
+    "j" : j,
+    "jr" : j,
+    "ori" : l_or,
+    "or" : l_or,
+    "nor" : nor,
+    "and" : l_and,
+    "andi" : l_and,
+    "ext" : ext,
+    "mul" : mul,
+    "sltu" : sltu,
+    "slt" : slt,
+    "slti" : slt,
+    "sltiu" : sltu,
+    "subu" : l_sub,
+    "movn" : movn,
+    "srl" : srl,
+    "sra" : sra,
+    "srav" : srav,
+    "sll" : sll,
+    "srlv" : srlv,
+    "sllv" : sllv,
+    "xori" : l_xor,
+    "xor" : l_xor,
+    "seb" : seb,
+    "bltz" : bltz,
+    "blez" : blez,
+    "wsbh" : wsbh,
+    "rotr" : rotr,
+    "mfc0" : mfc0,
+    "mfc1" : mfc1,
+    "mtc0" : mtc0,
+    "mtc1" : mtc1,
+    "tlbwi" : tlbwi,
+    "tlbp" : tlbp,
+    "ins" : ins,
+
+    "add.d" : add_d,
+    "sub.d" : sub_d,
+    "div.d" : div_d,
+    "mul.d" : mul_d,
+    "mov.d" : mov_d,
+    "lwc1" : lwc1,
+    "swc1" : swc1,
+    "c.lt.d" : c_lt_d,
+    "c.eq.d" : c_eq_d,
+    "c.le.d" : c_le_d,
+    "bc1t" : bc1t,
+    "bc1f" : bc1f,
+    "cvt.d.w":cvt_d_w,
+    "mult" : mult,
+
+    "mfhi" : mfhi,
+    "mflo" : mflo,
+
+    }
+
+def get_mnemo_expr(ir, instr, *args):
+    dst, instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args)
+    return dst, instr, extra_ir
+
+class ir_mips32(ir):
+
+    def __init__(self, symbol_pool=None):
+        ir.__init__(self, mn_mips32l, None, symbol_pool)
+        self.pc = mn_mips32l.getpc()
+        self.sp = mn_mips32l.getsp()
+
+    def get_ir(self, instr):
+        args = instr.args
+        dst, instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
+
+        for i, x in enumerate(instr_ir):
+            x = ExprAff(x.dst, x.src.replace_expr(
+                {self.pc: ExprInt32(instr.offset + 4)}))
+            instr_ir[i] = x
+        for b in extra_ir:
+            for irs in b.irs:
+                for i, x in enumerate(irs):
+                    x = ExprAff(x.dst, x.src.replace_expr(
+                        {self.pc: ExprInt32(instr.offset + 4)}))
+                    irs[i] = x
+        return dst, instr_ir, extra_ir