about summary refs log tree commit diff stats
path: root/miasm/arch/arm/arch.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm/arch/arm/arch.py')
-rw-r--r--miasm/arch/arm/arch.py93
1 files changed, 48 insertions, 45 deletions
diff --git a/miasm/arch/arm/arch.py b/miasm/arch/arm/arch.py
index fc6a0527..2b4476f0 100644
--- a/miasm/arch/arm/arch.py
+++ b/miasm/arch/arm/arch.py
@@ -413,10 +413,10 @@ class instruction_arm(instruction):
 
         if isinstance(expr, ExprOp) and expr.op == 'postinc':
             o = '[%s]' % r
-            if s and not (isinstance(s, ExprInt) and s.arg == 0):
+            if s and not (isinstance(s, ExprInt) and int(s) == 0):
                 o += ', %s' % s
         else:
-            if s and not (isinstance(s, ExprInt) and s.arg == 0):
+            if s and not (isinstance(s, ExprInt) and int(s) == 0):
                 o = '[%s, %s]' % (r, s)
             else:
                 o = '[%s]' % (r)
@@ -437,9 +437,9 @@ class instruction_arm(instruction):
         if not isinstance(expr, ExprInt):
             return
         if self.name == 'BLX':
-            addr = expr.arg + self.offset
+            addr = (int(expr) + self.offset) & int(expr.mask)
         else:
-            addr = expr.arg + self.offset
+            addr = (int(expr) + self.offset) & int(expr.mask)
         loc_key = loc_db.get_or_create_offset_location(addr)
         self.args[0] = ExprLoc(loc_key, expr.size)
 
@@ -481,7 +481,7 @@ class instruction_arm(instruction):
         if not isinstance(e, ExprInt):
             log.debug('dyn dst %r', e)
             return
-        off = e.arg - self.offset
+        off = (int(e) - self.offset) & int(e.mask)
         if int(off % 4):
             raise ValueError('strange offset! %r' % off)
         self.args[0] = ExprInt(off, 32)
@@ -514,15 +514,15 @@ class instruction_armt(instruction_arm):
         if not isinstance(expr, ExprInt):
             return
         if self.name == 'BLX':
-            addr = expr.arg + (self.offset & 0xfffffffc)
+            addr = (int(expr) + (self.offset & 0xfffffffc)) & int(expr.mask)
         elif self.name == 'BL':
-            addr = expr.arg + self.offset
+            addr = (int(expr) + self.offset) & int(expr.mask)
         elif self.name.startswith('BP'):
-            addr = expr.arg + self.offset
+            addr = (int(expr) + self.offset) & int(expr.mask)
         elif self.name.startswith('CB'):
-            addr = expr.arg + self.offset + self.l + 2
+            addr = (int(expr) + self.offset + self.l + 2) & int(expr.mask)
         else:
-            addr = expr.arg + self.offset
+            addr = (int(expr) + self.offset) & int(expr.mask)
 
         loc_key = loc_db.get_or_create_offset_location(addr)
         dst = ExprLoc(loc_key, expr.size)
@@ -564,7 +564,7 @@ class instruction_armt(instruction_arm):
         # The first +2 is to compensate instruction len, but strangely, 32 bits
         # thumb2 instructions len is 2... For the second +2, didn't find it in
         # the doc.
-        off = e.arg - self.offset
+        off = (int(e) - self.offset) & int(e.mask)
         if int(off % 2):
             raise ValueError('strange offset! %r' % off)
         self.args[0] = ExprInt(off, 32)
@@ -798,6 +798,9 @@ class arm_arg(m_arg):
             args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
             if None in args:
                 return None
+            if arg.op == "-":
+                assert len(args) == 2
+                return args[0] - args[1]
             return ExprOp(arg.op, *args)
         if isinstance(arg, AstInt):
             return ExprInt(arg.value, 32)
@@ -1345,7 +1348,7 @@ class arm_offs_blx(arm_imm):
         if not isinstance(self.expr, ExprInt):
             return False
         # Remove pipeline offset
-        v = int(self.expr.arg - 8)
+        v = (int(self.expr) - 8) & int(self.expr.mask)
         if v & 0x80000000:
             v &= (1 << 26) - 1
         self.parent.lowb.value = (v >> 1) & 1
@@ -1657,6 +1660,33 @@ bs_mr_name = bs_name(l=1, name=mr_name)
 bs_addi = bs(l=1, fname="add_imm")
 bs_rw = bs_mod_name(l=1, fname='rw', mn_mod=['W', ''])
 
