From 55dbd294b0d740648bb1b63e6159e3aa9361a2e1 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
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 <nocbos@gmail.com>
+15-04-30  Cyrille Bagard <nocbos@gmail.com>
+
+	* 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 <nocbos@gmail.com>
 
 	* 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 <nocbos@gmail.com>
+15-04-26  Cyrille Bagard <nocbos@gmail.com>
 
 	* 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 <nocbos@gmail.com>
+15-04-25  Cyrille Bagard <nocbos@gmail.com>
 
 	* 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+@title LDRB (register)
+
+@encoding(t1) {
+
+    @half 0 1 0 1 0 1 0 Rm(3) Rn(3) Rt(3)
+
+    @syntax <Rgt> <access>
+
+    @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" <Rgt>, <access>
+
+    @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 <Rgt> <access>
+
+    @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 <Rgt> <base> <offset> <?shift>
+
+    @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 <http://www.gnu.org/licenses/>.
+ */
+
+
+@title STRB (register)
+
+@encoding(t1) {
+
+    @half 0 1 0 1 0 1 0 Rm(3) Rn(3) Rt(3)
+
+    @syntax <Rgt> <access>
+
+    @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" <Rgt>, <access>
+
+    @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 <Rgt> <access>
+
+    @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 <Rgt> <base> <offset> <?shift>
+
+    @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