about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/mips32/arch.py2
-rw-r--r--miasm2/arch/mips32/ira.py2
-rw-r--r--miasm2/arch/mips32/sem.py36
-rw-r--r--miasm2/arch/x86/arch.py8
-rw-r--r--miasm2/core/cpu.py9
-rw-r--r--miasm2/expression/simplifications_common.py6
-rw-r--r--miasm2/ir/symbexec.py23
-rw-r--r--test/arch/mips32/arch.py4
8 files changed, 76 insertions, 14 deletions
diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py
index 19f8b26f..b3bbc3ff 100644
--- a/miasm2/arch/mips32/arch.py
+++ b/miasm2/arch/mips32/arch.py
@@ -688,9 +688,11 @@ mips32op("ext",     [bs('011111'), rs, rt, esize, epos, bs('000000')], [rt, rs,
 mips32op("ins",     [bs('011111'), rs, rt, eposh, epos, bs('000100')], [rt, rs, epos, eposh])
 
 mips32op("seb",     [bs('011111'), bs('00000'), rt, rd, bs('10000'), bs('100000')], [rd, rt])
+mips32op("seh",     [bs('011111'), bs('00000'), rt, rd, bs('11000'), bs('100000')], [rd, rt])
 mips32op("wsbh",    [bs('011111'), bs('00000'), rt, rd, bs('00010'), bs('100000')], [rd, rt])
 
 mips32op("di",      [bs('010000'), bs('01011'), rt, bs('01100'), bs('00000'), bs('0'), bs('00'), bs('000')])
+mips32op("ei",      [bs('010000'), bs('01011'), rt, bs('01100'), bs('00000'), bs('1'), bs('00'), bs('000')])
 
 
 mips32op("tlbp",    [bs('010000'), bs('1'), bs('0'*19), bs('001000')])
diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py
index bc9e2439..cb084411 100644
--- a/miasm2/arch/mips32/ira.py
+++ b/miasm2/arch/mips32/ira.py
@@ -55,7 +55,7 @@ class ir_a_mips32(ir_mips32, ira):
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
             irs = self.call_effects(pc_val)
-            irs.append([ExprAff(IRDst, ExprId(lbl, size=self.pc.size))])
+            irs.append([ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))])
             nbloc = irbloc(new_lbl, irs)
             nbloc.lines = [l]
             self.blocs[new_lbl] = nbloc
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
index b513a481..365444d7 100644
--- a/miasm2/arch/mips32/sem.py
+++ b/miasm2/arch/mips32/sem.py
@@ -60,6 +60,13 @@ def lhu(ir, instr, a, b):
     e.append(ExprAff(a, b.zeroExtend(32)))
     return e, []
 
+
+def lb(ir, instr, a, b):
+    e = []
+    b = ExprMem(b.arg, 8)
+    e.append(ExprAff(a, b.signExtend(32)))
+    return e, []
+
 def beq(ir, instr, a, b, c):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
@@ -218,6 +225,11 @@ def seb(ir, instr, a, b):
     e.append(ExprAff(a, b[:8].signExtend(32)))
     return e, []
 
+def seh(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(a, b[:16].signExtend(32)))
+    return e, []
+
 def bltz(ir, instr, a, b):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
@@ -394,6 +406,15 @@ def mult(ir, instr, a, b):
     e.append(ExprAff(R_HI, r[32:]))
     return e, []
 
+def multu(ir, instr, a, b):
+    e = []
+    size = a.size
+    r = a.zeroExtend(size * 2) * b.zeroExtend(size * 2)
+
+    e.append(ExprAff(R_LO, r[:32]))
+    e.append(ExprAff(R_HI, r[32:]))
+    return e, []
+
 def mfhi(ir, instr, a):
     e = []
     e.append(ExprAff(a, R_HI))
@@ -404,6 +425,14 @@ def mflo(ir, instr, a):
     e.append(ExprAff(a, R_LO))
     return e, []
 
