From 5511e355e7810f06bd610b79bcc94402c88d7ec9 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 1 Feb 2015 22:39:57 +0000
Subject: Added some development assertions and avoided to load code twice.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@464 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                                      |  33 ++++
 src/analysis/disass/area.c                     |  41 ++++-
 src/arch/arm/v7/helpers.h                      |  33 ++++
 src/arch/arm/v7/opcodes/opcodes_tmp_arm.h      |   1 -
 src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h |   3 -
 src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h |   2 -
 src/arch/arm/v7/opdefs/Makefile.am             |   3 +
 src/arch/arm/v7/opdefs/asr_A8816.d             |  93 +++++++++++
 src/arch/arm/v7/opdefs/sub_A88221.d            | 116 +++++++++++++
 src/arch/arm/v7/opdefs/uxtb_A88274.d           |  84 ++++++++++
 src/arch/arm/v7/operands/Makefile.am           |   1 +
 src/arch/arm/v7/operands/rotation.c            | 222 +++++++++++++++++++++++++
 src/arch/arm/v7/operands/rotation.h            |  61 +++++++
 src/arch/arm/v7/thumb_32.c                     |   2 +-
 14 files changed, 685 insertions(+), 10 deletions(-)
 create mode 100644 src/arch/arm/v7/opdefs/asr_A8816.d
 create mode 100644 src/arch/arm/v7/opdefs/sub_A88221.d
 create mode 100644 src/arch/arm/v7/opdefs/uxtb_A88274.d
 create mode 100644 src/arch/arm/v7/operands/rotation.c
 create mode 100644 src/arch/arm/v7/operands/rotation.h

diff --git a/ChangeLog b/ChangeLog
index b986ca4..daee274 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+15-02-01  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/area.c:
+	Add some development assertions and avoid to load code twice.
+
+	* src/arch/arm/v7/helpers.h:
+	Build rotations and fixed shifts.
+
+	* 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/asr_A8816.d:
+	New entry: support a new ARMv7 instruction.
+
+	* src/arch/arm/v7/opdefs/Makefile.am:
+	Add a new definition to ARMV7_DEFS.
+
+	* src/arch/arm/v7/opdefs/sub_A88221.d:
+	* src/arch/arm/v7/opdefs/uxtb_A88274.d:
+	New entries: support new ARMv7 instructions.
+
+	* src/arch/arm/v7/operands/Makefile.am:
+	Add the 'rotation.[ch]' files to libarcharmv7operands_la_SOURCES.
+
+	* src/arch/arm/v7/operands/rotation.c:
+	* src/arch/arm/v7/operands/rotation.h:
+	New entries: define rotations as operands.
+
+	* src/arch/arm/v7/thumb_32.c:
+	Fix a bug for one category mask (0xe8000000 vs 0xe0000000).
+
 15-01-31  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/fetch.c:
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 600818a..17df2af 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -359,10 +359,14 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph
         index = i / (sizeof(unsigned long) * 8);
         remaining = i % (sizeof(unsigned long) * 8);
 
+        assert((area->processed[index] & (1ul << remaining)) == 0);
+
         area->processed[index] |= (1ul << remaining);
 
     }
 
+    assert(area->instructions[start] == NULL);
+
     area->instructions[start] = instr;
 
     return true;
@@ -464,7 +468,8 @@ void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons
 
     for (i = diff; i < alen; i += diff)
     {
-        //il y a eu un point d'entrée... -> STOP
+        /* S'il y a eu un point d'entrée en milieu de zone, on s'arrête ! */
+        if (!is_range_blank_in_mem_area(area, i, 1, NULL)) break;
 
         /* Décodage d'une nouvelle instruction */
 
@@ -503,7 +508,7 @@ void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons
              has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr))
         {
             printf("depop :: %x / %x\n", (unsigned int)sym_addr.physical, (unsigned int)sym_addr.virtual);
-
+            //continue;
 
             //if (sym_addr.physical != 0x5bc && sym_addr.physical != 0x5c0) continue;
             //if (sym_addr.physical != 0x5bc) continue;
@@ -558,6 +563,8 @@ void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons
 
         }
 
