From 19e1a97fafb1b73d0efcd995b31951daf1a5c661 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 25 Dec 2014 16:31:33 +0000
Subject: Cleaned all the code for immediate operands.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@444 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                     |  48 +++++++
 src/analysis/disass/fetch.c   | 114 ++++++++++++++-
 src/arch/arm/v7/Makefile.am   |   1 +
 src/arch/arm/v7/link.c        | 113 +++++++++++++++
 src/arch/arm/v7/link.h        |  41 ++++++
 src/arch/arm/v7/post.c        | 175 ++++-------------------
 src/arch/arm/v7/post.h        |   5 +-
 src/arch/arm/v7/processor.c   |   7 +-
 src/arch/context-int.h        |   5 +-
 src/arch/context.c            | 108 ++++++++++++++-
 src/arch/context.h            |  18 ++-
 src/arch/dalvik/operand.c     |  16 ++-
 src/arch/immediate.c          | 312 +++++++++++++++++-------------------------
 src/arch/immediate.h          |  35 +++--
 src/arch/instruction-int.h    |   2 +-
 src/arch/instruction.c        |  32 +++--
 src/arch/instruction.h        |  19 ++-
 src/arch/raw.c                |   2 +-
 src/arch/x86/operand.c        |   9 +-
 src/arch/x86/operands/modrm.c |  13 +-
 src/arch/x86/operands/moffs.c |   3 +-
 src/format/elf/symbols.c      |   7 +-
 src/format/format-int.h       |   2 +
 src/format/format.c           |  19 +++
 src/format/format.h           |   3 +
 25 files changed, 710 insertions(+), 399 deletions(-)
 create mode 100644 src/arch/arm/v7/link.c
 create mode 100644 src/arch/arm/v7/link.h

diff --git a/ChangeLog b/ChangeLog
index a75ae31..9f1a780 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+14-12-25  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/fetch.c:
+	Prepare a new way to disassemble code.
+
+	* src/arch/arm/v7/link.c:
+	* src/arch/arm/v7/link.h:
+	New entries: define links between some kinds of instructions.
+
+	* src/arch/arm/v7/Makefile.am:
+	Add the 'link.[ch]' files to libarcharmv7_la_SOURCES.
+
+	* src/arch/arm/v7/post.c:
+	* src/arch/arm/v7/post.h:
+	Clean and update code for symbols resolutions.
+
+	* src/arch/arm/v7/processor.c:
+	Register new hooks for instructions processing.
+
+	* src/arch/context.c:
+	* src/arch/context.h:
+	* src/arch/context-int.h:
+	Prepare a new way to disassemble code.
+
+	* src/arch/dalvik/operand.c:
+	Update code.
+
+	* src/arch/immediate.c:
+	* src/arch/immediate.h:
+	Clean all the code for immediate operands.
+
+	* src/arch/instruction.c:
+	* src/arch/instruction.h:
+	* src/arch/instruction-int.h:
+	Refine hooks registered for processing instructions.
+
+	* src/arch/raw.c:
+	* src/arch/x86/operand.c:
+	* src/arch/x86/operands/modrm.c:
+	* src/arch/x86/operands/moffs.c:
+	Update code.
+
+	* src/format/elf/symbols.c:
+	* src/format/format.c:
+	* src/format/format.h:
+	* src/format/format-int.h:
+	Provide the address of the found entry point.
+
 14-12-24  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/arm/v7/opcodes/Makefile.am:
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index dea6645..1fd5550 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -434,8 +434,10 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp
 
 
 
+        g_arch_instruction_call_hook(instr, IPH_LINK, NULL, format);
 
-        g_arch_instruction_call_post_prod_function(instr, format); /* FIXME */
+
+        g_arch_instruction_call_hook(instr, IPH_POST, NULL, format);
 
 
 
@@ -447,6 +449,116 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp
 }
 
 
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary    = représentation de binaire chargé.                *
+*                statusbar = barre de statut avec progression à mettre à jour.*
+*                id        = identifiant du message affiché à l'utilisateur.  *
+*                                                                             *
+*  Description : Procède au désassemblage basique d'un contenu binaire.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GArchInstruction *follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area *areas, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
+{
+    GBinFormat *format;                     /* Format du fichier binaire   */
+
+    virt_t addr;
+
+
+
+    mem_area *area;                         /* Zone de désassemblage       */
+
+
+    format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+
+    /* Insertion du point de départ */
+
+    addr = g_binary_format_get_entry_point(format);
+
+    g_proc_context_push_drop_point(ctx, addr);
+
+    /* Suivi de l'exécution autant que possible */
+
+    while (g_proc_context_has_drop_points(ctx))
+    {
+        //virt = g_proc_context_pop_drop_point(ctx);
+
+
+        area = NULL;
+
+
+
+
+    }
+
+
+
+
+    // ctx.add(entry_point)
+
+    // while (ctx.has_pending_addresses)
+
+    //      virt = ctx.pop
+    //      find mem_area for virt
+
+    //      if area.limit < virt then continue
+
+
+
+
+
+}
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary    = représentation de binaire chargé.                *
+*                statusbar = barre de statut avec progression à mettre à jour.*
+*                id        = identifiant du message affiché à l'utilisateur.  *
+*                                                                             *
+*  Description : Procède au désassemblage basique d'un contenu binaire.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *disassemble_binary_content_new(const GLoadedBinary *binary, GtkExtStatusBar *statusbar, bstatus_id_t id)
+{
+
+    GBinFormat *format;                     /* Format du fichier binaire   */
+    GArchProcessor *proc;                   /* Architecture du binaire     */
+
+    GProcContext *ctx;                      /* Contexte de désassemblage   */
+
+
+
+    format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+    proc = get_arch_processor_from_format(G_EXE_FORMAT(format));
+
+
+    ctx = g_arch_processor_get_context(proc);
+
+
+
+}
+
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : binary    = représentation de binaire chargé.                *
diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am
index 704b3a6..28a899e 100644
--- a/src/arch/arm/v7/Makefile.am
+++ b/src/arch/arm/v7/Makefile.am
@@ -5,6 +5,7 @@ libarcharmv7_la_SOURCES =				\
 	arm.h arm.c							\
 	helpers.h helpers.c					\
 	instruction.h instruction.c			\