+def di(ir, instr, a):
+    return [], []
+
+def ei(ir, instr, a):
+    return [], []
+
+def ehb(ir, instr, a):
+    return [], []
 
 mnemo_func = {
     "addiu": addiu,
@@ -418,6 +447,7 @@ mnemo_func = {
     "b" : l_b,
     "lbu" : lbu,
     "lhu" : lhu,
+    "lb" : lb,
     "beq" : beq,
     "bgez" : bgez,
     "bltz" : bltz,
@@ -450,6 +480,7 @@ mnemo_func = {
     "xori" : l_xor,
     "xor" : l_xor,
     "seb" : seb,
+    "seh" : seh,
     "bltz" : bltz,
     "blez" : blez,
     "wsbh" : wsbh,
@@ -476,10 +507,15 @@ mnemo_func = {
     "bc1f" : bc1f,
     "cvt.d.w":cvt_d_w,
     "mult" : mult,
+    "multu" : multu,
 
     "mfhi" : mfhi,
     "mflo" : mflo,
 
+    "di" : di,
+    "ei" : ei,
+    "ehb" : ehb,
+
     }
 
 def get_mnemo_expr(ir, instr, *args):
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 31ee2eb9..186cbd8b 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -951,14 +951,6 @@ class mn_x86(cls_mn):
         return cand_same_mode + cand_diff_mode
 
 
-class bs8(bs):
-    prio = default_prio
-
-    def __init__(self, v, cls=None, fname=None, **kargs):
-        super(bs8, self).__init__(int2bin(v, 8), 8,
-                                  cls=cls, fname=fname, **kargs)
-
-
 class bs_modname_size(bs_divert):
     prio = 1
 
diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py
index a2bccbd3..d5464305 100644
--- a/miasm2/core/cpu.py
+++ b/miasm2/core/cpu.py
@@ -1759,6 +1759,15 @@ class int32_noarg(imm_noarg):
         self.value = v & self.lmask
         return True
 
+class bs8(bs):
+    prio = default_prio
+
+    def __init__(self, v, cls=None, fname=None, **kargs):
+        super(bs8, self).__init__(int2bin(v, 8), 8,
+                                  cls=cls, fname=fname, **kargs)
+
+
+
 
 def swap_uint(size, i):
     if size == 8:
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index d662cf3d..4f712bf0 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -208,6 +208,12 @@ def simp_cst_propagation(e_s, e):
         args0 = args[0].args[0]
         args = [args0, args1]
 
+    # A >> X >> Y  =>  A >> (X+Y)
+    if (op in ['<<', '>>'] and
+        isinstance(args[0], ExprOp) and
+        args[0].op == op):
+        args = [args[0].args[0], args[0].args[1] + args[1]]
+
     # ((A & A.mask)
     if op == "&" and args[-1] == e.mask:
         return ExprOp('&', *args[:-1])
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index 76bb65b6..5bdcac2f 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -79,7 +79,7 @@ class symbols():
         return s
 
 
-class symbexec:
+class symbexec(object):
 
     def __init__(self, ir_arch, known_symbols,
                  func_read=None,
@@ -99,6 +99,8 @@ class symbexec:
         return None
 
     def eval_ExprId(self, e, eval_cache=None):
+        if eval_cache is None:
+            eval_cache = {}
         if isinstance(e.name, asmbloc.asm_label) and e.name.offset is not None:
             return ExprInt_from(e, e.name.offset)
         if not e in self.symbols:
@@ -110,6 +112,8 @@ class symbexec:
         return e
 
     def eval_ExprMem(self, e, eval_cache=None):
+        if eval_cache is None:
+            eval_cache = {}
         a_val = self.expr_simp(self.eval_expr(e.arg, eval_cache))
         if a_val != e.arg:
             a = self.expr_simp(ExprMem(a_val, size=e.size))
@@ -198,9 +202,13 @@ class symbexec:
         return tmp
 
     def eval_expr_visit(self, e, eval_cache=None):
+        if eval_cache is None:
+            eval_cache = {}
         # print 'visit', e, e.is_term
         if e.is_term:
             return e
+        if e in eval_cache:
+            return eval_cache[e]
         c = e.__class__
         deal_class = {ExprId: self.eval_ExprId,
                       ExprInt: self.eval_ExprInt,
@@ -215,6 +223,8 @@ class symbexec:
         return e
 
     def eval_expr(self, e, eval_cache=None):
+        if eval_cache is None:
+            eval_cache = {}
         r = e.visit(lambda x: self.eval_expr_visit(x, eval_cache))
         return r
 
@@ -319,6 +329,8 @@ class symbexec:
 
     # give mem stored overlapping requested mem ptr
     def get_mem_overlapping(self, e, eval_cache=None):
+        if eval_cache is None:
+            eval_cache = {}
         if not isinstance(e, ExprMem):
             raise ValueError('mem overlap bad arg')
         ov = []
@@ -346,7 +358,7 @@ class symbexec:
     def eval_ir_expr(self, exprs):
         pool_out = {}
 
-        eval_cache = {}
+        eval_cache = dict(self.symbols.items())
 
         for e in exprs:
             if not isinstance(e, ExprAff):
@@ -377,10 +389,10 @@ class symbexec:
         mem_dst = []
         # src_dst = [(x.src, x.dst) for x in ir]
         src_dst = self.eval_ir_expr(ir)
-
+        eval_cache = dict(self.symbols.items())
         for dst, src in src_dst:
             if isinstance(dst, ExprMem):
-                mem_overlap = self.get_mem_overlapping(dst)
+                mem_overlap = self.get_mem_overlapping(dst, eval_cache)
                 for _, base in mem_overlap:
                     diff_mem = self.substract_mems(base, dst)
                     del(self.symbols[base])
@@ -401,7 +413,8 @@ class symbexec:
             if step:
                 print '_' * 80
                 self.dump_id()
-        return self.eval_expr(self.ir_arch.IRDst)
+        eval_cache = dict(self.symbols.items())
+        return self.eval_expr(self.ir_arch.IRDst, eval_cache)
 
     def emul_ir_bloc(self, myir, ad, step = False):
         b = myir.get_bloc(ad)
diff --git a/test/arch/mips32/arch.py b/test/arch/mips32/arch.py
index 2f1f5821..899748ce 100644
--- a/test/arch/mips32/arch.py
+++ b/test/arch/mips32/arch.py
@@ -192,8 +192,12 @@ reg_tests_mips32 = [
      "38630011"),
     ("8BA0F37C    SEB        S6, V0",
      "7C02B420"),
+    ("XXXXXXXX    SEH        V0, A3",
+     "7c071620"),
     ("8BA0F468    DI         ZERO",
      "41606000"),
+    ("XXXXXXXX    EI         ZERO",
+     "41606020"),
     ("8BA0F78C    WSBH       V1, V1",
      "7C0318A0"),
     ("8BA0F790    ROTR       V1, V1, 0x10",