+        assert(1 && !is_range_blank_in_mem_areas(*list, *count, &range));
+
 
         if (g_arch_instruction_is_return(instr))
             printf("BREAK @ 0x%08x\n", (unsigned int)get_virt_addr(&prev));
@@ -1306,9 +1313,37 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, s
     index = find_memory_area_by_addr(*list, *count, get_mrange_addr(sym_range));
     assert(index < *count);
 
-    if (index <= *old_index) (*old_index)++;
+    //if (index <= *old_index) (*old_index)++;
 
     area = &(*list)[index];
+
+
+    if (strcmp("Value used @ 0x00008a26", g_db_comment_get_text(g_binary_symbol_get_comment(symbol))) == 0)
+        printf("break\n");
+
+
+    do
+    {
+        size_t i;
+
+        printf("--- comment '%s'...\n",
+               g_db_comment_get_text(g_binary_symbol_get_comment(symbol)));
+
+        printf("--- insert @ 0x%04x + %u\n",
+               get_phy_addr(get_mrange_addr(sym_range)), get_mrange_length(sym_range));
+
+        for (i = 0; i < 3; i++)
+            printf("area [ %zu ]  <=>  0x%04x + %u (sym ? %d)\n",
+                   index - 1 + i,
+                   get_phy_addr(get_mrange_addr(&(&(*list)[index - 1 + i])->range)),
+                   get_mrange_length(&(&(*list)[index - 1 + i])->range),
+                   (&(*list)[index - 1 + i])->has_sym);
+
+    }
+    while (0);
+
+    if (area->has_sym) return true;
+
     assert(!area->has_sym);
 
     saved = *area;
diff --git a/src/arch/arm/v7/helpers.h b/src/arch/arm/v7/helpers.h
index 0a1d934..b4fe9b4 100644
--- a/src/arch/arm/v7/helpers.h
+++ b/src/arch/arm/v7/helpers.h
@@ -32,6 +32,7 @@
 #include "operands/maccess.h"
 #include "operands/offset.h"
 #include "operands/reglist.h"
+#include "operands/rotation.h"
 #include "operands/shift.h"
 #include "../../operand.h"
 
@@ -196,6 +197,38 @@ return shift_t;
 
 
 
+
+
+#define BuildRotation(val5)                                                         \
+    ({                                                                              \
+        GArchOperand *__result;                                                     \
+        uint8_t __rot;                                                              \
+        GArchOperand *__rot_op;                                                     \
+        __rot = val5;                                                               \
+        __rot_op = g_imm_operand_new_from_value(MDS_8_BITS_UNSIGNED, __rot);        \
+        __result = g_armv7_rotation_operand_new(__rot_op);                          \
+        if (__result == NULL)                                                       \
+            g_object_unref(G_OBJECT(__rot_op));                                     \
+        __result;                                                                   \
+    })
+
+
+
+
+// type == '10', pas 2 ! (FIXME)
+#define FixedShift(type, imm5)                                                      \
+    ({                                                                              \
+        GArchOperand *__result;                                                     \
+        uint32_t __shift_n;                                                         \
+        __shift_n = imm5;                                                           \
+        __result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, __shift_n);   \
+        __result;                                                                   \
+    })
+
+
+
+
+
 /**
  * Glue purement interne pour les listes de registres.
  */
diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h
index 3a5e646..5142648 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_asr_immediate(r) NULL
 #define armv7_read_arm_instr_ldmda_ldmfa(r) NULL
 #define armv7_read_arm_instr_ldmdb_ldmea(r) NULL
 #define armv7_read_arm_instr_ldm_exception_return(r) NULL
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 8fbd93e..3b07f7e 100644
--- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h
+++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h
@@ -1,6 +1,5 @@
 #ifndef thumb_16_def_tmp_h
 #define thumb_16_def_tmp_h