+	link.h link.c						\
 	post.h post.c						\
 	processor.h processor.c				\
 	pseudo.h pseudo.c					\
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c
new file mode 100644
index 0000000..278b8d0
--- /dev/null
+++ b/src/arch/arm/v7/link.c
@@ -0,0 +1,113 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * post.c - traitements complémentaires à la phase de désassemblage
+ *
+ * Copyright (C) 2014 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 "link.h"
+
+
+#include <assert.h>
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                                                                             *
+*  Description : Complète un désassemblage accompli pour une instruction.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+{
+    const mrange_t *range;                  /* Emplacementt d'instruction  */
+    virt_t pc;                              /* Position dans l'exécution   */
+    GArchOperand *op;                       /* Opérande numérique en place */
+    int32_t offset;                         /* Décallage encodé en dur     */
+
+    range = g_arch_instruction_get_range(instr);
+
+    pc = get_virt_addr(get_mrange_addr(range));
+
+    /**
+     * Qu'on se trouve en mode Thumb ou ARM, l'instruction
+     * ne peut qu'être encodée sur 4 octets.
+     */
+
+    assert(get_mrange_length(range) == 4);
+
+    pc += 4;
+
+    op = g_arch_instruction_get_operand(instr, 0);
+
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
+        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                                                                             *
+*  Description : Complète un désassemblage accompli pour une instruction.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void handle_links_with_thumb_instruction_blx(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+{
+    const mrange_t *range;                  /* Emplacementt d'instruction  */
+    virt_t pc;                              /* Position dans l'exécution   */
+    GArchOperand *op;                       /* Opérande numérique en place */
+    int32_t offset;                         /* Décallage encodé en dur     */
+
+    range = g_arch_instruction_get_range(instr);
+
+    pc = get_virt_addr(get_mrange_addr(range));
+
+    /**
+     * Qu'on se trouve en mode Thumb ou ARM, l'instruction
+     * ne peut qu'être encodée sur 4 octets.
+     */
+
+    assert(get_mrange_length(range) == 4);
+
+    pc += 4;
+    pc -= pc % 4;
+
+    op = g_arch_instruction_get_operand(instr, 0);
+
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
+        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+}
diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h
new file mode 100644
index 0000000..79da9f3
--- /dev/null
+++ b/src/arch/arm/v7/link.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * link.h - prototypes pour l'édition des liens durant la phase de désassemblage
+ *
+ * Copyright (C) 2014 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_LINK_H
+#define _ARCH_ARM_V7_LINK_H
+
+
+#include "../../instruction.h"
+#include "../../../format/format.h"
+
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void handle_links_with_thumb_instruction_bl(GArchInstruction *, GProcContext *, GBinFormat *);
+
+/* Complète un désassemblage accompli pour une instruction. */
+void handle_links_with_thumb_instruction_blx(GArchInstruction *, GProcContext *, GBinFormat *);
+
+
+
+#endif  /* _ARCH_ARM_V7_LINK_H */
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index 8ba12d8..f85fc91 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -24,19 +24,15 @@
 #include "post.h"
 
 
-
-
-
 #include "../../target.h"
 
 
 
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : instr  = instruction ARMv7 à traiter.                        *
-*                format = acès aux données du binaire d'origine.              *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = accès aux données du binaire d'origine.            *
 *                                                                             *
 *  Description : Complète un désassemblage accompli pour une instruction.     *
 *                                                                             *
@@ -46,22 +42,11 @@
 *                                                                             *
 ******************************************************************************/
 
-void post_process_thumb_instruction_bl(GArchInstruction *instr, GBinFormat *format)
+void post_process_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
 {
-
-
-    const mrange_t *range;
-
-    virt_t pc;
-
-
-
-
-
-    GArchOperand *op;
-    vmpa_t val;
-    GArchOperand *new;
-
+    GArchOperand *op;                       /* Opérande numérique en place */
+    uint32_t addr;                          /* Adresse visée par le saut   */
+    GArchOperand *new;                      /* Instruction de ciblage      */
     vmpa2t target;
     mrange_t trange;
     VMPA_BUFFER(loc);
@@ -69,148 +54,38 @@ void post_process_thumb_instruction_bl(GArchInstruction *instr, GBinFormat *form
     GBinRoutine *routine;                   /* Nouvelle routine trouvée    */
     GBinSymbol *symbol;                     /* Nouveau symbole construit   */
 
-
-
-
-    range = g_arch_instruction_get_range(instr);
-
-    pc = get_virt_addr(get_mrange_addr(range)) + 4 /* PC++ */;
-    printf("  -- PC = 0x%x\n", (unsigned int)pc);
-
-
     op = g_arch_instruction_get_operand(instr, 0);
 
-    g_imm_operand_to_vmpa_t(G_IMM_OPERAND(op), &val);
-
-    printf("  -> %llx = %lld  ==>> 0x%x\n", val, val, (unsigned int)(pc + val));
-
-
-
-    new = g_target_operand_new(MDS_32_BITS, pc + val);
-
-    if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
     {
-        init_vmpa(&target, VMPA_NO_PHYSICAL, pc + val);
-        init_mrange(&trange, &target, 0);
-
-        vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
-        snprintf(name, sizeof(name), "loc_%s", loc + 2);
-
-        routine = g_binary_routine_new();
-        g_binary_routine_set_name(routine, strdup(name));
-        //routine = try_to_demangle_routine(name);
-
-        g_binary_routine_set_range(routine, &trange);
-
-        symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
-        g_binary_symbol_attach_routine(symbol, routine);
-        g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+        new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
 
+        if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
+        {
+            init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
+            init_mrange(&trange, &target, 0);
 
+            vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
+            snprintf(name, sizeof(name), "loc_%s", loc + 2);
 
-        g_target_operand_resolve(G_TARGET_OPERAND(new), format);
+            routine = g_binary_routine_new();
+            g_binary_routine_set_name(routine, strdup(name));
+            //routine = try_to_demangle_routine(name);
 
+            g_binary_routine_set_range(routine, &trange);
 
-    }
-
-
-    g_arch_instruction_replace_operand(instr, new, op);
-    //g_arch_instruction_attach_extra_operand(result, new);
+            symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
+            g_binary_symbol_attach_routine(symbol, routine);
+            g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
 
 
 
-}
-
-
+            g_target_operand_resolve(G_TARGET_OPERAND(new), format);
 
+        }
 
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr  = instruction ARMv7 à traiter.                        *
-*                format = acès aux données du binaire d'origine.              *
-*                                                                             *
-*  Description : Complète un désassemblage accompli pour une instruction.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void post_process_thumb_instruction_blx(GArchInstruction *instr, GBinFormat *format)
-{
-
-
-
-
-
-    const mrange_t *range;
-
-    virt_t pc;
-
-
-
-    GArchOperand *op;
-    vmpa_t val;
-    GArchOperand *new;
-
-    vmpa2t target;
-    mrange_t trange;
-    VMPA_BUFFER(loc);
-    char name[5 + VMPA_MAX_LEN];
-    GBinRoutine *routine;                   /* Nouvelle routine trouvée    */
-    GBinSymbol *symbol;                     /* Nouveau symbole construit   */
-
-
-
-    range = g_arch_instruction_get_range(instr);
-
-    pc = get_virt_addr(get_mrange_addr(range)) + 4 /* PC++ */;
-
-    printf("  -- PC = 0x%x -> 0x%x\n", (unsigned int)pc, (unsigned int)pc - pc % 4);
-    pc = pc - pc % 4;
-
-    op = g_arch_instruction_get_operand(instr, 0);
-
-    g_imm_operand_to_vmpa_t(G_IMM_OPERAND(op), &val);
-
-    printf("  -> %llx = %lld  ==>> 0x%x\n", val, val, (unsigned int)(pc + val));
-
-
-
-    new = g_target_operand_new(MDS_32_BITS, pc + val);
-
-    if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
-    {
-        init_vmpa(&target, VMPA_NO_PHYSICAL, pc + val);
-        init_mrange(&trange, &target, 0);
-
-        vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
-        snprintf(name, sizeof(name), "loc_%s", loc + 2);
-
-        routine = g_binary_routine_new();
-        g_binary_routine_set_name(routine, strdup(name));
-        //routine = try_to_demangle_routine(name);
-
-        g_binary_routine_set_range(routine, &trange);
-
-        symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
-        g_binary_symbol_attach_routine(symbol, routine);
-        g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
-
-
-
-        g_target_operand_resolve(G_TARGET_OPERAND(new), format);
-
+        g_arch_instruction_replace_operand(instr, new, op);
 
     }
 
-    g_arch_instruction_replace_operand(instr, new, op);
-    //g_arch_instruction_attach_extra_operand(result, new);
-
-
-
-
 }
-
diff --git a/src/arch/arm/v7/post.h b/src/arch/arm/v7/post.h
index d9ad99e..dec51b2 100644
--- a/src/arch/arm/v7/post.h
+++ b/src/arch/arm/v7/post.h
@@ -31,10 +31,7 @@
 
 
 /* Complète un désassemblage accompli pour une instruction. */
-void post_process_thumb_instruction_bl(GArchInstruction *, GBinFormat *);
-
-/* Complète un désassemblage accompli pour une instruction. */
-void post_process_thumb_instruction_blx(GArchInstruction *, GBinFormat *);
+void post_process_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
 
 
 
diff --git a/src/arch/arm/v7/processor.c b/src/arch/arm/v7/processor.c
index 2b8617b..4ae933b 100644
--- a/src/arch/arm/v7/processor.c
+++ b/src/arch/arm/v7/processor.c
@@ -200,6 +200,7 @@ GArmV7Processor *g_armv7_processor_new(void)
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
+#include "link.h"
 #include "post.h"
 static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *proc, GArmContext *ctx, const bin_t *data, vmpa2t *pos, phys_t end)
 {
@@ -269,7 +270,8 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
     {
 
 
-        g_arch_instruction_set_post_prod_function(result, post_process_thumb_instruction_bl);
+        g_arch_instruction_set_hook(result, IPH_LINK, handle_links_with_thumb_instruction_bl);
+        g_arch_instruction_set_hook(result, IPH_POST, post_process_branch_instructions);
 
 
 
@@ -278,7 +280,8 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
     if (strcmp(g_arch_instruction_get_keyword(result, 0), "blx") == 0/* && pc == 0x000085b2*/)
     {
 
-        g_arch_instruction_set_post_prod_function(result, post_process_thumb_instruction_blx);
+        g_arch_instruction_set_hook(result, IPH_LINK, handle_links_with_thumb_instruction_blx);
+        g_arch_instruction_set_hook(result, IPH_POST, post_process_branch_instructions);
 
 
     }
diff --git a/src/arch/context-int.h b/src/arch/context-int.h
index 39d0278..3a65f79 100644
--- a/src/arch/context-int.h
+++ b/src/arch/context-int.h
@@ -2,7 +2,7 @@
 /* Chrysalide - Outil d'analyse de fichiers binaires
  * context-int.h - prototypes internes pour le contexte lié à l'exécution d'un processeur
  *
- * Copyright (C) 2011 Cyrille Bagard
+ * Copyright (C) 2011-2014 Cyrille Bagard
  *
  *  This file is part of Chrysalide.
  *
@@ -34,6 +34,9 @@ struct _GProcContext
 {
     GObject parent;                         /* A laisser en premier        */
 
+    virt_t *drop_points;                    /* Liste de points de départ   */
+    size_t dp_count;                        /* Taille de cette liste       */
+
 };
 
 
diff --git a/src/arch/context.c b/src/arch/context.c
index 220ed14..46c4dd1 100644
--- a/src/arch/context.c
+++ b/src/arch/context.c
@@ -2,7 +2,7 @@
 /* Chrysalide - Outil d'analyse de fichiers binaires
  * context.c - contexte lié à l'exécution d'un processeur
  *
- * Copyright (C) 2011 Cyrille Bagard
+ * Copyright (C) 2011-2014 Cyrille Bagard
  *
  *  This file is part of Chrysalide.
  *
@@ -24,6 +24,11 @@
 #include "context.h"
 
 
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
 #include "context-int.h"
 
 
@@ -73,5 +78,106 @@ static void g_proc_context_class_init(GProcContextClass *klass)
 
 static void g_proc_context_init(GProcContext *ctx)
 {
+    ctx->drop_points = NULL;
+    ctx->dp_count = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx  = contexte de désassemblage à compléter.                *
+*                addr = adresse d'un nouveau point de départ à traiter.       *
+*                                                                             *
+*  Description : Ajoute une adresse virtuelle comme point de départ de code.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_proc_context_push_drop_point(GProcContext *ctx, virt_t addr)
+{
+    ctx->drop_points = (virt_t *)realloc(ctx->drop_points, ++ctx->dp_count * sizeof(virt_t));
+
+    ctx->drop_points[ctx->dp_count - 1] = addr;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx = contexte de désassemblage à consulter.                 *
+*                                                                             *
+*  Description : Indique si des points de départ restent à traiter ou non.    *
+*                                                                             *
+*  Retour      : true s'il existe encore au moins un point, false sinon.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_proc_context_has_drop_points(const GProcContext *ctx)
+{
+    return ctx->dp_count > 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx  = contexte de désassemblage à consulter.                *
+*                addr = adresse de mémoire virtuelle à rechercher.            *
+*                                                                             *
+*  Description : Précise si une adresse donnée figure comme point de départ.  *
+*                                                                             *
+*  Retour      : true si l'adresse est connue en interne, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_proc_context_has_addr_as_drop_points(const GProcContext *ctx, virt_t addr)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = false;
+
+    for (i = 0; i < ctx->dp_count && !result; i++)
+        result = (ctx->drop_points[i] == addr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx  = contexte de désassemblage à compléter.                *
+*                                                                             *
+*  Description : Fournit une adresse virtuelle comme point de départ de code. *
+*                                                                             *
+*  Retour      : Adresse d'un point de départ de code à traiter.              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+virt_t g_proc_context_pop_drop_point(GProcContext *ctx)
+{
+    virt_t result;                          /* Adresse à retourner         */
+
+    assert(ctx->dp_count > 0);
+
+    result = ctx->drop_points[0];
+
+    if (ctx->dp_count > 1)
+        memmove(&ctx->drop_points[0], &ctx->drop_points[1], (ctx->dp_count - 1) * sizeof(virt_t));
+
+    ctx->drop_points = (virt_t *)realloc(ctx->drop_points, --ctx->dp_count * sizeof(virt_t));
+
+    return result;
 
 }
diff --git a/src/arch/context.h b/src/arch/context.h
index 0632970..9bb7cd3 100644
--- a/src/arch/context.h
+++ b/src/arch/context.h
@@ -2,7 +2,7 @@
 /* Chrysalide - Outil d'analyse de fichiers binaires
  * context.h - prototypes pour le contexte lié à l'exécution d'un processeur
  *
- * Copyright (C) 2011 Cyrille Bagard
+ * Copyright (C) 2011-2014 Cyrille Bagard
  *
  *  This file is part of Chrysalide.
  *
@@ -26,6 +26,10 @@
 
 
 #include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "vmpa.h"
 
 
 
@@ -47,6 +51,18 @@ typedef struct _GProcContextClass GProcContextClass;
 /* Indique le type définit par la GLib pour le contexte de processeur. */
 GType g_proc_context_get_type(void);
 
+/* Ajoute une adresse virtuelle comme point de départ de code. */
+void g_proc_context_push_drop_point(GProcContext *, virt_t);
+
+/* Indique si des points de départ restent à traiter ou non. */
+bool g_proc_context_has_drop_points(const GProcContext *);
+
+/* Précise si une adresse donnée figure comme point de départ. */
+bool g_proc_context_has_addr_as_drop_points(const GProcContext *, virt_t);
+
+/* Fournit une adresse virtuelle comme point de départ de code. */
+virt_t g_proc_context_pop_drop_point(GProcContext *);
+
 
 
 #endif  /* _ARCH_CONTEXT_H */
diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c
index ee033e7..a63369c 100644
--- a/src/arch/dalvik/operand.c
+++ b/src/arch/dalvik/operand.c
@@ -24,6 +24,7 @@
 #include "operand.h"
 
 
+#include <assert.h> // REMME (assert(0))
 #include <malloc.h>
 #include <stdarg.h>
 
@@ -298,23 +299,28 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const GDexFormat
                 break;
 
             case DOI_IMMEDIATE_4:
-                op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, end, low, endian);
+                assert(0);
+                //op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, end, low, endian);
                 break;
 
             case DOI_IMMEDIATE_8:
-                op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, end, endian);
+                assert(0);
+                //op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, end, endian);
                 break;
 
             case DOI_IMMEDIATE_16:
