From 55dbd294b0d740648bb1b63e6159e3aa9361a2e1 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 29 Apr 2015 23:35:10 +0000 Subject: Implemented a new category of instructions from Thumb32. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@522 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 24 ++++- src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h | 2 - src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h | 12 ++- src/arch/arm/v7/opdefs/Makefile.am | 2 + src/arch/arm/v7/opdefs/ldrb_A8870.d | 129 +++++++++++++++++++++++++ src/arch/arm/v7/opdefs/strb_A88208.d | 127 ++++++++++++++++++++++++ src/arch/arm/v7/thumb_32.c | 125 +++++++++++++++++++++++- 7 files changed, 414 insertions(+), 7 deletions(-) create mode 100644 src/arch/arm/v7/opdefs/ldrb_A8870.d create mode 100644 src/arch/arm/v7/opdefs/strb_A88208.d diff --git a/ChangeLog b/ChangeLog index d7f8dc8..89e6c08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,22 @@ -115-04-27 Cyrille Bagard +15-04-30 Cyrille Bagard + + * 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/ldrb_A8870.d: + New entry: introduce a new ARM instruction. + + * src/arch/arm/v7/opdefs/Makefile.am: + Update included headers list. + + * src/arch/arm/v7/opdefs/strb_A88208.d: + New entry: introduce a new ARM instruction. + + * src/arch/arm/v7/thumb_32.c: + Implement a new category of instructions from Thumb32. + +15-04-27 Cyrille Bagard * configure.ac: * po/POTFILES.in: @@ -7,7 +25,7 @@ * tools/d2c/d2c_genmakefile.sh: Allow to compile the project from a fresh install by fixing mistakes. -115-04-26 Cyrille Bagard +15-04-26 Cyrille Bagard * src/analysis/disass/output.c: Give more information about not found symbols. @@ -22,7 +40,7 @@ * src/gui/panels/symbols.c Display entry points as symbols too. -115-04-25 Cyrille Bagard +15-04-25 Cyrille Bagard * src/analysis/disass/macro.c: Use an uniq coverage memory for all visited branches. 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 3b07f7e..3d3aa3a 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h @@ -5,7 +5,6 @@ #define armv7_read_thumb_16_instr_cps_thumb(r) NULL #define armv7_read_thumb_16_instr_it(r) NULL #define armv7_read_thumb_16_instr_ldm_ldmia_ldmfd_thumb(r) NULL -#define armv7_read_thumb_16_instr_ldrb_register(r) NULL #define armv7_read_thumb_16_instr_ldrh_immediate_thumb(r) NULL #define armv7_read_thumb_16_instr_ldrh_register(r) NULL #define armv7_read_thumb_16_instr_ldrsb_register(r) NULL @@ -20,7 +19,6 @@ #define armv7_read_thumb_16_instr_setend(r) NULL #define armv7_read_thumb_16_instr_sev(r) NULL #define armv7_read_thumb_16_instr_stm_stmia_stmea(r) NULL -#define armv7_read_thumb_16_instr_strb_register(r) NULL #define armv7_read_thumb_16_instr_strh_immediate_thumb(r) NULL #define armv7_read_thumb_16_instr_strh_register(r) NULL #define armv7_read_thumb_16_instr_str_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 612052b..7510b20 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h @@ -18,6 +18,12 @@ #define armv7_read_thumb_32_instr_isb(r) NULL #define armv7_read_thumb_32_instr_ldmdb_ldmea(r) NULL #define armv7_read_thumb_32_instr_ldm_ldmia_ldmfd_thumb(r) NULL +#define armv7_read_thumb_32_instr_ldrb_literal(r) NULL +#define armv7_read_thumb_32_instr_ldrbt(r) NULL +#define armv7_read_thumb_32_instr_ldrsb_immediate(r) NULL +#define armv7_read_thumb_32_instr_ldrsb_literal(r) NULL +#define armv7_read_thumb_32_instr_ldrsb_register(r) NULL +#define armv7_read_thumb_32_instr_ldrsbt(r) NULL #define armv7_read_thumb_32_instr_ldrt(r) NULL #define armv7_read_thumb_32_instr_lsl_register(r) NULL #define armv7_read_thumb_32_instr_lsr_register(r) NULL @@ -28,6 +34,11 @@ #define armv7_read_thumb_32_instr_orn_immediate(r) NULL #define armv7_read_thumb_32_instr_orn_register(r) NULL #define armv7_read_thumb_32_instr_pkh(r) NULL +#define armv7_read_thumb_32_instr_pld_immediate(r) NULL +#define armv7_read_thumb_32_instr_pld_literal(r) NULL +#define armv7_read_thumb_32_instr_pld_register(r) NULL +#define armv7_read_thumb_32_instr_pli_immediate_literal(r) NULL +#define armv7_read_thumb_32_instr_pli_register(r) NULL #define armv7_read_thumb_32_instr_qadd(r) NULL #define armv7_read_thumb_32_instr_qdadd(r) NULL #define armv7_read_thumb_32_instr_qdsub(r) NULL @@ -80,7 +91,6 @@ #define armv7_read_thumb_32_instr_ssub8(r) NULL #define armv7_read_thumb_32_instr_stmdb_stmfd(r) NULL #define armv7_read_thumb_32_instr_stm_stmia_stmea(r) NULL -#define armv7_read_thumb_32_instr_strb_register(r) NULL #define armv7_read_thumb_32_instr_strbt(r) NULL #define armv7_read_thumb_32_instr_strh_immediate_thumb(r) NULL #define armv7_read_thumb_32_instr_strh_register(r) NULL diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index b897f1d..6678f0e 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -54,6 +54,7 @@ ARMV7_DEFS = \ ldr_A8864.d \ ldr_A8865.d \ ldrb_A8867.d \ + ldrb_A8870.d \ lsl_A8894.d \ mla_A88100.d \ mls_A88101.d \ @@ -81,6 +82,7 @@ ARMV7_DEFS = \ str_A88203.d \ str_A88204.d \ strb_A88206.d \ + strb_A88208.d \ sub_A88221.d \ sub_A88222.d \ sub_A88223.d \ diff --git a/src/arch/arm/v7/opdefs/ldrb_A8870.d b/src/arch/arm/v7/opdefs/ldrb_A8870.d new file mode 100644 index 0000000..0de0af2 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrb_A8870.d @@ -0,0 +1,129 @@ + +/* 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 LDRB (register) + +@encoding(t1) { + + @half 0 1 0 1 0 1 0 Rm(3) Rn(3) Rt(3) + + @syntax + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + Rgm = Register(Rm) + access = _MakeMemoryAccess(Rgn, Rgm, 0) + + } + + @rules { + + } + +} + +@encoding(T2) { + + @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) + + @syntax "ldrb.W" , + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + Rgm = Register(Rm) + shift = DecodeImmShift(0, imm2) + access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, 0) + + } + + @rules { + + //if Rn == '1111' then UNDEFINED; + //if t IN {13,15} || m IN {13,15} then UNPREDICTABLE; + + if (Rt == '1111'); chk_call DefineAsReturn(1) + + } + +} + +@encoding(A11) { + + @word cond(4) 0 1 1 1 U(1) 1 W(1) 1 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + + @syntax + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + Rgm = Register(Rm) + shift = DecodeImmShift(type, imm5) + access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, W) + + } + + @rules { + + //if P == '0' && W == '1' then SEE LDRBT; + //if t == 15 || m == 15 then UNPREDICTABLE; + //if wback && (n == 15 || n == t) then UNPREDICTABLE; + //if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; + if (Rt == '1111'); chk_call DefineAsReturn(1) + + } + +} + +@encoding(A12) { + + @word cond(4) 0 1 1 0 U(1) 1 W(1) 1 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + + @syntax + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + Rgm = Register(Rm) + base = MakeMemoryNotIndexed(Rgn, 1) + offset = MakeAccessOffset(U, Rgm) + shift = DecodeImmShift(type, imm5) + + } + + @rules { + + //if P == '0' && W == '1' then SEE LDRBT; + //if t == 15 || m == 15 then UNPREDICTABLE; + //if wback && (n == 15 || n == t) then UNPREDICTABLE; + //if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; + if (Rt == '1111'); chk_call DefineAsReturn(1) + + } + +} diff --git a/src/arch/arm/v7/opdefs/strb_A88208.d b/src/arch/arm/v7/opdefs/strb_A88208.d new file mode 100644 index 0000000..ab6c198 --- /dev/null +++ b/src/arch/arm/v7/opdefs/strb_A88208.d @@ -0,0 +1,127 @@ + +/* 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 STRB (register) + +@encoding(t1) { + + @half 0 1 0 1 0 1 0 Rm(3) Rn(3) Rt(3) + + @syntax + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + Rgm = Register(Rm) + access = _MakeMemoryAccess(Rgn, Rgm, 0) + + } + + @rules { + + } + +} + +@encoding(T2) { + + @word 1 1 1 1 1 0 0 0 0 0 0 0 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) + + @syntax "strb.W" , + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + Rgm = Register(Rm) + shift = DecodeImmShift(0, imm2) + access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, 0) + + } + + @rules { + + //if Rn == '1111' then UNDEFINED; + //if t IN {13,15} || m IN {13,15} then UNPREDICTABLE; + + if (Rt == '1111'); chk_call DefineAsReturn(1) + + } + +} + +@encoding(A11) { + + @word cond(4) 0 1 1 1 U(1) 1 W(1) 0 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + + @syntax + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + Rgm = Register(Rm) + shift = DecodeImmShift(type, imm5) + access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, W) + + } + + @rules { + + //if P == '0' && W == '1' then SEE STRT; + //if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; + //if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (Rt == '1111'); chk_call DefineAsReturn(1) + + } + +} + +@encoding(A12) { + + @word cond(4) 0 1 1 0 U(1) 1 W(1) 0 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + + @syntax + + @conv { + + Rgt = Register(Rt) + Rgn = Register(Rn) + Rgm = Register(Rm) + base = MakeMemoryNotIndexed(Rgn, 1) + offset = MakeAccessOffset(U, Rgm) + shift = DecodeImmShift(type, imm5) + + } + + @rules { + + //if P == '0' && W == '1' then SEE STRT; + //if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; + //if wback && (n == 15 || n == t) then UNPREDICTABLE; + if (Rt == '1111'); chk_call DefineAsReturn(1) + + } + +} diff --git a/src/arch/arm/v7/thumb_32.c b/src/arch/arm/v7/thumb_32.c index 8fc4d91..9d9de57 100644 --- a/src/arch/arm/v7/thumb_32.c +++ b/src/arch/arm/v7/thumb_32.c @@ -61,6 +61,10 @@ static GArchInstruction *process_armv7_thumb_32_load_word(uint32_t); + +/* Désassemble une instruction ARMv7 classique. */ +static GArchInstruction *process_armv7_thumb_32_load_byte_memory_hints(uint32_t); + /* Désassemble une instruction ARMv7 classique. */ static GArchInstruction *process_armv7_thumb_32_store_single_data_item(uint32_t); @@ -93,7 +97,7 @@ static GArchInstruction *process_armv7_thumb_32_long_multiply_long_multiply_accu #define process_armv7_thumb_32_load_store_dual_load_store_exclusive_table_branch(r) NULL #define process_armv7_thumb_32_coprocessor_advanced_simd_and_floating_point_instructions(r) NULL -#define process_armv7_thumb_32_load_byte_memory_hints(r) NULL + #define process_armv7_thumb_32_load_halfword_memory_hints(r) NULL #define process_armv7_thumb_32_advanced_simd_element_or_structure_load_store_instructions(r) NULL #define process_armv7_thumb_32_move_register_and_immediate_shifts(r) NULL @@ -826,6 +830,125 @@ static GArchInstruction *process_armv7_thumb_32_load_word(uint32_t raw) + + + + +/****************************************************************************** +* * +* Paramètres : raw = donnée brute de 32 bits à désassembler. * +* * +* Description : Désassemble une instruction ARMv7 classique. * +* * +* Retour : Instruction mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *process_armv7_thumb_32_load_byte_memory_hints(uint32_t raw) +{ + GArchInstruction *result; /* Instruction à renvoyer */ + uint32_t op1; /* Champ 'op1' à retrouver */ + uint32_t rn; /* Champ 'rn' à retrouver */ + uint32_t rt; /* Champ 'rt' à retrouver */ + uint32_t op2; /* Champ 'op2' à retrouver */ + + /** + * Suit les directives de : + * § A6.3.9 Load byte, memory hints + */ + + if ((raw & 0xfe700000) != 0xf8100000) return NULL; + + result = NULL; + + op1 = (raw >> 23) & b11; + rn = (raw >> 16) & b1111; + rt = (raw >> 12) & b1111; + op2 = (raw >> 6) & b111111; + + if (op1 == b00 && op2 == b000000 && rn != b1111) + { + if (rt != b1111) + result = armv7_read_thumb_32_instr_ldrb_register(raw); + else /*if (rt == b1111) */ + result = armv7_read_thumb_32_instr_pld_register(raw); + } + + else if ((op1 & b10) == b00 && rn == b1111) + { + if (rt != b1111) + result = armv7_read_thumb_32_instr_ldrb_literal(raw); + else /*if (rt == b1111) */ + result = armv7_read_thumb_32_instr_pld_literal(raw); + } + + else if (op1 == b00 && (op2 & b100100) == b100100 && rn != b1111) + result = armv7_read_thumb_32_instr_ldrb_immediate_thumb(raw); + + else if (op1 == b00 && (op2 & b111100) == b110000 && rn != b1111) + { + if (rt != b1111) + result = armv7_read_thumb_32_instr_ldrb_immediate_thumb(raw); + else /*if (rt == b1111) */ + result = armv7_read_thumb_32_instr_pld_immediate(raw); + } + + else if (op1 == b00 && (op2 & b111100) == b111000 && rn != b1111) + result = armv7_read_thumb_32_instr_ldrbt(raw); + + else if (op1 == b01 && rn != b1111) + { + if (rt != b1111) + result = armv7_read_thumb_32_instr_ldrb_immediate_thumb(raw); + else /*if (rt == b1111) */ + result = armv7_read_thumb_32_instr_pld_immediate(raw); + } + + if (op1 == b10 && op2 == b000000 && rn != b1111) + { + if (rt != b1111) + result = armv7_read_thumb_32_instr_ldrsb_register(raw); + else /*if (rt == b1111) */ + result = armv7_read_thumb_32_instr_pli_register(raw); + } + + else if ((op1 & b10) == b10 && rn == b1111) + { + if (rt != b1111) + result = armv7_read_thumb_32_instr_ldrsb_literal(raw); + else /*if (rt == b1111) */ + result = armv7_read_thumb_32_instr_pli_immediate_literal(raw); + } + + else if (op1 == b10 && (op2 & b100100) == b100100 && rn != b1111) + result = armv7_read_thumb_32_instr_ldrsb_immediate(raw); + + else if (op1 == b10 && (op2 & b111100) == b110000 && rn != b1111) + { + if (rt != b1111) + result = armv7_read_thumb_32_instr_ldrsb_immediate(raw); + else /*if (rt == b1111) */ + result = armv7_read_thumb_32_instr_pli_immediate_literal(raw); + } + + else if (op1 == b10 && (op2 & b111100) == b111000 && rn != b1111) + result = armv7_read_thumb_32_instr_ldrsbt(raw); + + else if (op1 == b11 && rn != b1111) + { + if (rt != b1111) + result = armv7_read_thumb_32_instr_ldrsb_immediate(raw); + else /*if (rt == b1111) */ + result = armv7_read_thumb_32_instr_pli_immediate_literal(raw); + } + + return result; + +} + + /****************************************************************************** * * * Paramètres : raw = donnée brute de 32 bits à désassembler. * -- cgit v0.11.2-87-g4458