-#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_bkpt(r) NULL
 #define armv7_read_thumb_16_instr_cps_thumb(r) NULL
@@ -25,12 +24,10 @@
 #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
-#define armv7_read_thumb_16_instr_sub_immediate_thumb(r) NULL
 #define armv7_read_thumb_16_instr_svc_previously_swi(r) NULL
 #define armv7_read_thumb_16_instr_sxtb(r) NULL
 #define armv7_read_thumb_16_instr_sxth(r) NULL
 #define armv7_read_thumb_16_instr_udf(r) NULL
-#define armv7_read_thumb_16_instr_uxtb(r) NULL
 #define armv7_read_thumb_16_instr_uxth(r) NULL
 #define armv7_read_thumb_16_instr_wfe(r) NULL
 #define armv7_read_thumb_16_instr_wfi(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 115b515..612052b 100644
--- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h
+++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h
@@ -87,7 +87,6 @@
 #define armv7_read_thumb_32_instr_strht(r) NULL
 #define armv7_read_thumb_32_instr_str_register(r) NULL
 #define armv7_read_thumb_32_instr_strt(r) NULL
-#define armv7_read_thumb_32_instr_sub_immediate_thumb(r) NULL
 #define armv7_read_thumb_32_instr_sub_register_thumb(r) NULL
 #define armv7_read_thumb_32_instr_subs_pc_lr_thumb(r) NULL
 #define armv7_read_thumb_32_instr_sxtab(r) NULL
@@ -124,7 +123,6 @@
 #define armv7_read_thumb_32_instr_uxtab(r) NULL
 #define armv7_read_thumb_32_instr_uxtab16(r) NULL
 #define armv7_read_thumb_32_instr_uxtah(r) NULL
-#define armv7_read_thumb_32_instr_uxtb(r) NULL
 #define armv7_read_thumb_32_instr_uxtb16(r) NULL
 #define armv7_read_thumb_32_instr_uxth(r) NULL
 #define armv7_read_thumb_32_instr_wfe(r) NULL
diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am
index 36509b4..45d4932 100644
--- a/src/arch/arm/v7/opdefs/Makefile.am
+++ b/src/arch/arm/v7/opdefs/Makefile.am
@@ -34,6 +34,7 @@ ARMV7_DEFS = 							\
 	adr_A8812.d							\
 	and_A8813.d							\
 	and_A8814.d							\
+	asr_A8816.d							\
 	b_A8818.d							\
 	bic_A8821.d							\
 	bic_A8822.d							\
@@ -79,6 +80,7 @@ ARMV7_DEFS = 							\
 	str_A88203.d						\
 	str_A88204.d						\
 	strb_A88206.d						\
+	sub_A88221.d						\
 	sub_A88222.d						\
 	sub_A88223.d						\
 	sub_A88225.d						\
@@ -89,6 +91,7 @@ ARMV7_DEFS = 							\
 	umaal_A88255.d						\
 	umlal_A88256.d						\
 	umull_A88257.d						\
+	uxtb_A88274.d						\
 	yield_A88426.d						\
 	subs_B9320.d
 
