From 55c034aa3d975320dbaa7e643e68289732386eec Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 23 Dec 2011 15:49:56 +0000
Subject: Decoded Dalvik pseudo-instructions properly.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@216 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                          |  35 ++++++
 configure.ac                       |   1 +
 src/arch/dalvik/Makefile.am        |   8 +-
 src/arch/dalvik/instruction-def.h  | 208 +++++++++++++++++++++++++++++++++++
 src/arch/dalvik/instruction-int.h  |  52 +++++++++
 src/arch/dalvik/instruction.c      |  18 +--
 src/arch/dalvik/instruction.h      | 171 +----------------------------
 src/arch/dalvik/processor.c        |  83 +++++++++++---
 src/arch/dalvik/pseudo/Makefile.am |  17 +++
 src/arch/dalvik/pseudo/fill.c      | 214 ++++++++++++++++++++++++++++++++++++
 src/arch/dalvik/pseudo/fill.h      |  57 ++++++++++
 src/arch/dalvik/pseudo/switch.c    | 217 +++++++++++++++++++++++++++++++++++++
 src/arch/dalvik/pseudo/switch.h    |  57 ++++++++++
 src/arch/dalvik/specins.c          | 115 --------------------
 src/arch/dalvik/specins.h          |  51 ---------
 src/arch/instruction-int.h         |   4 +
 src/arch/instruction.c             |  35 +++++-
 17 files changed, 973 insertions(+), 370 deletions(-)
 create mode 100644 src/arch/dalvik/instruction-def.h
 create mode 100644 src/arch/dalvik/instruction-int.h
 create mode 100644 src/arch/dalvik/pseudo/Makefile.am
 create mode 100644 src/arch/dalvik/pseudo/fill.c
 create mode 100644 src/arch/dalvik/pseudo/fill.h
 create mode 100644 src/arch/dalvik/pseudo/switch.c
 create mode 100644 src/arch/dalvik/pseudo/switch.h
 delete mode 100644 src/arch/dalvik/specins.c
 delete mode 100644 src/arch/dalvik/specins.h

diff --git a/ChangeLog b/ChangeLog
index 8ca6ee2..0799cf7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+11-12-23  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Add the new Makefile from the 'src/arch/dalvik/pseudo' directory to
+	AC_CONFIG_FILES.
+
+	* src/arch/dalvik/instruction.c:
+	* src/arch/dalvik/instruction-def.h:
+	* src/arch/dalvik/instruction.h:
+	* src/arch/dalvik/instruction-int.h:
+	Reorganize the definition of Dalvik instructions.
+
+	* src/arch/dalvik/Makefile.am:
+	Add the instruction-{def,int}.h files to libarchdalvik_la_SOURCES and
+	pseudo/libarchdalvikpseudo.la to libarchdalvik_la_LIBADD. Remove all
+	specins.[ch]-related things.
+
+	* src/arch/dalvik/processor.c:
+	Decode Dalvik pseudo-instructions.
+
+	* src/arch/dalvik/pseudo/fill.c:
+	* src/arch/dalvik/pseudo/fill.h:
+	* src/arch/dalvik/pseudo/Makefile.am:
+	* src/arch/dalvik/pseudo/switch.c:
+	* src/arch/dalvik/pseudo/switch.h:
+	New entries: decode pseudo-instructions properly.
+
+	* src/arch/dalvik/specins.c:
+	* src/arch/dalvik/specins.h:
+	Deleted entries.
+
+	* src/arch/instruction.c:
+	* src/arch/instruction-int.h:
+	Allow each instruction to provide its own printing method.
+
 11-12-09  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/configuration.c:
diff --git a/configure.ac b/configure.ac
index ad71854..f3679d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -251,6 +251,7 @@ AC_CONFIG_FILES([Makefile
                  src/arch/arm/Makefile
                  src/arch/dalvik/Makefile
                  src/arch/dalvik/operands/Makefile
+                 src/arch/dalvik/pseudo/Makefile
                  src/arch/jvm/Makefile
                  src/arch/mips/Makefile
                  src/arch/x86/Makefile
diff --git a/src/arch/dalvik/Makefile.am b/src/arch/dalvik/Makefile.am
index 6640180..18fb08d 100644
--- a/src/arch/dalvik/Makefile.am
+++ b/src/arch/dalvik/Makefile.am
@@ -3,6 +3,8 @@ noinst_LTLIBRARIES = libarchdalvik.la
 
 libarchdalvik_la_SOURCES =				\
 	context.h context.c					\
+	instruction-def.h					\
+	instruction-int.h					\
 	instruction.h instruction.c			\
 	dop_aget.c							\
 	dop_aput.c							\
@@ -43,11 +45,11 @@ libarchdalvik_la_SOURCES =				\
 	operand.h operand.c					\
 	processor.h processor.c				\
 	register.h register.c				\
-	specins.h specins.c					\
 	translate.h
 
 libarchdalvik_la_LIBADD =				\
-	operands/libarchdalvikoperands.la
+	operands/libarchdalvikoperands.la	\
+	pseudo/libarchdalvikpseudo.la
 
 libarchdalvik_la_CFLAGS = $(AM_CFLAGS)
 
@@ -59,4 +61,4 @@ AM_CPPFLAGS =
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
 
-SUBDIRS = operands
+SUBDIRS = operands pseudo
diff --git a/src/arch/dalvik/instruction-def.h b/src/arch/dalvik/instruction-def.h
new file mode 100644
index 0000000..48d7e96
--- /dev/null
+++ b/src/arch/dalvik/instruction-def.h
@@ -0,0 +1,208 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * instruction-def.h - définition interne des identifiants d'instructions Dalvik
+ *
+ * Copyright (C) 2011 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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_DALVIK_INSTRUCTION_DEF_H
+#define _ARCH_DALVIK_INSTRUCTION_DEF_H
+
+
+
+/* Enumération de tous les opcodes */
+typedef enum _DalvikOpcodes
+{
+    DOP_NOP,                                /* nop (0x00)                  */
+    DOP_MOVE,                               /* move (0x01)                 */
+    DOP_MOVE_FROM_16,                       /* move/from16 (0x02)          */
+
+    DOP_MOVE_OBJECT,                        /* move-object (0x07)          */
+
+    DOP_MOVE_RESULT,                        /* move-result (0x0a)          */
+    DOP_MOVE_RESULT_WIDE,                   /* move-result-wide (0x0b)     */
+    DOP_MOVE_RESULT_OBJECT,                 /* move-result-object (0x0c)   */
+    DOP_MOVE_EXCEPTION,                     /* move-exception (0x0d)       */
+    DOP_RETURN_VOID,                        /* return-void (0x0e)          */
+    DOP_RETURN,                             /* return (0x0f)               */
+    DOP_RETURN_WIDE,                        /* return-wide (0x10)          */
+    DOP_RETURN_OBJECT,                      /* return-object (0x11)        */
+    DOP_CONST_4,                            /* const/4 (0x12)              */
+    DOP_CONST_16,                           /* const/16 (0x13)             */
+    DOP_CONST,                              /* const (0x14)                */
+    DOP_CONST_HIGH16,                       /* const/high16 (0x15)         */
+    DOP_CONST_WIDE_16,                      /* const-wide/16 (0x16)        */
+
+    DOP_CONST_WIDE,                         /* const-wide (0x18)           */
+
+    DOP_CONST_STRING,                       /* const-string (0x1a)         */
+
+
+    DOP_CHECK_CAST,                         /* check-cast (0x1f)           */
+
+    DOP_ARRAY_LENGTH,                       /* array-length (0x21)         */
+    DOP_NEW_INSTANCE,                       /* new-instance (0x22)         */
+    DOP_NEW_ARRAY,                          /* new-array (0x23)            */
+
+    DOP_FILL_ARRAY_DATA,                    /* fill-array-data (0x26)      */
+
+    DOP_GOTO,                               /* goto (0x28)                 */
+    DOP_GOTO_16,                            /* goto/16 (0x29)              */
+    DOP_GOTO_32,                            /* goto/32 (0x2a)              */
+
+
+    DOP_CMPL_FLOAT,                         /* cmp-long (0x2d)             */
+    DOP_CMPG_FLOAT,                         /* cmpg-float (0x2e)           */
+    DOP_CMPL_DOUBLE,                        /* cmpl-double (0x2f)          */
+    DOP_CMPG_DOUBLE,                        /* cmpg-double (0x30)          */
+    DOP_CMP_LONG,                           /* cmp-long (0x31)             */
+    DOP_IF_EQ,                              /* if-eq (0x32)                */
+    DOP_IF_NE,                              /* if-ne (0x33)                */
+    DOP_IF_LT,                              /* if-lt (0x34)                */
+    DOP_IF_GE,                              /* if-ge (0x35)                */
+    DOP_IF_GT,                              /* if-gt (0x36)                */
+    DOP_IF_LE,                              /* if-le (0x37)                */
+    DOP_IF_EQZ,                             /* if-eqz (0x38)               */
+    DOP_IF_NEZ,                             /* if-nez (0x39)               */
+    DOP_IF_LTZ,                             /* if-ltz (0x3a)               */
+    DOP_IF_GEZ,                             /* if-gez (0x3b)               */
+    DOP_IF_GTZ,                             /* if-gtz (0x3c)               */
+    DOP_IF_LEZ,                             /* if-lez (0x3d)               */
+
+
+
+    DOP_AGET,                               /* aget (0x44)                 */
+    DOP_AGET_WIDE,                          /* aget-wide (0x45)            */
+    DOP_AGET_OBJECT,                        /* aget-object (0x46)          */
+    DOP_AGET_BOOLEAN,                       /* aget-boolean (0x47)         */
+    DOP_AGET_BYTE,                          /* aget-byte (0x48)            */
+    DOP_AGET_CHAR,                          /* aget-char (0x49)            */
+    DOP_AGET_SHORT,                         /* aget-short (0x4a)           */
+    DOP_APUT,                               /* aput (0x4b)                 */
+    DOP_APUT_WIDE,                          /* aput-wide (0x4c)            */
+    DOP_APUT_OBJECT,                        /* aput-object (0x4d)          */
+    DOP_APUT_BOOLEAN,                       /* aput-boolean (0x4e)         */
+    DOP_APUT_BYTE,                          /* aput-byte (0x4f)            */
+    DOP_APUT_CHAR,                          /* aput-char (0x50)            */
+    DOP_APUT_SHORT,                         /* aput-short (0x51)           */
+    DOP_IGET,                               /* iget (0x52)                 */
+    DOP_IGET_WIDE,                          /* iget-wide (0x53)            */
+    DOP_IGET_OBJECT,                        /* iget-object (0x54)          */
+    DOP_IGET_BOOLEAN,                       /* iget-boolean (0x55)         */
+    DOP_IGET_BYTE,                          /* iget-byte (0x56)            */
+    DOP_IGET_CHAR,                          /* iget-char (0x57)            */
+    DOP_IGET_SHORT,                         /* iget-short (0x58)           */
+    DOP_IPUT,                               /* iput (0x59)                 */
+    DOP_IPUT_WIDE,                          /* iput-wide (0x5a)            */
+    DOP_IPUT_OBJECT,                        /* iput-object (0x5b)          */
+    DOP_IPUT_BOOLEAN,                       /* iput-boolean (0x5c)         */
+    DOP_IPUT_BYTE,                          /* iput-byte (0x5d)            */
+    DOP_IPUT_CHAR,                          /* iput-char (0x5e)            */
+    DOP_IPUT_SHORT,                         /* iput-short (0x5f)           */
+    DOP_SGET,                               /* sget (0x60)                 */
+    DOP_SGET_WIDE,                          /* sget-wide (0x61)            */
+    DOP_SGET_OBJECT,                        /* sget-object (0x62)          */
+    DOP_SGET_BOOLEAN,                       /* sget-boolean (0x63)         */
+    DOP_SGET_BYTE,                          /* sget-byte (0x64)            */
+    DOP_SGET_CHAR,                          /* sget-char (0x65)            */
+    DOP_SGET_SHORT,                         /* sget-short (0x66)           */
+    DOP_SPUT,                               /* sput (0x67)                 */
+    DOP_SPUT_WIDE,                          /* sput-wide (0x68)            */
+    DOP_SPUT_OBJECT,                        /* sput-object (0x69)          */
+    DOP_SPUT_BOOLEAN,                       /* sput-boolean (0x6a)         */
+    DOP_SPUT_BYTE,                          /* sput-byte (0x6b)            */
+    DOP_SPUT_CHAR,                          /* sput-char (0x6c)            */
+    DOP_SPUT_SHORT,                         /* sput-short (0x6d)           */
+    DOP_INVOKE_VIRTUAL,                     /* invoke-virtual (0x6e)       */
+    DOP_INVOKE_SUPER,                       /* invoke-super (0x6f)         */
+    DOP_INVOKE_DIRECT,                      /* invoke-direct (0x70)        */
+    DOP_INVOKE_STATIC,                      /* invoke-static (0x71)        */
+    DOP_INVOKE_INTERFACE,                   /* invoke-interface (0x72)     */
+
+
+
+    DOP_TO_INT_LONG,                        /* int-to-long (0x81)          */
+    DOP_TO_INT_FLOAT,                       /* int-to-float (0x82)         */
+    DOP_TO_INT_DOUBLE,                      /* int-to-double (0x83)        */
+    DOP_TO_LONG_INT,                        /* long-to-int (0x84)          */
+    DOP_TO_LONG_FLOAT,                      /* long-to-float (0x85)        */
+    DOP_TO_LONG_DOUBLE,                     /* long-to-double (0x86)       */
+    DOP_TO_FLOAT_INT,                       /* float-to-int (0x87)         */
+    DOP_TO_FLOAT_LONG,                      /* float-to-long (0x88)        */
+    DOP_TO_FLOAT_DOUBLE,                    /* float-to-double (0x89)      */
+    DOP_TO_DOUBLE_INT,                      /* double-to-int (0x8a)        */
+    DOP_TO_DOUBLE_LONG,                     /* double-to-long (0x8b)       */
+    DOP_TO_DOUBLE_FLOAT,                    /* double-to-float (0x8c)      */
+    DOP_TO_INT_BYTE,                        /* int-to-byte (0x8d)          */
+    DOP_TO_INT_CHAR,                        /* int-to-char (0x8e)          */
+    DOP_TO_INT_SHORT,                       /* int-to-short (0x8f)         */
+    DOP_ADD_INT,                            /* add-int (0x90)              */
+    DOP_SUB_INT,                            /* sub-int (0x91)              */
+    DOP_MUL_INT,                            /* mul-int (0x92)              */
+    DOP_DIV_INT,                            /* div-int (0x93)              */
+    DOP_REM_INT,                            /* rem-int (0x94)              */
+    DOP_AND_INT,                            /* and-int (0x95)              */
+    DOP_OR_INT,                             /* or-int (0x96)               */
+    DOP_XOR_INT,                            /* xor-int (0x97)              */
+
+    DOP_ADD_INT_2ADDR,                      /* add-int/2addr (0xb0)        */
+
+    DOP_MUL_INT_2ADDR,                      /* mul-int/2addr (0xb2)        */
+    DOP_DIV_INT_2ADDR,                      /* div-int/2addr (0xb3)        */
+    DOP_REM_INT_2ADDR,                      /* rem-int/2addr (0xb4)        */
+    DOP_AND_INT_2ADDR,                      /* and-int/2addr (0xb5)        */
+    DOP_OR_INT_2ADDR,                       /* or-int/2addr (0xb6)         */
+    DOP_XOR_INT_2ADDR,                      /* xor-int/2addr (0xb7)        */
+
+    DOP_MUL_DOUBLE_2ADDR,                   /* mul-double/2addr (0xcd)     */
+
+    DOP_ADD_INT_LIT16,                      /* add-int/lit16 (0xd0)        */
+    DOP_RSUB_INT,                           /* rsub-int (0xd1)             */
+    DOP_MUL_INT_LIT16,                      /* mul-int/lit16 (0xd2)        */
+    DOP_DIV_INT_LIT16,                      /* div-int/lit16 (0xd3)        */
+    DOP_REM_INT_LIT16,                      /* rem-int/lit16 (0xd4)        */
+    DOP_AND_INT_LIT16,                      /* and-int/lit16 (0xd5)        */
+    DOP_OR_INT_LIT16,                       /* or-int/lit16 (0xd6)         */
+    DOP_XOR_INT_LIT16,                      /* xor-int/lit16 (0xd7)        */
+    DOP_ADD_INT_LIT8,                       /* add-int/lit8 (0xd8)         */
+    DOP_RSUB_INT_LIT8,                      /* rsub-int/lit8 (0xd9)        */
+    DOP_MUL_INT_LIT8,                       /* mul-int/lit8 (0xda)         */
+    DOP_DIV_INT_LIT8,                       /* div-int/lit8 (0xdb)         */
+    DOP_REM_INT_LIT8,                       /* rem-int/lit8 (0xdc)         */
+    DOP_AND_INT_LIT8,                       /* and-int/lit8 (0xdd)         */
+    DOP_OR_INT_LIT8,                        /* or-int/lit8 (0xde)          */
+    DOP_XOR_INT_LIT8,                       /* xor-int/lit8 (0xdf)         */
+
+    DOP_COUNT
+
+} DalvikOpcodes;
+
+
+/* Enumération de tous les pseudo-opcodes */
+typedef enum _DalvikPseudoOpcodes
+{
+    DPO_PACKED_SWITCH   = 0x0100,           /* Switch aux clefs compactes  */
+    DPO_SPARSE_SWITCH   = 0x0200,           /* Switch aux clefs éclatées   */
+    DPO_FILL_ARRAY_DATA = 0x0300            /* Contenu de tableau          */
+
+} DalvikPseudoOpcodes;
+
+
+
+#endif  /* _ARCH_DALVIK_INSTRUCTION_DEF_H */
diff --git a/src/arch/dalvik/instruction-int.h b/src/arch/dalvik/instruction-int.h
new file mode 100644
index 0000000..9166c0c
--- /dev/null
+++ b/src/arch/dalvik/instruction-int.h
@@ -0,0 +1,52 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * instruction-int.h - prototypes pour la définition générique interne des instructions Dalvik
+ *
+ * Copyright (C) 2011 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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_DALVIK_INSTRUCTION_INT_H
+#define _ARCH_DALVIK_INSTRUCTION_INT_H
+
+
+#include "instruction-def.h"
+#include "../instruction-int.h"
+
+
+
+/* Définition générique d'une instruction d'architecture Dalvik (instance) */
+struct _GDalvikInstruction
+{
+    GArchInstruction parent;                /* A laisser en premier        */
+
+    DalvikOpcodes type;                     /* Position dans la liste      */
+    DalvikPseudoOpcodes ptype;              /* Position dans la liste #2   */
+
+};
+
+/* Définition générique d'une instruction d'architecture Dalvik (classe) */
+struct _GDalvikInstructionClass
+{
+    GArchInstructionClass parent;           /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ARCH_DALVIK_INSTRUCTION_INT_H */
diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c
index 4595193..0d68a83 100644
--- a/src/arch/dalvik/instruction.c
+++ b/src/arch/dalvik/instruction.c
@@ -24,28 +24,12 @@
 #include "instruction.h"
 
 
+#include "instruction-int.h"
 #include "translate.h"
 #include "../instruction-int.h"
 
 
 
-/* Définition générique d'une instruction d'architecture Dalvik (instance) */
-struct _GDalvikInstruction
-{
-    GArchInstruction parent;                /* A laisser en premier        */
-
-    DalvikOpcodes type;                     /* Position dans la liste      */
-
-};
-
-/* Définition générique d'une instruction d'architecture Dalvik (classe) */
-struct _GDalvikInstructionClass
-{
-    GArchInstructionClass parent;           /* A laisser en premier        */
-
-};
-
-
 /* Initialise la classe des instructions pour Dalvik. */
 static void g_dalvik_instruction_class_init(GDalvikInstructionClass *);
 
diff --git a/src/arch/dalvik/instruction.h b/src/arch/dalvik/instruction.h
index c359c66..0caee00 100644
--- a/src/arch/dalvik/instruction.h
+++ b/src/arch/dalvik/instruction.h
@@ -25,178 +25,11 @@
 #define _ARCH_DALVIK_INSTRUCTION_H
 
 
+#include "instruction-def.h"
 #include "../instruction.h"
 
 
 
-/* Enumération de tous les opcodes */
-typedef enum _DalvikOpcodes
-{
-    DOP_NOP,                                /* nop (0x00)                  */
-    DOP_MOVE,                               /* move (0x01)                 */
-    DOP_MOVE_FROM_16,                       /* move/from16 (0x02)          */
-
-    DOP_MOVE_OBJECT,                        /* move-object (0x07)          */
-
-    DOP_MOVE_RESULT,                        /* move-result (0x0a)          */
-    DOP_MOVE_RESULT_WIDE,                   /* move-result-wide (0x0b)     */
-    DOP_MOVE_RESULT_OBJECT,                 /* move-result-object (0x0c)   */
-    DOP_MOVE_EXCEPTION,                     /* move-exception (0x0d)       */
-    DOP_RETURN_VOID,                        /* return-void (0x0e)          */
-    DOP_RETURN,                             /* return (0x0f)               */
-    DOP_RETURN_WIDE,                        /* return-wide (0x10)          */
-    DOP_RETURN_OBJECT,                      /* return-object (0x11)        */
-    DOP_CONST_4,                            /* const/4 (0x12)              */
-    DOP_CONST_16,                           /* const/16 (0x13)             */
-    DOP_CONST,                              /* const (0x14)                */
-    DOP_CONST_HIGH16,                       /* const/high16 (0x15)         */
-    DOP_CONST_WIDE_16,                      /* const-wide/16 (0x16)        */
-
-    DOP_CONST_WIDE,                         /* const-wide (0x18)           */
-
-    DOP_CONST_STRING,                       /* const-string (0x1a)         */
-
-
-    DOP_CHECK_CAST,                         /* check-cast (0x1f)           */
-
-    DOP_ARRAY_LENGTH,                       /* array-length (0x21)         */
-    DOP_NEW_INSTANCE,                       /* new-instance (0x22)         */
-    DOP_NEW_ARRAY,                          /* new-array (0x23)            */
-
-    DOP_FILL_ARRAY_DATA,                    /* fill-array-data (0x26)      */
-
-    DOP_GOTO,                               /* goto (0x28)                 */
-    DOP_GOTO_16,                            /* goto/16 (0x29)              */
-    DOP_GOTO_32,                            /* goto/32 (0x2a)              */
-
-
-    DOP_CMPL_FLOAT,                         /* cmp-long (0x2d)             */
-    DOP_CMPG_FLOAT,                         /* cmpg-float (0x2e)           */
-    DOP_CMPL_DOUBLE,                        /* cmpl-double (0x2f)          */
-    DOP_CMPG_DOUBLE,                        /* cmpg-double (0x30)          */
-    DOP_CMP_LONG,                           /* cmp-long (0x31)             */
-    DOP_IF_EQ,                              /* if-eq (0x32)                */
-    DOP_IF_NE,                              /* if-ne (0x33)                */
-    DOP_IF_LT,                              /* if-lt (0x34)                */
-    DOP_IF_GE,                              /* if-ge (0x35)                */
-    DOP_IF_GT,                              /* if-gt (0x36)                */
-    DOP_IF_LE,                              /* if-le (0x37)                */
-    DOP_IF_EQZ,                             /* if-eqz (0x38)               */
-    DOP_IF_NEZ,                             /* if-nez (0x39)               */
-    DOP_IF_LTZ,                             /* if-ltz (0x3a)               */
-    DOP_IF_GEZ,                             /* if-gez (0x3b)               */
-    DOP_IF_GTZ,                             /* if-gtz (0x3c)               */
-    DOP_IF_LEZ,                             /* if-lez (0x3d)               */
-
-
-
-    DOP_AGET,                               /* aget (0x44)                 */
-    DOP_AGET_WIDE,                          /* aget-wide (0x45)            */
-    DOP_AGET_OBJECT,                        /* aget-object (0x46)          */
-    DOP_AGET_BOOLEAN,                       /* aget-boolean (0x47)         */
-    DOP_AGET_BYTE,                          /* aget-byte (0x48)            */
-    DOP_AGET_CHAR,                          /* aget-char (0x49)            */
-    DOP_AGET_SHORT,                         /* aget-short (0x4a)           */
-    DOP_APUT,                               /* aput (0x4b)                 */
-    DOP_APUT_WIDE,                          /* aput-wide (0x4c)            */
-    DOP_APUT_OBJECT,                        /* aput-object (0x4d)          */
-    DOP_APUT_BOOLEAN,                       /* aput-boolean (0x4e)         */
-    DOP_APUT_BYTE,                          /* aput-byte (0x4f)            */
-    DOP_APUT_CHAR,                          /* aput-char (0x50)            */
-    DOP_APUT_SHORT,                         /* aput-short (0x51)           */
-    DOP_IGET,                               /* iget (0x52)                 */
-    DOP_IGET_WIDE,                          /* iget-wide (0x53)            */
-    DOP_IGET_OBJECT,                        /* iget-object (0x54)          */
-    DOP_IGET_BOOLEAN,                       /* iget-boolean (0x55)         */
-    DOP_IGET_BYTE,                          /* iget-byte (0x56)            */
-    DOP_IGET_CHAR,                          /* iget-char (0x57)            */
-    DOP_IGET_SHORT,                         /* iget-short (0x58)           */
-    DOP_IPUT,                               /* iput (0x59)                 */
-    DOP_IPUT_WIDE,                          /* iput-wide (0x5a)            */
-    DOP_IPUT_OBJECT,                        /* iput-object (0x5b)          */
-    DOP_IPUT_BOOLEAN,                       /* iput-boolean (0x5c)         */
-    DOP_IPUT_BYTE,                          /* iput-byte (0x5d)            */
-    DOP_IPUT_CHAR,                          /* iput-char (0x5e)            */
-    DOP_IPUT_SHORT,                         /* iput-short (0x5f)           */
-    DOP_SGET,                               /* sget (0x60)                 */
-    DOP_SGET_WIDE,                          /* sget-wide (0x61)            */
-    DOP_SGET_OBJECT,                        /* sget-object (0x62)          */
-    DOP_SGET_BOOLEAN,                       /* sget-boolean (0x63)         */
-    DOP_SGET_BYTE,                          /* sget-byte (0x64)            */
-    DOP_SGET_CHAR,                          /* sget-char (0x65)            */
-    DOP_SGET_SHORT,                         /* sget-short (0x66)           */
-    DOP_SPUT,                               /* sput (0x67)                 */
-    DOP_SPUT_WIDE,                          /* sput-wide (0x68)            */
-    DOP_SPUT_OBJECT,                        /* sput-object (0x69)          */
-    DOP_SPUT_BOOLEAN,                       /* sput-boolean (0x6a)         */
-    DOP_SPUT_BYTE,                          /* sput-byte (0x6b)            */
-    DOP_SPUT_CHAR,                          /* sput-char (0x6c)            */
-    DOP_SPUT_SHORT,                         /* sput-short (0x6d)           */
-    DOP_INVOKE_VIRTUAL,                     /* invoke-virtual (0x6e)       */
-    DOP_INVOKE_SUPER,                       /* invoke-super (0x6f)         */
-    DOP_INVOKE_DIRECT,                      /* invoke-direct (0x70)        */
-    DOP_INVOKE_STATIC,                      /* invoke-static (0x71)        */
-    DOP_INVOKE_INTERFACE,                   /* invoke-interface (0x72)     */
-
-
-
-    DOP_TO_INT_LONG,                        /* int-to-long (0x81)          */
-    DOP_TO_INT_FLOAT,                       /* int-to-float (0x82)         */
-    DOP_TO_INT_DOUBLE,                      /* int-to-double (0x83)        */
-    DOP_TO_LONG_INT,                        /* long-to-int (0x84)          */
-    DOP_TO_LONG_FLOAT,                      /* long-to-float (0x85)        */
-    DOP_TO_LONG_DOUBLE,                     /* long-to-double (0x86)       */
-    DOP_TO_FLOAT_INT,                       /* float-to-int (0x87)         */
-    DOP_TO_FLOAT_LONG,                      /* float-to-long (0x88)        */
-    DOP_TO_FLOAT_DOUBLE,                    /* float-to-double (0x89)      */
-    DOP_TO_DOUBLE_INT,                      /* double-to-int (0x8a)        */
-    DOP_TO_DOUBLE_LONG,                     /* double-to-long (0x8b)       */
-    DOP_TO_DOUBLE_FLOAT,                    /* double-to-float (0x8c)      */
-    DOP_TO_INT_BYTE,                        /* int-to-byte (0x8d)          */
-    DOP_TO_INT_CHAR,                        /* int-to-char (0x8e)          */
-    DOP_TO_INT_SHORT,                       /* int-to-short (0x8f)         */
-    DOP_ADD_INT,                            /* add-int (0x90)              */
-    DOP_SUB_INT,                            /* sub-int (0x91)              */
-    DOP_MUL_INT,                            /* mul-int (0x92)              */
-    DOP_DIV_INT,                            /* div-int (0x93)              */
-    DOP_REM_INT,                            /* rem-int (0x94)              */
-    DOP_AND_INT,                            /* and-int (0x95)              */
-    DOP_OR_INT,                             /* or-int (0x96)               */
-    DOP_XOR_INT,                            /* xor-int (0x97)              */
-
-    DOP_ADD_INT_2ADDR,                      /* add-int/2addr (0xb0)        */
-
-    DOP_MUL_INT_2ADDR,                      /* mul-int/2addr (0xb2)        */
-    DOP_DIV_INT_2ADDR,                      /* div-int/2addr (0xb3)        */
-    DOP_REM_INT_2ADDR,                      /* rem-int/2addr (0xb4)        */
-    DOP_AND_INT_2ADDR,                      /* and-int/2addr (0xb5)        */
-    DOP_OR_INT_2ADDR,                       /* or-int/2addr (0xb6)         */
-    DOP_XOR_INT_2ADDR,                      /* xor-int/2addr (0xb7)        */
-
-    DOP_MUL_DOUBLE_2ADDR,                   /* mul-double/2addr (0xcd)     */
-
-    DOP_ADD_INT_LIT16,                      /* add-int/lit16 (0xd0)        */
-    DOP_RSUB_INT,                           /* rsub-int (0xd1)             */
-    DOP_MUL_INT_LIT16,                      /* mul-int/lit16 (0xd2)        */
-    DOP_DIV_INT_LIT16,                      /* div-int/lit16 (0xd3)        */
-    DOP_REM_INT_LIT16,                      /* rem-int/lit16 (0xd4)        */
-    DOP_AND_INT_LIT16,                      /* and-int/lit16 (0xd5)        */
-    DOP_OR_INT_LIT16,                       /* or-int/lit16 (0xd6)         */
-    DOP_XOR_INT_LIT16,                      /* xor-int/lit16 (0xd7)        */
-    DOP_ADD_INT_LIT8,                       /* add-int/lit8 (0xd8)         */
-    DOP_RSUB_INT_LIT8,                      /* rsub-int/lit8 (0xd9)        */
-    DOP_MUL_INT_LIT8,                       /* mul-int/lit8 (0xda)         */
-    DOP_DIV_INT_LIT8,                       /* div-int/lit8 (0xdb)         */
-    DOP_REM_INT_LIT8,                       /* rem-int/lit8 (0xdc)         */
-    DOP_AND_INT_LIT8,                       /* and-int/lit8 (0xdd)         */
-    DOP_OR_INT_LIT8,                        /* or-int/lit8 (0xde)          */
-    DOP_XOR_INT_LIT8,                       /* xor-int/lit8 (0xdf)         */
-
-    DOP_COUNT
-
-} DalvikOpcodes;
-
-
 #define G_TYPE_DALVIK_INSTRUCTION                 g_dalvik_instruction_get_type()
 #define G_DALVIK_INSTRUCTION(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_instruction_get_type(), GDalvikInstruction))
 #define G_IS_DALVIK_INSTRUCTION(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_instruction_get_type()))
@@ -217,7 +50,7 @@ GType g_dalvik_instruction_get_type(void);
 GArchInstruction *g_dalvik_instruction_new(DalvikOpcodes);
 
 /* Indique l'opcode associé à une instruction Dalvik. */
-DalvikOpcodes g_dalvik_instruction_get_opcode(const GDalvikInstruction *);
+DalvikOpcodes g_dalvik_instruction_get_opcode(const struct _GDalvikInstruction *);
 
 
 
diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c
index 2f56f87..7925c55 100644
--- a/src/arch/dalvik/processor.c
+++ b/src/arch/dalvik/processor.c
@@ -27,7 +27,8 @@
 #include "context.h"
 #include "instruction.h"
 #include "opcodes.h"
-#include "specins.h"
+#include "pseudo/fill.h"
+#include "pseudo/switch.h"
 #include "../processor-int.h"
 
 
@@ -57,6 +58,9 @@ static void g_dalvik_processor_init(GDalvikProcessor *);
 /* Fournit un contexte pour l'exécution du processeur Dalvik. */
 static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *);
 
+/* Décode une pseudo-instruction dans un flux de données. */
+static GArchInstruction *g_dalvik_guess_pseudo_instruction(const GDalvikProcessor *, const bin_t *, off_t *, off_t, vmpa_t);
+
 /* Décode une instruction dans un flux de données. */
 static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProcessor *, GDalvikContext *, const bin_t *, off_t *, off_t, vmpa_t);
 
@@ -157,6 +161,58 @@ static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *pr
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : proc = architecture visée par la procédure.                  *
+*                data = flux de données à analyser.                           *
+*                pos  = position courante dans ce flux. [OUT]                 *
+*                len  = taille totale des données à analyser.                 *
+*                addr = adresse virtuelle de l'instruction.                   *
+*                                                                             *
+*  Description : Décode une pseudo-instruction dans un flux de données.       *
+*                                                                             *
+*  Retour      : Instruction mise en place ou NULL si aucune trouvée.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GArchInstruction *g_dalvik_guess_pseudo_instruction(const GDalvikProcessor *proc, const bin_t *data, off_t *pos, off_t len, vmpa_t addr)
+{
+    GArchInstruction *result;               /* Instruction à renvoyer      */
+    off_t tmp;                              /* Position modifiable         */
+    uint16_t ident;                         /* Valeur lue dans le code     */
+
+    /* Vérification astucieuse et rapide...*/
+    if (data[*pos] != 0x00 /* DOP_NOP */) return NULL; 
+
+    tmp = *pos;
+
+    if (!read_u16(&ident, data, &tmp, len, SRE_LITTLE))
+        return NULL;
+
+    switch (ident)
+    {
+        case DPO_PACKED_SWITCH:
+        case DPO_SPARSE_SWITCH:
+            result = g_dalvik_switch_instr_new(data, pos, len, addr, proc);
+            break;
+
+        case DPO_FILL_ARRAY_DATA:
+            result = g_dalvik_fill_instr_new(data, pos, len, addr, proc);
+            break;
+
+        default:
+            result = NULL;
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : proc = architecture visée par la procédure.                  *
 *                ctx  = contexte lié à l'exécution du processeur.             *
 *                data = flux de données à analyser.                           *
 *                pos  = position courante dans ce flux. [OUT]                 *
@@ -341,22 +397,21 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc
 
     };
 
-    /* Continuité d'une zone spéciale... */
-    if (g_dalvik_context_have_to_skip(ctx, addr))
-        return SKIPPED_INSTR;
-
-    /* Début d'une nouvelle zone spéciale... */
-    if (g_dalvik_guess_special_instruction(ctx, data, *pos, len, addr))
-        return SKIPPED_INSTR;
-
-    /* Ou instruction classique */
+    /* Pseudo-instruction... */
+    result = g_dalvik_guess_pseudo_instruction(proc, data, pos, len, addr);
 
-    id = dalvik_guess_next_instruction(data, *pos, len);
+    /* ... ou instruction classique */
+    if (result == NULL)
+    {
+        id = dalvik_guess_next_instruction(data, *pos, len);
 
-    if (id != DOP_COUNT) (*pos)++;
+        if (id != DOP_COUNT)
+        {
+            (*pos)++;
+            result = decodings[id](data, pos, len, addr, proc);
+        }
 
-    if (id == DOP_COUNT) result = NULL;
-    else result = decodings[id](data, pos, len, addr, proc);
+    }
 
     return result;
 
diff --git a/src/arch/dalvik/pseudo/Makefile.am b/src/arch/dalvik/pseudo/Makefile.am
new file mode 100644
index 0000000..05e361f
--- /dev/null
+++ b/src/arch/dalvik/pseudo/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES = libarchdalvikpseudo.la
+
+libarchdalvikpseudo_la_SOURCES =		\
+	fill.h fill.c						\
+	switch.h switch.c
+
+libarchdalvikpseudo_la_LIBADD = 
+
+libarchdalvikpseudo_la_CFLAGS = $(AM_CFLAGS)
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CPPFLAGS = 
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/src/arch/dalvik/pseudo/fill.c b/src/arch/dalvik/pseudo/fill.c
new file mode 100644
index 0000000..9573000
--- /dev/null
+++ b/src/arch/dalvik/pseudo/fill.c
@@ -0,0 +1,214 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * fill.c - prise en charge de l'instruction spéciale fill-array-data
+ *
+ * Copyright (C) 2011 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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 "fill.h"
+
+
+#include <string.h> 
+
+
+#include "../instruction-int.h"
+
+
+
+/* Définition générique d'une instruction d'architecture Dalvik (instance) */
+struct _GDalvikFillInstr
+{
+    GDalvikInstruction parent;              /* A laisser en premier        */
+
+    uint16_t array_width;                   /* Taille des éléments         */
+    uint32_t array_size;                    /* Taille du tableau           */
+
+};
+
+/* Définition générique d'une instruction d'architecture Dalvik (classe) */
+struct _GDalvikFillInstrClass
+{
+    GDalvikInstructionClass parent;         /* A laisser en premier        */
+
+};
+
+
+
+/* Initialise la classe générique des instructions. */
+static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *);
+
+/* Initialise une instance d'opérande d'architecture. */
+static void g_dalvik_fill_instr_init(GDalvikFillInstr *);
+
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_dalvik_fill_instr_print(const GDalvikFillInstr *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax);
+
+
+
+/* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */
+G_DEFINE_TYPE(GDalvikFillInstr, g_dalvik_fill_instr, G_TYPE_DALVIK_INSTRUCTION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe générique des instructions.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance d'instruction d'architecture.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dalvik_fill_instr_init(GDalvikFillInstr *instr)
+{
+    GArchInstruction *parent;               /* Instance parente            */
+
+    parent = G_ARCH_INSTRUCTION(instr);
+
+    parent->print = (print_instruction_fc)g_dalvik_fill_instr_print;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : data = flux de données à analyser.                           *
+*                pos  = position courante dans ce flux. [OUT]                 *
+*                len  = taille totale des données à analyser.                 *
+*                addr = adresse virtuelle de l'instruction.                   *
+*                proc = architecture ciblée par le désassemblage.             *
+*                                                                             *
+*  Description : Crée une pesudo-instruction Dalvik de remplissage.           *
+*                                                                             *
+*  Retour      : Instruction mise en place.                                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *g_dalvik_fill_instr_new(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc)
+{
+    GDalvikFillInstr *result;               /* Structure à retourner       */
+    uint16_t ident;                         /* Valeur lue dans le code     */
+
+    result = g_object_new(G_TYPE_DALVIK_FILL_INSTR, NULL);
+
+    if (!read_u16(&ident, data, pos, len, SRE_LITTLE))
+        goto gdfin_bad;
+
+    G_DALVIK_INSTRUCTION(result)->ptype = DPO_FILL_ARRAY_DATA;
+
+    if (!read_u16(&result->array_width, data, pos, len, SRE_LITTLE))
+        goto gdfin_bad;
+    if (!read_u32(&result->array_size, data, pos, len, SRE_LITTLE))
+        goto gdfin_bad;
+
+    *pos += result->array_width * result->array_size;
+
+    return G_ARCH_INSTRUCTION(result);
+
+ gdfin_bad:
+
+    g_object_unref(result);
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = instruction d'assemblage à représenter.             *
+*                buffer = espace où placer ledit contenu.                     *
+*                syntax = type de représentation demandée.                    *
+*                                                                             *
+*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dalvik_fill_instr_print(const GDalvikFillInstr *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax)
+{
+    GArchInstruction *base;                 /* Version basique de l'objet  */
+    GBufferLine *line;                      /* Ligne de destination        */
+    char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */
+    size_t len;                             /* Taille de l'élément inséré  */
+    char *bin_code;                         /* Tampon du code binaire      */
+    off_t i;                                /* Boucle de parcours          */
+    const char *key;                        /* Mot clef principal          */
+    size_t klen;                            /* Taille de ce mot clef       */
+
+    base = G_ARCH_INSTRUCTION(instr);
+
+    line = g_code_buffer_append_new_line(buffer);
+
+    /* Adresse virtuelle ou physique */
+
+    len = vmpa_to_string(base->address, msize, address);
+
+    g_buffer_line_insert_text(line, BLC_ADDRESS, address, len, RTT_RAW);
+
+    /* Code brut */
+
+    bin_code = (char *)calloc(3 * 3 + 3, sizeof(char));
+
+    for (i = 0; i < 3; i++)
+    {
+        if ((i + 1) < 3)
+            snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[base->offset + i]);
+        else
+            snprintf(&bin_code[i * (2 + 1)], 6, "%02hhx...", content[base->offset + i]);
+    }
+
+    g_buffer_line_insert_text(line, BLC_BINARY,
+                              bin_code, 3 * 3 + 2, RTT_RAW_CODE);
+
+    free(bin_code);
+
+    /* Instruction proprement dite */
+
+    key = "<fill-array>";
+    klen = strlen(key);
+
+    g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION);
+
+}
diff --git a/src/arch/dalvik/pseudo/fill.h b/src/arch/dalvik/pseudo/fill.h
new file mode 100644
index 0000000..058e67b
--- /dev/null
+++ b/src/arch/dalvik/pseudo/fill.h
@@ -0,0 +1,57 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * fill.h - prototypes pour la prise en charge de l'instruction spéciale fill-array-data
+ *
+ * Copyright (C) 2011 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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_DALVIK_PSEUDO_FILL_H
+#define _ARCH_DALVIK_PSEUDO_FILL_H
+
+
+#include "../instruction.h"
+#include "../processor.h"
+
+
+#include <glib-object.h>
+
+
+
+#define G_TYPE_DALVIK_FILL_INSTR                 g_dalvik_fill_instr_get_type()
+#define G_DALVIK_FILL_INSTR(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_fill_instr_get_type(), GDalvikFillInstr))
+#define G_IS_DALVIK_FILL_INSTR(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_fill_instr_get_type()))
+#define G_DALVIK_FILL_INSTR_GET_IFACE(inst)      (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_fill_instr_get_type(), GDalvikFillInstrIface))
+
+
+/* Définition générique d'une instruction d'architecture (instance) */
+typedef struct _GDalvikFillInstr GDalvikFillInstr;
+
+/* Définition générique d'une instruction d'architecture (classe) */
+typedef struct _GDalvikFillInstrClass GDalvikFillInstrClass;
+
+
+/* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */
+GType g_dalvik_fill_instr_get_type(void);
+
+/* Crée une pesudo-instruction Dalvik de remplissage. */
+GArchInstruction *g_dalvik_fill_instr_new(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *);
+
+
+
+#endif  /* _ARCH_DALVIK_PSEUDO_FILL_H */
diff --git a/src/arch/dalvik/pseudo/switch.c b/src/arch/dalvik/pseudo/switch.c
new file mode 100644
index 0000000..30511ac
--- /dev/null
+++ b/src/arch/dalvik/pseudo/switch.c
@@ -0,0 +1,217 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * switch.c - prise en charge des instructions spéciales (packed|sparse)switch
+ *
+ * Copyright (C) 2011 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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 "switch.h"
+
+
+#include <string.h> 
+
+
+#include "../instruction-int.h"
+
+
+
+/* Définition générique d'une instruction d'architecture Dalvik (instance) */
+struct _GDalvikSwitchInstr
+{
+    GDalvikInstruction parent;              /* A laisser en premier        */
+
+    uint16_t switch_size;                   /* Taille du switch considéré  */
+
+};
+
+/* Définition générique d'une instruction d'architecture Dalvik (classe) */
+struct _GDalvikSwitchInstrClass
+{
+    GDalvikInstructionClass parent;         /* A laisser en premier        */
+
+};
+
+
+
+/* Initialise la classe générique des instructions. */
+static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *);
+
+/* Initialise une instance d'opérande d'architecture. */
+static void g_dalvik_switch_instr_init(GDalvikSwitchInstr *);
+
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_dalvik_switch_instr_print(const GDalvikSwitchInstr *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax);
+
+
+
+/* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */
+G_DEFINE_TYPE(GDalvikSwitchInstr, g_dalvik_switch_instr, G_TYPE_DALVIK_INSTRUCTION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe générique des instructions.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance d'instruction d'architecture.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dalvik_switch_instr_init(GDalvikSwitchInstr *instr)
+{
+    GArchInstruction *parent;               /* Instance parente            */
+
+    parent = G_ARCH_INSTRUCTION(instr);
+
+    parent->print = (print_instruction_fc)g_dalvik_switch_instr_print;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : data = flux de données à analyser.                           *
+*                pos  = position courante dans ce flux. [OUT]                 *
+*                len  = taille totale des données à analyser.                 *
+*                addr = adresse virtuelle de l'instruction.                   *
+*                proc = architecture ciblée par le désassemblage.             *
+*                                                                             *
+*  Description : Crée une pesudo-instruction Dalvik de branchement.           *
+*                                                                             *
+*  Retour      : Instruction mise en place.                                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *g_dalvik_switch_instr_new(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc)
+{
+    GDalvikSwitchInstr *result;               /* Structure à retourner       */
+    uint16_t ident;                         /* Valeur lue dans le code     */
+
+    result = g_object_new(G_TYPE_DALVIK_SWITCH_INSTR, NULL);
+
+    if (!read_u16(&ident, data, pos, len, SRE_LITTLE))
+        goto gdsin_bad;
+
+    if (ident != DPO_PACKED_SWITCH && ident != DPO_SPARSE_SWITCH)
+        goto gdsin_bad;
+
+    G_DALVIK_INSTRUCTION(result)->ptype = ident;
+
+    if (!read_u16(&result->switch_size, data, pos, len, SRE_LITTLE))
+        goto gdsin_bad;
+
+    if (ident != DPO_PACKED_SWITCH)
+        *pos += (1 + result->switch_size) * sizeof(uint32_t);
+    else
+        *pos += (2 * result->switch_size) * sizeof(uint32_t);
+
+    return G_ARCH_INSTRUCTION(result);
+
+ gdsin_bad:
+
+    g_object_unref(result);
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr  = instruction d'assemblage à représenter.             *
+*                buffer = espace où placer ledit contenu.                     *
+*                syntax = type de représentation demandée.                    *
+*                                                                             *
+*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dalvik_switch_instr_print(const GDalvikSwitchInstr *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax)
+{
+    GArchInstruction *base;                 /* Version basique de l'objet  */
+    GBufferLine *line;                      /* Ligne de destination        */
+    char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */
+    size_t len;                             /* Taille de l'élément inséré  */
+    char *bin_code;                         /* Tampon du code binaire      */
+    off_t i;                                /* Boucle de parcours          */
+    const char *key;                        /* Mot clef principal          */
+    size_t klen;                            /* Taille de ce mot clef       */
+
+    base = G_ARCH_INSTRUCTION(instr);
+
+    line = g_code_buffer_append_new_line(buffer);
+
+    /* Adresse virtuelle ou physique */
+
+    len = vmpa_to_string(base->address, msize, address);
+
+    g_buffer_line_insert_text(line, BLC_ADDRESS, address, len, RTT_RAW);
+
+    /* Code brut */
+
+    bin_code = (char *)calloc(3 * 3 + 3, sizeof(char));
+
+    for (i = 0; i < 3; i++)
+    {
+        if ((i + 1) < 3)
+            snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[base->offset + i]);
+        else
+            snprintf(&bin_code[i * (2 + 1)], 6, "%02hhx...", content[base->offset + i]);
+    }
+
+    g_buffer_line_insert_text(line, BLC_BINARY,
+                              bin_code, 3 * 3 + 2, RTT_RAW_CODE);
+
+    free(bin_code);
+
+    /* Instruction proprement dite */
+
+    key = "<fill-array>";
+    klen = strlen(key);
+
+    g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION);
+
+}
diff --git a/src/arch/dalvik/pseudo/switch.h b/src/arch/dalvik/pseudo/switch.h
new file mode 100644
index 0000000..602af48
--- /dev/null
+++ b/src/arch/dalvik/pseudo/switch.h
@@ -0,0 +1,57 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * switch.h - prototypes pour la prise en charge des instructions spéciales (packed|sparse)switch
+ *
+ * Copyright (C) 2011 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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_DALVIK_PSEUDO_SWITCH_H
+#define _ARCH_DALVIK_PSEUDO_SWITCH_H
+
+
+#include "../instruction.h"
+#include "../processor.h"
+
+
+#include <glib-object.h>
+
+
+
+#define G_TYPE_DALVIK_SWITCH_INSTR                 g_dalvik_switch_instr_get_type()
+#define G_DALVIK_SWITCH_INSTR(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_switch_instr_get_type(), GDalvikSwitchInstr))
+#define G_IS_DALVIK_SWITCH_INSTR(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_switch_instr_get_type()))
+#define G_DALVIK_SWITCH_INSTR_GET_IFACE(inst)      (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_switch_instr_get_type(), GDalvikSwitchInstrIface))
+
+
+/* Définition générique d'une instruction d'architecture (instance) */
+typedef struct _GDalvikSwitchInstr GDalvikSwitchInstr;
+
+/* Définition générique d'une instruction d'architecture (classe) */
+typedef struct _GDalvikSwitchInstrClass GDalvikSwitchInstrClass;
+
+
+/* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */
+GType g_dalvik_switch_instr_get_type(void);
+
+/* Crée une pesudo-instruction Dalvik de branchement. */
+GArchInstruction *g_dalvik_switch_instr_new(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *);
+
+
+
+#endif  /* _ARCH_DALVIK_PSEUDO_SWITCH_H */
diff --git a/src/arch/dalvik/specins.c b/src/arch/dalvik/specins.c
deleted file mode 100644
index b6a7c4e..0000000
--- a/src/arch/dalvik/specins.c
+++ /dev/null
@@ -1,115 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * specins.c - gestion des instructions spéciales de la VM Dalvik
- *
- * Copyright (C) 2011 Cyrille Bagard
- *
- *  This file is part of OpenIDA.
- *
- *  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 "specins.h"
-
-
-#include "../../common/endianness.h"
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : ctx  = contexte lié à l'exécution du processeur.             *
-*                data = flux de données à analyser.                           *
-*                pos  = position courante dans ce flux.                       *
-*                len  = taille totale des données à analyser.                 *
-*                addr = adresse virtuelle de l'instruction.                   *
-*                                                                             *
-*  Description : Détermine si du code doit être écarté du traitement.         *
-*                                                                             *
-*  Retour      : true si une nouvelle zone de données est à écarter.          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_dalvik_guess_special_instruction(GDalvikContext *ctx, const bin_t *data, off_t pos, off_t len, vmpa_t addr)
-{
-    bool result;                            /* Bilan à retourner           */
-    uint16_t ident;                         /* Valeur lue dans le code     */
-    vmpa_t start;                           /* Début d'une zone de données */
-    vmpa_t end;                             /* Fin d'une zone de données   */
-    uint16_t switch_size;                   /* Taille du switch considéré  */
-    uint16_t array_width;                   /* Taille des éléments         */
-    uint32_t array_size;                    /* Taille du tableau           */
-
-    /* Vérification astucieuse et rapide...*/
-    if (data[pos] != 0x00 /* DOP_NOP */) return false; 
-
-    if (!read_u16(&ident, data, &pos, len, SRE_LITTLE))
-        return false;
-
-    start = addr + sizeof(ident);
-    end = start;
-
-    switch (ident)
-    {
-        case DID_PACKED_SWITCH:
-
-            if (!read_u16(&switch_size, data, &pos, len, SRE_LITTLE))
-                return false;
-
-            end += sizeof(switch_size) + (1 + switch_size) * sizeof(uint32_t);
-
-            g_dalvik_context_skip_new_area(ctx, start, end);
-            result = true;
-
-            break;
-
-        case DID_SPARSE_SWITCH:
-
-            if (!read_u16(&switch_size, data, &pos, len, SRE_LITTLE))
-                return false;
-
-            end += sizeof(switch_size) + (2 * switch_size) * sizeof(uint32_t);
-
-            g_dalvik_context_skip_new_area(ctx, start, end);
-            result = true;
-
-            break;
-
-        case DID_FILL_ARRAY_DATA:
-
-            if (!read_u16(&array_width, data, &pos, len, SRE_LITTLE))
-                return false;
-            if (!read_u32(&array_size, data, &pos, len, SRE_LITTLE))
-                return false;
-
-            end += sizeof(array_width) + sizeof(array_size)
-                + array_width * array_size;
-
-            g_dalvik_context_skip_new_area(ctx, start, end);
-            result = true;
-
-            break;
-
-        default:
-            result = false;
-            break;
-
-    }
-
-    return result;
-
-}
diff --git a/src/arch/dalvik/specins.h b/src/arch/dalvik/specins.h
deleted file mode 100644
index 51cf6e9..0000000
--- a/src/arch/dalvik/specins.h
+++ /dev/null
@@ -1,51 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * specins.h - prototypes pour la gestion des instructions spéciales de la VM Dalvik
- *
- * Copyright (C) 2011 Cyrille Bagard
- *
- *  This file is part of OpenIDA.
- *
- *  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_DALVIK_SPECINS_H
-#define _ARCH_DALVIK_SPECINS_H
-
-
-#include <stdbool.h>
-
-
-#include "../archbase.h"
-#include "context.h"
-
-
-
-/* Speinss spéciales */
-typedef enum _DalvikIdents
-{
-    DID_PACKED_SWITCH   = 0x0100,           /* Switch aux clefs compactes  */
-    DID_SPARSE_SWITCH   = 0x0200,           /* Switch aux clefs éclatées   */
-    DID_FILL_ARRAY_DATA = 0x0300            /* Contenu de tableau          */
-
-} DalvikIdents;
-
-
-/*  Détermine si du code doit être écarté du traitement. */
-bool g_dalvik_guess_special_instruction(GDalvikContext *, const bin_t *, off_t, off_t, vmpa_t);
-
-
-
-#endif  /* _ARCH_DALVIK_SPECINS_H */
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 4eca0a5..4ffb5b0 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -33,6 +33,9 @@
 
 
 
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+typedef void (* print_instruction_fc) (const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax);
+
 /* Traduit une instruction en version humainement lisible. */
 typedef const char * (* get_instruction_text_fc) (const GArchInstruction *, const GExeFormat *, AsmSyntax);
 
@@ -64,6 +67,7 @@ struct _GArchInstruction
     InstructionLinkType *links_type;        /* Type des liens de dest.     */
     size_t to_count;                        /* Nombre de ces destinations  */
 
+    print_instruction_fc print;             /* Imprime l'ensemble          */
     get_instruction_text_fc get_text;       /* Texte humain équivalent     */
     get_instruction_link_fc get_link;       /* Référence à une instruction */
     is_instruction_return_fc is_return;     /* Retour de fonction ou pas ? */
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 677a1a3..047ed86 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -46,6 +46,14 @@ static void g_arch_instruction_to_buffer(const GArchInstruction *, GBufferLine *
 
 
 
+/* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */
+
+
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void _g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax);
+
+
+
 /* Indique le type défini pour une instruction d'architecture. */
 G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_CONTENT_EXPORTER);
 
@@ -590,7 +598,7 @@ size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, GArchI
 *                                                                             *
 ******************************************************************************/
 
-void g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax)
+static void _g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax)
 {
     GBufferLine *line;                      /* Ligne de destination        */
     char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */
@@ -653,6 +661,31 @@ void g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : instr  = instruction d'assemblage à représenter.             *
+*                buffer = espace où placer ledit contenu.                     *
+*                syntax = type de représentation demandée.                    *
+*                                                                             *
+*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax)
+{
+    if (instr->print != NULL)
+        instr->print(instr, buffer, msize, content, syntax);
+
+    else
+        _g_arch_instruction_print(instr, buffer, msize, content, syntax);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : instr = instruction d'origine à convertir.                   *
 *                ctx   = contexte de la phase de décompilation.               *
 *                                                                             *
-- 
cgit v0.11.2-87-g4458