From 67d0b838e4e3ad77eeafef851c2e095da7ec172f Mon Sep 17 00:00:00 2001 From: moom Date: Sun, 7 Apr 2024 23:53:28 +0800 Subject: [PATCH] More arm instructions --- miasm/arch/arm/arch.py | 207 +++++++++++++++++++++++++++++++++++++++-- miasm/arch/arm/regs.py | 95 +++++++++++++++++++ miasm/arch/arm/sem.py | 62 ++++++++++++ test/arch/arm/arch.py | 42 +++++++++ test/arch/arm/sem.py | 20 +++- 5 files changed, 416 insertions(+), 10 deletions(-) diff --git a/miasm/arch/arm/arch.py b/miasm/arch/arm/arch.py index 91c22bd59..8a6053f65 100644 --- a/miasm/arch/arm/arch.py +++ b/miasm/arch/arm/arch.py @@ -50,6 +50,21 @@ regs_expr[:13] + [reg_dum, regs_expr[14], regs_expr[15]]) +# Single-Precision +spregs_str = ['S%d' % r for r in range(32)] +spregs_expr = [ExprId(x, 32) for x in spregs_str] +spregs = reg_info(spregs_str, spregs_expr) + +# Double-Precision +dpregs_str = ['D%d' % r for r in range(32)] +dpregs_expr = [ExprId(x, 64) for x in dpregs_str] +dpregs = reg_info(dpregs_str, dpregs_expr) + +# Quadword +qpregs_str = ['Q%d' % r for r in range(16)] +qpregs_expr = [ExprId(x, 128) for x in qpregs_str] +qpregs = reg_info(qpregs_str, qpregs_expr) + # psr sr_flags = "cxsf" cpsr_regs_str = [] @@ -1834,6 +1849,7 @@ def check_fbits(self, v): armop("dsb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0100'), barrier_option]) armop("isb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0110'), barrier_option]) +armop("dmb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0101'), barrier_option]) armop("nop", [bs8(0xE3), bs8(0x20), bs8(0xF0), bs8(0)]) class arm_widthm1(arm_imm, m_arg): @@ -2127,6 +2143,13 @@ def decodeval(self, v): def encodeval(self, v): return v >> 2 +class arm_off8(arm_imm): + + def decodeval(self, v): + return v << 2 + + def encodeval(self, v): + return v >> 2 class arm_off7(arm_imm): @@ -2137,11 +2160,16 @@ def encodeval(self, v): return v >> 2 class arm_deref_reg_imm(arm_arg): + reg_info = gpregs parser = deref_reg_imm def decode(self, v): v = v & self.lmask - rbase = regs_expr[v] + # We should not use regs_expr direct + # subclass overwrite reg_info in some case + if regs_expr[v] not in self.reg_info.expr: + return False + rbase = self.reg_info.expr[v] e = ExprOp('preinc', rbase, self.parent.off.expr) self.expr = ExprMem(e, 32) return True @@ -2164,9 +2192,6 @@ def encode(self): log.debug('cannot encode off %r', off) return False self.value = gpregs.expr.index(e.args[0]) - if self.value >= 1 << self.l: - log.debug('cannot encode reg %r', off) - return False return True class arm_derefl(arm_deref_reg_imm): @@ -2440,8 +2465,9 @@ class arm_sp(arm_reg): off5 = bs(l=5, cls=(arm_imm,), fname="off") off3 = bs(l=3, cls=(arm_imm,), fname="off") -off8 = bs(l=8, cls=(arm_imm,), fname="off") +imm8 = bs(l=8, cls=(arm_imm,), fname="off") off7 = bs(l=7, cls=(arm_off7,), fname="off") +off8 = bs(l=8, cls=(arm_off8,), fname="off", order=-1) rdl = bs(l=3, cls=(arm_gpreg_l,), fname="rd") rnl = bs(l=3, cls=(arm_gpreg_l,), fname="rn") @@ -2543,7 +2569,7 @@ class arm_sp(arm_reg): armtop("mshift", [bs('000'), bs_mshift_name, off5, rsl, rdl], [rdl, rsl, off5]) armtop("addsubr", [bs('000110'), bs_addsub_name, rnl, rsl, rdl], [rdl, rsl, rnl]) armtop("addsubi", [bs('000111'), bs_addsub_name, off3, rsl, rdl], [rdl, rsl, off3]) -armtop("mcas", [bs('001'), bs_mov_cmp_add_sub_name, rnl, off8]) +armtop("mcas", [bs('001'), bs_mov_cmp_add_sub_name, rnl, imm8]) armtop("alu", [bs('010000'), bs_alu_name, rsl, rdl], [rdl, rsl]) # should not be used ?? armtop("hiregop00", [bs('010001'), bs_hiregop_name, bs('00'), rsl, rdl], [rdl, rsl]) @@ -3436,9 +3462,69 @@ def encode(self): armtop("ldrd", [bs('1110100'), ppi, updown, bs('1'), wback_no_t, bs('1'), rn_nopc_noarg, rt, rt2, deref_immpuw00], [rt, rt2, deref_immpuw00]) -armtop("ldr", [bs('111110001101'), rn_deref, rt, off12], [rt, rn_deref]) -armtop("ldr", [bs('111110000101'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw]) -armtop("ldr", [bs('111110000101'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg]) +class armt_rn_deref_up(arm_arg): + parser = deref_reg_imm + + def decode(self, v): + v = v & self.lmask + rbase = regs_expr[v] + e = None + if self.parent.updown.value == 1: + e = ExprOp('preinc', rbase, self.parent.off.expr) + else: + e = ExprOp('preinc', rbase, -self.parent.off.expr) + self.expr = ExprMem(e, 32) + return True + + def encode(self): + self.parent.off.expr = None + e = self.expr + if not isinstance(e, ExprMem): + return False + e = e.ptr + if not (isinstance(e, ExprOp) and e.op == 'preinc'): + log.debug('cannot encode %r', e) + return False + off = e.args[1] + + if not isinstance(off, ExprInt): + log.debug('cannot encode off %r', off) + return False + + v = int(off) + + if v < 0 or v & (1 << 31): + self.parent.updown.value = 0 + v = (-v) & 0xFFFFFFFF + else: + self.parent.updown.value = 1 + + self.parent.off.expr = ExprInt(v, 32) + self.value = gpregs.expr.index(e.args[0]) + return True + +class arm_gpreg_nopc_noarg(reg_noarg): + reg_info = gpregs_nopc + parser = reg_info.parser + +class arm_nopc_deref(arm_deref_reg_imm): + reg_info = gpregs_nopc + +class armt_pc_deref_up(armt_rn_deref_up): + parser = deref_pc + +class armt_nopc_deref_up(armt_rn_deref_up): + pass + +rn_nopc_noarg = bs(l=4, cls=(arm_gpreg_nopc_noarg,), fname="rn") +rn_nopc_deref = bs(l=4, cls=(arm_nopc_deref,), fname="rt") +rn_nopc_deref_up = bs(l=4, cls=(armt_nopc_deref_up,)) +pc_deref_up = bs("1111", l=4, cls=(armt_pc_deref_up,)) + +armtop("ldr", [bs('11111000'), updown, bs('101'), pc_deref_up, rt, off12], [rt, pc_deref_up]) +armtop("ldr", [bs('111110001101'), rn_nopc_deref, rt, off12], [rt, rn_nopc_deref]) +armtop("ldr", [bs('111110000101'), rn_nopc_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw]) +armtop("ldr", [bs('111110000101'), rn_nopc_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg]) armtop("ldrb", [bs('111110000001'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg]) armtop("ldrb", [bs('111110000001'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw]) armtop("ldrb", [bs('111110001001'), rn_deref, rt_nopc, off12], [rt_nopc, rn_deref]) @@ -3456,3 +3542,106 @@ def encode(self): armtop("dsb", [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0100'), barrier_option]) armtop("adr", [bs('11110'), imm12_1, bs('100000'), bs('1111'), bs('0'), imm12_3, rd, imm12_8_t4], [rd, imm12_8_t4]) + +class arm_dpregs_1_4(reg_noarg): + reg_info = dpregs + parser = reg_info.parser + + + def decode(self, v): + v = v & self.lmask + v = self.parent.dpregs_1_x.value << 4 | v + self.expr = self.reg_info.expr[v] + return True + + def encode(self): + if not self.expr in self.reg_info.expr: + log.debug("cannot encode reg %r", self.expr) + return False + self.value = self.reg_info.expr.index(self.expr) + self.parent.dpregs_1_x.value = self.value >> 4 & self.parent.dpregs_1_x.lmask + return True + + +class arm_spregs_4_1(reg_noarg): + reg_info = spregs + parser = reg_info.parser + + + def decode(self, v): + v = v & self.lmask + v = self.parent.spregs_x_1.value | (v << 1) + self.expr = self.reg_info.expr[v] + return True + + def encode(self): + if not self.expr in self.reg_info.expr: + log.debug("cannot encode reg %r", self.expr) + return False + self.value = self.reg_info.expr.index(self.expr) + self.parent.spregs_x_1.value = self.value & self.parent.spregs_x_1.lmask + return True + +class arm_dpregs_4_1: + reg_info = dpregs + parser = reg_info.parser + + def decode(self, v): + v = v & self.lmask + v = self.parent.dpregs_x_1.value | v << 1 + self.expr = self.reg_info.expr[v] + return True + + def encode(self): + if not self.expr in self.reg_info.expr: + log.debug("cannot encode reg %r", self.expr) + return False + self.value = self.reg_info.expr.index(self.expr) + self.parent.dpregs_x_1.value = self.value & self.parent.dpregs_x_1.lmask + return True + + +sn_4_1 = bs(l=4, cls=(arm_spregs_4_1, arm_arg)) +sn_x_1 = bs(l=1, fname="spregs_x_1", order=-1) +sm_4_1 = bs(l=4, cls=(arm_spregs_4_1, arm_arg)) +sm_x_1 = bs(l=1, fname="spregs_x_1", order=-1) +dn_1_4 = bs(l=4, cls=(arm_dpregs_1_4, arm_arg)) +dn_1_x = bs(l=1, fname="dpregs_1_x", order=-1) +dm_4_1 = bs(l=4, cls=(arm_dpregs_4_1, arm_arg)) +dm_x_1 = bs(l=1, fname="dpregs_x_1", order=-1) +round_zero = bs('1', l=1, fname="round_zero") +vunsigned = bs(l=1, fname="unsigned") + +rt2_nopc = bs(l=4, cls=(arm_gpreg_nopc, arm_arg), fname="rt") +rn_sp_nowb = bs("1101", cls=(arm_gpreg,), fname='rnsp') + +armtop("dmb", [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0101'), barrier_option]) +armtop("teq", [bs('111010101001'), rn_nosppc, bs('0'), imm5_3, bs('1111'), imm5_2, imm_stype, rm_sh]) + +armtop("btransfersp", [bs('1110100010'), wback, bs_tbtransfer_name, rn_wb, pc_in, lr_in, bs('0'), trlist13pclr]) +armtop("add", [bs('11110'), imm12_1, bs('10000'), bs('0'), rn_sp_nowb, bs('0'), imm12_3, rd, imm12_8_t4], [rd, rn_sp_nowb, imm12_8_t4]) +armtop("strb", [bs('111110000000'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg]) +armtop("strex", [bs('111010000100'), rn_deref, rt, rd, off8], [rd, rt, rn_deref]) +armtop("ldrex",[bs('111010000101'), rn_deref, rt, bs('1111'), off8], [rt, rn_deref]) + +# DDI0406C.d, A8.8.344 +armtop("vmov", [bs('11101110000'), bs('1'), sn_4_1, rt_nopc, bs('1010'), sn_x_1, bs('0010000')], [rt_nopc, sn_4_1]) +armtop("vmov", [bs('11101110000'), bs('0'), sn_4_1, rt_nopc, bs('1010'), sn_x_1, bs('0010000')], [sn_4_1, rt_nopc]) + +# DDI0406C.d, A8.8.346 +armtop("vmov", [bs('11101100010'), bs('1'), rt2_nopc, rt_nopc, bs('101100'), dn_1_x, bs('1'), dn_1_4], [rt_nopc, rt2_nopc, dn_1_4]) +armtop("vmov", [bs('11101100010'), bs('0'), rt2_nopc, rt_nopc, bs('101100'), dn_1_x, bs('1'), dn_1_4], [dn_1_4, rt_nopc, rt2_nopc]) + +# DDI0406C.d, A8.8.310 +armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('1'), round_zero, bs('1'), dn_1_x, bs('0'), dn_1_4], [sn_4_1, dn_1_4]) +armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('0'), round_zero, bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1]) +armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("100"), sn_4_1, bs('101'), bs('1'), round_zero, bs('1'), dn_1_x, bs('0'), dn_1_4], [sn_4_1, dn_1_4]) +armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("100"), sn_4_1, bs('101'), bs('0'), round_zero, bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1]) +armtop("vcvt", [bs('111011101'), dn_1_x, bs('111'), bs("000"), dn_1_4, bs('101'), bs('1'), bs('1'), bs('1'), sm_x_1, bs('0'), sm_4_1], [dn_1_4, sm_4_1]) +armtop("vcvt", [bs('111011101'), dn_1_x, bs('111'), bs("000"), dn_1_4, bs('101'), bs('1'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [dn_1_4, sm_4_1]) +armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("000"), sn_4_1, bs('101'), bs('0'), bs('1'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1]) +armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("000"), sn_4_1, bs('101'), bs('0'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1]) + +# DDI0406C.d, A8.8.414 +armtop("vstr", [bs('11101101'), updown, dn_1_x, bs('00'), rn_nopc_deref_up, dn_1_4, bs('1011'), off8], [dn_1_4, rn_nopc_deref_up]) +armtop("vstr", [bs('11101101'), updown, sn_x_1, bs('00'), rn_nopc_deref_up, sn_4_1, bs('1010'), off8], [sn_4_1, rn_nopc_deref_up]) \ No newline at end of file diff --git a/miasm/arch/arm/regs.py b/miasm/arch/arm/regs.py index 2b24b0d5a..826c177e1 100644 --- a/miasm/arch/arm/regs.py +++ b/miasm/arch/arm/regs.py @@ -4,6 +4,101 @@ from miasm.expression.expression import * from miasm.core.cpu import gen_reg, gen_regs +# SP, DP, QP + +spregs_str = ['S%d' % r for r in range(32)] +spregs_expr = [ExprId(x, 32) for x in spregs_str] + +dpregs_str = ['D%d' % r for r in range(32)] +dpregs_expr = [ExprId(x, 64) for x in dpregs_str] + +qpregs_str = ['Q%d' % r for r in range(16)] +qpregs_expr = [ExprId(x, 128) for x in qpregs_str] + +D0 = dpregs_expr[0] +D1 = dpregs_expr[1] +D2 = dpregs_expr[2] +D3 = dpregs_expr[3] +D4 = dpregs_expr[4] +D5 = dpregs_expr[5] +D6 = dpregs_expr[6] +D7 = dpregs_expr[7] +D8 = dpregs_expr[8] +D9 = dpregs_expr[9] +D10 = dpregs_expr[10] +D11 = dpregs_expr[11] +D12 = dpregs_expr[12] +D13 = dpregs_expr[13] +D14 = dpregs_expr[14] +D15 = dpregs_expr[15] +D16 = dpregs_expr[16] +D17 = dpregs_expr[17] +D18 = dpregs_expr[18] +D19 = dpregs_expr[19] +D20 = dpregs_expr[20] +D21 = dpregs_expr[21] +D22 = dpregs_expr[22] +D23 = dpregs_expr[23] +D24 = dpregs_expr[24] +D25 = dpregs_expr[25] +D26 = dpregs_expr[26] +D27 = dpregs_expr[27] +D28 = dpregs_expr[28] +D29 = dpregs_expr[29] +D30 = dpregs_expr[30] +D31 = dpregs_expr[31] + + +S0 = spregs_expr[0] +S1 = spregs_expr[1] +S2 = spregs_expr[2] +S3 = spregs_expr[3] +S4 = spregs_expr[4] +S5 = spregs_expr[5] +S6 = spregs_expr[6] +S7 = spregs_expr[7] +S8 = spregs_expr[8] +S9 = spregs_expr[9] +S10 = spregs_expr[10] +S11 = spregs_expr[11] +S12 = spregs_expr[12] +S13 = spregs_expr[13] +S14 = spregs_expr[14] +S15 = spregs_expr[15] +S16 = spregs_expr[16] +S17 = spregs_expr[17] +S18 = spregs_expr[18] +S19 = spregs_expr[19] +S20 = spregs_expr[20] +S21 = spregs_expr[21] +S22 = spregs_expr[22] +S23 = spregs_expr[23] +S24 = spregs_expr[24] +S25 = spregs_expr[25] +S26 = spregs_expr[26] +S27 = spregs_expr[27] +S28 = spregs_expr[28] +S29 = spregs_expr[29] +S30 = spregs_expr[30] +S31 = spregs_expr[31] + +Q0 = qpregs_expr[0] +Q1 = qpregs_expr[1] +Q2 = qpregs_expr[2] +Q3 = qpregs_expr[3] +Q4 = qpregs_expr[4] +Q5 = qpregs_expr[5] +Q6 = qpregs_expr[6] +Q7 = qpregs_expr[7] +Q8 = qpregs_expr[8] +Q9 = qpregs_expr[9] +Q10 = qpregs_expr[10] +Q11 = qpregs_expr[11] +Q12 = qpregs_expr[12] +Q13 = qpregs_expr[13] +Q14 = qpregs_expr[14] +Q15 = qpregs_expr[15] + # GP regs32_str = ["R%d" % i for i in range(13)] + ["SP", "LR", "PC"] diff --git a/miasm/arch/arm/sem.py b/miasm/arch/arm/sem.py index a138ef919..d98c6a405 100644 --- a/miasm/arch/arm/sem.py +++ b/miasm/arch/arm/sem.py @@ -6,6 +6,7 @@ from miasm.ir.ir import Lifter, IRBlock, AssignBlock from miasm.arch.arm.arch import mn_arm, mn_armt from miasm.arch.arm.regs import * +from miasm.arch.arm.arch import regs_expr from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX @@ -1139,6 +1140,60 @@ def blx(ir, instr, a): e.append(ExprAssign(LR, l)) return e, [] +def vmov(ir, instr, a, b, c=None): + e = [] + if c is None: + if a not in spregs_expr and b not in spregs_expr: + raise NotImplementedError('Not implemented') + e.append(ExprAssign(a, b)) + else: + if a in dpregs_expr: + # two gp to one dp + # a[:32] = b + # a[32:] = c + e.append(ExprAssign(a, (c.zeroExtend(a.size) << ExprInt(32, 64) | b.zeroExtend(a.size)))) + elif a in regs_expr: + # one dp to two gp + # a = c[:32] + # b = c[32:] + e.append(ExprAssign(a, c[:32])) + e.append(ExprAssign(b, c[32:])) + else: + raise NotImplementedError('Not implemented') + + return e, [] + +def vstr(ir, instr, a, b): + e = [] + if a in spregs_expr: + e.append(ExprAssign(b, a)) + elif a in dpregs_expr: + if instr.mode == 'l': + e.append(ExprAssign(b, a[:32])) + e.append(ExprAssign(ExprMem(b.ptr + ExprInt(4, 32), 32), a[32:])) + else: + e.append(ExprAssign(b, a[32:])) + e.append(ExprAssign(ExprMem(b.ptr + ExprInt(4, 32), 32), a[:32])) + else: + raise NotImplementedError('Not implemented') + return e, [] + +# todo +def vcvt(ir, instr, a, b): + raise NotImplementedError('Not implemented') + +# todo +def strex(ir, instr, a, b, c=None): + raise NotImplementedError('Not implemented') + +# todo +def ldrex(ir, instr, a, b): + raise NotImplementedError('Not implemented') + +def dmb(ir, instr, a): + """Memory barrier""" + e = [] + return e, [] def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False): e = [] @@ -1930,6 +1985,8 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): 'pkhtb': pkhtb, 'pkhbt': pkhbt, + 'ldrex': ldrex, + 'strex': strex, } mnemo_condm1 = {'adds': add, @@ -1959,6 +2016,10 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): 'ldrb': ldrb, 'ldsb': ldrsb, 'strb': strb, + + 'vmov': vmov, + 'vstr': vstr, + 'vcvt': vcvt } mnemo_condm2 = {'ldmia': ldmia, @@ -2014,6 +2075,7 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): 'smlatt': smlatt, 'uadd8': uadd8, 'sel': sel, + 'dmb': dmb } mn_cond_x = [mnemo_condm0, diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py index a3f3a9742..cf2dd5e49 100644 --- a/test/arch/arm/arch.py +++ b/test/arch/arm/arch.py @@ -719,6 +719,48 @@ def u16swap(i): "B5EB102F"), + ("xxxxxxxx LDMIA R0, {R2, R3, R6, R7}", + "90E8CC00"), + ("xxxxxxxx DMB SY", + "BFF35F8F"), + ("xxxxxxxx STRB R3, [R4, R8]", + "04F80830"), + ("xxxxxxxx STRB R2, [R3, R9]", + "03F80920"), + ("xxxxxxxx LDREX R3, [R1]", + "51E8003F"), + ("xxxxxxxx LDREX R2, [R12]", + "5CE8002F"), + ("xxxxxxxx STREX LR, R1, [R3]", + "43E8001E"), + ("xxxxxxxx STREX R0, LR, [R2]", + "42E800E0"), + ("xxxxxxxx TEQ R0, R1", + "90EA010F"), + ("xxxxxxxx ADD R0, SP, 0x714", + "0DF21470"), + ("xxxxxxxx VMOV S0, R0", + "00EE100A"), + ("xxxxxxxx VMOV R2, R3, D0", + "53EC102B"), + ("xxxxxxxx VCVT D0, S0", + "B8EEC00B"), + ("xxxxxxxx VMOV R2, R3, D0", + "53EC102B"), + ("xxxxxxxx VMOV D0, R0, R1", + "41EC100B"), + ("xxxxxxxx VCVT S0, D0", + "BDEEC00B"), + ("xxxxxxxx VSTR S0, [SP, 0x30]", + "8DED0C0A"), + ("xxxxxxxx VSTR D0, [SP, 0x90]", + "8DED240B"), + ("xxxxxxxx ADD R7, SP, 0xC", + "03af"), + ("xxxxxxxx LDR R5, [PC, 0xF80]", + "DFF8805F"), + ("xxxxxxxx LDR R1, [PC, 0xFFFFF970]", + "5FF89016"), ] print("#" * 40, 'armthumb', '#' * 40) diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py index 343bc063f..bbb238f5d 100755 --- a/test/arch/arm/sem.py +++ b/test/arch/arm/sem.py @@ -8,7 +8,7 @@ from future.utils import viewitems from miasm.ir.symbexec import SymbolicExecutionEngine -from miasm.arch.arm.arch import mn_arm as mn +from miasm.arch.arm.arch import mn_arm, mn_armt from miasm.arch.arm.sem import Lifter_Arml as Lifter from miasm.arch.arm.regs import * from miasm.expression.expression import * @@ -23,8 +23,14 @@ def M(addr): return ExprMem(ExprInt(addr, 16), 16) +# compute for armt +def compute_t(asm, inputstate={}, debug=False): + return _compute(asm, mn_armt, inputstate, debug) def compute(asm, inputstate={}, debug=False): + return _compute(asm, mn_arm, inputstate, debug) + +def _compute(asm, mn, inputstate={}, debug=False): loc_db = LocationDB() sympool = dict(regs_init) sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)}) @@ -546,6 +552,18 @@ def test_SMLAL(self): self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x0, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c768e, R4: 0x12345678, R5: 0x87654321}) self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x00000002, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c7690, R4: 0x12345678, R5: 0x87654321}) + def test_vmov(self): + self.assertEqual(compute_t('VMOV S0, R0', {S0: 0x1, R0: 0x2}), {S0: 0x2, R0: 0x2}) + self.assertEqual(compute_t('VMOV R0, S0', {S0: 0x1, R0: 0x2}), {S0: 0x1, R0: 0x1}) + self.assertEqual(compute_t('VMOV D0, R0, R1', {D0: 0x1, R0: 0x2, R1:0x3}), {D0: 0x2 | (0x3 << 32), R0: 0x2, R1: 0x3}) + self.assertEqual(compute_t('VMOV R0, R1, D0', {D0: 0xfffffffcfffffffe, R0: 0x2, R1:0x3}), {D0: 0xfffffffcfffffffe, R0: 0xfffffffe, R1: 0xfffffffc}) + self.assertEqual(compute_t('VSTR S0, [SP, 0x30]', + {S0: 0x10000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x50}), + {S0: 0x10000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x10000}) + self.assertEqual(compute_t('VSTR D0, [SP, 0x30]', + {D0: 0x1000000020000000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x50 , ExprMem(ExprOp('+', ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), ExprInt(4, 32)), 32): 0x50}), + {D0: 0x1000000020000000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x20000000, ExprMem(ExprOp('+', ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), ExprInt(4, 32)), 32): 0x10000000}) + if __name__ == '__main__': testsuite = unittest.TestLoader().loadTestsFromTestCase(TestARMSemantic) report = unittest.TextTestRunner(verbosity=2).run(testsuite)