about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/arm/arch.py30
-rw-r--r--miasm2/arch/arm/ira.py16
-rw-r--r--miasm2/core/cpu.py2
-rw-r--r--test/arch/arm/arch.py3
4 files changed, 41 insertions, 10 deletions
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index 1810cd6a..82664476 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -913,6 +913,8 @@ class arm_offs(arm_imm):
         if (1 << (self.l - 1)) & v:
             v = -((0xffffffff ^ v) + 1)
         v = self.encodeval(v)
+        if v is False:
+            return False
         self.value = (v & 0xffffffff) & self.lmask
         return True
 
@@ -1877,7 +1879,11 @@ class arm_offpc(arm_offreg):
             log.debug('cannot encode reg %r', e.args[0])
             return False
         v = int(e.args[1])
+        if v & 3:
+            return False
         v >>= 2
+        if v > self.lmask:
+            return False
         self.value = v
         return True
 
@@ -1900,8 +1906,11 @@ class arm_offspc(arm_offs):
     def encodeval(self, v):
         # Remove pipeline offset
         v -= 2 + 2
-        if v % 2 == 0:
-            return v >> 1
+        if v % 2 != 0:
+            return False
+        if v > (1 << (self.l - 1)) - 1:
+            return False
+        return v >> 1
         return False
 
 
@@ -2533,6 +2542,8 @@ class armt4_imm12(arm_imm):
         if not self.expr.is_int():
             return False
         value = int(self.expr)
+        if value >= (1 << 16):
+            return False
         self.value = value & self.lmask
         self.parent.imm12_3.value = (value >> 8) & self.parent.imm12_3.lmask
         self.parent.imm12_1.value = (value >> 11) & self.parent.imm12_1.lmask
@@ -2540,7 +2551,6 @@ class armt4_imm12(arm_imm):
 
 
 
-
 class armt2_imm16(arm_imm):
 
     def decode(self, v):
@@ -2555,6 +2565,8 @@ class armt2_imm16(arm_imm):
         if not self.expr.is_int():
             return False
         value = int(self.expr)
+        if value >= (1 << 16):
+            return False
         self.value = value & self.lmask
         self.parent.imm16_3.value = (value >> 8) & self.parent.imm16_3.lmask
         self.parent.imm16_1.value = (value >> 11) & self.parent.imm16_1.lmask
@@ -2644,8 +2656,8 @@ class armt2_imm10l(arm_imm):
         s = 0
         if v & 0x80000000:
             s = 1
-            v = (-v) & 0xffffffff
-        if v > (1 << 26):
+            v &= (1<<26) - 1
+        if v >= (1 << 26):
             return False
         i1, i2, imm10h, imm10l = (v >> 23) & 1, (v >> 22) & 1, (v >> 12) & 0x3ff, (v >> 2) & 0x3ff
         j1, j2 = i1 ^ s ^ 1, i2 ^ s ^ 1
@@ -2681,7 +2693,7 @@ class armt2_imm11l(arm_imm):
         s = 0
         if v & 0x80000000:
             s = 1
-            v = (-v) & 0xffffffff
+            v &= (1<<26) - 1
         if v >= (1 << 26):
             return False
         if v & 1:
@@ -2717,11 +2729,11 @@ class armt2_imm6_11l(arm_imm):
             return False
         v = self.expr.arg.arg - 4
         s = 0
+        if v != sign_ext(v & ((1 << 22) - 1), 21, 32):
+            return False 
         if v & 0x80000000:
             s = 1
-            v = (-v) & 0xffffffff
-        if v >= (1 << 22):
-            return False
+        v &= (1<<22) - 1
         if v & 1:
             return False
         i2, i1, imm6h, imm11l = (v >> 19) & 1, (v >> 18) & 1, (v >> 12) & 0x3f, (v >> 1) & 0x7ff
diff --git a/miasm2/arch/arm/ira.py b/miasm2/arch/arm/ira.py
index 0c84c919..7b26a6e4 100644
--- a/miasm2/arch/arm/ira.py
+++ b/miasm2/arch/arm/ira.py
@@ -2,7 +2,8 @@
 
 from miasm2.ir.analysis import ira
 from miasm2.arch.arm.sem import ir_arml, ir_armtl, ir_armb, ir_armtb
-
+from miasm2.expression.expression import ExprAff, ExprOp
+from miasm2.ir.ir import AssignBlock
 
 class ir_a_arml_base(ir_arml, ira):
     def __init__(self, loc_db=None):
@@ -21,6 +22,19 @@ class ir_a_arml(ir_a_arml_base):
         ir_a_arml_base.__init__(self, loc_db)
         self.ret_reg = self.arch.regs.R0
 
+    def call_effects(self, ad, instr):
+        return [AssignBlock([ExprAff(self.ret_reg, ExprOp('call_func_ret', ad,
+                                                          self.arch.regs.R0,
+                                                          self.arch.regs.R1,
+                                                          self.arch.regs.R2,
+                                                          self.arch.regs.R3,
+                                                          )),
+                             ExprAff(self.sp, ExprOp('call_func_stack',
+                                                     ad, self.sp)),
+                            ],
+                             instr
+                           )]
+
     def get_out_regs(self, _):
         return set([self.ret_reg, self.sp])
 
diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py
index dc6fc392..1326d08b 100644
--- a/miasm2/core/cpu.py
+++ b/miasm2/core/cpu.py
@@ -1649,6 +1649,8 @@ class int32_noarg(imm_noarg):
         if sign_ext(v & self.lmask, self.l, self.intsize) != v:
             return False
         v = self.encodeval(v & self.lmask)
+        if v is False:
+            return False
         self.value = v & self.lmask
         return True
 
diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py
index 3550a816..d92c24b2 100644
--- a/test/arch/arm/arch.py
+++ b/test/arch/arm/arch.py
@@ -401,6 +401,9 @@ reg_tests_armt = [
 
     ("0007479c    B          0x12",
      "07e0"),
+    ("XXXXXXXX    BLT        0xFFFFFFEA",
+     "F3DB"),
+
     ("0006b946    B          0xFFFFFFE8",
      "f2e7"),
     ("C010163C    BLX        0x1F916C",