diff options
Diffstat (limited to 'miasm2/arch/aarch64/sem.py')
| -rw-r--r-- | miasm2/arch/aarch64/sem.py | 87 |
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)) |