-                op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, end, endian);
+                assert(0);
+                //op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, end, endian);
                 break;
 
             case DOI_IMMEDIATE_32:
-                op = g_imm_operand_new_from_data(MDS_32_BITS, data, pos, end, endian);
+                assert(0);
+                //op = g_imm_operand_new_from_data(MDS_32_BITS, data, pos, end, endian);
                 break;
 
             case DOI_IMMEDIATE_64:
-                op = g_imm_operand_new_from_data(MDS_64_BITS, data, pos, end, endian);
+                assert(0);
+                //op = g_imm_operand_new_from_data(MDS_64_BITS, data, pos, end, endian);
                 break;
 
             case DOI_IMMEDIATE_H16:
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index f8ef432..4d0c0b8 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -43,6 +43,7 @@ struct _GImmOperand
     GArchOperand parent;                    /* Instance parente            */
 
     MemoryDataSize size;                    /* Taille de l'opérande        */
+    uint64_t raw;                           /* Valeur transtypée           */
 
     /**
      * Note : dans le cas d'une valeur signée,
@@ -197,7 +198,7 @@ static void g_imm_operand_finalize(GImmOperand *operand)
 *                                                                             *
 *  Paramètres  : size   = taille de l'opérande souhaitée.                     *
 *                data   = flux de données à analyser.                         *
-*                pos    = position courante dans ce flux. [OUT]               *
+*                addr   = position courante dans ce flux. [OUT]               *
 *                end    = limite des données à analyser.                      *
 *                low    = position éventuelle des 4 bits visés. [OUT]         *
 *                endian = ordre des bits dans la source.                      *
@@ -210,64 +211,87 @@ static void g_imm_operand_finalize(GImmOperand *operand)
 *                                                                             *
 ******************************************************************************/
 
-GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t end, bool *low, SourceEndian endian)
+GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian)
 {
     GImmOperand *result;                    /* Opérande à retourner        */
+    off_t old;                              /* Ancienne tête de lecture    */
+    off_t pos;                              /* Position physique           */
+    uint8_t uval8;                          /* Valeur sur 8 bits           */
+    uint16_t uval16;                        /* Valeur sur 16 bits          */
+    uint32_t uval32;                        /* Valeur sur 32 bits          */
+    uint64_t uval64;                        /* Valeur sur 64 bits          */
+    int8_t sval8;                           /* Valeur sur 8 bits           */
+    int16_t sval16;                         /* Valeur sur 16 bits          */
+    int32_t sval32;                         /* Valeur sur 32 bits          */
+    int64_t sval64;                         /* Valeur sur 64 bits          */
 
     result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
 
     result->size = size;
 
+    pos = get_phy_addr(addr);
+    old = pos;
+
     switch (size)
     {
         case MDS_4_BITS_UNSIGNED:
-            if (!read_u4(&result->unsigned_imm.val8, data, pos, end, low, endian))
+            if (!read_u4(&uval8, data, &pos, end, low, endian))
                 goto gionfd_error;
+            result->raw = uval8;
             break;
 
         case MDS_8_BITS_UNSIGNED:
-            if (!read_u8(&result->unsigned_imm.val8, data, pos, end, endian))
+            if (!read_u8(&uval8, data, &pos, end, endian))
                 goto gionfd_error;
+            result->raw = uval8;
             break;
 
         case MDS_16_BITS_UNSIGNED:
-            if (!read_u16(&result->unsigned_imm.val16, data, pos, end, endian))
+            if (!read_u16(&uval16, data, &pos, end, endian))
                 goto gionfd_error;
+            result->raw = uval16;
             break;
 
         case MDS_32_BITS_UNSIGNED:
-            if (!read_u32(&result->unsigned_imm.val32, data, pos, end, endian))
+            if (!read_u32(&uval32, data, &pos, end, endian))
                 goto gionfd_error;
+            result->raw = uval32;
             break;
 
         case MDS_64_BITS_UNSIGNED:
-            if (!read_u64(&result->unsigned_imm.val64, data, pos, end, endian))
+            if (!read_u64(&uval64, data, &pos, end, endian))
                 goto gionfd_error;
+            result->raw = uval64;
             break;
 
         case MDS_4_BITS_SIGNED:
-            if (!read_s4(&result->signed_imm.val8, data, pos, end, low, endian))
+            if (!read_s4(&sval8, data, &pos, end, low, endian))
                 goto gionfd_error;
+            result->raw = sval8;
             break;
 
         case MDS_8_BITS_SIGNED:
-            if (!read_s8(&result->signed_imm.val8, data, pos, end, endian))
+            if (!read_s8(&sval8, data, &pos, end, endian))
                 goto gionfd_error;
+            result->raw = sval8;
             break;
 
         case MDS_16_BITS_SIGNED:
-            if (!read_s16(&result->signed_imm.val16, data, pos, end, endian))
+            if (!read_s16(&sval16, data, &pos, end, endian))
                 goto gionfd_error;
+            result->raw = sval16;
             break;
 
         case MDS_32_BITS_SIGNED:
-            if (!read_s32(&result->signed_imm.val32, data, pos, end, endian))
+            if (!read_s32(&sval32, data, &pos, end, endian))
                 goto gionfd_error;
+            result->raw = sval32;
             break;
 
         case MDS_64_BITS_SIGNED:
-            if (!read_s64(&result->signed_imm.val64, data, pos, end, endian))
+            if (!read_s64(&sval64, data, &pos, end, endian))
                 goto gionfd_error;
+            result->raw = sval64;
             break;
 
         case MDS_UNDEFINED:
@@ -276,6 +300,8 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
 
     }
 
+    advance_vmpa(addr, pos - old);
+
     return G_ARCH_OPERAND(result);
 
  gionfd_error:
@@ -287,17 +313,10 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
 }
 
 
