From 8e5c8417e8ef79c1b475cb1b86a1754b24f9af78 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 20 Apr 2017 20:52:01 +0200
Subject: Shared immediate operands in order to avoid useless allocations.

---
 ChangeLog                           |  53 +++++
 plugins/pychrysa/arch/immediate.c   |  12 +-
 plugins/pychrysa/helpers.h          |   8 +
 plugins/stackvars/stackvars.c       |   2 +-
 src/analysis/db/items/switcher.c    |   4 +-
 src/analysis/disass/links.c         |   2 +-
 src/arch/arm/v7/fetch.c             |  37 ++--
 src/arch/arm/v7/post.c              |   2 +-
 src/arch/dalvik/operands/args.c     |   2 +-
 src/arch/dalvik/operands/pool.c     |   2 +-
 src/arch/dalvik/operands/register.c |   2 +-
 src/arch/immediate.c                | 431 ++++++++++++++++++++++++++++++++----
 src/arch/immediate.h                |  28 ++-
 src/arch/instruction.c              |  85 ++++++-
 src/arch/instruction.h              |  12 +-
 src/arch/operand-int.h              |   9 +-
 src/arch/operand.c                  |  31 ++-
 src/arch/post.c                     |   2 +-
 src/arch/raw.c                      |  17 +-
 src/arch/sharing/container-int.h    |   2 +-
 src/arch/sharing/container.c        |  12 +-
 src/arch/sharing/container.h        |   2 +-
 src/arch/sharing/instance-int.h     |   4 +
 src/arch/sharing/instance.c         |  24 ++
 src/arch/sharing/instance.h         |   3 +
 src/arch/sharing/manager.c          | 101 ++++++++-
 src/arch/sharing/manager.h          |   6 +
 src/core/processors.c               |   7 +-
 src/format/symbol.h                 |  16 +-
 tools/d2c/syntax/manager.c          |  20 +-
 30 files changed, 808 insertions(+), 130 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 448352b..f163828 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+17-04-20  Cyrille Bagard <nocbos@gmail.com>
+
+	* plugins/pychrysa/arch/immediate.c:
+	Update code.
+
+	* plugins/pychrysa/helpers.h:
+	Provide a way to update the GLib instance linked to a Python object.
+
+	* plugins/stackvars/stackvars.c:
+	* src/analysis/db/items/switcher.c:
+	* src/analysis/disass/links.c:
+	* src/arch/arm/v7/fetch.c:
+	* src/arch/arm/v7/post.c:
+	Update code.
+
+	* src/arch/dalvik/operands/args.c:
+	* src/arch/dalvik/operands/pool.c:
+	* src/arch/dalvik/operands/register.c:
+	Update class callbacks.
+
+	* src/arch/immediate.c:
+	* src/arch/immediate.h:
+	Share immediate operands in order to avoid useless allocations.
+
+	* src/arch/instruction.c:
+	* src/arch/instruction.h:
+	Make instructions become share containers.
+
+	* src/arch/operand-int.h:
+	* src/arch/operand.c:
+	Update class callbacks.
+
+	* src/arch/post.c:
+	* src/arch/raw.c:
+	Update code.
+
+	* src/arch/sharing/container-int.h:
+	* src/arch/sharing/container.c:
+	* src/arch/sharing/container.h:
+	* src/arch/sharing/instance-int.h:
+	* src/arch/sharing/instance.c:
+	* src/arch/sharing/instance.h:
+	* src/arch/sharing/manager.c:
+	* src/arch/sharing/manager.h:
+	Extend the features of the share system.
+
+	* src/core/processors.c:
+	Register the share manager for immediate operands.
+
+	* src/format/symbol.h:
+	* tools/d2c/syntax/manager.c:
+	Update code.
+
 17-04-19  Cyrille Bagard <nocbos@gmail.com>
 
 	* plugins/pychrysa/analysis/db/items/comment.c:
