summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-02-01 22:39:57 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-02-01 22:39:57 (GMT)
commit5511e355e7810f06bd610b79bcc94402c88d7ec9 (patch)
tree59023590f49f01cbd4ebfa9c1e82f797315e6f36 /src/arch/arm
parent21a05df6423bdc13ca148ff2b96aec80bf7af2b2 (diff)
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
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/v7/helpers.h33
-rw-r--r--src/arch/arm/v7/opcodes/opcodes_tmp_arm.h1
-rw-r--r--src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h3
-rw-r--r--src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h2
-rw-r--r--src/arch/arm/v7/opdefs/Makefile.am3
-rw-r--r--src/arch/arm/v7/opdefs/asr_A8816.d93
-rw-r--r--src/arch/arm/v7/opdefs/sub_A88221.d116
-rw-r--r--src/arch/arm/v7/opdefs/uxtb_A88274.d84
-rw-r--r--src/arch/arm/v7/operands/Makefile.am1
-rw-r--r--src/arch/arm/v7/operands/rotation.c222
-rw-r--r--src/arch/arm/v7/operands/rotation.h61
-rw-r--r--src/arch/arm/v7/thumb_32.c2
12 files changed, 614 insertions, 7 deletions
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;