-
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : size   = taille de l'opérande souhaitée.                     *
-*                data   = flux de données à analyser.                         *
-*                addr   = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                low    = position éventuelle des 4 bits visés. [OUT]         *
-*                endian = ordre des bits dans la source.                      *
+*  Paramètres  : size  = taille de l'opérande souhaitée.                      *
+*                value = valeur sur x bits à venir récupérer.                 *
 *                                                                             *
 *  Description : Crée un opérande réprésentant une valeur numérique.          *
 *                                                                             *
@@ -307,121 +326,70 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
 *                                                                             *
 ******************************************************************************/
 
-GArchOperand *_g_imm_operand_new_from_data2(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian)
+GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
 {
     GImmOperand *result;                    /* Opérande à retourner        */
-    off_t old;                              /* Ancienne tête de lecture    */
-    off_t pos;                              /* Position physique           */
 
-    result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
-
-    result->size = size;
-
-    pos = get_phy_addr(addr);
-    old = pos;
-
-    switch (size)
-    {
-        case MDS_4_BITS_UNSIGNED:
-            if (!read_u4(&result->unsigned_imm.val8, data, &pos, end, low, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_8_BITS_UNSIGNED:
-            if (!read_u8(&result->unsigned_imm.val8, data, &pos, end, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_16_BITS_UNSIGNED:
-            if (!read_u16(&result->unsigned_imm.val16, data, &pos, end, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_32_BITS_UNSIGNED:
-            if (!read_u32(&result->unsigned_imm.val32, data, &pos, end, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_64_BITS_UNSIGNED:
-            if (!read_u64(&result->unsigned_imm.val64, data, &pos, end, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_4_BITS_SIGNED:
-            if (!read_s4(&result->signed_imm.val8, data, &pos, end, low, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_8_BITS_SIGNED:
-            if (!read_s8(&result->signed_imm.val8, data, &pos, end, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_16_BITS_SIGNED:
-            if (!read_s16(&result->signed_imm.val16, data, &pos, end, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_32_BITS_SIGNED:
-            if (!read_s32(&result->signed_imm.val32, data, &pos, end, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_64_BITS_SIGNED:
-            if (!read_s64(&result->signed_imm.val64, data, &pos, end, endian))
-                goto gionfd_error;
-            break;
-
-        case MDS_UNDEFINED:
-            goto gionfd_error;
-            break;
+    if (size == MDS_UNDEFINED) return NULL;
 
-    }
+    result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
 
-    advance_vmpa(addr, pos - old);
+    g_imm_operand_set_value(result, size, value);
 
     return G_ARCH_OPERAND(result);
 
- gionfd_error:
+}
 
-    g_object_unref(G_OBJECT(result));
 
-    return NULL;
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = structure dont le contenu est à consulter.         *
+*                                                                             *
+*  Description : Renseigne la taille de la valeur indiquée à la construction. *
+*                                                                             *
+*  Retour      : Taille de la valeur représentée en mémoire.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
+{
+    return operand->size;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : size = taille de l'opérande souhaitée.                       *
+*  Paramètres  : operand = structure dont le contenu est à consulter.         *
+*                size  = taille de l'opérande souhaitée.                      *
 *                ...  = valeur sur x bits à venir récupérer.                  *
 *                                                                             *
-*  Description : Crée un opérande réprésentant une valeur numérique.          *
+*  Description : Fournit la valeur portée par une opérande numérique.         *
 *                                                                             *
-*  Retour      : Instruction mise en place.                                   *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
+bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...)
 {
-    GImmOperand *result;                    /* Opérande à retourner        */
+    bool result;                            /* Bilan à retourner           */
     va_list ap;                             /* Liste des compléments       */
-    uint8_t uval8;                          /* Valeur sur 8 bits           */
-    uint16_t uval16;                        /* Valeur sur 16 bits          */
-    uint32_t uval32;                        /* Valeur sur 32 bits          */
-    uint64_t uval64;                        /* Valeur sur 64 bits          */
-    int8_t sval8;                           /* Valeur sur 8 bits           */
-    int16_t sval16;                         /* Valeur sur 16 bits          */
-    int32_t sval32;                         /* Valeur sur 32 bits          */
-    int64_t sval64;                         /* Valeur sur 64 bits          */
+    uint8_t *uval8;                         /* Valeur sur 8 bits           */
+    uint16_t *uval16;                       /* Valeur sur 16 bits          */
+    uint32_t *uval32;                       /* Valeur sur 32 bits          */
+    uint64_t *uval64;                       /* Valeur sur 64 bits          */
+    int8_t *sval8;                          /* Valeur sur 8 bits           */
+    int16_t *sval16;                        /* Valeur sur 16 bits          */
+    int32_t *sval32;                        /* Valeur sur 32 bits          */
+    int64_t *sval64;                        /* Valeur sur 64 bits          */
 
-    if (size == MDS_UNDEFINED) return NULL;
+    if (operand->size != size) return false;
 
-    result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
-
-    result->size = size;
+    result = true;
 
     va_start(ap, size);
 
@@ -429,65 +397,73 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
     {
         /* Pour GCC... */
         case MDS_UNDEFINED:
+            result = false;
             break;
         case MDS_4_BITS_UNSIGNED:
         case MDS_8_BITS_UNSIGNED:
-            uval8 = (uint8_t)va_arg(ap, unsigned int);
-            result->unsigned_imm.val8 = uval8;
+            uval8 = va_arg(ap, uint8_t *);
+            *uval8 = operand->raw;
             break;
         case MDS_16_BITS_UNSIGNED:
-            uval16 = (uint16_t)va_arg(ap, unsigned int);
-            result->unsigned_imm.val16 = uval16;
+            uval16 = va_arg(ap, uint16_t *);
+            *uval16 = operand->raw;
             break;
         case MDS_32_BITS_UNSIGNED:
-            uval32 = (uint32_t)va_arg(ap, unsigned int);
-            result->unsigned_imm.val32 = uval32;
+            uval32 = va_arg(ap, uint32_t *);
+            *uval32 = operand->raw;
             break;
         case MDS_64_BITS_UNSIGNED:
-            uval64 = (uint64_t)va_arg(ap, unsigned int);
-            result->unsigned_imm.val64 = uval64;
+            uval64 = va_arg(ap, uint64_t *);
+            *uval64 = operand->raw;
             break;
         case MDS_4_BITS_SIGNED:
         case MDS_8_BITS_SIGNED:
-            sval8 = (int8_t)va_arg(ap, int);
-            result->signed_imm.val8 = sval8;
+            sval8 = va_arg(ap, int8_t *);
+            *sval8 = operand->raw;
             break;
         case MDS_16_BITS_SIGNED:
-            sval16 = (int16_t)va_arg(ap, int);
-            result->signed_imm.val16 = sval16;
+            sval16 = va_arg(ap, int16_t *);
+            *sval16 = operand->raw;
             break;
         case MDS_32_BITS_SIGNED:
-            sval32 = (int32_t)va_arg(ap, int);
-            result->signed_imm.val32 = sval32;
+            sval32 = va_arg(ap, int32_t *);
+            *sval32 = operand->raw;
             break;
         case MDS_64_BITS_SIGNED:
-            sval64 = (int64_t)va_arg(ap, int);
-            result->signed_imm.val64 = sval64;
+            sval64 = va_arg(ap, int64_t *);
+            *sval64 = operand->raw;
             break;
     }
 
     va_end(ap);
 
-    return G_ARCH_OPERAND(result);
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : operand = structure dont le contenu est à consulter.         *
+*  Paramètres  : operand = structure dont le contenu est à mettre à jour.     *
+*                size  = taille de l'opérande souhaitée.                      *
+*                value = valeur sur x bits à venir récupérer.                 *
 *                                                                             *
-*  Description : Renseigne la taille de la valeur indiquée à la construction. *
+*  Description : Définit la nouvelle valeur de l'opérande à une valeur.       *
 *                                                                             *
-*  Retour      : Taille de la valeur représentée en mémoire.                  *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
+bool g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value)
 {
-    return operand->size;
+    if (size == MDS_UNDEFINED) return false;
+
+    operand->size = size;
+    operand->raw = value;
+
+    return true;
 
 }
 
@@ -589,19 +565,15 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
     switch (operand->size)
     {
         case MDS_4_BITS_SIGNED:
-            result = (operand->signed_imm.val8 & 0x08);
-            break;
         case MDS_8_BITS_SIGNED:
-            result = (operand->signed_imm.val8 & 0x80);
-            break;
         case MDS_16_BITS_SIGNED:
-            result = (operand->signed_imm.val16 & 0x8000);
-            break;
         case MDS_32_BITS_SIGNED:
-            result = (operand->signed_imm.val32 & 0x80000000);
-            break;
         case MDS_64_BITS_SIGNED:
-            result = (operand->signed_imm.val64 & 0x8000000000000000ll);
+            /**
+             * Pour les valeurs plus petites que 64 bits, le compilateur
+             * réalise une extension de signe lors du transtypage.
+             */
+            result = (operand->raw & 0x8000000000000000ll);
             break;
         default:
             result = false;
@@ -627,46 +599,7 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
 
 bool g_imm_operand_is_null(const GImmOperand *operand)
 {
-    bool result;                            /* Bilan à renvoyer            */
-
-    switch (operand->size)
-    {
-        case MDS_4_BITS_SIGNED:
-            result = !(operand->signed_imm.val8 & 0x0f);
-            break;
-        case MDS_4_BITS_UNSIGNED:
-            result = !(operand->unsigned_imm.val8 & 0x0f);
-            break;
-        case MDS_8_BITS_SIGNED:
-            result = !(operand->signed_imm.val8 & 0xff);
-            break;
-        case MDS_8_BITS_UNSIGNED:
-            result = !(operand->unsigned_imm.val8 & 0xff);
-            break;
-        case MDS_16_BITS_SIGNED:
-            result = !(operand->signed_imm.val16 & 0xffff);
-            break;
-        case MDS_16_BITS_UNSIGNED:
-            result = !(operand->unsigned_imm.val16 & 0xffff);
-            break;
-        case MDS_32_BITS_SIGNED:
-            result = !(operand->signed_imm.val32 & 0xffffffff);
-            break;
-        case MDS_32_BITS_UNSIGNED:
-            result = !(operand->unsigned_imm.val32 & 0xffffffff);
-            break;
-        case MDS_64_BITS_SIGNED:
-            result = !(operand->signed_imm.val64 & 0xffffffffffffffffll);
-            break;
-        case MDS_64_BITS_UNSIGNED:
-            result = !(operand->unsigned_imm.val64 & 0xffffffffffffffffll);
-            break;
-        default:
-            result = false;
-            break;
-    }
-
-    return result;
+    return (operand->raw == 0ll);
 
 }
 
@@ -750,43 +683,43 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
             break;
 
         case MDS_4_BITS_UNSIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val8);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (uint8_t)operand->raw);
             break;
 
         case MDS_8_BITS_UNSIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val8);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (uint8_t)operand->raw);
             break;
 
         case MDS_16_BITS_UNSIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val16);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (uint16_t)operand->raw);
             break;
 
         case MDS_32_BITS_UNSIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val32);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (uint32_t)operand->raw);
             break;
 
         case MDS_64_BITS_UNSIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val64);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (uint64_t)operand->raw);
             break;
 
         case MDS_4_BITS_SIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val8);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (int8_t)operand->raw);
             break;
 
         case MDS_8_BITS_SIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val8);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (int8_t)operand->raw);
             break;
 
         case MDS_16_BITS_SIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val16);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (int16_t)operand->raw);
             break;
 
         case MDS_32_BITS_SIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val32);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (int32_t)operand->raw);
             break;
 
         case MDS_64_BITS_SIGNED:
-            result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val64);
+            result = snprintf(value, VMPA_MAX_SIZE, format, (int64_t)operand->raw);
             break;
 
     }