diff --git a/plugins/pychrysa/arch/immediate.c b/plugins/pychrysa/arch/immediate.c
index e600a9a..363c3cc 100644
--- a/plugins/pychrysa/arch/immediate.c
+++ b/plugins/pychrysa/arch/immediate.c
@@ -243,7 +243,9 @@ static int py_imm_operand_set_padding(PyObject *self, PyObject *value, void *clo
     operand = G_IMM_OPERAND(pygobject_get(self));
     assert(operand != NULL);
 
-    g_imm_operand_pad(operand, padding);
+    g_imm_operand_pad(&operand, padding, NULL);
+
+    pygobject_set(self, operand);
 
     return 0;
 
@@ -316,7 +318,9 @@ static int py_imm_operand_set_default_display(PyObject *self, PyObject *value, v
     operand = G_IMM_OPERAND(pygobject_get(self));
     assert(operand != NULL);
 
-    g_imm_operand_set_default_display(operand, display);
+    g_imm_operand_set_default_display(&operand, display, NULL);
+
+    pygobject_set(self, operand);
 
     return 0;
 
@@ -390,7 +394,9 @@ static int py_imm_operand_set_display(PyObject *self, PyObject *value, void *clo
     operand = G_IMM_OPERAND(pygobject_get(self));
     assert(operand != NULL);
 
-    g_imm_operand_set_display(operand, display);
+    g_imm_operand_set_display(&operand, display, NULL);
+
+    pygobject_set(self, operand);
 
     return 0;
 
diff --git a/plugins/pychrysa/helpers.h b/plugins/pychrysa/helpers.h
index 22f3702..3e079b7 100644
--- a/plugins/pychrysa/helpers.h
+++ b/plugins/pychrysa/helpers.h
@@ -65,5 +65,13 @@ bool PyDict_AddStringConstant(PyTypeObject *, const char *, const char *);
 bool register_class_for_pygobject(PyObject *, GType, PyTypeObject *, PyTypeObject *);
 
 
+/**
+ * Quand on remplace un objet GLib dans le dos de Python, il faut
+ * le remplacer de la même manière qu'on l'a obtenu !
+ */
+
+#define pygobject_set(p, v) ((PyGObject *)(p))->obj = (GObject *)v
+
+
 
 #endif  /* _PLUGINS_HELPERS_H */
diff --git a/plugins/stackvars/stackvars.c b/plugins/stackvars/stackvars.c
index f3baeef..4e07035 100644
--- a/plugins/stackvars/stackvars.c
+++ b/plugins/stackvars/stackvars.c
@@ -216,7 +216,7 @@ static bool replace_stack_vars_in_instruction(GArchInstruction *instr, GBinRouti
 
         if (!dryrun && result)
         {
-            _g_arch_instruction_replace_operand(instr, new, operand);
+            _g_arch_instruction_replace_operand(instr, operand, new);
 
             result = true;
 
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index b7957ff..35acf5f 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -547,7 +547,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
     if (new == IOD_COUNT)
         new = g_imm_operand_get_default_display(operand);
 
-    g_imm_operand_set_display(operand, new);
+    g_imm_operand_set_display(&operand, new, G_SHARE_CONTAINER(instr));
 
     len = g_imm_operand_to_string(operand, ASX_INTEL, value);
 
@@ -561,7 +561,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
 
  exit_operand:
 
-    g_object_unref(G_OBJECT(proc));
+    g_object_unref(G_OBJECT(instr));
 
  exit_instr:
 
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index e1bc58c..036a621 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -229,7 +229,7 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index,
             if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format, false))
                 g_object_unref(G_OBJECT(new));
             else
-                _g_arch_instruction_replace_operand(instr, new, op);
+                _g_arch_instruction_replace_operand(instr, op, new);
 
         }
 
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
index 84319cc..11864f6 100644
--- a/src/arch/arm/v7/fetch.c
+++ b/src/arch/arm/v7/fetch.c
@@ -34,6 +34,7 @@
 #include "operands/offset.h"
 #include "../register.h"
 #include "../../raw.h"
+#include "../../sharing/container.h"
 #include "../../../format/format.h"
 
 
@@ -58,7 +59,7 @@ void help_fetching_with_instruction_b_with_orig(GArchInstruction *instr, GArchPr
 {
     const mrange_t *range;                  /* Emplacementt d'instruction  */
     virt_t pc;                              /* Position dans l'exécution   */
-    GArchOperand *op;                       /* Opérande numérique en place */
+    GImmOperand *op;                        /* Opérande numérique en place */
     int32_t offset;                         /* Décallage encodé en dur     */
     virt_t target;                          /* Adresse virtuelle visée     */
 
@@ -86,10 +87,10 @@ void help_fetching_with_instruction_b_with_orig(GArchInstruction *instr, GArchPr
 
     //pc += get_mrange_length(range);
 
-    op = g_arch_instruction_get_operand(instr, 0);
+    op = G_IMM_OPERAND(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);
+    if (g_imm_operand_get_value(op, MDS_32_BITS_SIGNED, &offset))
+        g_imm_operand_set_value(&op, MDS_32_BITS_UNSIGNED, pc + offset, G_SHARE_CONTAINER(instr));
 
     else assert(0);
 
@@ -121,7 +122,7 @@ void help_fetching_with_instruction_bl_with_orig(GArchInstruction *instr, GArchP
 {
     const mrange_t *range;                  /* Emplacementt d'instruction  */
     virt_t pc;                              /* Position dans l'exécution   */
-    GArchOperand *op;                       /* Opérande numérique en place */
+    GImmOperand *op;                        /* Opérande numérique en place */
     int32_t offset;                         /* Décallage encodé en dur     */
     virt_t target;                          /* Adresse virtuelle visée     */
 
@@ -149,10 +150,10 @@ void help_fetching_with_instruction_bl_with_orig(GArchInstruction *instr, GArchP
             break;
     }
 
-    op = g_arch_instruction_get_operand(instr, 0);
+    op = G_IMM_OPERAND(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);
+    if (g_imm_operand_get_value(op, MDS_32_BITS_SIGNED, &offset))
+        g_imm_operand_set_value(&op, MDS_32_BITS_UNSIGNED, pc + offset, G_SHARE_CONTAINER(instr));
 
     else assert(0);
 
@@ -184,7 +185,7 @@ void help_fetching_with_instruction_blx_with_dest(GArchInstruction *instr, GArch
 {
     const mrange_t *range;                  /* Emplacementt d'instruction  */
     virt_t pc;                              /* Position dans l'exécution   */
-    GArchOperand *op;                       /* Opérande numérique en place */
+    GImmOperand *op;                        /* Opérande numérique en place */
     int32_t offset;                         /* Décallage encodé en dur     */
     virt_t target;                          /* Adresse virtuelle visée     */
 
@@ -202,10 +203,10 @@ void help_fetching_with_instruction_blx_with_dest(GArchInstruction *instr, GArch
     pc += 4;
     pc -= pc % 4;
 
-    op = g_arch_instruction_get_operand(instr, 0);
+    op = G_IMM_OPERAND(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);
+    if (g_imm_operand_get_value(op, MDS_32_BITS_SIGNED, &offset))
+        g_imm_operand_set_value(&op, MDS_32_BITS_UNSIGNED, pc + offset, G_SHARE_CONTAINER(instr));
 
     else assert(0);
 
@@ -307,7 +308,7 @@ void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcess
 {
     const mrange_t *range;                  /* Emplacementt d'instruction  */
     virt_t pc;                              /* Position dans l'exécution   */
-    GArchOperand *op;                       /* Opérande numérique en place */
+    GImmOperand *op;                        /* Opérande numérique en place */
     uint32_t offset;                        /* Décallage encodé en dur     */
     virt_t target;                          /* Adresse virtuelle visée     */
 
@@ -321,10 +322,10 @@ void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcess
 
     pc += 4;
 
-    op = g_arch_instruction_get_operand(instr, 1);
+    op = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, 1));
 
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset))
-        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+    if (g_imm_operand_get_value(op, MDS_32_BITS_UNSIGNED, &offset))
+        g_imm_operand_set_value(&op, MDS_32_BITS_UNSIGNED, pc + offset, G_SHARE_CONTAINER(instr));
 
     else assert(0);
 
@@ -486,7 +487,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
 
 
 
-    //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target);
+    //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target, G_SHARE_CONTAINER(instr));
 
 
     /// FIXME ?!
@@ -496,7 +497,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
 
 
     new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
-    _g_arch_instruction_replace_operand(instr, new, op);
+    _g_arch_instruction_replace_operand(instr, op, new);
 
     g_arch_instruction_unlock_operands(instr);
 
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index 6c63832..cfdc3be 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -93,7 +93,7 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
 
         }
 
-        _g_arch_instruction_replace_operand(instr, new, op);
+        _g_arch_instruction_replace_operand(instr, op, new);
 
     }
 
diff --git a/src/arch/dalvik/operands/args.c b/src/arch/dalvik/operands/args.c
index 1eccf3a..8a687db 100644
--- a/src/arch/dalvik/operands/args.c
+++ b/src/arch/dalvik/operands/args.c
@@ -119,7 +119,7 @@ static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass)
     object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_args_operand_dispose;
     object->finalize = (GObjectFinalizeFunc)g_dalvik_args_operand_finalize;
 
-    operand->init = (init_shared_fc)g_dalvik_args_operand_do_init;
+    operand->init = (operand_do_init_fc)g_dalvik_args_operand_do_init;
 
     operand->compare = (operand_compare_fc)g_dalvik_args_operand_compare;
     operand->print = (operand_print_fc)g_dalvik_args_operand_print;
diff --git a/src/arch/dalvik/operands/pool.c b/src/arch/dalvik/operands/pool.c
index f40c839..a450ffe 100644
--- a/src/arch/dalvik/operands/pool.c
+++ b/src/arch/dalvik/operands/pool.c
@@ -125,7 +125,7 @@ static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *klass)
 
     operand = G_ARCH_OPERAND_CLASS(klass);
 
-    operand->init = (init_shared_fc)g_dalvik_pool_operand_do_init;
+    operand->init = (operand_do_init_fc)g_dalvik_pool_operand_do_init;
 
     operand->compare = (operand_compare_fc)g_dalvik_pool_operand_compare;
     operand->print = (operand_print_fc)g_dalvik_pool_operand_print;
diff --git a/src/arch/dalvik/operands/register.c b/src/arch/dalvik/operands/register.c
index b90f02b..b415d3f 100644
--- a/src/arch/dalvik/operands/register.c
+++ b/src/arch/dalvik/operands/register.c
@@ -116,7 +116,7 @@ static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *kl
 
     operand = G_ARCH_OPERAND_CLASS(klass);
 
-    operand->init = (init_shared_fc)g_dalvik_register_operand_do_init;
+    operand->init = (operand_do_init_fc)g_dalvik_register_operand_do_init;
 
     operand->compare = (operand_compare_fc)g_dalvik_register_operand_compare;
     operand->print = (operand_print_fc)g_dalvik_register_operand_print;
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index 6c8be5c..6c52892 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -37,6 +37,7 @@
 
 
 #include "operand-int.h"
+#include "sharing/manager.h"
 #include "../common/asm.h"
 #include "../common/extstr.h"
 #include "../format/format.h"
@@ -78,6 +79,15 @@ static void g_imm_operand_dispose(GImmOperand *);
 /* Procède à la libération totale de la mémoire. */
 static void g_imm_operand_finalize(GImmOperand *);
 
+/* Initialise un nouvel objet partagé avec des informations. */
+static bool g_imm_operand_do_init(GImmOperand *, const GImmOperand *);
+
+/* Réalise une copie minimale d'un contenu partagé. */
+static void g_imm_operand_quickly_copy(const GImmOperand *, GImmOperand *);
+
+/* Compare un opérande avec un autre. */
+static int g_imm_operand_compare(const GImmOperand * const *, const GImmOperand * const *);
+
 /* Construit la chaîne de caractères correspondant à l'opérande. */
 static size_t _g_imm_operand_to_string(const GImmOperand *, AsmSyntax, ImmOperandDisplay, char [IMM_MAX_SIZE]);
 
@@ -89,6 +99,19 @@ static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinar
 
 
 
+/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */
+
+
+/* Gestionnaire des partages d'instances */
+static GShareManager *_imm_operand_manager = NULL;
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                    MANIPULATION D'OPERANDES DE VALEUR IMMEDIATE                    */
+/* ---------------------------------------------------------------------------------- */
+
+
 /* Indique le type défini pour un opérande de valeur numérique. */
 G_DEFINE_TYPE(GImmOperand, g_imm_operand, G_TYPE_ARCH_OPERAND);
 
@@ -117,6 +140,10 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)
     object->dispose = (GObjectFinalizeFunc/* ! */)g_imm_operand_dispose;
     object->finalize = (GObjectFinalizeFunc)g_imm_operand_finalize;
 
+    operand->init = (operand_do_init_fc)g_imm_operand_do_init;
+    operand->qck_copy = (operand_qck_copy_fc)g_imm_operand_quickly_copy;
+
+    operand->compare = (operand_compare_fc)g_imm_operand_compare;
     operand->print = (operand_print_fc)g_imm_operand_print;
     operand->build_tooltip = (operand_build_tooltip_fc)g_imm_operand_build_tooltip;
 
@@ -201,7 +228,8 @@ static void g_imm_operand_finalize(GImmOperand *operand)
 
 GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian)
 {
-    GImmOperand *result;                    /* Opérande à retourner        */
+    GArchOperand *result;                   /* Opérande à retourner        */
+    GImmOperand fake;                       /* Transport d'informations    */
     uint8_t uval8;                          /* Valeur sur 8 bits           */
     uint16_t uval16;                        /* Valeur sur 16 bits          */
     uint32_t uval32;                        /* Valeur sur 32 bits          */
@@ -211,70 +239,70 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten
     int32_t sval32;                         /* Valeur sur 32 bits          */
     int64_t sval64;                         /* Valeur sur 64 bits          */
 
-    result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
+    g_imm_operand_init(&fake);
 
-    result->size = size;
+    fake.size = size;
 
     switch (size)
     {
         case MDS_4_BITS_UNSIGNED:
             if (!g_binary_content_read_u4(content, addr, low, &uval8))
                 goto gionfd_error;
-            result->raw = uval8;
+            fake.raw = uval8;
             break;
 
         case MDS_8_BITS_UNSIGNED:
             if (!g_binary_content_read_u8(content, addr, &uval8))
                 goto gionfd_error;
-            result->raw = uval8;
+            fake.raw = uval8;
             break;
 
         case MDS_16_BITS_UNSIGNED:
             if (!g_binary_content_read_u16(content, addr, endian, &uval16))
                 goto gionfd_error;
-            result->raw = uval16;
+            fake.raw = uval16;
             break;
 
         case MDS_32_BITS_UNSIGNED:
             if (!g_binary_content_read_u32(content, addr, endian, &uval32))
                 goto gionfd_error;
-            result->raw = uval32;
+            fake.raw = uval32;
             break;
 
         case MDS_64_BITS_UNSIGNED:
             if (!g_binary_content_read_u64(content, addr, endian, &uval64))
                 goto gionfd_error;
-            result->raw = uval64;
+            fake.raw = uval64;
             break;
 
         case MDS_4_BITS_SIGNED:
             if (!g_binary_content_read_s4(content, addr, low, &sval8))
                 goto gionfd_error;
-            result->raw = sval8;
+            fake.raw = sval8;
             break;
 
         case MDS_8_BITS_SIGNED:
             if (!g_binary_content_read_s8(content, addr, &sval8))
                 goto gionfd_error;
-            result->raw = sval8;
+            fake.raw = sval8;
             break;
 
         case MDS_16_BITS_SIGNED:
             if (!g_binary_content_read_s16(content, addr, endian, &sval16))
                 goto gionfd_error;
-            result->raw = sval16;
+            fake.raw = sval16;
             break;
 
         case MDS_32_BITS_SIGNED:
             if (!g_binary_content_read_s32(content, addr, endian, &sval32))
                 goto gionfd_error;
-            result->raw = sval32;
+            fake.raw = sval32;
             break;
 
         case MDS_64_BITS_SIGNED:
             if (!g_binary_content_read_s64(content, addr, endian, &sval64))
                 goto gionfd_error;
-            result->raw = sval64;
+            fake.raw = sval64;
             break;
 
         case MDS_UNDEFINED:
@@ -283,11 +311,11 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten
 
     }
 
-    return G_ARCH_OPERAND(result);
+    result = G_ARCH_OPERAND(g_share_manager_get(_imm_operand_manager, (GSharedInstance *)&fake));
 
- gionfd_error:
+    return result;
 
-    g_object_unref(G_OBJECT(result));
+ gionfd_error:
 
     return NULL;
 
@@ -309,15 +337,157 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten
 
 GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
 {
-    GImmOperand *result;                    /* Opérande à retourner        */
+    GArchOperand *result;                   /* Opérande à retourner        */
+    GImmOperand fake;                       /* Transport d'informations    */
 
-    if (size == MDS_UNDEFINED) return NULL;
+    if (size == MDS_UNDEFINED)
+        result = NULL;
 
-    result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
+    else
+    {
+        g_imm_operand_init(&fake);
 
-    g_imm_operand_set_value(result, size, value);
+        fake.size = size;
+        fake.raw = value;
 
-    return G_ARCH_OPERAND(result);
+        result = G_ARCH_OPERAND(g_share_manager_get(_imm_operand_manager, (GSharedInstance *)&fake));
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = objet partagé à initialiser.                       *
+*                fake    = coquille vide contenant les infos à enregistrer.   *
+*                                                                             *
+*  Description : Initialise un nouvel objet partagé avec des informations.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_imm_operand_do_init(GImmOperand *operand, const GImmOperand *fake)
+{
+    operand->raw = fake->raw;
+    operand->size = fake->size;
+
+    operand->zpad = fake->zpad;
+    operand->def_display = fake->def_display;
+    operand->display = fake->display;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand  = objet partagé à consulter.                        *
+*                template = informations à retrouver intégralement.           *
+*                                                                             *
+*  Description : Réalise une copie minimale d'un contenu partagé.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_imm_operand_quickly_copy(const GImmOperand *operand, GImmOperand *template)
+{
+    template->raw = operand->raw;
+    template->size = operand->size;
+
+    template->zpad = operand->zpad;
+    template->def_display = operand->def_display;
+    template->display = operand->display;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier opérande à consulter.                            *
+*                b = second opérande à consulter.                             *
+*                                                                             *
+*  Description : Compare un opérande avec un autre.                           *
+*                                                                             *
+*  Retour      : Bilan de la comparaison.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int g_imm_operand_compare(const GImmOperand * const *a, const GImmOperand * const *b)
+{
+    int result;                             /* Bilan à retourner           */
+    const GImmOperand *imm_a;               /* Accès simplifié à A         */
+    const GImmOperand *imm_b;               /* Accès simplifié à B         */
+
+    imm_a = *a;
+    imm_b = *b;
+
+    if (imm_a->size < imm_b->size)
+    {
+        result = -1;
+        goto gioc_done;
+    }
+    else if (imm_a->size > imm_b->size)
+    {
+        result = 1;
+        goto gioc_done;
+    }
+
+    if (imm_a->raw < imm_b->raw)
+    {
+        result = -1;
+        goto gioc_done;
+    }
+    else if (imm_a->raw > imm_b->raw)
+    {
+        result = 1;
+        goto gioc_done;
+    }
+
+    if (imm_a->zpad != imm_b->zpad)
+    {
+        result = (imm_a->zpad ? 1 : -1);
+        goto gioc_done;
+    }
+
+    if (imm_a->def_display < imm_b->def_display)
+    {
+        result = -1;
+        goto gioc_done;
+    }
+    else if (imm_a->def_display > imm_b->def_display)
+    {
+        result = 1;
+        goto gioc_done;
+    }
+
+    if (imm_a->display < imm_b->display)
+    {
+        result = -1;
+        goto gioc_done;
+    }
+    else if (imm_a->display > imm_b->display)
+    {
+        result = 1;
+        goto gioc_done;
+    }
+
+    result = 0;
+
+ gioc_done:
+
+    return result;
 
 }
 
@@ -443,34 +613,62 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand)
 
 /******************************************************************************
 *                                                                             *
-*  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.                 *
+*  Paramètres  : operand   = structure dont le contenu est à actualiser. [OUT]*
+*                size      = taille de l'opérande souhaitée.                  *
+*                value     = valeur sur x bits à venir récupérer.             *
+*                container = propriétaire d'origine à tenir au courant.       *
 *                                                                             *
 *  Description : Définit la nouvelle valeur de l'opérande à une valeur.       *
 *                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-bool g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value)
+void g_imm_operand_set_value(GImmOperand **operand, MemoryDataSize size, uint64_t value, GShareContainer *container)
 {
-    if (size == MDS_UNDEFINED) return false;
+    GSharedInstance *shared;                /* Instace de travail partagée */
+    size_t index;                           /* Indice du déménagement      */
+    GImmOperand fake;                       /* Transport d'informations    */
 
-    operand->size = size;
-    operand->raw = value;
+    assert(size != MDS_UNDEFINED);
 
-    return true;
+    shared = G_SHARED_INSTANCE(*operand);
+
+    if (container == NULL)
+    {
+        index = g_share_manager_prepare_light_update(_imm_operand_manager, shared);
+
+        (*operand)->size = size;
+        (*operand)->raw = value;
+
+        shared = g_share_manager_complete_light_update(_imm_operand_manager, shared, index);
+
+    }
+
+    else
+    {
+        g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake);
+
+        fake.size = size;
+        fake.raw = value;
+
+        shared = g_share_manager_update(_imm_operand_manager, shared,
+                                        (GSharedInstance *)&fake, container);
+
+    }
+
+    *operand = G_IMM_OPERAND(shared);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : operand = structure dont le contenu est à définir.           *
-*                state   = true si des zéro sont à ajouter, false sinon.      *
+*  Paramètres  : operand   = structure dont le contenu est à actualiser. [OUT]*
+*                state     = true si des zéro sont à ajouter, false sinon.    *
+*                container = propriétaire d'origine à tenir au courant.       *
 *                                                                             *
 *  Description : Précise si des zéro doivent compléter l'affichage ou non.    *
 *                                                                             *
@@ -480,9 +678,36 @@ bool g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t
 *                                                                             *
 ******************************************************************************/
 
-void g_imm_operand_pad(GImmOperand *operand, bool state)
+void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *container)
 {
-    operand->zpad = state;
+    GSharedInstance *shared;                /* Instace de travail partagée */
+    size_t index;                           /* Indice du déménagement      */
+    GImmOperand fake;                       /* Transport d'informations    */
+
+    shared = G_SHARED_INSTANCE(*operand);
+
+    if (container == NULL)
+    {
+        index = g_share_manager_prepare_light_update(_imm_operand_manager, shared);
+
+        (*operand)->zpad = state;
+
+        shared = g_share_manager_complete_light_update(_imm_operand_manager, shared, index);
+
+    }
+
+    else
+    {
+        g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake);
+
+        fake.zpad = state;
+
+        shared = g_share_manager_update(_imm_operand_manager, shared,
+                                        (GSharedInstance *)&fake, container);
+
+    }
+
+    *operand = G_IMM_OPERAND(shared);
 
 }
 
@@ -508,8 +733,9 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : operand = structure dont le contenu par défaut est à définir.*
-*                display = format global d'un affichage de valeur.            *
+*  Paramètres  : operand   = structure dont le contenu est à actualiser. [OUT]*
+*                display   = format global d'un affichage de valeur.          *
+*                container = propriétaire d'origine à tenir au courant.       *
 *                                                                             *
 *  Description : Définit le format textuel par défaut de la valeur.           *
 *                                                                             *
@@ -519,9 +745,36 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)
 *                                                                             *
 ******************************************************************************/
 
-void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display)
+void g_imm_operand_set_default_display(GImmOperand **operand, ImmOperandDisplay display, GShareContainer *container)
 {
-    operand->def_display = display;
+    GSharedInstance *shared;                /* Instace de travail partagée */
+    size_t index;                           /* Indice du déménagement      */
+    GImmOperand fake;                       /* Transport d'informations    */
+
+    shared = G_SHARED_INSTANCE(*operand);
+
+    if (container == NULL)
+    {
+        index = g_share_manager_prepare_light_update(_imm_operand_manager, shared);
+
+        (*operand)->def_display = display;
+
+        shared = g_share_manager_complete_light_update(_imm_operand_manager, shared, index);
+
+    }
+
+    else
+    {
+        g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake);
+
+        fake.def_display = display;
+
+        shared = g_share_manager_update(_imm_operand_manager, shared,
+                                        (GSharedInstance *)&fake, container);
+
+    }
+
+    *operand = G_IMM_OPERAND(shared);
 
 }
 
