about summary refs log tree commit diff stats
path: root/miasm2/arch/aarch64/sem.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/arch/aarch64/sem.py')
-rw-r--r--miasm2/arch/aarch64/sem.py87
1 files changed, 65 insertions, 22 deletions
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index ab45425c..697fa981 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -3,7 +3,7 @@ from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.arch.aarch64.arch import mn_aarch64, conds_expr, replace_regs
 from miasm2.arch.aarch64.regs import *
 from miasm2.core.sembuilder import SemBuilder
-from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO
+from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX
 
 
 # CPSR: N Z C V
@@ -73,6 +73,13 @@ def update_flag_sub_of(op1, op2, res):
     "Compote OF in @res = @op1 - @op2"
     return m2_expr.ExprAff(of, (((op1 ^ res) & (op1 ^ op2))).msb())
 
+
+# clearing cv flags for bics (see C5.6.25)
+
+def update_flag_bics ():
+    "Clear CF and OF"
+    return [ExprAff(cf, ExprInt (0,1)), ExprAff(of, ExprInt (0,1))]
+
 # z = x+y (+cf?)
 
 
@@ -119,11 +126,14 @@ def extend_arg(dst, arg):
     op, (reg, shift) = arg.op, arg.args
     if op == 'SXTW':
         base = reg.signExtend(dst.size)
-    else:
+        op = "<<"
+    elif op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>']:
         base = reg.zeroExtend(dst.size)
+    else:
+        raise NotImplementedError('Unknown shifter operator')
 
-    out = base << (shift.zeroExtend(dst.size)
-                   & m2_expr.ExprInt(dst.size - 1, dst.size))
+    out = ExprOp(op, base, (shift.zeroExtend(dst.size)
+                            & m2_expr.ExprInt(dst.size - 1, dst.size)))
     return out
 
 
@@ -138,7 +148,9 @@ ctx = {"PC": PC,
        "extend_arg": extend_arg,
        "m2_expr":m2_expr,
        "exception_flags": exception_flags,
+       "interrupt_num": interrupt_num,
        "EXCEPT_DIV_BY_ZERO": EXCEPT_DIV_BY_ZERO,
+       "EXCEPT_INT_XX": EXCEPT_INT_XX,
        }
 
 sbuild = SemBuilder(ctx)
@@ -191,6 +203,14 @@ def bic(arg1, arg2, arg3):
     arg1 = arg2 & (~extend_arg(arg2, arg3))
 
 
+def bics(ir, instr, arg1, arg2, arg3):
+    e = []
+    arg1 = arg2 & (~extend_arg(arg2, arg3))
+    e += update_flag_logic (arg1)
+    e += update_flag_bics ()
+    return e, []
+
+
 @sbuild.parse
 def mvn(arg1, arg2):
     arg1 = (~extend_arg(arg1, arg2))
@@ -402,26 +422,47 @@ def ldr(ir, instr, arg1, arg2):
     return e, []
 
 
-def ldrb(ir, instr, arg1, arg2):
+def ldr_size(ir, instr, arg1, arg2, size):
     e = []
     addr, updt = get_mem_access(arg2)
     e.append(
-        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 8).zeroExtend(arg1.size)))
+        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, size).zeroExtend(arg1.size)))
     if updt:
         e.append(updt)
     return e, []
 
 
+def ldrb(ir, instr, arg1, arg2):
+    return ldr_size(ir, instr, arg1, arg2, 8)
+
+
 def ldrh(ir, instr, arg1, arg2):
+    return ldr_size(ir, instr, arg1, arg2, 16)
+
+
+def ldrs_size(ir, instr, arg1, arg2, size):
     e = []
     addr, updt = get_mem_access(arg2)
     e.append(
-        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 16).zeroExtend(arg1.size)))
+        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, size).signExtend(arg1.size)))
     if updt:
         e.append(updt)
     return e, []
 
 
+def ldrsb(ir, instr, arg1, arg2):
+    return ldrs_size(ir, instr, arg1, arg2, 8)
+
+
+def ldrsh(ir, instr, arg1, arg2):
+    return ldrs_size(ir, instr, arg1, arg2, 16)
+
+
+def ldrsw(ir, instr, arg1, arg2):
+    return ldrs_size(ir, instr, arg1, arg2, 32)
+
+
+
 def l_str(ir, instr, arg1, arg2):
     e = []
     addr, updt = get_mem_access(arg2)
@@ -471,16 +512,6 @@ def ldp(ir, instr, arg1, arg2, arg3):
     return e, []
 
 
-def ldrsw(ir, instr, arg1, arg2):
-    e = []
-    addr, updt = get_mem_access(arg2)
-    e.append(
-        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 32).signExtend(arg1.size)))
-    if updt:
-        e.append(updt)
-    return e, []
-
-
 def sbfm(ir, instr, arg1, arg2, arg3, arg4):
     e = []
     rim, sim = int(arg3.arg), int(arg4) + 1
@@ -691,6 +722,12 @@ def extr(arg1, arg2, arg3, arg4):
     compose = m2_expr.ExprCompose(arg2, arg3)
     arg1 = compose[int(arg4.arg):int(arg4)+arg1.size]
 
+
+@sbuild.parse
+def svc(arg1):
+    exception_flags = m2_expr.ExprInt(EXCEPT_INT_XX, exception_flags.size)
+    interrupt_num = m2_expr.ExprInt(int(arg1), interrupt_num.size)
+
 mnemo_func = sbuild.functions
 mnemo_func.update({
     'and': and_l,
@@ -718,6 +755,8 @@ mnemo_func.update({
     'b.ls': b_ls,
     'b.lt': b_lt,
 
+    'bics': bics,
+
     'ret': ret,
     'stp': stp,
     'ldp': ldp,
@@ -728,7 +767,14 @@ mnemo_func.update({
 
     'ldur': ldr,
     'ldurb': ldrb,
+    'ldursb': ldrsb,
     'ldurh': ldrh,
+    'ldursh': ldrsh,
+    'ldursw': ldrsw,
+
+    'ldrsb': ldrsb,
+    'ldrsh': ldrsh,
+    'ldrsw': ldrsw,
 
     'str': l_str,
     'strb': strb,
@@ -738,8 +784,6 @@ mnemo_func.update({
     'sturb': strb,
     'sturh': strh,
 
-    'ldrsw': ldrsw,
-
 
     'bfm': bfm,
     'sbfm': sbfm,
@@ -781,7 +825,6 @@ class ir_aarch64l(IntermediateRepresentation):
         instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
         self.mod_pc(instr, instr_ir, extra_ir)
         instr_ir, extra_ir = self.del_dst_zr(instr, instr_ir, extra_ir)
-
         return instr_ir, extra_ir
 
     def expr_fix_regs_for_mode(self, e):
@@ -794,7 +837,7 @@ class ir_aarch64l(IntermediateRepresentation):
 
     def irbloc_fix_regs_for_mode(self, irblock, mode=64):
         irs = []
-        for assignblk in irblock.irs:
+        for assignblk in irblock:
             new_assignblk = dict(assignblk)
             for dst, src in assignblk.iteritems():
                 del(new_assignblk[dst])
@@ -837,7 +880,7 @@ class ir_aarch64l(IntermediateRepresentation):
         new_irblocks = []
         for irblock in extra_ir:
             irs = []
-            for assignblk in irblock.irs:
+            for assignblk in irblock:
                 new_dsts = {dst:src for dst, src in assignblk.iteritems()
                                 if dst not in regs_to_fix}
                 irs.append(AssignBlock(new_dsts, assignblk.instr))