about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/arm/arch.py64
-rw-r--r--miasm2/arch/arm/sem.py13
-rw-r--r--miasm2/ir/translators/C.py3
-rw-r--r--miasm2/jitter/arch/JitCore_arm.c11
-rw-r--r--miasm2/jitter/arch/JitCore_arm.h2
-rw-r--r--test/arch/arm/arch.py6
6 files changed, 99 insertions, 0 deletions
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index 7dc5d959..e14549ec 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -39,6 +39,9 @@ gpregs_sp = reg_info(regs_str[13:14], regs_expr[13:14])
 gpregs_nosppc = reg_info(regs_str[:13] + [str(reg_dum), regs_str[14]],
                          regs_expr[:13] + [reg_dum, regs_expr[14]])
 
+gpregs_nopc = reg_info(regs_str[:14],
+                       regs_expr[:14])
+
 
 # psr
 sr_flags = "cxsf"
@@ -106,9 +109,18 @@ def check_bounds(left_bound, right_bound, value):
     else:
         raise ValueError('shift operator immediate value out of bound')
 
+
+def check_values(values, value):
+    if value in values:
+        return ExprInt32(value)
+    else:
+        raise ValueError('shift operator immediate value out of bound')
+
 int_1_31 = str_int.copy().setParseAction(lambda v: check_bounds(1, 31, v[0]))
 int_1_32 = str_int.copy().setParseAction(lambda v: check_bounds(1, 32, v[0]))
 
+int_8_16_24 = str_int.copy().setParseAction(lambda v: check_values([8, 16, 24], v[0]))
+
 
 def reglistparse(s, l, t):
     t = t[0]
@@ -145,6 +157,9 @@ all_binaryop_1_32_shifts_t = literal_list(
     ['LSR', 'ASR']).setParseAction(op_shift2expr)
 all_unaryop_shifts_t = literal_list(['RRX']).setParseAction(op_shift2expr)
 
+ror_shifts_t = literal_list(['ROR']).setParseAction(op_shift2expr)
+
+
 allshifts_t_armt = literal_list(
     ['LSL', 'LSR', 'ASR', 'ROR', 'RRX']).setParseAction(op_shift2expr)
 