+class armt_barrier_option(reg_noarg, arm_arg):
+    reg_info = barrier_info
+    parser = reg_info.parser
+
+    def decode(self, v):
+        v = v & self.lmask
+        if v not in self.reg_info.dct_expr:
+            return False
+        self.expr = self.reg_info.dct_expr[v]
+        return True
+
+    def encode(self):
+        if not self.expr in self.reg_info.dct_expr_inv:
+            log.debug("cannot encode reg %r", self.expr)
+            return False
+        self.value = self.reg_info.dct_expr_inv[self.expr]
+        if self.value > self.lmask:
+            log.debug("cannot encode field value %x %x",
+                      self.value, self.lmask)
+            return False
+        return True
+
+    def check_fbits(self, v):
+        return v & self.fmask == self.fbits
+
+barrier_option = bs(l=4, cls=(armt_barrier_option,))
+
 armop("mul", [bs('000000'), bs('0'), scc, rd, bs('0000'), rs, bs('1001'), rm], [rd, rm, rs])
 armop("umull", [bs('000010'), bs('0'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs])
 armop("umlal", [bs('000010'), bs('1'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs])
@@ -1706,7 +1736,8 @@ armop("rev16", [bs('01101011'), bs('1111'), rd, bs('1111'), bs('1011'), rm])
 
 armop("pld", [bs8(0xF5), bs_addi, bs_rw, bs('01'), mem_rn_imm, bs('1111'), imm12_off])
 
-armop("isb", [bs8(0xF5), bs8(0x7F), bs8(0xF0), bs8(0x6F)])
+armop("dsb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0100'), barrier_option])
+armop("isb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0110'), barrier_option])
 armop("nop", [bs8(0xE3), bs8(0x20), bs8(0xF0), bs8(0)])
 
 class arm_widthm1(arm_imm, m_arg):
@@ -2323,7 +2354,6 @@ class arm_sp(arm_reg):
     reg_info = gpregs_sp
     parser = reg_info.parser
 
-
 off5 = bs(l=5, cls=(arm_imm,), fname="off")
 off3 = bs(l=3, cls=(arm_imm,), fname="off")
 off8 = bs(l=8, cls=(arm_imm,), fname="off")
@@ -2738,7 +2768,7 @@ class armt2_imm10l(arm_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         s = 0
         if v & 0x80000000:
             s = 1
@@ -2775,7 +2805,7 @@ class armt2_imm11l(arm_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg - 4
+        v = (int(self.expr) - 4) & int(self.expr.mask)
         s = 0
         if v & 0x80000000:
             s = 1
@@ -2813,7 +2843,7 @@ class armt2_imm6_11l(arm_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg - 4
+        v = (int(self.expr) - 4) & int(self.expr.mask)
         s = 0
         if v != sign_ext(v & ((1 << 22) - 1), 21, 32):
             return False
@@ -2881,7 +2911,7 @@ class armt_imm5_1(arm_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & 0x1:
             return False
         self.parent.imm1.value = (v >> 6) & 1
@@ -3227,33 +3257,6 @@ bs_deref_reg_reg = bs(l=4, cls=(armt_deref_reg_reg,))
 bs_deref_reg_reg_lsl_1 = bs(l=4, cls=(armt_deref_reg_reg_lsl_1,))
 
 
-class armt_barrier_option(reg_noarg, arm_arg):
-    reg_info = barrier_info
-    parser = reg_info.parser
-
-    def decode(self, v):
-        v = v & self.lmask
-        if v not in self.reg_info.dct_expr:
-            return False
-        self.expr = self.reg_info.dct_expr[v]
-        return True
-
-    def encode(self):
-        if not self.expr in self.reg_info.dct_expr_inv:
-            log.debug("cannot encode reg %r", self.expr)
-            return False
-        self.value = self.reg_info.dct_expr_inv[self.expr]
-        if self.value > self.lmask:
-            log.debug("cannot encode field value %x %x",
-                      self.value, self.lmask)
-            return False
-        return True
-
-    def check_fbits(self, v):
-        return v & self.fmask == self.fbits
-
-barrier_option = bs(l=4, cls=(armt_barrier_option,))
-
 armtop("adc", [bs('11110'),  imm12_1, bs('0'), bs('1010'), scc, rn_nosppc, bs('0'), imm12_3, rd_nosppc, imm12_8])
 armtop("adc", [bs('11101'),  bs('01'), bs('1010'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh])
 armtop("bl", [bs('11110'), tsign, timm10H, bs('11'), tj1, bs('1'), tj2, timm11L])