diff --git a/src/arch/arm/v7/opdefs/asr_A8816.d b/src/arch/arm/v7/opdefs/asr_A8816.d
new file mode 100644
index 0000000..7c1fda6
--- /dev/null
+++ b/src/arch/arm/v7/opdefs/asr_A8816.d
@@ -0,0 +1,93 @@
+
+/* 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 ASR (immediate)
+
+@encoding(t1) {
+
+    @half 0 0 0 1 0 imm5(5) Rm(3) Rd(3)
+
+    @syntax <Rd> <Rm> <#imm>
+
+    @conv {
+
+        Rd = Register(Rd)
+        Rm = Register(Rm)
+        imm = FixedShift(2, imm5)
+
+    }
+
+    @rules {
+
+        //setflags = !InITBlock();
+
+    }
+
+}
+
+@encoding(T2) {
+
+    @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 1 0 Rm(4)
+
+    @syntax {S} ".W" <Rd> <Rm> <#imm>
+
+    @conv {
+
+        S = SetFlags(S)
+        Rd = Register(Rd)
+        Rm = Register(Rm)
+        imm = FixedShift(2, imm3:imm2)
+
+    }
+
+    @rules {
+
+        //if d IN {13,15} || m IN {13,15} then UNPREDICTABLE;
+
+    }
+
+}
+
+@encoding(A1) {
+
+    @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm5(5) 1 0 0 Rm(4)
+
+    @syntax {S} {c} <Rd> <Rm> <#imm>
+
+    @conv {
+
+        S = SetFlags(S)
+        c = Condition(cond)
+        Rd = Register(Rd)
+        Rm = Register(Rm)
+        imm = FixedShift(2, imm5)
+
+    }
+
+    @rules {
+
+        //if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
+
+    }
+
+}
diff --git a/src/arch/arm/v7/opdefs/sub_A88221.d b/src/arch/arm/v7/opdefs/sub_A88221.d
new file mode 100644
index 0000000..0ef0e11
--- /dev/null
+++ b/src/arch/arm/v7/opdefs/sub_A88221.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 <http://www.gnu.org/licenses/>.
+ */
+
+
+@title SUB (immediate, Thumb)
+
+@encoding(t1) {
+
+    @half 0 0 0 1 1 1 1 imm3(3) Rn(3) Rd(3)
+
+    @syntax <Rd> <Rn> <const>
+
+    @conv {
+
+        Rd = Register(Rd)
+        Rn = Register(Rn)
+        const = ZeroExtend(imm3, 3, 32);
+
+    }
+
+    @rules {
+
+        //setflags = !InITBlock();
+
+    }
+
+}
+
+@encoding(t2) {
+
+    @half 0 0 1 1 1 Rdn(3) imm8(8)
+
+    @syntax <Rdn> <const>
+
+    @conv {
+
+        Rdn = Register(Rdn)
+        const = ZeroExtend(imm8, 8, 32);
+
+    }
+
+    @rules {
+
+        //setflags = !InITBlock();
+
+    }
+
+}
+
+@encoding(T3) {
+
+    @word 1 1 1 1 0 i(1) 0 1 1 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8)
+
+    @syntax {S} ".W" <Rd> <Rn> <const>
+
+    @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 CMP (immediate);
+        //if Rn == '1101' then SEE SUB (SP minus immediate);
+        //if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
+
+    }
+
+}
+
+@encoding(T4) {
+
+    @word 1 1 1 1 0 i(1) 1 0 1 0 1 0 Rn(4) 0 imm3(3) Rd(4) imm8(8)
+
+    @syntax "subw" <Rd> <Rn> <const>
+
+    @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 SUB (SP minus immediate);
+        //if d IN {13,15} then UNPREDICTABLE;
+
+    }
+
+}
diff --git a/src/arch/arm/v7/opdefs/uxtb_A88274.d b/src/arch/arm/v7/opdefs/uxtb_A88274.d
new file mode 100644
index 0000000..97b17de
--- /dev/null
+++ b/src/arch/arm/v7/opdefs/uxtb_A88274.d
@@ -0,0 +1,84 @@
+
+/* 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 UXTB
+
+@encoding(t1) {
+
+    @half 1 0 1 1 0 0 1 0 1 1 Rm(3) Rd(3)
+
+    @syntax <Rd> <Rm>
+
+    @conv {
+
+        Rd = Register(Rd)
+        Rm = Register(Rm)
+
+    }
+
+}
+
+@encoding(T2) {
+
+    @word 1 1 1 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 Rd(4) 1 0 rotate(2) Rm(4)
+
+    @syntax <Rd> <Rm> <?rotation>
+
+    @conv {
+
+        Rd = Register(Rd)
+        Rm = Register(Rm)
+        rotation = BuildRotation(rotate:'000')
+
+    }
+
+    @rules {
+
+        //if d IN {13,15} || m IN {13,15} then UNPREDICTABLE;
+
+    }
+
+}
+
+@encoding(A1) {
+
+    @word cond(4) 0 1 1 0 1 1 1 0 1 1 1 1 Rd(4) rotate(2) 0 0 0 1 1 1 Rm(4)
+
+    @syntax {c} <Rd> <Rm> <?rotation>
+
+    @conv {
+
+        c = Condition(cond)
+        Rd = Register(Rd)
+        Rm = Register(Rm)
+        rotation = BuildRotation(rotate:'000')
+
+    }
+
+    @rules {
+
+        //if d == 15 || m == 15 then UNPREDICTABLE;
+
+    }
+
+}
diff --git a/src/arch/arm/v7/operands/Makefile.am b/src/arch/arm/v7/operands/Makefile.am
index 32648c9..a33e175 100644
--- a/src/arch/arm/v7/operands/Makefile.am
+++ b/src/arch/arm/v7/operands/Makefile.am
@@ -5,6 +5,7 @@ libarcharmv7operands_la_SOURCES = 		\
 	maccess.h maccess.c					\
 	offset.h offset.c					\
 	reglist.h reglist.c					\
+	rotation.h rotation.c				\
 	shift.h shift.c
 
 libarcharmv7operands_la_LIBADD =
diff --git a/src/arch/arm/v7/operands/rotation.c b/src/arch/arm/v7/operands/rotation.c
new file mode 100644
index 0000000..1532270
--- /dev/null
+++ b/src/arch/arm/v7/operands/rotation.c
@@ -0,0 +1,222 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rotation.c - rotations de valeurs
+ *
+ * Copyright (C) 2010-2013 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA 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.
+ *
+ *  OpenIDA 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/>.
+ */
+
+
+#include "rotation.h"
+
+
+#include "../../../operand-int.h"
+
+
+
+/* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */
+struct _GArmV7RotationOperand
+{
+    GArchOperand parent;                    /* Instance parente            */
+
+    GArchOperand *value;                    /* Valeur du décallage         */
+
+};
+
+
+/* Définition d'un opérande visant une liste d'opérandes Dalvik (classe) */
+struct _GArmV7RotationOperandClass
+{
+    GArchOperandClass parent;               /* Classe parente              */
+
+};
+
+
+/* Initialise la classe des listes d'opérandes Dalvik. */
+static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *);
+
+/* Initialise une instance de liste d'opérandes Dalvik. */
+static void g_armv7_rotation_operand_init(GArmV7RotationOperand *);
+
+/* Supprime toutes les références externes. */
+static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *);
+
+/* Traduit un opérande en version humainement lisible. */
+static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *, GBufferLine *, AsmSyntax);
+
+
+
+/* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */
+G_DEFINE_TYPE(GArmV7RotationOperand, g_armv7_rotation_operand, G_TYPE_ARCH_OPERAND);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des listes d'opérandes Dalvik.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GArchOperandClass *operand;             /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+    operand = G_ARCH_OPERAND_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_rotation_operand_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_armv7_rotation_operand_finalize;
+
+    operand->print = (operand_print_fc)g_armv7_rotation_operand_print;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de liste d'opérandes Dalvik.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_rotation_operand_init(GArmV7RotationOperand *operand)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *operand)
+{
+    g_object_unref(G_OBJECT(operand->value));
+
+    G_OBJECT_CLASS(g_armv7_rotation_operand_parent_class)->dispose(G_OBJECT(operand));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *operand)
+{
+    G_OBJECT_CLASS(g_armv7_rotation_operand_parent_class)->finalize(G_OBJECT(operand));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un réceptacle pour opérandes Dalvik servant d'arguments.*
+*                                                                             *
+*  Retour      : Opérande mis en place.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchOperand *g_armv7_rotation_operand_new(GArchOperand *value)
+{
+    GArmV7RotationOperand *result;             /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_ARMV7_ROTATION_OPERAND, NULL);
+
+    result->value = value;
+
+    return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = opérande à traiter.                                *
+*                line    = ligne tampon où imprimer l'opérande donné.         *
+*                syntax  = type de représentation demandée.                   *
+*                                                                             *
+*  Description : Traduit un opérande en version humainement lisible.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *operand, GBufferLine *line, AsmSyntax syntax)
+{
+    g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ror", 3, RTT_KEY_WORD);
+
+    g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW);
+
+    g_arch_operand_print(operand->value, line, syntax);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = opérande à consulter.                              *
+*                                                                             *
+*  Description : Founit la valeur utilisée pour un décallage.                 *
+*                                                                             *
+*  Retour      : Opérande en place.                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *operand)
+{
+    return operand->value;
+
+}
diff --git a/src/arch/arm/v7/operands/rotation.h b/src/arch/arm/v7/operands/rotation.h
new file mode 100644
index 0000000..fdf5219
--- /dev/null
+++ b/src/arch/arm/v7/operands/rotation.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rotation.h - prototypes pour les rotations de valeurs
+ *
+ * Copyright (C) 2010-2012 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA 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.
+ *
+ *  OpenIDA 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/>.
+ */
+
+
+#ifndef _ARCH_ARM_V7_OPERANDS_ROTATION_H
+#define _ARCH_ARM_V7_OPERANDS_ROTATION_H
+
+
+#include <glib-object.h>
+
+
+#include "../../../operand.h"
+
+
+
+#define G_TYPE_ARMV7_ROTATION_OPERAND                  g_armv7_rotation_operand_get_type()
+#define G_ARMV7_ROTATION_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_rotation_operand_get_type(), GArmV7RotationOperand))
+#define G_IS_ARMV7_ROTATION_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_rotation_operand_get_type()))
+#define G_ARMV7_ROTATION_OPERAND_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_ROTATION_OPERAND, GArmV7RotationOperandClass))
+#define G_IS_ARMV7_ROTATION_OPERAND_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_ROTATION_OPERAND))
+#define G_ARMV7_ROTATION_OPERAND_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_ROTATION_OPERAND, GArmV7RotationOperandClass))
+
+
+/* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */
+typedef struct _GArmV7RotationOperand GArmV7RotationOperand;
+
+/* Définition d'un opérande visant une liste d'opérandes Dalvik (classe) */
+typedef struct _GArmV7RotationOperandClass GArmV7RotationOperandClass;
+
+
+/* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */
+GType g_armv7_rotation_operand_get_type(void);
+
+/* Crée un réceptacle pour opérandes Dalvik servant d'arguments. */
+GArchOperand *g_armv7_rotation_operand_new(GArchOperand *);
+
+/* Founit la valeur utilisée pour un décallage. */
+GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *);
+
+
+
+#endif  /* _ARCH_ARM_V7_OPERANDS_ROTATION_H */
diff --git a/src/arch/arm/v7/thumb_32.c b/src/arch/arm/v7/thumb_32.c
index 757abc4..8fc4d91 100644
--- a/src/arch/arm/v7/thumb_32.c
+++ b/src/arch/arm/v7/thumb_32.c
@@ -679,7 +679,7 @@ static GArchInstruction *process_armv7_thumb_32_load_store_multiple(uint32_t raw
      * § A6.3.5 Load/store multiple
      */
 
-    if ((raw & 0xfe400000) != 0xe0000000) return NULL;
+    if ((raw & 0xfe400000) != 0xe8000000) return NULL;
 
     result = NULL;
 
-- 
cgit v0.11.2-87-g4458