about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2018-07-18 08:03:13 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2018-07-18 08:03:13 +0200
commit39586f91cf2c67e52156024dc61b75c2a3af1abd (patch)
tree63ebbcff6e5614eb2bf05175db5f17bc43765980
parent7d2227eeb09a0ec43a837082570a0cb955651daa (diff)
downloadmiasm-39586f91cf2c67e52156024dc61b75c2a3af1abd.tar.gz
miasm-39586f91cf2c67e52156024dc61b75c2a3af1abd.zip
Arm: support conditional subcall IR
-rw-r--r--miasm2/arch/arm/ira.py31
1 files changed, 28 insertions, 3 deletions
diff --git a/miasm2/arch/arm/ira.py b/miasm2/arch/arm/ira.py
index 09a9cabc..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):
@@ -43,7 +44,31 @@ class ir_a_arml(ir_a_arml_base):
             ],
             instr
         )
-        return [call_assignblk], []
+
+
+        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])