@@ -857,7 +790,6 @@ bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr)
             *addr = operand->unsigned_imm.val64;
             break;
         default:
-            *addr = operand->signed_imm.val32;//////
             result = false;
             break;
     }
diff --git a/src/arch/immediate.h b/src/arch/immediate.h
index 99d1b7f..a218c16 100644
--- a/src/arch/immediate.h
+++ b/src/arch/immediate.h
@@ -27,6 +27,7 @@
 
 #include <glib-object.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 
 #include "archbase.h"
@@ -46,10 +47,12 @@ typedef enum _ImmOperandDisplay
 } ImmOperandDisplay;
 
 
-#define G_TYPE_IMM_OPERAND                  g_imm_operand_get_type()
-#define G_IMM_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_imm_operand_get_type(), GImmOperand))
-#define G_IS_IMM_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_imm_operand_get_type()))
-#define G_IMM_OPERAND_GET_IFACE(inst)       (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_imm_operand_get_type(), GImmOperandIface))
+#define G_TYPE_IMM_OPERAND               g_imm_operand_get_type()
+#define G_IMM_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_imm_operand_get_type(), GImmOperand))
+#define G_IS_IMM_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_imm_operand_get_type()))
+#define G_IMM_OPERAND_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_IMM_OPERAND, GImmOperandClass))
+#define G_IS_IMM_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_IMM_OPERAND))
+#define G_IMM_OPERAND_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_IMM_OPERAND, GImmOperandClass))
 
 
 /* Définition d'un opérande de valeur numérique (instance) */