@@ -190,6 +205,12 @@ shift_off = (gpregs.parser + Optional(
 shift_off |= base_expr
 
 
+rot2_expr = (gpregs.parser + Optional(
+    (ror_shifts_t + (int_8_16_24))
+)).setParseAction(shift2expr)
+
+
+
 def deref2expr_nooff(s, l, t):
     t = t[0]
     # XXX default
@@ -1595,12 +1616,54 @@ class arm_widthm1(arm_imm, m_arg):
         return True
 
 
+class arm_rm_rot2(m_arg):
+    parser = rot2_expr
+    def decode(self, v):
+        expr = gpregs.expr[v]
+        shift_value = self.parent.rot2.value
+        if shift_value:
+            expr = ExprOp(allshifts[3], expr, ExprInt32(shift_value * 8))
+        self.expr = expr
+        return True
+    def encode(self):
+        if self.expr in gpregs.expr:
+            self.value = gpregs.expr.index(self.expr)
+            self.parent.rot2.value = 0
+        elif (isinstance(self.expr, ExprOp) and
+              self.expr.op == allshifts[3]):
+            reg, value = self.expr.args
+            if reg not in gpregs.expr:
+                return False
+            self.value = gpregs.expr.index(reg)
+            if not isinstance(value, ExprInt):
+                return False
+            value = int(value.arg)
+            if not value in [8, 16, 24]:
+                return False
+            self.parent.rot2.value = value / 8
+        return True
+
+class arm_gpreg_nopc(arm_reg):
+    reg_info = gpregs_nopc
+    parser = reg_info.parser
+
+
+rm_rot2 = bs(l=4, cls=(arm_rm_rot2,), fname="rm")
+rot2 = bs(l=2, fname="rot2")
+
 widthm1 = bs(l=5, cls=(arm_widthm1, m_arg))
 lsb = bs(l=5, cls=(arm_imm, m_arg))
 
+rn_nopc = bs(l=4, cls=(arm_gpreg_nopc,), fname="rn")
+
 armop("ubfx", [bs('0111111'), widthm1, rd, lsb, bs('101'), rn], [rd, rn, lsb, widthm1])
 
 armop("bfc", [bs('0111110'), widthm1, rd, lsb, bs('001'), bs('1111')], [rd, lsb, widthm1])
+
+armop("uxtab", [bs('01101110'), rn_nopc, rd, rot2, bs('000111'), rm_rot2], [rd, rn_nopc, rm_rot2])
+
+
+
 #
 # thumnb #######################
 #
@@ -2080,6 +2143,7 @@ class arm_gpreg_nosppc(arm_reg):
     reg_info = gpregs_nosppc
 
 
+
 class armt_gpreg_rm_shift_off(arm_reg):
     parser = armt_gpreg_shift_off
 
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index 5bd4db24..be44061e 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -937,6 +937,17 @@ def pld(ir, instr, a):
     return []
 
 
+def clz(ir, instr, a, b):
+    e = []
+    e.append(ExprAff(a, ExprOp('clz', b)))
+    return e
+
+def uxtab(ir, instr, a, b, c):
+    e = []
+    e.append(ExprAff(a, b + (c & ExprInt32(0xff))))
+    return e
+
+
 
 COND_EQ = 0
 COND_NE = 1
@@ -1080,6 +1091,8 @@ mnemo_condm0 = {'add': add,
                 'ubfx': ubfx,
                 'bfc': bfc,
                 'rev': rev,
+                'clz': clz,
+                'uxtab': uxtab,
                 }
 
 mnemo_condm1 = {'adds': add,
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index 2c44d9e1..340fbfec 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -50,6 +50,9 @@ class TranslatorC(Translator):
                 return "x86_%s(%s, 0x%x)" % (expr.op,
                                              self.from_expr(expr.args[0]),
                                              expr.args[0].size)
+            elif expr.op in ['clz']:
+                return "%s(%s)" % (expr.op,
+                                   self.from_expr(expr.args[0]))
             elif expr.op == '!':
                 return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]),
                                         size2mask(expr.args[0].size))
diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c
index a7ed67d0..0d7caeec 100644
--- a/miasm2/jitter/arch/JitCore_arm.c
+++ b/miasm2/jitter/arch/JitCore_arm.c
@@ -201,6 +201,17 @@ void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src)
 }
 
 
+uint32_t clz(uint32_t arg)
+{
+
+	int i;
+
+	for (i=0; i<32; i++) {
+		if (arg & (1 << (31-i)))
+			break;
+	}
+	return i;
+}
 
 
 
diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h
index 9fde5e93..dda8a65d 100644
--- a/miasm2/jitter/arch/JitCore_arm.h
+++ b/miasm2/jitter/arch/JitCore_arm.h
@@ -32,3 +32,5 @@ typedef struct {
 void dump_gpregs(vm_cpu_t* vmcpu);
 
 #define RETURN_PC return BlockDst;
+
+uint32_t clz(uint32_t arg);
diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py
index a00fe3d6..6b010d20 100644
--- a/test/arch/arm/arch.py
+++ b/test/arch/arm/arch.py
@@ -250,6 +250,12 @@ reg_tests_arm = [
     ('XXXXXXXX    PLD        [R1, 0x1C]',
      '1CF0D1F5'),
 
+    ('XXXXXXXX    UXTAB      R5, R2, R8',
+     '7850e2e6'),
+
+    ('XXXXXXXX    UXTAB      R5, R2, R8 ROR 0x8',
+     '7854e2e6'),
+
 
 ]
 ts = time.time()