about summary refs log tree commit diff stats
path: root/miasm2/arch/arm/arch.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/arch/arm/arch.py')
-rw-r--r--miasm2/arch/arm/arch.py64
1 files changed, 64 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