@@ -63,21 +66,23 @@ typedef struct _GImmOperandClass GImmOperandClass;
 GType g_imm_operand_get_type(void);
 
 /* Crée un opérande réprésentant une valeur numérique. */
-GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, off_t *, off_t, bool *, SourceEndian);
+GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, vmpa2t *, off_t, bool *, SourceEndian);
 
-#define g_imm_operand_new_from_data(size, data, pos, len, endian) _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian)
+#define g_imm_operand_new_from_data(size, data, pos, len, endian) \
+    _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian)
 
 /* Crée un opérande réprésentant une valeur numérique. */
-GArchOperand *_g_imm_operand_new_from_data2(MemoryDataSize, const bin_t *, vmpa2t *, off_t, bool *, SourceEndian);
-
-#define g_imm_operand_new_from_data2(size, data, pos, len, endian) _g_imm_operand_new_from_data2(size, data, pos, len, NULL, endian)
-
-/* Crée un opérande réprésentant une valeur numérique. */
-GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, ...);
+GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, uint64_t);
 
 /* Renseigne la taille de la valeur indiquée à la construction. */
 MemoryDataSize g_imm_operand_get_size(const GImmOperand *);
 
+/* Fournit la valeur portée par une opérande numérique. */
+bool g_imm_operand_get_value(const GImmOperand *, MemoryDataSize, ...);
+
+/* Définit la nouvelle valeur de l'opérande à une valeur. */
+bool g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t);
+
 /* Précise si des zéro doivent compléter l'affichage ou non. */
 void g_imm_operand_pad(GImmOperand *, bool);
 
@@ -97,13 +102,13 @@ bool g_imm_operand_is_negative(const GImmOperand *);
 bool g_imm_operand_is_null(const GImmOperand *);
 
 /* Convertit une valeur immédiate en adresse de type vmpa_t. */
-bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *);
+bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *) __attribute__ ((deprecated));
 
 /* Convertit une valeur immédiate en valeur de type size_t. */
-bool g_imm_operand_to_size_t(const GImmOperand *, size_t *, bool *);
+bool g_imm_operand_to_size_t(const GImmOperand *, size_t *, bool *) __attribute__ ((deprecated));
 
 /* Convertit une valeur immédiate en valeur de type off_t. */
-bool g_imm_operand_to_off_t(const GImmOperand *, off_t *, bool *);
+bool g_imm_operand_to_off_t(const GImmOperand *, off_t *, bool *) __attribute__ ((deprecated));
 
 
 
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index aedd468..5bdcedb 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -58,7 +58,7 @@ struct _GArchInstruction
     const char *suffix;                     /* Complément au nom affiché   */
     char *cached_keyword;                   /* Désignation complète        */
 
-    instr_post_prod_fc post_prod;   /* A remplacer par un signal... */
+    instr_hook_fc hooks[IPH_COUNT];         /* Traitements complémentaires */
 
     mrange_t range;                         /* Emplacement en mémoire      */
 
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index a96f0e4..598da6d 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -24,6 +24,7 @@
 #include "instruction.h"
 
 
+#include <assert.h>
 #include <stdarg.h>
 #include <string.h>
 
@@ -168,9 +169,10 @@ void g_arch_instruction_append_suffix(GArchInstruction *instr, const char *suffi
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instr = instruction quelconque à modifier.                   *
-*                post  = fonction à appeler sur commande.                     *
+*                type  = type de procédure à mémoriser.                       *
+*                hook  = fonction à appeler sur commande.                     *
 *                                                                             *
-*  Description : Définit une fonction de post-traitement après désassemblage. *
+*  Description : Définit un traitement complémentare au désassemblage.        *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -178,17 +180,21 @@ void g_arch_instruction_append_suffix(GArchInstruction *instr, const char *suffi
 *                                                                             *
 ******************************************************************************/
 
-void g_arch_instruction_set_post_prod_function(GArchInstruction *instr, instr_post_prod_fc post)
+void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type, instr_hook_fc hook)
 {
-    instr->post_prod = post;
+    assert(type < IPH_COUNT);
+
+    instr->hooks[type] = hook;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : instr = instruction quelconque à traiter.                    *
-*                data  = données éventuelles associées à l'opération.         *
+*  Paramètres  : instr   = instruction quelconque à traiter.                  *
+*                type    = type de procédure à utiliser.                      *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = accès aux données du binaire d'origine.            *
 *                                                                             *
 *  Description : Complète un désassemblage accompli pour une instruction.     *
 *                                                                             *
@@ -198,16 +204,14 @@ void g_arch_instruction_set_post_prod_function(GArchInstruction *instr, instr_po
 *                                                                             *
 ******************************************************************************/
 
-void g_arch_instruction_call_post_prod_function(GArchInstruction *instr, void *data)
+void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GProcContext *context, GBinFormat *format)
 {
-    if (instr->post_prod != NULL)
-        instr->post_prod(instr, data);
-
-}
-
-
+    assert(type < IPH_COUNT);
 
+    if (instr->hooks[type] != NULL)
+        instr->hooks[type](instr, context, format);
 
+}
 
 
 /******************************************************************************
@@ -338,6 +342,8 @@ GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size
     if (index >= instr->operands_count) result = NULL;
     else result = instr->operands[index];
 
+    /* TODO : incrémenter la référence ! */
+
     return result;
 
 }
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 7b9fe66..5657f73 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -28,6 +28,7 @@
 #include <sys/types.h>
 
 
+#include "context.h"
 #include "immediate.h"
 #include "register.h"
 #include "vmpa.h"
