about summary refs log tree commit diff stats
path: root/miasm2/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/arch/arm')
-rw-r--r--miasm2/arch/arm/arch.py4
-rw-r--r--miasm2/arch/arm/ira.py61
-rw-r--r--miasm2/arch/arm/regs.py5
-rw-r--r--miasm2/arch/arm/sem.py9
4 files changed, 60 insertions, 19 deletions
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index 82664476..e25e4911 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -420,6 +420,8 @@ class instruction_arm(instruction):
 
 
     def dstflow(self):
+        if self.is_subcall():
+            return True
         return self.name in conditional_branch + unconditional_branch
 
     def dstflow2label(self, loc_db):
@@ -434,6 +436,8 @@ class instruction_arm(instruction):
         self.args[0] = ExprLoc(loc_key, expr.size)
 
     def breakflow(self):
+        if self.is_subcall():
+            return True
         if self.name in conditional_branch + unconditional_branch:
             return True
         if self.name.startswith("LDM") and PC in self.args[1].args:
diff --git a/miasm2/arch/arm/ira.py b/miasm2/arch/arm/ira.py
index 7b26a6e4..fd8096d7 100644
--- a/miasm2/arch/arm/ira.py
+++ b/miasm2/arch/arm/ira.py
@@ -1,8 +1,9 @@
 #-*- coding:utf-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 IRBlock
+from miasm2.arch.arm.sem import ir_arml, ir_armtl, ir_armb, ir_armtb, tab_cond
+from miasm2.expression.expression import ExprAff, ExprOp, ExprLoc, ExprCond
 from miasm2.ir.ir import AssignBlock
 
 class ir_a_arml_base(ir_arml, ira):
@@ -23,17 +24,51 @@ class ir_a_arml(ir_a_arml_base):
         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
-                           )]
+        call_assignblk = 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
+        )
+
+
+        cond = instr.additional_info.cond
+        if cond == 14: # COND_ALWAYS:
+            return [call_assignblk], []
+
+        # Call is a conditional instruction
+        cond = tab_cond[cond]
+
+        loc_next = self.get_next_loc_key(instr)
+        loc_next_expr = ExprLoc(loc_next, 32)
+        loc_do = self.loc_db.add_location()
+        loc_do_expr = ExprLoc(loc_do, 32)
+        dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr)
+
+        call_assignblks = [
+            call_assignblk,
+            AssignBlock([ExprAff(self.IRDst, loc_next_expr)], instr),
+        ]
+        e_do = IRBlock(loc_do, call_assignblks)
+        assignblks_out = [
+            AssignBlock([ExprAff(self.IRDst, dst_cond)], instr)
+        ]
+        return assignblks_out, [e_do]
+
 
     def get_out_regs(self, _):
         return set([self.ret_reg, self.sp])
diff --git a/miasm2/arch/arm/regs.py b/miasm2/arch/arm/regs.py
index dce4cb98..e20b00bd 100644
--- a/miasm2/arch/arm/regs.py
+++ b/miasm2/arch/arm/regs.py
@@ -9,6 +9,7 @@ regs32_str = ["R%d" % i for i in xrange(13)] + ["SP", "LR", "PC"]
 regs32_expr = [ExprId(x, 32) for x in regs32_str]
 
 exception_flags = ExprId('exception_flags', 32)
+interrupt_num = ExprId('interrupt_num', 32)
 bp_num = ExprId('bp_num', 32)
 
 
@@ -84,7 +85,7 @@ all_regs_ids = [
     R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, SP, LR, PC,
     zf, nf, of, cf,
     ge0, ge1, ge2, ge3,
-    exception_flags, bp_num
+    exception_flags, interrupt_num, bp_num
 ]
 
 all_regs_ids_no_alias = all_regs_ids
@@ -102,7 +103,7 @@ all_regs_ids_init = [R0_init, R1_init, R2_init, R3_init,
                      R12_init, SP_init, LR_init, PC_init,
                      zf_init, nf_init, of_init, cf_init,
                      ge0_init, ge1_init, ge2_init, ge3_init,
-                     ExprInt(0, 32), ExprInt(0, 32)
+                     ExprInt(0, 32), ExprInt(0, 32), ExprInt(0, 32)
                      ]
 
 regs_init = {}
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index 00250157..d9c2d6cd 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -3,7 +3,7 @@ from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.arch.arm.arch import mn_arm, mn_armt
 from miasm2.arch.arm.regs import *
 
-from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO
+from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX
 
 # liris.cnrs.fr/~mmrissa/lib/exe/fetch.php?media=armv7-a-r-manual.pdf
 EXCEPT_SOFT_BP = (1 << 1)
@@ -805,9 +805,10 @@ def stmdb(ir, instr, a, b):
 
 
 def svc(ir, instr, a):
-    # XXX TODO implement
-    e = [
-        ExprAff(exception_flags, ExprInt(EXCEPT_PRIV_INSN, 32))]
+    e = []
+    except_int = EXCEPT_INT_XX
+    e.append(ExprAff(exception_flags, ExprInt(except_int, 32)))
+    e.append(ExprAff(interrupt_num, a))
     return e, []