From 40b4e78e6b4fde10b634201194f7e6d5f03744fc Mon Sep 17 00:00:00 2001 From: atlas0fd00m Date: Wed, 18 Dec 2024 14:24:53 -0500 Subject: [PATCH] arm improvements (#672) * more * more * more * more arm improvements * updates for undefined and arch='arm' * unittests * more ARM disasm coverage * undefined, so let's not test :) * test count --- envi/archs/arm/const.py | 1 + envi/archs/arm/disasm.py | 44 ++++++++++++++++++------------------ envi/archs/thumb16/disasm.py | 21 +++++++++++++++++ envi/tests/test_arch_arm.py | 25 ++++++++++++++++++-- 4 files changed, 67 insertions(+), 24 deletions(-) diff --git a/envi/archs/arm/const.py b/envi/archs/arm/const.py index 8c30ee148..1d14e72d2 100644 --- a/envi/archs/arm/const.py +++ b/envi/archs/arm/const.py @@ -415,6 +415,7 @@ 'MOV', 'BIC', 'MVN', + 'HLT', 'ORN', 'ADR', 'B', diff --git a/envi/archs/arm/disasm.py b/envi/archs/arm/disasm.py index 2e1f518be..ba1dcf88d 100644 --- a/envi/archs/arm/disasm.py +++ b/envi/archs/arm/disasm.py @@ -756,17 +756,14 @@ def p_dp_imm(opval, va): return (opcode, mnem, olist, iflags, 0) def p_undef(opval, va): - # FIXME: make this an actual opcode with the opval as an imm oper? - raise envi.InvalidInstruction( - mesg="p_undef: invalid instruction (by definition in ARM spec)", - bytez=struct.pack("> 26 ) & 0x3 if optop == 0: @@ -2319,21 +2316,21 @@ def p_advsimd_secondary(val, va, mnem, opcode, flags, opers): ('vcgt', INS_VCGT, IFS_S8, None), ('vcgt', INS_VCGT, IFS_S16, None), ('vcgt', INS_VCGT, IFS_S32, None), - (None, None, 0, None), + ('vcgt', INS_VCGT, IFS_S64, None), ('vcgt', INS_VCGT, IFS_U8, None), ('vcgt', INS_VCGT, IFS_U16, None), ('vcgt', INS_VCGT, IFS_U32, None), - (None, None, 0, None), + ('vcgt', INS_VCGT, IFS_U64, None), # a=0011 b=1 ('vcge', INS_VCGE, IFS_S8, None), ('vcge', INS_VCGE, IFS_S16, None), ('vcge', INS_VCGE, IFS_S32, None), - (None, None, 0, None), + ('vcge', INS_VCGE, IFS_S64, None), ('vcge', INS_VCGE, IFS_U8, None), ('vcge', INS_VCGE, IFS_U16, None), ('vcge', INS_VCGE, IFS_U32, None), - (None, None, 0, None), + ('vcge', INS_VCGE, IFS_U64, None), # a=0100 b=0 ('vshl', INS_VSHL, IFS_S8, None), # d, m, n, not d, n, m like all the others in this category @@ -2847,15 +2844,15 @@ def p_advsimd_secondary(val, va, mnem, opcode, flags, opers): (None, 0, 0, 0,0, 0), (None, 0, 0, 0,0, 0), # a=11 b=000xx - (None, 0, 0, 0,0, 0), - (None, 0, 0, 0,0, 0), - (None, 0, 0, 0,0, 0), - (None, 0, 0, 0,0, 0), + ('vcgt', INS_VCGT, ADV_SIMD_S8, 0,0, 0), # , #0 + ('vcgt', INS_VCGT, ADV_SIMD_S8, 1,1, 0), # , #0 + ('vcge', INS_VCGE, ADV_SIMD_S8, 0,0, 0), # , #0 + ('vcge', INS_VCGE, ADV_SIMD_S8, 1,1, 0), # , #0 # a=11 b=001xx - (None, 0, 0, 0,0, 0), - (None, 0, 0, 0,0, 0), - (None, 0, 0, 0,0, 0), - (None, 0, 0, 0,0, 0), + ('vceq', INS_VCEQ, ADV_SIMD_I8, 0,0, 0), # , #0 + ('vceq', INS_VCEQ, ADV_SIMD_I8, 1,1, 0), # , #0 + ('vcle', INS_VCLE, ADV_SIMD_I8, 0,0, 0), # , #0 + ('vcle', INS_VCLE, ADV_SIMD_I8, 1,1, 0), # , #0 # a=11 b=010xx (None, 0, 0, 0,0, 0), (None, 0, 0, 0,0, 0), @@ -3340,6 +3337,9 @@ def _do_adv_simd_ldst_32(val, va, u): return opcode, mnem, opers, iflags, simdflags # no iflags, only simdflags for this one def adv_simd_32(val, va): + if val == 0xffffffff: + return p_undef(val, va) + u = (val>>24) & 1 return _do_adv_simd_32(val, va, u) @@ -3367,9 +3367,9 @@ def _do_adv_simd_32(val, va, u): if not (a & 0x10): # three registers of the same length - a = (val>>8) & 0xf - b = (val>>4) & 1 - c = (val>>20) & 3 + a = (val>>8) & 0xf # opc + b = (val>>4) & 1 # o1 + c = (val>>20) & 3 # size index = c | (u<<2) | (b<<3) | (a<<4) mnem, opcode, simdflags, handler = adv_simd_3_regs[index] diff --git a/envi/archs/thumb16/disasm.py b/envi/archs/thumb16/disasm.py index 873fc6ebe..75d4ab096 100644 --- a/envi/archs/thumb16/disasm.py +++ b/envi/archs/thumb16/disasm.py @@ -584,6 +584,12 @@ def i_imm5_rn(va, value): return COND_AL, (oper0, oper1,), None +def i_imm6(va, value): + imm6 = shmaskval(value, 0, 0x3f) + oper0 = ArmImmOper(imm6, va=va) + return COND_AL, (oper0,), None + + def ldm16(va, value): raise Exception("32bit wrapping of 16bit instruction... and it's not implemented") @@ -1940,6 +1946,14 @@ def adv_simd_ldst_32(va, val1, val2): def adv_simd_32(va, val1, val2): + if val1 == 0xffff and val2 == 0xffff: # skip this known-bad encoding + olist = ( + ArmImmOper(0xffffffff), + ) + iflags = envi.IF_NOFALL | IF_THUMB32 + + return COND_AL, IENC_UNDEF, 'undefined', olist, iflags, 0 + val = (val1 << 16) | val2 u = (val1 >> 12) & 1 opcode, mnem, opers, iflags, simdflags = _do_adv_simd_32(val, va, u) @@ -2265,6 +2279,7 @@ def adv_xfer_arm_ext_64(va, val1, val2): ('10111011', (INS_CBNZ, 'cbnz', i_imm5_rn, envi.IF_COND | envi.IF_BRANCH)), ('1011101000', (INS_REV, 'rev', rm_rdn, 0)), # REV Rd, Rn ('1011101001', (INS_REV16, 'rev16', rm_rdn, 0)), # REV16 Rd, Rn + ('1011101010', (INS_HLT, 'hlt', i_imm6, envi.IF_NOFALL)), # HLT imm6 ('1011101011', (INS_REVSH, 'revsh', rm_rdn, 0)), # REVSH Rd, Rn ('101100000', (INS_ADD, 'add', sp_sp_imm7, 0)), # ADD SP,SP,# @@ -2454,10 +2469,16 @@ def adv_xfer_arm_ext_64(va, val1, val2): ('11110000010', (INS_ORR, 'orr', dp_mod_imm_32, IF_THUMB32)), ('11110000011', (INS_ORN, 'orn', dp_mod_imm_32, IF_THUMB32)), # mvn if rn=1111 + ('11110000101', (INS_BL, 'bl', + branch_misc, IF_THUMB32)), # necessary # teq if rd=1111 and s=1 ('11110000100', (INS_EOR, 'eor', dp_mod_imm_32, IF_THUMB32)), + ('11110000101', (INS_BL, 'bl', + branch_misc, IF_THUMB32)), # necessary ('11110000110', (INS_BLX, 'blx', branch_misc, IF_THUMB32)), # necessary + ('11110000111', (INS_BL, 'bl', + branch_misc, IF_THUMB32)), # necessary # cmn if rd=1111 and s=1 ('11110001000', (INS_ADD, 'add', dp_mod_imm_32, IF_THUMB32)), ('11110001001', (INS_BLX, 'blx', diff --git a/envi/tests/test_arch_arm.py b/envi/tests/test_arch_arm.py index d1e243b46..75f929176 100644 --- a/envi/tests/test_arch_arm.py +++ b/envi/tests/test_arch_arm.py @@ -31,9 +31,9 @@ logger = logging.getLogger(__name__) -GOOD_TESTS_ALL = 6125 +GOOD_TESTS_ALL = 6144 GOOD_TESTS_THUMB = 8849 -GOOD_EMU_TESTS = 1205 +GOOD_EMU_TESTS = 1208 GOOD_EMU_THUMB = 8776 @@ -145,6 +145,10 @@ (REV_ALL_ARM, '22209ae7', 0xbfb00000, 'ldr r2, [r10, r2, lsr #32]', 0, ()), (REV_ALL_ARM, '08309fe5', 0xbfb00000, 'ldr r3, [#0xbfb00010]', 0, ()), (REV_ALL_ARM, '08309fe5', 0xbfb00000, 'ldr r3, [#0xbfb00010]', 0, ()), + + (REV_ALL_ARM, 'ffffffff', 0xbfb00000, 'undefined #0xffffff', IF_NOFALL, ()), + (REV_ALL_ARM, 'aaba', 0x4561, 'hlt #0x2a', IF_NOFALL, ()), + (REV_ALL_ARM, '674503e0', 0x4560, 'and r4, r3, r7, ror #10', 0, ()), (REV_ALL_ARM, '674513e0', 0x4560, 'ands r4, r3, r7, ror #10', 0, ()), (REV_ALL_ARM, '674523e0', 0x4560, 'eor r4, r3, r7, ror #10', 0, ()), @@ -179,6 +183,9 @@ (REV_ALL_ARM, '774553e0', 0x4560, 'subs r4, r3, r7, ror r5', 0, ()), (REV_ALL_ARM, '774563e0', 0x4560, 'rsb r4, r3, r7, ror r5', 0, ()), (REV_ALL_ARM, '774573e0', 0x4560, 'rsbs r4, r3, r7, ror r5', 0, ()), + (REV_ALL_ARM, '774553e0', 0x4560, 'subs r4, r3, r7, ror r5', 0, ()), + (REV_ALL_ARM, '774563e0', 0x4560, 'rsb r4, r3, r7, ror r5', 0, ()), + (REV_ALL_ARM, '774573e0', 0x4560, 'rsbs r4, r3, r7, ror r5', 0, ()), (REV_ALL_ARM, '774583e0', 0x4560, 'add r4, r3, r7, ror r5', 0, ()), (REV_ALL_ARM, '774593e0', 0x4560, 'adds r4, r3, r7, ror r5', 0, ()), (REV_ALL_ARM, '7745a3e0', 0x4560, 'adc r4, r3, r7, ror r5', 0, ()), @@ -1401,54 +1408,68 @@ (REV_ALL_ARM, '4861b1f3', 0x4560, 'vceq.i8 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '4861b5f3', 0x4560, 'vceq.i16 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '4861b9f3', 0x4560, 'vceq.i32 q3, q4, #0x00', 0, ()), + (REV_ALL_ARM, '4861bdf3', 0x4560, 'vceq.i64 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '4865b9f3', 0x4560, 'vceq.f32 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '0431b1f3', 0x4560, 'vceq.i8 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '0431b5f3', 0x4560, 'vceq.i16 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '0431b9f3', 0x4560, 'vceq.i32 d3, d4, #0x00', 0, ()), + (REV_ALL_ARM, '0431bdf3', 0x4560, 'vceq.i64 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '0435b9f3', 0x4560, 'vceq.f32 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '5e6308f2', 0x4560, 'vcge.s8 q3, q4, q7', 0, ()), (REV_ALL_ARM, '5e6318f2', 0x4560, 'vcge.s16 q3, q4, q7', 0, ()), (REV_ALL_ARM, '5e6328f2', 0x4560, 'vcge.s32 q3, q4, q7', 0, ()), + (REV_ALL_ARM, '5e6338f2', 0x4560, 'vcge.s64 q3, q4, q7', 0, ()), (REV_ALL_ARM, '5e6308f3', 0x4560, 'vcge.u8 q3, q4, q7', 0, ()), (REV_ALL_ARM, '5e6318f3', 0x4560, 'vcge.u16 q3, q4, q7', 0, ()), (REV_ALL_ARM, '5e6328f3', 0x4560, 'vcge.u32 q3, q4, q7', 0, ()), + (REV_ALL_ARM, '5e6338f3', 0x4560, 'vcge.u64 q3, q4, q7', 0, ()), (REV_ALL_ARM, '4e6e08f3', 0x4560, 'vcge.f32 q3, q4, q7', 0, ()), (REV_ALL_ARM, '173304f2', 0x4560, 'vcge.s8 d3, d4, d7', 0, ()), (REV_ALL_ARM, '173314f2', 0x4560, 'vcge.s16 d3, d4, d7', 0, ()), (REV_ALL_ARM, '173324f2', 0x4560, 'vcge.s32 d3, d4, d7', 0, ()), + (REV_ALL_ARM, '173334f2', 0x4560, 'vcge.s64 d3, d4, d7', 0, ()), (REV_ALL_ARM, '173304f3', 0x4560, 'vcge.u8 d3, d4, d7', 0, ()), (REV_ALL_ARM, '173314f3', 0x4560, 'vcge.u16 d3, d4, d7', 0, ()), (REV_ALL_ARM, '173324f3', 0x4560, 'vcge.u32 d3, d4, d7', 0, ()), + (REV_ALL_ARM, '173334f3', 0x4560, 'vcge.u64 d3, d4, d7', 0, ()), (REV_ALL_ARM, '073e04f3', 0x4560, 'vcge.f32 d3, d4, d7', 0, ()), (REV_ALL_ARM, '8430b1f3', 0x4560, 'vcge.s8 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '8430b5f3', 0x4560, 'vcge.s16 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '8430b9f3', 0x4560, 'vcge.s32 d3, d4, #0x00', 0, ()), + (REV_ALL_ARM, '8430bdf3', 0x4560, 'vcge.s64 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '8434b9f3', 0x4560, 'vcge.f32 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, 'c860b1f3', 0x4560, 'vcge.s8 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, 'c860b5f3', 0x4560, 'vcge.s16 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, 'c860b9f3', 0x4560, 'vcge.s32 q3, q4, #0x00', 0, ()), + (REV_ALL_ARM, 'c860bdf3', 0x4560, 'vcge.s64 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, 'c864b9f3', 0x4560, 'vcge.f32 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '4e6308f2', 0x4560, 'vcgt.s8 q3, q4, q7', 0, ()), (REV_ALL_ARM, '4e6318f2', 0x4560, 'vcgt.s16 q3, q4, q7', 0, ()), (REV_ALL_ARM, '4e6328f2', 0x4560, 'vcgt.s32 q3, q4, q7', 0, ()), + (REV_ALL_ARM, '4e6338f2', 0x4560, 'vcgt.s64 q3, q4, q7', 0, ()), (REV_ALL_ARM, '4e6308f3', 0x4560, 'vcgt.u8 q3, q4, q7', 0, ()), (REV_ALL_ARM, '4e6318f3', 0x4560, 'vcgt.u16 q3, q4, q7', 0, ()), (REV_ALL_ARM, '4e6328f3', 0x4560, 'vcgt.u32 q3, q4, q7', 0, ()), + (REV_ALL_ARM, '4e6338f3', 0x4560, 'vcgt.u64 q3, q4, q7', 0, ()), (REV_ALL_ARM, '4e6e28f3', 0x4560, 'vcgt.f32 q3, q4, q7', 0, ()), (REV_ALL_ARM, '073304f2', 0x4560, 'vcgt.s8 d3, d4, d7', 0, ()), (REV_ALL_ARM, '073314f2', 0x4560, 'vcgt.s16 d3, d4, d7', 0, ()), (REV_ALL_ARM, '073324f2', 0x4560, 'vcgt.s32 d3, d4, d7', 0, ()), + (REV_ALL_ARM, '073334f2', 0x4560, 'vcgt.s64 d3, d4, d7', 0, ()), (REV_ALL_ARM, '073304f3', 0x4560, 'vcgt.u8 d3, d4, d7', 0, ()), (REV_ALL_ARM, '073314f3', 0x4560, 'vcgt.u16 d3, d4, d7', 0, ()), (REV_ALL_ARM, '073324f3', 0x4560, 'vcgt.u32 d3, d4, d7', 0, ()), + (REV_ALL_ARM, '073334f3', 0x4560, 'vcgt.u64 d3, d4, d7', 0, ()), (REV_ALL_ARM, '073e24f3', 0x4560, 'vcgt.f32 d3, d4, d7', 0, ()), (REV_ALL_ARM, '0430b1f3', 0x4560, 'vcgt.s8 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '0430b5f3', 0x4560, 'vcgt.s16 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '0430b9f3', 0x4560, 'vcgt.s32 d3, d4, #0x00', 0, ()), + (REV_ALL_ARM, '0430bdf3', 0x4560, 'vcgt.s64 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '0434b9f3', 0x4560, 'vcgt.f32 d3, d4, #0x00', 0, ()), (REV_ALL_ARM, '4860b1f3', 0x4560, 'vcgt.s8 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '4860b5f3', 0x4560, 'vcgt.s16 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '4860b9f3', 0x4560, 'vcgt.s32 q3, q4, #0x00', 0, ()), + (REV_ALL_ARM, '4860bdf3', 0x4560, 'vcgt.s64 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '4864b9f3', 0x4560, 'vcgt.f32 q3, q4, #0x00', 0, ()), (REV_ALL_ARM, '0434b0f3', 0x4560, 'vcls.s8 d3, d4', 0, ()), (REV_ALL_ARM, '0434b4f3', 0x4560, 'vcls.s16 d3, d4', 0, ()),