@@ -547,8 +800,9 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : operand = structure dont le contenu est à définir.           *
-*                display = format global d'un affichage de valeur.            *
+*  Paramètres  : operand   = structure dont le contenu est à actualiser. [OUT]*
+*                display   = format global d'un affichage de valeur.          *
+*                container = propriétaire d'origine à tenir au courant.       *
 *                                                                             *
 *  Description : Définit la grande ligne du format textuel de la valeur.      *
 *                                                                             *
@@ -558,9 +812,36 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
 *                                                                             *
 ******************************************************************************/
 
-void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
+void g_imm_operand_set_display(GImmOperand **operand, ImmOperandDisplay display, GShareContainer *container)
 {
-    operand->display = display;
+    GSharedInstance *shared;                /* Instace de travail partagée */
+    size_t index;                           /* Indice du déménagement      */
+    GImmOperand fake;                       /* Transport d'informations    */
+
+    shared = G_SHARED_INSTANCE(*operand);
+
+    if (container == NULL)
+    {
+        index = g_share_manager_prepare_light_update(_imm_operand_manager, shared);
+
+        (*operand)->display = display;
+
+        shared = g_share_manager_complete_light_update(_imm_operand_manager, shared, index);
+
+    }
+
+    else
+    {
+        g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake);
+
+        fake.display = display;
+
+        shared = g_share_manager_update(_imm_operand_manager, shared,
+                                        (GSharedInstance *)&fake, container);
+
+    }
+
+    *operand = G_IMM_OPERAND(shared);
 
 }
 
