From 0a028b306093746324eabdb94881083f9b7e61c1 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 14 Jan 2015 20:59:18 +0000 Subject: Supported new ARMv7 instructions and fixed a silent bug in a computed mask. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@454 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 28 +++++ src/arch/arm/v7/arm.c | 163 ++++++++++++++++++++++++- src/arch/arm/v7/opcodes/opcodes_tmp_arm.h | 4 +- src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h | 4 - src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h | 2 - src/arch/arm/v7/opdefs/Makefile.am | 5 + src/arch/arm/v7/opdefs/add_A884.d | 117 ++++++++++++++++++ src/arch/arm/v7/opdefs/add_A885.d | 1 - src/arch/arm/v7/opdefs/add_A889.d | 139 +++++++++++++++++++++ src/arch/arm/v7/opdefs/adr_A8812.d | 116 ++++++++++++++++++ src/arch/arm/v7/opdefs/blx_A8826.d | 66 ++++++++++ src/arch/arm/v7/opdefs/ldr_A8863.d | 81 ++++++++++++ src/arch/arm/v7/thumb_32.c | 2 +- 13 files changed, 717 insertions(+), 11 deletions(-) create mode 100644 src/arch/arm/v7/opdefs/add_A884.d create mode 100644 src/arch/arm/v7/opdefs/add_A889.d create mode 100644 src/arch/arm/v7/opdefs/adr_A8812.d create mode 100644 src/arch/arm/v7/opdefs/blx_A8826.d create mode 100644 src/arch/arm/v7/opdefs/ldr_A8863.d diff --git a/ChangeLog b/ChangeLog index a1a901b..f902da1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +15-01-14 Cyrille Bagard + + * src/arch/arm/v7/arm.c: + Extend the range of supported ARMv7 instructions. + + * src/arch/arm/v7/opcodes/opcodes_tmp_arm.h: + * src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h: + * src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h: + Update missing prototypes. + + * src/arch/arm/v7/opdefs/add_A884.d: + New entry: support a new ARMv7 instruction. + + * src/arch/arm/v7/opdefs/add_A885.d: + Typo. + + * src/arch/arm/v7/opdefs/add_A889.d: + * src/arch/arm/v7/opdefs/adr_A8812.d: + * src/arch/arm/v7/opdefs/blx_A8826.d: + * src/arch/arm/v7/opdefs/ldr_A8863.d: + New entries: support new ARMv7 instructions. + + * src/arch/arm/v7/opdefs/Makefile.am: + Add new definitions to ARMV7_DEFS. + + * src/arch/arm/v7/thumb_32.c: + Fix a silent bug in a computed mask. + 15-01-10 Cyrille Bagard * src/arch/arm/context.c: diff --git a/src/arch/arm/v7/arm.c b/src/arch/arm/v7/arm.c index 60e0e22..2c0cabb 100644 --- a/src/arch/arm/v7/arm.c +++ b/src/arch/arm/v7/arm.c @@ -46,6 +46,12 @@ static GArchInstruction *process_armv7_arm_data_processing_immediate(uint32_t); /* Désassemble une instruction ARMv7 liées aux multiplications. */ static GArchInstruction *process_armv7_arm_multiply_and_multiply_accumulate(uint32_t); + + +/* Désassemble une instruction ARMv7 de données ou autre. */ +static GArchInstruction *process_armv7_arm_load_store_word_and_unsigned_byte(uint32_t); + + /* Désassemble une instruction ARMv7 de données ou autre. */ static GArchInstruction *process_armv7_arm_branch_branch_with_link_and_block_data_transfer(uint32_t); @@ -53,8 +59,8 @@ static GArchInstruction *process_armv7_arm_branch_branch_with_link_and_block_dat // process_armv7_arm_instruction_set_encoding -#define process_armv7_arm_load_store_word_and_unsigned_byte(raw) NULL -#define process_armv7_arm_load_store_word_and_unsigned_byte(raw) NULL +//#define process_armv7_arm_load_store_word_and_unsigned_byte(raw) NULL +//#define process_armv7_arm_load_store_word_and_unsigned_byte(raw) NULL #define process_armv7_arm_media_instructions(raw) NULL //#define process_armv7_arm_branch_branch_with_link_and_block_data_transfer(raw) NULL #define process_armv7_arm_coprocessor_instructions_and_Supervisor_call(raw) NULL @@ -583,6 +589,159 @@ static GArchInstruction *process_armv7_arm_multiply_and_multiply_accumulate(uint * * ******************************************************************************/ +static GArchInstruction *process_armv7_arm_load_store_word_and_unsigned_byte(uint32_t raw) +{ + GArchInstruction *result; /* Instruction à retourner */ + uint32_t a; /* Champ 'a' à retrouver */ + uint32_t op1; /* Champ 'op1' à retrouver */ + uint32_t rn; /* Champ 'rn' à retrouver */ + uint32_t b; /* Champ 'b' à retrouver */ + + /** + * Suit les directives de : + * § A5.3 Load/store word and unsigned byte + */ + + result = NULL; + + a = (raw >> 25) & 0x1; + op1 = (raw >> 20) & 0x1f; + rn = (raw >> 16) & 0xf; + b = (raw >> 4) & 0x1; + + if ((op1 & b10111) == b00010) + { + 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) + { + 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_strt(raw); + goto a53_done; + } + else if (/*a == b1 && */b == b0) + goto a53_done; + } + else if ((op1 & b00101) == b00001) + { + if (a == b0) + { + if (rn == b1111) + result = armv7_read_arm_instr_ldr_literal(raw); + else + result = armv7_read_arm_instr_ldr_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) == b00110) + { + 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) == b00100) + { + if (a == b0) + { + 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) == b00111) + { + 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) == b00101) + { + if (a == b0) + { + if (rn == b1111) + result = armv7_read_arm_instr_ldr_literal(raw); + else + result = armv7_read_arm_instr_ldr_immediate_arm(raw); + + goto a53_done; + + } + else if (/*a == b1 && */b == b0) + { + result = armv7_read_arm_instr_str_register(raw); + goto a53_done; + } + } + + a53_done: + + return result; + +} + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : raw = donnée brute de 32 bits à désassembler. * +* * +* Description : Désassemble une instruction ARMv7 de données ou autre. * +* * +* Retour : Instruction mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + static GArchInstruction *process_armv7_arm_branch_branch_with_link_and_block_data_transfer(uint32_t raw) { GArchInstruction *result; /* Instruction à retourner */ diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h index 666ca71..4fbf93d 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h @@ -1,6 +1,5 @@ #ifndef arm_def_tmp_h #define arm_def_tmp_h -#define armv7_read_arm_instr_adr(r) NULL #define armv7_read_arm_instr_asr_immediate(r) NULL #define armv7_read_arm_instr_ldmda_ldmfa(r) NULL #define armv7_read_arm_instr_ldmdb_ldmea(r) NULL @@ -17,4 +16,7 @@ #define armv7_read_arm_instr_stmib_stmfa(r) NULL #define armv7_read_arm_instr_stm_stmia_stmea(r) NULL #define armv7_read_arm_instr_stm_user_registers(r) NULL +#define armv7_read_arm_instr_str_immediate_arm(r) NULL +#define armv7_read_arm_instr_str_register(r) NULL +#define armv7_read_arm_instr_strt(r) NULL #endif diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h index fe67305..990d1c6 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h @@ -1,15 +1,11 @@ #ifndef thumb_16_def_tmp_h #define thumb_16_def_tmp_h #define armv7_read_thumb_16_instr_adc_register(r) NULL -#define armv7_read_thumb_16_instr_add_immediate_thumb(r) NULL -#define armv7_read_thumb_16_instr_add_sp_plus_immediate(r) NULL -#define armv7_read_thumb_16_instr_adr(r) NULL #define armv7_read_thumb_16_instr_and_register(r) NULL #define armv7_read_thumb_16_instr_asr_immediate(r) NULL #define armv7_read_thumb_16_instr_asr_register(r) NULL #define armv7_read_thumb_16_instr_bic_register(r) NULL #define armv7_read_thumb_16_instr_bkpt(r) NULL -#define armv7_read_thumb_16_instr_blx_register(r) NULL #define armv7_read_thumb_16_instr_cmn_register(r) NULL #define armv7_read_thumb_16_instr_cmp_immediate(r) NULL #define armv7_read_thumb_16_instr_cmp_register(r) NULL diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h index 1f0abb9..4ed909c 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h @@ -1,7 +1,5 @@ #ifndef thumb_32_def_tmp_h #define thumb_32_def_tmp_h -#define armv7_read_thumb_32_instr_add_immediate_thumb(r) NULL -#define armv7_read_thumb_32_instr_adr(r) NULL #define armv7_read_thumb_32_instr_asr_register(r) NULL #define armv7_read_thumb_32_instr_bfc(r) NULL #define armv7_read_thumb_32_instr_bfi(r) NULL diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index 10deadb..223cf41 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -25,15 +25,19 @@ D2C_MACROS = \ ARMV7_DEFS = \ adc_A881.d \ adc_A882.d \ + add_A884.d \ add_A885.d \ add_A886.d \ add_A887.d \ + add_A889.d \ + adr_A8812.d \ and_A8813.d \ and_A8814.d \ b_A8818.d \ bic_A8821.d \ bic_A8822.d \ bl_A8825.d \ + blx_A8826.d \ bx_A8827.d \ cbnz_A8829.d \ cmn_A8834.d \ @@ -43,6 +47,7 @@ ARMV7_DEFS = \ eor_A8846.d \ eor_A8847.d \ ldr_A8862.d \ + ldr_A8863.d \ ldr_A8864.d \ ldr_A8865.d \ ldrb_A8867.d \ diff --git a/src/arch/arm/v7/opdefs/add_A884.d b/src/arch/arm/v7/opdefs/add_A884.d new file mode 100644 index 0000000..90e1235 --- /dev/null +++ b/src/arch/arm/v7/opdefs/add_A884.d @@ -0,0 +1,117 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +@title ADD (immediate, Thumb) + +@encoding(t1) { + + @half 0 0 0 1 1 1 0 imm3(3) Rn(3) Rd(3) + + @syntax + + @conv { + + Rd = Register(Rd) + Rn = Register(Rn) + const = ZeroExtend(imm3, 3, 32); + + } + + @rules { + + //setflags = !InITBlock(); + + } + +} + +@encoding(t2) { + + @half 0 0 1 1 0 Rdn(3) imm8(8) + + @syntax + + @conv { + + Rdn = Register(Rdn) + const = ZeroExtend(imm8, 8, 32); + + } + + @rules { + + //setflags = !InITBlock(); + + } + +} + +@encoding(T3) { + + @word 1 1 1 1 0 i(1) 0 1 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} ".W" + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + Rn = Register(Rn) + const = ThumbExpandImm_C(i:imm3:imm8, i) + + } + + @rules { + + //if Rd == '1111' && S == '1' then SEE CMN (immediate); + //if Rn == '1101' then SEE ADD (SP plus immediate); + //if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; + + } + +} + +@encoding(T4) { + + @word 1 1 1 1 0 i(1) 1 0 0 0 0 0 Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax "addw" + + @conv { + + Rd = Register(Rd) + Rn = Register(Rn) + const = ZeroExtend((i:imm3:imm8, 12, 32) + + } + + @rules { + + //if Rn == '1111' then SEE ADR; + //if Rn == '1101' then SEE ADD (SP plus immediate); + //setflags = FALSE + //if d IN {13,15} then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/add_A885.d b/src/arch/arm/v7/opdefs/add_A885.d index bacddc8..d3220c5 100644 --- a/src/arch/arm/v7/opdefs/add_A885.d +++ b/src/arch/arm/v7/opdefs/add_A885.d @@ -45,7 +45,6 @@ //if (Rn == '1101') ; see ADD (SP plus immediate) //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions - } } diff --git a/src/arch/arm/v7/opdefs/add_A889.d b/src/arch/arm/v7/opdefs/add_A889.d new file mode 100644 index 0000000..1f81776 --- /dev/null +++ b/src/arch/arm/v7/opdefs/add_A889.d @@ -0,0 +1,139 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +@title ADD (SP plus immediate) + +@encoding(t1) { + + @half 1 0 1 0 1 Rd(3) imm8(8) + + @syntax + + @conv { + + Rd = Register(Rd) + SP = Register(13) + const = ZeroExtend(imm8:'00', 10, 32); + + } + + @rules { + + //setflags = FALSE + + } + +} + +@encoding(t2) { + + @half 1 0 1 1 0 0 0 0 0 imm7(7) + + @syntax + + @conv { + + SP1 = Register(13) + SP2 = Register(13) + const = ZeroExtend(imm7:'00', 9, 32); + + } + + @rules { + + //setflags = FALSE + + } + +} + +@encoding(T3) { + + @word 1 1 1 1 0 i(1) 0 1 0 0 0 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} ".W" + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + SP = Register(13) + const = ThumbExpandImm_C(i:imm3:imm8, i) + + } + + @rules { + + //if Rd == '1111' && S == '1' then SEE CMN (immediate); + //if d == 15 && S == '0' then UNPREDICTABLE; + + } + +} + +@encoding(T4) { + + @word 1 1 1 1 0 i(1) 0 1 0 0 0 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm8(8) + + @syntax "addw" + + @conv { + + Rd = Register(Rd) + SP = Register(13) + const = ZeroExtend((i:imm3:imm8, 12, 32) + + } + + @rules { + + //if Rd == '1111' && S == '1' then SEE CMN (immediate); + //if d == 15 && S == '0' then UNPREDICTABLE; + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 0 1 0 0 S(1) 1 1 0 1 Rd(4) imm12(12) + + @syntax {S} {c} + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + SP = Register(13) + const = ARMExpandImm(imm12) + + } + + @rules { + + //if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; + + } + +} diff --git a/src/arch/arm/v7/opdefs/adr_A8812.d b/src/arch/arm/v7/opdefs/adr_A8812.d new file mode 100644 index 0000000..38ad6af --- /dev/null +++ b/src/arch/arm/v7/opdefs/adr_A8812.d @@ -0,0 +1,116 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +@title ADR + +@encoding(t1) { + + @half 1 0 1 0 0 Rd(3) imm8(8) + + @syntax "add" + + @conv { + + Rd = Register(Rd) + PC = Register(15) + imm32 = ZeroExtend(imm8:'00', 10, 32) + + } + +} + +@encoding(T2) { + + @word 1 1 1 1 0 i(1) 1 0 1 0 1 0 1 1 1 1 0 imm3(3) Rd(4) imm8(8) + + @syntax "sub" + + @conv { + + Rd = Register(Rd) + PC = Register(15) + imm32 = ZeroExtend(i:imm3:imm8, 12, 32) + + } + + @rules { + + //if d IN {13,15} then UNPREDICTABLE; + + } + +} + +@encoding(T3) { + + @word 1 1 1 1 0 i(1) 1 0 0 0 0 0 1 1 1 1 0 imm3(3) Rd(4) imm8(8) + + @syntax "add" + + @conv { + + Rd = Register(Rd) + PC = Register(15) + imm32 = ZeroExtend(i:imm3:imm8, 12, 32) + + } + + @rules { + + //if d IN {13,15} then UNPREDICTABLE; + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 0 1 0 0 0 1 1 1 1 Rd(4) imm12(12) + + @syntax "add" + + @conv { + + Rd = Register(Rd) + PC = Register(15) + const = ARMExpandImm(imm12) + + } + +} + +@encoding(A2) { + + @word cond(4) 0 0 1 0 0 1 0 0 1 1 1 1 Rd(4) imm12(12) + + @syntax "sub" + + @conv { + + Rd = Register(Rd) + PC = Register(15) + const = ARMExpandImm(imm12) + + } + +} diff --git a/src/arch/arm/v7/opdefs/blx_A8826.d b/src/arch/arm/v7/opdefs/blx_A8826.d new file mode 100644 index 0000000..178515a --- /dev/null +++ b/src/arch/arm/v7/opdefs/blx_A8826.d @@ -0,0 +1,66 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +@title BLX (register) + +@encoding(t1) { + + @half 0 1 0 0 0 1 1 1 1 Rm(4) 0 0 0 + + @syntax + + @conv { + + Rm = Register(Rm) + + } + + @rules { + + //if m == 15 then UNPREDICTABLE; + //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 Rm(4) + + @syntax {c} + + @conv { + + c = Condition(cond) + Rm = Register(Rm) + + } + + @rules { + + //if m == 15 then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/ldr_A8863.d b/src/arch/arm/v7/opdefs/ldr_A8863.d new file mode 100644 index 0000000..2526671 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldr_A8863.d @@ -0,0 +1,81 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +@title LDR (immediate, ARM) + +@encoding(A11) { + + @word cond(4) 0 1 0 1 U(1) 0 W(1) 1 Rn(4) Rt(4) imm12(12) + + @syntax + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + imm32 = ZeroExtend(imm12, 12, 32); + access = MakeMemoryAccess(Rgn, imm32, U, 1) + + } + + @rules { + + //if Rn == '1111' then SEE LDR (literal); + //if P == '0' && W == '1' then SEE LDRT; + //if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; + //t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); + //if wback && n == t then UNPREDICTABLE; + + } + +} + +@encoding(A12) { + + @word cond(4) 0 1 0 0 U(1) 0 W(1) 0 Rn(4) Rt(4) imm12(12) + + @syntax + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + imm32 = ZeroExtend(imm12, 12, 32); + base = MakeMemoryNotIndexed(Rgn, W) + offset = MakeAccessOffset(U, imm32) + + } + + @rules { + + //if Rn == '1111' then SEE LDR (literal); + //if P == '0' && W == '1' then SEE LDRT; + //if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; + //t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); + //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); + //if wback && n == t then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/thumb_32.c b/src/arch/arm/v7/thumb_32.c index 04d760b..8ea6ecb 100644 --- a/src/arch/arm/v7/thumb_32.c +++ b/src/arch/arm/v7/thumb_32.c @@ -348,7 +348,7 @@ static GArchInstruction *process_armv7_thumb_32_data_processing_plain_binary_imm * § A6.3.3 Data-processing (plain binary immediate) */ - if ((raw & 0xfa000000) != 0xf2000000) return NULL; + if ((raw & 0xfa008000) != 0xf2000000) return NULL; result = NULL; -- cgit v0.11.2-87-g4458