@@ -60,16 +61,24 @@ GType g_arch_instruction_get_type(void);
 /* Etend la désignation d'un nom d'instruction. */
 void g_arch_instruction_append_suffix(GArchInstruction *, const char *);
 
-/* Complète un désassemblage accompli pour une instruction. */
-typedef void (* instr_post_prod_fc)(GArchInstruction *, void *);
+/* Types de crochet de traitement */
+typedef enum _InstrProcessHook
+{
+    IPH_LINK,                               /* Edition des liens           */
+    IPH_POST,                               /* Résolution des symboles     */
 
-/* Définit une fonction de post-traitement après désassemblage. */
-void g_arch_instruction_set_post_prod_function(GArchInstruction *, instr_post_prod_fc);
+    IPH_COUNT
+
+} InstrProcessHook;
 
 /* Complète un désassemblage accompli pour une instruction. */
-void g_arch_instruction_call_post_prod_function(GArchInstruction *, void *);
+typedef void (* instr_hook_fc) (GArchInstruction *, GProcContext *, GBinFormat *);
 
+/* Définit un traitement complémentare au désassemblage. */
+void g_arch_instruction_set_hook(GArchInstruction *, InstrProcessHook, instr_hook_fc);
 
+/* Complète un désassemblage accompli pour une instruction. */
+void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GProcContext *, GBinFormat *);
 
 /* Définit la localisation d'une instruction. */
 void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *);
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 9b13dac..e76d75d 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -201,7 +201,7 @@ GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize
 
     for (i = 0; i < count; i++)
     {
-        operand = g_imm_operand_new_from_data2(size, data, addr, end, endian);
+        operand = g_imm_operand_new_from_data(size, data, addr, end, endian);
         if (operand == NULL) goto grina_error;
 
         g_imm_operand_pad(G_IMM_OPERAND(operand), true);
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index cf3af50..8eb79dc 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -117,16 +117,19 @@ bool _x86_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos,
         switch (types[i])
         {
             case X86_OTP_IMM8:
-                op = g_imm_operand_new_from_data(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
+                assert(0);
+                //op = g_imm_operand_new_from_data(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
                 break;
 
             case X86_OTP_IMM16:
-                op = g_imm_operand_new_from_data(MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
+                assert(0);
+                //op = g_imm_operand_new_from_data(MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
                 break;
 
             case X86_OTP_IMM1632:
                 if (oprsize == MDS_UNDEFINED) oprsize = va_arg(ap, MemoryDataSize);
-                op = g_imm_operand_new_from_data(oprsize == MDS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
+                assert(0);
+                //op = g_imm_operand_new_from_data(oprsize == MDS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
                 break;
 
             case X86_OTP_MOFFS8:
diff --git a/src/arch/x86/operands/modrm.c b/src/arch/x86/operands/modrm.c
index 6c70762..1da734f 100644
--- a/src/arch/x86/operands/modrm.c
+++ b/src/arch/x86/operands/modrm.c
@@ -136,7 +136,9 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,
     if (g_x86_register_is_base_pointer(reg) && mod == 0x00)
     {
         /* FIXME *///free_x86_register(reg);
-        return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/);
+        assert(0);
+        return NULL;
+        //return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/);
     }
 
     result = g_object_new(G_TYPE_X86_MOD_RM_OPERAND, NULL);
@@ -176,19 +178,22 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,
                 /* FIXME *///free_x86_register(result->base);
                 result->base = NULL;
 
-                result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);
+                assert(0);
+                //result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);
                 if (result->displacement == NULL) goto gxmron_error;
 
             }
             break;
 
         case 0x40:
-            result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */);
+            assert(0);
+            //result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */);
             if (result->displacement == NULL) goto gxmron_error;
             break;
 
         case 0x80:
-            result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */);
+            assert(0);
+            //result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */);
             if (result->displacement == NULL) goto gxmron_error;
             break;
 
diff --git a/src/arch/x86/operands/moffs.c b/src/arch/x86/operands/moffs.c
index 55e758d..689a400 100644
--- a/src/arch/x86/operands/moffs.c
+++ b/src/arch/x86/operands/moffs.c
@@ -116,7 +116,8 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len,
 
     result = NULL;
 
-    offset = g_imm_operand_new_from_data(size, data, pos, len, SRE_LITTLE /* FIXME */);
+    assert(0);
+    //offset = g_imm_operand_new_from_data(size, data, pos, len, SRE_LITTLE /* FIXME */);
 
     if (offset != NULL)
     {
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index 30bdcca..d69e41a 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -141,10 +141,15 @@ bool load_elf_symbols(GElfFormat *format)
     result = load_elf_internal_symbols(format);
 #endif
 
+
+
     entry_point = ELF_HDR(format, format->header, e_entry);
 
+    G_BIN_FORMAT(format)->entry_point = entry_point;
+
+
 
-	printf("E_ENTRY : 0x%08lx\n", (unsigned long)entry_point);
+    printf("E_ENTRY : 0x%08lx\n", (unsigned long)entry_point);
 
 	if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
 		entry_point &= ~0x1;
diff --git a/src/format/format-int.h b/src/format/format-int.h
index 95e171d..21a97b3 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -44,6 +44,8 @@ struct _GBinFormat
     const bin_t *content;                   /* Contenu binaire à étudier   */
     off_t length;                           /* Taille de ce contenu        */
 
+    virt_t entry_point;                     /* Point d'entrée dans le code */
+
     GBinSymbol **symbols;                   /* Liste des symboles trouvés  */
     size_t symbols_count;                   /* Quantité de ces symboles    */
 
diff --git a/src/format/format.c b/src/format/format.c
index cb43a94..8e1b9f4 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -180,6 +180,25 @@ const bin_t *g_binary_format_get_content(const GBinFormat *format, off_t *length
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : format = description de l'exécutable à consulter.            *
+*                                                                             *
+*  Description : Fournit l'adresse mémoire du point d'entrée d'un binaire.    *
+*                                                                             *
+*  Retour      : Adresse de mémoire virtuelle, voire VMPA_NO_VIRTUAL.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+virt_t g_binary_format_get_entry_point(const GBinFormat *format)
+{
+    return format->entry_point;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : format = informations chargées à compléter.                  *
 *                symbol = symbole à ajouter à la liste.                       *
 *                                                                             *
diff --git a/src/format/format.h b/src/format/format.h
index 3c74b50..364f71a 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -58,6 +58,9 @@ GType g_binary_format_get_type(void);
 /* Fournit une référence vers le contenu binaire analysé. */
 const bin_t *g_binary_format_get_content(const GBinFormat *, off_t *);
 
+/* Fournit l'adresse mémoire du point d'entrée d'un binaire. */
+virt_t g_binary_format_get_entry_point(const GBinFormat *);
+
 /* Ajoute un symbole à la collection du format binaire. */
 void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
 
-- 
cgit v0.11.2-87-g4458