@@ -1116,3 +1397,69 @@ bool g_imm_operand_to_off_t(const GImmOperand *operand, off_t *value, bool *nega
     return false;
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            PARTAGES DE CONTENUS UNIQUES                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Initialise les mécanismes de partage d'opérandes immédiates. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool init_imm_operand_sharing(void)
+{
+    _imm_operand_manager = g_share_manager_new(G_TYPE_IMM_OPERAND);
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Imprime des statistiques quant aux partages dans l'archi.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+#ifdef DEBUG_DUMP_STATS
+void dump_imm_operand_share_stats(void)
+{
+    g_share_manager_dump_stats(_imm_operand_manager);
+
+}
+#endif
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Supprime les mécanismes de partage des opérandes immédiates. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void exit_imm_operand_sharing(void)
+{
+    g_object_unref(G_OBJECT(_imm_operand_manager));
+
+}
diff --git a/src/arch/immediate.h b/src/arch/immediate.h
index fa30fe0..b4d1f84 100644
--- a/src/arch/immediate.h
+++ b/src/arch/immediate.h
@@ -32,10 +32,14 @@
 
 #include "archbase.h"
 #include "operand.h"
+#include "sharing/container.h"
 #include "../analysis/content.h"
 
 
 
+/* ------------------ MANIPULATION D'OPERANDES DE VALEUR IMMEDIATE ------------------ */
+
+
 /* Grande ligne d'un format d'affichage */
 typedef enum _ImmOperandDisplay
 {
@@ -87,22 +91,22 @@ bool g_imm_operand_get_value(const GImmOperand *, MemoryDataSize, ...);
 uint64_t g_imm_operand_get_raw_value(const GImmOperand *);
 
 /* Définit la nouvelle valeur de l'opérande à une valeur. */
-bool g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t);
+void g_imm_operand_set_value(GImmOperand **, MemoryDataSize, uint64_t, GShareContainer *);
 
 /* Précise si des zéro doivent compléter l'affichage ou non. */
-void g_imm_operand_pad(GImmOperand *, bool);
+void g_imm_operand_pad(GImmOperand **, bool, GShareContainer *);
 
 /* Indique le signe d'une valeur immédiate. */
 bool g_imm_operand_does_padding(const GImmOperand *);
 
 /* Définit le format textuel par défaut de la valeur. */
-void g_imm_operand_set_default_display(GImmOperand *, ImmOperandDisplay);
+void g_imm_operand_set_default_display(GImmOperand **, ImmOperandDisplay, GShareContainer *);
 
 /* Indique le format textuel par défaut de la valeur. */
 ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *);
 
 /* Définit la grande ligne du format textuel de la valeur. */
-void g_imm_operand_set_display(GImmOperand *, ImmOperandDisplay);
+void g_imm_operand_set_display(GImmOperand **, ImmOperandDisplay, GShareContainer *);
 
 /* Indique la grande ligne du format textuel de la valeur. */
 ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *);
