From 1b524ce0e645e451ca76723f4f86fe2a71c1adf2 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 25 May 2016 23:19:42 +0200 Subject: Fixed various mistakes in the decoding of ARM instructions. --- ChangeLog | 7 ++ src/arch/arm/v7/arm.c | 144 ++++++++++-------------------- src/arch/arm/v7/opcodes/opcodes_tmp_arm.h | 2 - src/arch/arm/v7/pseudo.c | 6 +- 4 files changed, 58 insertions(+), 101 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6895d32..3660bbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +16-05-25 Cyrille Bagard + + * src/arch/arm/v7/arm.c: + * src/arch/arm/v7/opcodes/opcodes_tmp_arm.h: + * src/arch/arm/v7/pseudo.c: + Fix various mistakes in the decoding of ARM instructions. + 16-05-24 Cyrille Bagard * src/analysis/disass/area.c: diff --git a/src/arch/arm/v7/arm.c b/src/arch/arm/v7/arm.c index af92096..9a29939 100644 --- a/src/arch/arm/v7/arm.c +++ b/src/arch/arm/v7/arm.c @@ -531,7 +531,7 @@ static GArchInstruction *process_armv7_arm_data_processing_immediate(uint32_t ra * § A5.2.3 Data-processing (immediate) */ - if ((raw & 0x0e000000) != 0x04000000) return NULL; + if ((raw & 0x0e000000) != 0x02000000) return NULL; result = NULL; @@ -1101,7 +1101,7 @@ static GArchInstruction *process_armv7_arm_miscellaneous_instructions(uint32_t r * § A5.2.12 Miscellaneous instructions */ - if ((raw & 0x0f900080) != 0x00100000) return NULL; + if ((raw & 0x0f900080) != 0x01000000) return NULL; result = NULL; @@ -1229,126 +1229,74 @@ static GArchInstruction *process_armv7_arm_load_store_word_and_unsigned_byte(uin rn = (raw >> 16) & 0xf; b = (raw >> 4) & 0x1; - if ((op1 & b10111) == b00010) + if (a == b0) { - if (a == b0) - { - result = armv7_read_arm_instr_strt(raw); - goto a53_done; - } - else if (/*a == b1 && */b == b0) - goto a53_done; - } - else if ((op1 & b00101) == b00000) - { - if (a == b0) - { + if ((op1 & b00101) == b00000 && (op1 & b10111) != b00010) result = armv7_read_arm_instr_str_immediate_arm(raw); - goto a53_done; - } - else if (/*a == b1 && */b == b0) - { - result = armv7_read_arm_instr_str_register(raw); - goto a53_done; - } - } - if ((op1 & b10111) == b00011) - { - if (a == b0) - { - result = armv7_read_arm_instr_ldrt(raw); - goto a53_done; - } - else if (/*a == b1 && */b == b0) - goto a53_done; - } - else if ((op1 & b00101) == b00001) - { - if (a == b0) + else if ((op1 & b10111) == b00010) + result = armv7_read_arm_instr_strt(raw); + + else if ((op1 & b00101) == b00001 && (op1 & b10111) != b00011) { - if (rn == b1111) - result = armv7_read_arm_instr_ldr_literal(raw); - else + if (rn != b1111) result = armv7_read_arm_instr_ldr_immediate_arm(raw); + else + result = armv7_read_arm_instr_ldr_literal(raw); + } - goto a53_done; + else if ((op1 & b10111) == b00011) + result = armv7_read_arm_instr_ldrt(raw); - } - else if (/*a == b1 && */b == b0) - { - result = armv7_read_arm_instr_ldr_register(raw); - goto a53_done; - } - } + else if ((op1 & b00101) == b00100 && (op1 & b10110) != b00110) + result = armv7_read_arm_instr_strb_immediate_arm(raw); - if ((op1 & b10111) == b00110) - { - if (a == b0) - { + else if ((op1 & b10110) == b00110) result = armv7_read_arm_instr_strbt(raw); - goto a53_done; - } - else if (/*a == b1 && */b == b0) - goto a53_done; - } - else if ((op1 & b00101) == b00100) - { - if (a == b0) - { - result = armv7_read_arm_instr_strb_immediate_arm(raw); - goto a53_done; - } - else if (/*a == b1 && */b == b0) - { - result = armv7_read_arm_instr_strb_register(raw); - goto a53_done; - } - } - if ((op1 & b10111) == b00111) - { - if (a == b0) + else if ((op1 & b00101) == b00101 && (op1 & b10111) != b00111) { - result = armv7_read_arm_instr_ldrbt(raw); - goto a53_done; - } - else if (/*a == b1 && */b == b0) - goto a53_done; - } - else if ((op1 & b00101) == b00101) - { - if (a == b0) - { - if (rn == b1111) - result = armv7_read_arm_instr_ldrb_literal(raw); - else + if (rn != b1111) result = armv7_read_arm_instr_ldrb_immediate_arm(raw); - - goto a53_done; - - } - else if (/*a == b1 && */b == b0) - { - result = armv7_read_arm_instr_ldrb_register(raw); - goto a53_done; + else + result = armv7_read_arm_instr_ldrb_literal(raw); } - } - a53_done: + else if ((op1 & b10111) == b00111) + result = armv7_read_arm_instr_ldrbt(raw); - return result; + } + else /*if (a == b1)*/ + { + if ((op1 & b00101) == b00000 && (op1 & b10111) != b00010 && b == b0) + result = armv7_read_arm_instr_str_register(raw); -} + else if ((op1 & b10111) == b00010 && b == b0) + result = armv7_read_arm_instr_strt(raw); + else if ((op1 & b00101) == b00001 && (op1 & b10111) != b00011 && b == b0) + result = armv7_read_arm_instr_ldr_register_arm(raw); + else if ((op1 & b10111) == b00011 && b == b0) + result = armv7_read_arm_instr_ldrt(raw); + else if ((op1 & b00101) == b00100 && (op1 & b10110) != b00110 && b == b0) + result = armv7_read_arm_instr_strb_register(raw); + else if ((op1 & b10110) == b00110 && b == b0) + result = armv7_read_arm_instr_strbt(raw); + else if ((op1 & b00101) == b00101 && (op1 & b10111) != b00111 && b == b0) + result = armv7_read_arm_instr_ldrb_register(raw); + else if ((op1 & b10111) == b00111 && b == b0) + result = armv7_read_arm_instr_ldrbt(raw); + } + return result; +} /****************************************************************************** @@ -2291,7 +2239,7 @@ static GArchInstruction *process_armv7_arm_memory_hints_advanced_simd_instructio result = armv7_read_arm_instr_dsb(raw); else if (op2 == b0101) - result = armv7_read_arm_instr_dmd(raw); + result = armv7_read_arm_instr_dmb(raw); else if (op2 == b0110) result = armv7_read_arm_instr_isb(raw); diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h index ec8372a..dcfd635 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h @@ -1,7 +1,6 @@ #ifndef arm_def_tmp_h #define arm_def_tmp_h #define armv7_read_arm_instr_cps_arm(r) NULL -#define armv7_read_arm_instr_dmd(r) NULL #define armv7_read_arm_instr_eret(r) NULL #define armv7_read_arm_instr_hvc(r) NULL #define armv7_read_arm_instr_isb(r) NULL @@ -13,7 +12,6 @@ #define armv7_read_arm_instr_ldmib_ldmed(r) NULL #define armv7_read_arm_instr_ldm_ldmia_ldmfd_arm(r) NULL #define armv7_read_arm_instr_ldm_user_registers(r) NULL -#define armv7_read_arm_instr_ldr_register(r) NULL #define armv7_read_arm_instr_mrs(r) NULL #define armv7_read_arm_instr_mrs_banked_register(r) NULL #define armv7_read_arm_instr_msr_banked_register(r) NULL diff --git a/src/arch/arm/v7/pseudo.c b/src/arch/arm/v7/pseudo.c index 03644e2..6f2451b 100644 --- a/src/arch/arm/v7/pseudo.c +++ b/src/arch/arm/v7/pseudo.c @@ -601,7 +601,11 @@ bool armv7_shift_c(uint32_t x, unsigned int n, SRType type, unsigned int amount, if (type == SRType_RRX && amount != 1) return false; - if (amount == 0) return true; + if (amount == 0) + { + *value = 0; + return true; + } result = true; /* Pour GCC... */ -- cgit v0.11.2-87-g4458