@@ -145,4 +149,20 @@ bool g_imm_operand_to_off_t(const GImmOperand *, off_t *, bool *) __attribute__
 
 
 
+/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */
+
+
+/* Initialise les mécanismes de partage des opérandes immédiates. */
+bool init_imm_operand_sharing(void);
+
+/* Imprime des statistiques quant aux partages dans l'archi. */
+#ifdef DEBUG_DUMP_STATS
+void dump_imm_operand_share_stats(void);
+#endif
+
+/* Supprime les mécanismes de partage des opérandes immédiates. */
+void exit_imm_operand_sharing(void);
+
+
+
 #endif  /* _ARCH_IMMEDIATE_H */
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 14e78dc..a2ba138 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -30,6 +30,7 @@
 
 
 #include "instruction-int.h"
+#include "sharing/container-int.h"
 #include "../glibext/linegen-int.h"
 
 
@@ -40,8 +41,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);
 /* Initialise une instance d'opérande d'architecture. */
 static void g_arch_instruction_init(GArchInstruction *);
 
+/* Procède à l'initialisation de l'interface de partage. */
+static void g_arch_instruction_share_interface_init(GShareContainerInterface *);
+
 /* Procède à l'initialisation de l'interface de génération. */
-static void g_arch_instruction_interface_init(GLineGeneratorInterface *);
+static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *);
 
 /* Supprime toutes les références externes. */
 static void g_arch_instruction_dispose(GArchInstruction *);
@@ -76,7 +80,8 @@ static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t,
 
 /* Indique le type défini pour une instruction d'architecture. */
 G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT,
-                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_interface_init));
+                        G_IMPLEMENT_INTERFACE(G_TYPE_SHARE_CONTAINER, g_arch_instruction_share_interface_init)
+                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_interface_init));
 
 
 /******************************************************************************
@@ -134,6 +139,25 @@ static void g_arch_instruction_init(GArchInstruction *instr)
 *                                                                             *
 *  Paramètres  : iface = interface GLib à initialiser.                        *
 *                                                                             *
+*  Description : Procède à l'initialisation de l'interface de partage.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arch_instruction_share_interface_init(GShareContainerInterface *iface)
+{
+    iface->replace = (replace_shared_fc)g_arch_instruction_replace_operand;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
 *  Description : Procède à l'initialisation de l'interface de génération.     *
 *                                                                             *
 *  Retour      : -                                                            *
@@ -142,7 +166,7 @@ static void g_arch_instruction_init(GArchInstruction *instr)
 *                                                                             *
 ******************************************************************************/
 
-static void g_arch_instruction_interface_init(GLineGeneratorInterface *iface)
+static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *iface)
 {
     iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines;
     iface->compute = (linegen_compute_fc)g_arch_instruction_compute_addr;
@@ -475,8 +499,8 @@ void g_arch_instruction_unlock_operands(GArchInstruction *instr)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : instr     = instance à mettre à jour.                        *
-*                opererand = instruction à venir associer.                    *
+*  Paramètres  : instr   = instance à mettre à jour.                          *
+*                operand = instruction à venir associer.                      *
 *                                                                             *
 *  Description : Attache un opérande supplémentaire à une instruction.        *
 *                                                                             *
@@ -552,23 +576,55 @@ GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, siz
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instr = instance à mettre à jour.                            *
-*                new   = nouvelle opérande à attacher.                        *
+*                old   = ancien opérande à remplacer.                         *
+*                new   = nouvel opérande à intégrer.                          *
+*                                                                             *
+*  Description : Remplace un opérande d'une instruction par un autre.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *old, GArchOperand *new)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    g_arch_instruction_lock_operands(instr);
+
+    result = _g_arch_instruction_replace_operand(instr, old, new);
+
+    g_arch_instruction_unlock_operands(instr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instance à mettre à jour.                            *
 *                old   = ancienne opérande à détacher.                        *
+*                new   = nouvelle opérande à attacher.                        *
 *                                                                             *
 *  Description : Remplace un opérande d'une instruction par un autre.         *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, GArchOperand *old)
+bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *old, GArchOperand *new)
 {
+    bool result;                            /* Bilan à retourner           */
     size_t count;                           /* Nombre d'opérandes en place */
     size_t i;                               /* Boucle de parcours          */
     GArchOperand *op;                       /* Opérande à manipuler        */
 
+    result = false;
+
     count = _g_arch_instruction_count_operands(instr);
 
     for (i = 0; i < count; i++)
@@ -576,13 +632,22 @@ void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *
         op = _g_arch_instruction_get_operand(instr, i);
 
         if (op == old)
+        {
+            result = true;
             break;
+        }
 
     }
 
-    rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *));
+    if (result)
+    {
+        rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *));
+
+        g_object_unref(G_OBJECT(old));
 
-    g_object_unref(G_OBJECT(old));
+    }
+
+    return result;
 
 }
 
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index bb2dc94..55c845e 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -147,7 +147,10 @@ size_t _g_arch_instruction_count_operands(const GArchInstruction *);
 GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *, size_t);
 
 /* Remplace un opérande d'une instruction par un autre. */
-void _g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, GArchOperand *);
+bool g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, GArchOperand *);
+
+/* Remplace un opérande d'une instruction par un autre. */
+bool _g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, GArchOperand *);
 
 /* Détache un opérande liée d'une instruction. */
 void _g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
@@ -171,13 +174,6 @@ void _g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
         __result;                                               \
     })
 
-#define g_arch_instruction_replace_operand(ins, n, o)           \
-    ({                                                          \
-        g_arch_instruction_lock_operands(ins);                  \
-        _g_arch_instruction_replace_operand(ins, n, o);         \
-        g_arch_instruction_unlock_operands(ins);                \
-    })
-
 #define g_arch_instruction_detach_operand(ins, o)               \
     ({                                                          \
         g_arch_instruction_lock_operands(ins);                  \
diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h
index 8335614..535df1b 100644
--- a/src/arch/operand-int.h
+++ b/src/arch/operand-int.h
@@ -30,6 +30,12 @@
 
 
 
+/* Initialise un nouvel objet partagé avec des informations. */
+typedef bool (* operand_do_init_fc) (GArchOperand *, const GArchOperand *);
+
+/* Réalise une copie minimale d'un contenu partagé. */
+typedef void (* operand_qck_copy_fc) (const GArchOperand *, GArchOperand *);
+
 /* Compare un opérande avec un autre. */
 typedef int (* operand_compare_fc) (const GArchOperand * const *, const GArchOperand * const *);
 
@@ -66,7 +72,8 @@ struct _GArchOperandClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
-    init_shared_fc init;                    /* Mise en place via interface */
+    operand_do_init_fc init;                /* Mise en place via interface */
+    operand_qck_copy_fc qck_copy;           /* Copie minimale via interface*/
 
     operand_compare_fc compare;             /* Comparaison d'opérandes     */
     operand_print_fc print;                 /* Texte humain équivalent     */
diff --git a/src/arch/operand.c b/src/arch/operand.c
index dd28238..584e3c0 100644
--- a/src/arch/operand.c
+++ b/src/arch/operand.c
@@ -50,7 +50,10 @@ static void g_arch_operand_dispose(GArchOperand *);
 static void g_arch_operand_finalize(GArchOperand *);
 
 /* Initialise un nouvel objet partagé avec des informations. */
-static bool g_arch_operand_do_init(GArchOperand *, const void *);
+static bool g_arch_operand_do_init(GArchOperand *, const GArchOperand *);
+
+/* Réalise une copie minimale d'un contenu partagé. */
+static void g_arch_operand_quickly_copy(const GArchOperand *, GArchOperand *);
 
 /* Fournit la valeur du compteur de partage. */
 static unsigned int g_arch_operand_get_references(const GArchOperand *);
@@ -65,6 +68,7 @@ static void g_arch_operand_dec_references(GArchOperand *);
 static int g_arch_operand_quickly_compare(const GArchOperand **, const GArchOperand **);
 
 
+
 /* Indique le type défini pour un opérande d'architecture. */
 G_DEFINE_TYPE_WITH_CODE(GArchOperand, g_arch_operand, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE(G_TYPE_SHARED_INSTANCE, g_arch_operand_interface_init));
@@ -128,6 +132,7 @@ static void g_arch_operand_init(GArchOperand *operand)
 static void g_arch_operand_interface_init(GSharedInstanceInterface *iface)
 {
     iface->init = (init_shared_fc)g_arch_operand_do_init;
+    iface->qck_copy = (qck_copy_shared_fc)g_arch_operand_quickly_copy;
 
     iface->get_ref = (get_shared_ref_fc)g_arch_operand_get_references;
     iface->inc_ref = (inc_shared_ref_fc)g_arch_operand_inc_references;
@@ -191,11 +196,11 @@ static void g_arch_operand_finalize(GArchOperand *operand)
 *                                                                             *
 ******************************************************************************/
 
-static bool g_arch_operand_do_init(GArchOperand *operand, const void *info)
+static bool g_arch_operand_do_init(GArchOperand *operand, const GArchOperand *info)
 {
     bool result;                            /* Bilan à retourner           */
 
-    result = G_ARCH_OPERAND_GET_CLASS(operand)->init(G_SHARED_INSTANCE(operand), info);
+    result = G_ARCH_OPERAND_GET_CLASS(operand)->init(operand, info);
 
     return result;
 
@@ -204,6 +209,26 @@ static bool g_arch_operand_do_init(GArchOperand *operand, const void *info)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : operand  = objet partagé à consulter.                        *
+*                template = informations à retrouver intégralement.           *
+*                                                                             *
+*  Description : Réalise une copie minimale d'un contenu partagé.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arch_operand_quickly_copy(const GArchOperand *operand, GArchOperand *template)
+{
+    G_ARCH_OPERAND_GET_CLASS(operand)->qck_copy(operand, template);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : operand = objet partagé à consulter.                         *
 *                                                                             *
 *  Description : Fournit la valeur du compteur de partage.                    *
diff --git a/src/arch/post.c b/src/arch/post.c
index 5c7ed13..184430d 100644
--- a/src/arch/post.c
+++ b/src/arch/post.c
@@ -111,7 +111,7 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro
 
         }
 
-        _g_arch_instruction_replace_operand(instr, new, op);
+        _g_arch_instruction_replace_operand(instr, op, new);
 
     }
 
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 9d9b8de..b84d9f7 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -195,17 +195,17 @@ static void g_raw_instruction_finalize(GRawInstruction *instr)
 GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value)
 {
     GArchInstruction *result;               /* Instruction à retourner     */
-    GArchOperand *operand;                  /* Octet non décodé à afficher */
+    GImmOperand *operand;                   /* Octet non décodé à afficher */
     mrange_t range;                         /* Couverture de l'instruction */
 
     result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL);
 
-    operand = g_imm_operand_new_from_value(size, value);
+    operand = G_IMM_OPERAND(g_imm_operand_new_from_value(size, value));
     if (operand == NULL) goto grinfv_error;
 
-    g_imm_operand_pad(G_IMM_OPERAND(operand), true);
+    g_imm_operand_pad(&operand, true, NULL);
 
-    g_arch_instruction_attach_extra_operand(result, operand);
+    g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
 
     switch (size)
     {
@@ -348,7 +348,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory
     GArchInstruction *result;               /* Instruction à retourner     */
     vmpa2t old;                             /* Sauvegarde de la position   */
     size_t i;                               /* Boucle de parcours          */
-    GArchOperand *operand;                  /* Octet non décodé à afficher */
+    GImmOperand *operand;                   /* Octet non décodé à afficher */
     mrange_t range;                         /* Couverture de l'instruction */
 
     /* Par soucis de cohérence */
@@ -360,12 +360,13 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory
 
     for (i = 0; i < count; i++)
     {
-        operand = g_imm_operand_new_from_data(size, content, addr, endian);
+        operand = G_IMM_OPERAND(g_imm_operand_new_from_data(size, content, addr, endian));
         if (operand == NULL) goto grina_error;
 
-        g_imm_operand_pad(G_IMM_OPERAND(operand), true);
+        g_imm_operand_pad(&operand, true, NULL);
+
+        g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
 
-        g_arch_instruction_attach_extra_operand(result, operand);
     }
 
     init_mrange(&range, &old, compute_vmpa_diff(addr, &old));
diff --git a/src/arch/sharing/container-int.h b/src/arch/sharing/container-int.h
index 8e4ccbd..bc67bf6 100644
--- a/src/arch/sharing/container-int.h
+++ b/src/arch/sharing/container-int.h
@@ -30,7 +30,7 @@
 
 
 /* Assure la mise à jour du contenu d'un intégrateur. */
-typedef void (* replace_shared_fc) (GShareContainer *, GSharedInstance *, GSharedInstance *);
+typedef bool (* replace_shared_fc) (GShareContainer *, GSharedInstance *, GSharedInstance *);
 
 
 /* Règles de partage d'une instance GObject (interface) */
diff --git a/src/arch/sharing/container.c b/src/arch/sharing/container.c
index f027673..5ff62b7 100644
--- a/src/arch/sharing/container.c
+++ b/src/arch/sharing/container.c
@@ -66,22 +66,28 @@ static void g_share_container_default_init(GShareContainerInterface *iface)
 *                                                                             *
 *  Description : Assure la mise à jour du contenu d'un intégrateur.           *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void g_share_container_replace(GShareContainer *container, GSharedInstance *old, GSharedInstance *new)
+bool g_share_container_replace(GShareContainer *container, GSharedInstance *old, GSharedInstance *new)
 {
+    bool result;                            /* Bilan à retourner           */
     GShareContainerIface *iface;            /* Interface utilisée          */
 
     if (old != new)
     {
         iface = G_SHARE_CONTAINER_GET_IFACE(container);
 
-        iface->replace(container, old, new);
+        result = iface->replace(container, old, new);
 
     }
 
+    else
+        result = false;
+
+    return result;
+
 }
diff --git a/src/arch/sharing/container.h b/src/arch/sharing/container.h
index 06d55a1..3312f9d 100644
--- a/src/arch/sharing/container.h
+++ b/src/arch/sharing/container.h
@@ -52,7 +52,7 @@ typedef struct _GShareContainerIface GShareContainerIface;
 GType g_share_container_get_type(void) G_GNUC_CONST;
 
 /* Assure la mise à jour du contenu d'un intégrateur. */
-void g_share_container_replace(GShareContainer *, GSharedInstance *, GSharedInstance *);
+bool g_share_container_replace(GShareContainer *, GSharedInstance *, GSharedInstance *);
 
 
 
diff --git a/src/arch/sharing/instance-int.h b/src/arch/sharing/instance-int.h
index c3ebae5..f9a91ba 100644
--- a/src/arch/sharing/instance-int.h
+++ b/src/arch/sharing/instance-int.h
@@ -32,6 +32,9 @@
 /* Initialise un nouvel objet partagé avec des informations. */
 typedef bool (* init_shared_fc) (GSharedInstance *, const GSharedInstance *);
 
+/* Procède à l'initialisation de l'interface de partage. */
+typedef void (* qck_copy_shared_fc) (const GSharedInstance *, GSharedInstance *);
+
 /* Fournit la valeur du compteur de partage. */
 typedef unsigned int (* get_shared_ref_fc) (const GSharedInstance *);
 
@@ -51,6 +54,7 @@ struct _GSharedInstanceIface
     GTypeInterface base_iface;              /* A laisser en premier        */
 
     init_shared_fc init;                    /* Initialisation de l'objet   */
+    qck_copy_shared_fc qck_copy;            /* Copie minimale des détails  */
 
     get_shared_ref_fc get_ref;              /* Obtention du compteur       */
     inc_shared_ref_fc inc_ref;              /* Incrémentation du compteur  */
diff --git a/src/arch/sharing/instance.c b/src/arch/sharing/instance.c
index abcb653..c0038aa 100644
--- a/src/arch/sharing/instance.c
+++ b/src/arch/sharing/instance.c
@@ -88,6 +88,30 @@ bool g_shared_instance_init(GSharedInstance *instance, const GSharedInstance *te
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instance = objet partagé à consulter.                        *
+*                template = informations à retrouver intégralement.           *
+*                                                                             *
+*  Description : Réalise une copie minimale d'un contenu partagé.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_shared_instance_quickly_copy(const GSharedInstance *instance, GSharedInstance *template)
+{
+    GSharedInstanceIface *iface;            /* Interface utilisée          */
+
+    iface = G_SHARED_INSTANCE_GET_IFACE(instance);
+
+    iface->qck_copy(instance, template);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instance = objet partagé à consulter.                        *
 *                                                                             *
 *  Description : Fournit la valeur du compteur de partage.                    *
 *                                                                             *
diff --git a/src/arch/sharing/instance.h b/src/arch/sharing/instance.h
index b79fa33..fdc94d7 100644
--- a/src/arch/sharing/instance.h
+++ b/src/arch/sharing/instance.h
@@ -51,6 +51,9 @@ GType g_shared_instance_get_type(void) G_GNUC_CONST;
 /* Initialise un nouvel objet partagé avec des informations. */
 bool g_shared_instance_init(GSharedInstance *, const GSharedInstance *);
 
+/* Réalise une copie minimale d'un contenu partagé. */
+void g_shared_instance_quickly_copy(const GSharedInstance *, GSharedInstance *);
+
 /* Fournit la valeur du compteur de partage. */
 unsigned int g_shared_instance_get_references(const GSharedInstance *);
 
diff --git a/src/arch/sharing/manager.c b/src/arch/sharing/manager.c
index 43e7e25..952fc33 100644
--- a/src/arch/sharing/manager.c
+++ b/src/arch/sharing/manager.c
@@ -235,8 +235,8 @@ GSharedInstance *g_share_manager_get(GShareManager *manager, GSharedInstance *te
         {
             g_shared_instance_inc_references(result);
 
-            manager->instances = (GSharedInstance **)_qinsert(manager->instances, &manager->count,
-                                                              sizeof(GSharedInstance *), &result, index);
+            manager->instances = _qinsert(manager->instances, &manager->count,
+                                          sizeof(GSharedInstance *), &result, index);
 
         }
 
@@ -276,13 +276,96 @@ GSharedInstance *g_share_manager_get(GShareManager *manager, GSharedInstance *te
 GSharedInstance *g_share_manager_update(GShareManager *manager, GSharedInstance *old, GSharedInstance *template, GShareContainer *container)
 {
     GSharedInstance *result;                /* Nouvelle instance à renvoyer*/
+    bool replaced;                          /* Remplacement effectué ?     */
 
     result = g_share_manager_get(manager, template);
 
     if (container != NULL)
-        g_share_container_replace(container, old, result);
+        replaced = g_share_container_replace(container, old, result);
+    else
+        replaced = false;
+
+    if (replaced)
+        g_share_manager_put(manager, old);
 
-    g_share_manager_put(manager, old);
+    else
+    {
+        g_share_manager_put(manager, result);
+        result = old;
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : manager  = gestionnaire d'instance à consulter.              *
+*                instance = instance partagée vouée à évoluer.                *
+*                                                                             *
+*  Description : Prépare une modification légère et locale d'un élément.      *
+*                                                                             *
+*  Retour      : Indice de l'élément prêt à être modifié.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_share_manager_prepare_light_update(GShareManager *manager, GSharedInstance *instance)
+{
+    size_t result;                          /* Indice courant à retourner  */
+#ifndef NDEBUG
+    bool found;                             /* Validation de présence      */
+#endif
+
+    g_mutex_lock(&manager->access);
+
+#ifndef NDEBUG
+
+    found = bsearch_index(&instance, manager->instances, manager->count,sizeof(GSharedInstance *),
+                          (__compar_fn_t)g_shared_instance_quickly_compare, &result);
+
+    assert(found);
+
+#else
+
+    bsearch_index(&instance, manager->instances, manager->count,sizeof(GSharedInstance *),
+                  (__compar_fn_t)g_shared_instance_quickly_compare, &result);
+
+#endif
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : manager  = gestionnaire d'instance à consulter.              *
+*                instance = instance partagée vouée à évoluer.                *
+*                index    = indice de la place de l'élément avant modifcation.*
+*                                                                             *
+*  Description : Conclut une modification légère et locale d'un élément.      *
+*                                                                             *
+*  Retour      : Indice de l'élément prêt à être modifié.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GSharedInstance *g_share_manager_complete_light_update(GShareManager *manager, GSharedInstance *instance, size_t index)
+{
+    GSharedInstance *result;                /* Nouvelle instance à renvoyer*/
+
+    manager->instances = _qdelete(manager->instances, &manager->count,
+                                  sizeof(GSharedInstance *), index);
+
+    g_mutex_unlock(&manager->access);
+
+    result = g_share_manager_get(manager, instance);
+
+    g_object_unref(G_OBJECT(instance));
 
     return result;
 
@@ -310,12 +393,12 @@ void g_share_manager_put(GShareManager *manager, GSharedInstance *shared)
 
     if (g_shared_instance_get_references(shared) == 1)
     {
-        g_object_unref(G_OBJECT(shared));
+        manager->instances = qdelete(manager->instances, &manager->count,
+                                     sizeof(GSharedInstance *),
+                                     (__compar_fn_t)g_shared_instance_quickly_compare,
+                                     &shared);
 
-        manager->instances = (GSharedInstance **)qdelete(manager->instances, &manager->count,
-                                                         sizeof(GSharedInstance *),
-                                                         (__compar_fn_t)g_shared_instance_quickly_compare,
-                                                         &shared);
+        g_object_unref(G_OBJECT(shared));
 
     }
 
diff --git a/src/arch/sharing/manager.h b/src/arch/sharing/manager.h
index 959087d..f2fcea6 100644
--- a/src/arch/sharing/manager.h
+++ b/src/arch/sharing/manager.h
@@ -65,6 +65,12 @@ GSharedInstance *g_share_manager_get(GShareManager *, GSharedInstance *);
 /* Met à jour une instance partagée. */
 GSharedInstance *g_share_manager_update(GShareManager *, GSharedInstance *, GSharedInstance *, GShareContainer *);
 
+/* Prépare une modification légère et locale d'un élément. */
+size_t g_share_manager_prepare_light_update(GShareManager *, GSharedInstance *);
+
+/* Conclut une modification légère et locale d'un élément. */
+GSharedInstance *g_share_manager_complete_light_update(GShareManager *, GSharedInstance *, size_t);
+
 /* Abandonne un usage d'une instance partagée. */
 void g_share_manager_put(GShareManager *, GSharedInstance *);
 
diff --git a/src/core/processors.c b/src/core/processors.c
index 864b066..193cd25 100644
--- a/src/core/processors.c
+++ b/src/core/processors.c
@@ -29,6 +29,7 @@
 #include <string.h>
 
 
+#include "../arch/immediate.h"
 #include "../arch/arm/v7/core.h"
 #include "../arch/arm/v7/processor.h"
 #include "../arch/dalvik/core.h"
@@ -141,7 +142,7 @@ bool load_hard_coded_processors_definitions(void)
 {
     bool result;                            /* Bilan à retourner           */
 
-    result = true;
+    result = init_imm_operand_sharing();
 
     result &= register_processor_type("armv7", "ARM v7", G_TYPE_ARMV7_PROCESSOR,
 #ifdef DEBUG_DUMP_STATS
@@ -194,6 +195,8 @@ void unload_processors_definitions(void)
     _processors_definitions = NULL;
     _processors_definitions_count = 0;
 
+    exit_imm_operand_sharing();
+
     G_UNLOCK(_pdef_access);
 
 }
@@ -319,6 +322,8 @@ void display_share_stats(GArchProcessor *proc)
 
     G_LOCK(_pdef_access);
 
+    dump_imm_operand_share_stats();
+
     for (i = 0; i < _processors_definitions_count; i++)
         if (_processors_definitions[i].instance == type)
         {
diff --git a/src/format/symbol.h b/src/format/symbol.h
index 7389195..d5c9a79 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -133,13 +133,15 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *);
  * Confort pour l'ajout de symboles basés sur des formats.
  */
 
-#define SET_IMM_DISPLAY(_ins, _op, _idx, _dsp)                          \
-    do                                                                  \
-    {                                                                   \
-        _op = g_arch_instruction_get_operand(_ins, _idx);               \
-        g_imm_operand_set_default_display(G_IMM_OPERAND(_op), _dsp);    \
-        g_imm_operand_set_display(G_IMM_OPERAND(_op), _dsp);            \
-    }                                                                   \
+#define SET_IMM_DISPLAY(_ins, _op, _idx, _dsp)                                      \
+    do                                                                              \
+    {                                                                               \
+        GImmOperand *_imm;                                                          \
+        _imm = G_IMM_OPERAND(g_arch_instruction_get_operand(_ins, _idx));           \
+        g_imm_operand_set_default_display(&_imm, _dsp, G_SHARE_CONTAINER(_ins));    \
+        g_imm_operand_set_display(&_imm, _dsp, G_SHARE_CONTAINER(_ins));            \
+        _op = G_ARCH_OPERAND(_imm);                                                 \
+    }                                                                               \
     while (0)
 
 #define ADD_RAW_AS_SYM(_fmt, _sym, _ins, _cmt, _txt)                        \
diff --git a/tools/d2c/syntax/manager.c b/tools/d2c/syntax/manager.c
index cfbf826..6857e9a 100644
--- a/tools/d2c/syntax/manager.c
+++ b/tools/d2c/syntax/manager.c
@@ -230,12 +230,14 @@ bool declare_syntax_items(const asm_syntax *syntax, int fd, const coding_bits *b
 {
     bool result;                            /* Bilan à retourner           */
     bool has_operand;                       /* Présence d'un opérande      */
+    bool has_immediate;                     /* Présence d'une conversion   */
     size_t i;                               /* Boucle de parcours          */
     syntax_item *item;                      /* Lien vers un opérande       */
 
     result = true;
 
     has_operand = false;
+    has_immediate = false;
 
     for (i = 0; i < syntax->items_count && result; i++)
     {
@@ -244,11 +246,17 @@ bool declare_syntax_items(const asm_syntax *syntax, int fd, const coding_bits *b
 
         has_operand |= (item->impact == SIT_EXT_OPERAND);
 
+        if (has_operand)
+            has_immediate = (item->flags & SIF_DECIMAL);
+
     }
 
     if (has_operand)
         dprintf(fd, "\t\tGArchOperand *op;\n");
 
+    if (has_immediate)
+        dprintf(fd, "\t\tGImmOperand *imm;\n");
+
     return result;
 
 }
@@ -355,7 +363,11 @@ bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, con
                     dprintf(fd, "\n");
 
                     if (item->flags & SIF_DECIMAL)
-                        dprintf(fd, "\t\tg_imm_operand_set_default_display(G_IMM_OPERAND(op), IOD_DEC);\n");
+                    {
+                        dprintf(fd, "\t\timm = G_IMM_OPERAND(op)\n");
+                        dprintf(fd, "\t\tg_imm_operand_set_default_display(&imm, IOD_DEC, NULL);\n");
+                        dprintf(fd, "\t\timm = G_IMM_OPERAND(op)\n");
+                    }
 
                     dprintf(fd, "\t\tg_arch_instruction_attach_extra_operand(instr, op);\n");
 
@@ -382,7 +394,11 @@ bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, con
                         dprintf(fd, "\n");
 
                         if (item->flags & SIF_DECIMAL)
-                            dprintf(fd, "\t\tg_imm_operand_set_default_display(G_IMM_OPERAND(op), IOD_DEC);\n");
+                        {
+                            dprintf(fd, "\t\timm = G_IMM_OPERAND(op)\n");
+                            dprintf(fd, "\t\tg_imm_operand_set_default_display(&imm, IOD_DEC, NULL);\n");
+                            dprintf(fd, "\t\timm = G_IMM_OPERAND(op)\n");
+                        }
 
                         dprintf(fd, "\t\tg_arch_instruction_attach_extra_operand(instr, op);\n");
 
-- 
cgit v0.11.2-87-g4458