From aaba88dea2f207de9f88f3e35ba328162a778a7e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 4 Feb 2020 17:39:31 +0100
Subject: Compressed the operands relative to immediate values.

---
 src/arch/operands/immediate.c | 437 +++++++++++++++++++++++++++++-------------
 1 file changed, 304 insertions(+), 133 deletions(-)

diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c
index 58e40aa..a63bae5 100644
--- a/src/arch/operands/immediate.c
+++ b/src/arch/operands/immediate.c
@@ -44,39 +44,77 @@
 #include "../../common/extstr.h"
 #include "../../core/logs.h"
 #include "../../format/format.h"
+#include "../../glibext/objhole.h"
 
 
 
 /* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */
 
 
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _ImmOpFlag
+{
+    IOF_ZERO_PADDING_BY_DEFAULT,            /* Bourrage avec 0 par défaut ?*/
+    IOF_ZERO_PADDING,                       /* Bourrage avec 0 ?           */
+
+} ImmOpFlag;
+
+/* Informations glissées dans la structure GObject de GArchInstruction */
+typedef union _immop_obj_extra
+{
+    struct
+    {
+        MemoryDataSize size;                /* Taille de l'opérande        */
+
+        ImmOperandDisplay def_display;      /* Type par défaut d'affichage */
+        ImmOperandDisplay display;          /* Format général d'affichage  */
+        ImmOpFlag flags;                    /* Informations diverses       */
+
+    };
+
+    gint lock;                              /* Gestion d'accès aux fanions */
+
+} immop_obj_extra;
+
 /* Définition d'un opérande de valeur numérique (instance) */
 struct _GImmOperand
 {
     GArchOperand parent;                    /* Instance parente            */
 
     uint64_t raw;                           /* Valeur transtypée           */
-    MemoryDataSize size;                    /* Taille de l'opérande        */
 
-    ImmOperandDisplay def_display;          /* Type par défaut d'affichage */
-    ImmOperandDisplay display;              /* Format général d'affichage  */
-    unsigned char misc;                     /* Informations diverses       */
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+    /**
+     * L'inclusion des informations suivantes dépend de l'architecture.
+     *
+     * Si la structure GObject possède un trou, on remplit de préférence
+     * ce dernier.
+     */
+
+    immop_obj_extra extra;                  /* Externalisation embarquée   */
+
+#endif
 
 };
 
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
 
-#define IMM_GET_DEF_ZERO_PADDING(op)      ((op)->misc & (1 << 0))
-#define IMM_SET_DEF_ZERO_PADDING(op, v)   (op)->misc = ((op)->misc & ~(1 << 0)) | ((v) ? (1 << 0) : 0)
+#   define INIT_IMM_OP_EXTRA(op) op->extra.lock = 0
 
-#define IMM_HAS_ZERO_PADDING(op)          ((op)->misc & (1 << 1))
-#define IMM_SET_ZERO_PADDING(op)          (op)->misc |= (1 << 1)
+#   define GET_IMM_OP_EXTRA(op) &op->extra
 
-#define IMM_GET_ZERO_PADDING_VALUE(op)    ((op)->misc & (1 << 2))
-#define IMM_SET_ZERO_PADDING_VALUE(op, v) (op)->misc = ((op)->misc & ~(1 << 2)) | ((v) ? (1 << 2) : 0)
+#else
 
-#define IMM_HAS_DISPLAY(op)               ((op)->misc & (1 << 3))
-#define IMM_SET_DISPLAY(op)               (op)->misc |= (1 << 3)
+#   define INIT_IMM_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op))
 
+#   define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_obj_extra)
+
+#endif
 
 /* Définition d'un opérande de valeur numérique (classe) */
 struct _GImmOperandClass
@@ -107,9 +145,6 @@ static void g_imm_operand_finalize(GImmOperand *);
 /* Compare un opérande avec un autre. */
 static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *);
 
-/* Indique si une valeur est complétée par des zéros. */
-static bool g_imm_operand_does_padding_for_display(const GImmOperand *, ImmOperandDisplay);
-
 /* Construit la chaîne de caractères correspondant à l'opérande. */
 static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]);
 
@@ -243,10 +278,9 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)
 
 static void g_imm_operand_init(GImmOperand *operand)
 {
-    operand->def_display = IOD_HEX;
-    operand->misc = 0;
+    operand->raw = 0;
 
-    IMM_SET_DEF_ZERO_PADDING(operand, false);
+    INIT_IMM_OP_EXTRA(operand);
 
 }
 
@@ -346,6 +380,7 @@ 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        */
+    immop_obj_extra *extra;                 /* Données insérées à modifier */
     uint8_t uval8;                          /* Valeur sur 8 bits           */
     uint16_t uval16;                        /* Valeur sur 16 bits          */
     uint32_t uval32;                        /* Valeur sur 32 bits          */
@@ -357,7 +392,9 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten
 
     result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
 
-    result->size = size;
+    extra = GET_IMM_OP_EXTRA(result);
+
+    extra->size = size;
 
     switch (size)
     {
@@ -454,6 +491,7 @@ 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        */
+    immop_obj_extra *extra;                 /* Données insérées à modifier */
 
     if (size == MDS_UNDEFINED)
         result = NULL;
@@ -462,7 +500,10 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
     {
         result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
 
-        result->size = size;
+        extra = GET_IMM_OP_EXTRA(result);
+
+        extra->size = size;
+
         result->raw = value;
 
     }
@@ -488,84 +529,76 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
 static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b)
 {
     int result;                             /* Bilan à retourner           */
+    immop_obj_extra *ea;                    /* Données insérées à modifier */
+    immop_obj_extra *eb;                    /* Données insérées à modifier */
 
-    if (a->size < b->size)
+    ea = GET_IMM_OP_EXTRA(a);
+    eb = GET_IMM_OP_EXTRA(b);
+
+    g_bit_lock(&ea->lock, HOLE_LOCK_BIT);
+    g_bit_lock(&eb->lock, HOLE_LOCK_BIT);
+
+    if (ea->size < eb->size)
     {
         result = -1;
-        goto gioc_done;
+        goto done;
     }
-    else if (a->size > b->size)
+    else if (ea->size > eb->size)
     {
         result = 1;
-        goto gioc_done;
+        goto done;
     }
 
     if (a->raw < b->raw)
     {
         result = -1;
-        goto gioc_done;
+        goto done;
     }
     else if (a->raw > b->raw)
     {
         result = 1;
-        goto gioc_done;
+        goto done;
     }
 
-    if (a->def_display < b->def_display)
+    if (ea->def_display < eb->def_display)
     {
         result = -1;
-        goto gioc_done;
-    }
-    else if (a->def_display > b->def_display)
+        goto done; 
+   }
+    else if (ea->def_display > eb->def_display)
     {
         result = 1;
-        goto gioc_done;
-    }
-
-    if (IMM_HAS_DISPLAY(a) != IMM_HAS_DISPLAY(b))
-    {
-        result = (IMM_HAS_DISPLAY(a) ? 1 : -1);
-        goto gioc_done;
+        goto done;
     }
 
-    if (IMM_HAS_DISPLAY(a))
+    if (ea->display < eb->display)
     {
-        if (a->display < b->display)
-        {
-            result = -1;
-            goto gioc_done;
-        }
-        else if (a->display > b->display)
-        {
-            result = 1;
-            goto gioc_done;
-        }
+        result = -1;
+        goto done;
     }
-
-    if (IMM_GET_DEF_ZERO_PADDING(a) != IMM_GET_DEF_ZERO_PADDING(b))
+    else if (ea->display > eb->display)
     {
-        result = (IMM_GET_DEF_ZERO_PADDING(a) ? 1 : -1);
-        goto gioc_done;
+        result = 1;
+        goto done;
     }
 
-    if (IMM_HAS_ZERO_PADDING(a) != IMM_HAS_ZERO_PADDING(b))
+    if (ea->flags < eb->flags)
     {
-        result = (IMM_HAS_ZERO_PADDING(a) ? 1 : -1);
-        goto gioc_done;
+        result = -1;
+        goto done;
     }
-
-    if (IMM_HAS_ZERO_PADDING(a))
+    else if (ea->flags > eb->flags)
     {
-        if (IMM_GET_ZERO_PADDING_VALUE(a) != IMM_GET_ZERO_PADDING_VALUE(b))
-        {
-            result = (IMM_GET_ZERO_PADDING_VALUE(a) ? 1 : -1);
-            goto gioc_done;
-        }
+        result = 1;
+        goto done;
     }
 
     result = 0;
 
- gioc_done:
+ done:
+
+    g_bit_unlock(&eb->lock, HOLE_LOCK_BIT);
+    g_bit_unlock(&ea->lock, HOLE_LOCK_BIT);
 
     return result;
 
@@ -586,7 +619,18 @@ static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b)
 
 MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
 {
-    return operand->size;
+    MemoryDataSize result;                  /* Taille à retourner          */
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    result = extra->size;
+
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
+    return result;
 
 }
 
@@ -608,6 +652,7 @@ MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
 bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...)
 {
     bool result;                            /* Bilan à retourner           */
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
     va_list ap;                             /* Liste des compléments       */
     uint8_t *uval8;                         /* Valeur sur 8 bits           */
     uint16_t *uval16;                       /* Valeur sur 16 bits          */
@@ -618,7 +663,12 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..
     int32_t *sval32;                        /* Valeur sur 32 bits          */
     int64_t *sval64;                        /* Valeur sur 64 bits          */
 
-    if (operand->size != size) return false;
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    if (extra->size != size)
+        goto exit;
 
     result = true;
 
@@ -668,6 +718,10 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..
 
     va_end(ap);
 
+ exit:
+
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
     return result;
 
 }
@@ -708,11 +762,20 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand)
 
 void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value)
 {
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
     assert(size != MDS_UNDEFINED);
 
-    operand->size = size;
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    extra->size = size;
+
     operand->raw = value;
 
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
 }
 
 
@@ -731,8 +794,15 @@ void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t
 bool g_imm_operand_get_default_padding(const GImmOperand *operand)
 {
     bool result;                            /* Statut à retourner          */
+    immop_obj_extra *extra;                 /* Données insérées à modifier */
 
-    result = IMM_GET_DEF_ZERO_PADDING(operand);
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    result = (extra->flags & IOF_ZERO_PADDING_BY_DEFAULT);
+
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
 
     return result;
 
@@ -754,7 +824,18 @@ bool g_imm_operand_get_default_padding(const GImmOperand *operand)
 
 void g_imm_operand_set_default_padding(GImmOperand *operand, bool state)
 {
-    IMM_SET_DEF_ZERO_PADDING(operand, state);
+    immop_obj_extra *extra;                 /* Données insérées à modifier */
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    if (state)
+        extra->flags |= IOF_ZERO_PADDING_BY_DEFAULT;
+    else
+        extra->flags &= ~IOF_ZERO_PADDING_BY_DEFAULT;
+
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
 
 }
 
@@ -774,34 +855,18 @@ void g_imm_operand_set_default_padding(GImmOperand *operand, bool state)
 
 void g_imm_operand_pad(GImmOperand *operand, bool state)
 {
-    IMM_SET_ZERO_PADDING(operand);
-    IMM_SET_ZERO_PADDING_VALUE(operand, state);
+    immop_obj_extra *extra;                 /* Données insérées à modifier */
 
-}
+    extra = GET_IMM_OP_EXTRA(operand);
 
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = structure dont le contenu est à consulter.         *
-*                                                                             *
-*  Description : Indique si une valeur est complétée par des zéros.           *
-*                                                                             *
-*  Retour      : true si des zéro sont ajoutés à l'affichage, false sinon.    *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_imm_operand_does_padding(const GImmOperand *operand)
-{
-    bool result;                            /* Statut à retourner          */
-
-    if (IMM_HAS_ZERO_PADDING(operand))
-        result = IMM_GET_ZERO_PADDING_VALUE(operand);
+    if (state)
+        extra->flags |= (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
     else
-        result = IMM_GET_DEF_ZERO_PADDING(operand);
+        extra->flags &= ~(IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
 
-    return result;
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
 
 }
 
@@ -809,7 +874,6 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : operand = structure dont le contenu est à consulter.         *
-*                display = type d'affichage à considérer.                     *
 *                                                                             *
 *  Description : Indique si une valeur est complétée par des zéros.           *
 *                                                                             *
@@ -819,20 +883,18 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)
 *                                                                             *
 ******************************************************************************/
 
-static bool g_imm_operand_does_padding_for_display(const GImmOperand *operand, ImmOperandDisplay display)
+bool g_imm_operand_does_padding(const GImmOperand *operand)
 {
     bool result;                            /* Statut à retourner          */
+    immop_obj_extra *extra;                 /* Données insérées à modifier */
 
-    result = g_imm_operand_does_padding(operand);
+    extra = GET_IMM_OP_EXTRA(operand);
 
-    if (result)
-    {
-        display = g_imm_operand_get_display(operand);
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
 
-        if (display != IOD_BIN && display != IOD_HEX)
-            result = false;
+    result = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING));
 
-    }
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
 
     return result;
 
@@ -854,7 +916,15 @@ static bool g_imm_operand_does_padding_for_display(const GImmOperand *operand, I
 
 void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display)
 {
-    operand->def_display = display;
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    extra->def_display = display;
+
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
 
 }
 
@@ -873,7 +943,18 @@ void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay d
 
 ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
 {
-    return operand->def_display;
+    ImmOperandDisplay result;               /* Affichage à retourner       */
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    result = extra->def_display;
+
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
+    return result;
 
 }
 
@@ -893,8 +974,15 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
 
 void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
 {
-    IMM_SET_DISPLAY(operand);
-    operand->display = display;
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    extra->display = display;
+
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
 
 }
 
@@ -914,11 +1002,18 @@ void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
 ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)
 {
     ImmOperandDisplay result;               /* Affichage à retourner       */
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
 
-    if (IMM_HAS_DISPLAY(operand))
-        result = operand->display;
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    if (extra->display != IOD_COUNT)
+        result = extra->display;
     else
-        result = operand->def_display;
+        result = extra->def_display;
+
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
 
     return result;
 
@@ -940,8 +1035,13 @@ ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)
 bool g_imm_operand_is_negative(const GImmOperand *operand)
 {
     bool result;                            /* Bilan à renvoyer            */
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
 
-    switch (operand->size)
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    switch (extra->size)
     {
         case MDS_4_BITS_SIGNED:
         case MDS_8_BITS_SIGNED:
@@ -959,6 +1059,8 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
             break;
     }
 
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
     return result;
 
 }
@@ -1000,6 +1102,7 @@ bool g_imm_operand_is_null(const GImmOperand *operand)
 static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE])
 {
     size_t result;                          /* Longueur à retourner        */
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
     unsigned int range;                     /* Catégorie de la taille      */
     const char *prefix;                     /* Entrée en matière           */
     const char *suffix;                     /* Sortie de matière           */
@@ -1021,7 +1124,11 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
 
     assert(display <= IOD_LAST_VALID);
 
-    range = MDS_RANGE(operand->size);
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
+    range = MDS_RANGE(extra->size);
 
     /* Encadrement pour les caractères */
     if (display == IOD_CHAR)
@@ -1060,7 +1167,15 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
 
     /* Drapeau de remplissage ? */
 
-    do_padding = g_imm_operand_does_padding_for_display(operand, display);
+    do_padding = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING));
+
+    if (do_padding)
+    {
+        if (extra->display != IOD_COUNT)
+            do_padding = (extra->display != IOD_BIN && extra->display != IOD_HEX);
+        else
+            do_padding = (extra->def_display != IOD_BIN && extra->def_display != IOD_HEX);
+    }
 
     switch (display)
     {
@@ -1086,7 +1201,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
 
     if (display != IOD_BIN)
     {
-        if (MDS_IS_SIGNED(operand->size))
+        if (MDS_IS_SIGNED(extra->size))
             conv = conv_si_defs[display];
         else
             conv = conv_us_defs[display];
@@ -1123,7 +1238,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
 
     snprintf(format, sizeof(format), "%s%s%s%s%s%s%s", prefix, alternate, intro, zpad, lmod, conv, suffix);
 
-    switch (operand->size)
+    switch (extra->size)
     {
         case MDS_UNDEFINED:
             result = snprintf(value, IMM_MAX_SIZE, "<? undef value ?>");
@@ -1176,6 +1291,8 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
 
     }
 
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
     assert(result > 0);
 
     return result;
@@ -1340,12 +1457,19 @@ static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoad
 bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos)
 {
     bool result;                            /* Bilan à renvoyer            */
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
 
-    result = !MDS_IS_SIGNED(operand->size);
+    result = !MDS_IS_SIGNED(extra->size);
 
     if (result)
         *pos = operand->raw;
 
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
     return result;
 
 }
@@ -1367,12 +1491,19 @@ bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos)
 bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr)
 {
     bool result;                            /* Bilan à renvoyer            */
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
 
-    result = !MDS_IS_SIGNED(operand->size);
+    result = !MDS_IS_SIGNED(extra->size);
 
     if (result)
         *addr = operand->raw;
 
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
     return result;
 
 }
@@ -1393,8 +1524,16 @@ bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr)
 
 void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val)
 {
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
     *val = operand->raw;
 
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
 }
 
 
@@ -1413,8 +1552,16 @@ void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val)
 
 void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val)
 {
+    immop_obj_extra *extra;                 /* Données insérées à consulter*/
+
+    extra = GET_IMM_OP_EXTRA(operand);
+
+    g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+
     *val = operand->raw;
 
+    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
 }
 
 
@@ -1499,6 +1646,7 @@ static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage
 {
     bool result;                            /* Bilan à retourner           */
     GArchOperandClass *parent;              /* Classe parente à consulter  */
+    immop_obj_extra *extra;                 /* Données insérées à modifier */
 
     parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
 
@@ -1508,16 +1656,25 @@ static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage
         result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true);
 
     if (result)
-        result = extract_packed_buffer(pbuf, &operand->size, sizeof(MemoryDataSize), true);
+    {
+        extra = GET_IMM_OP_EXTRA(operand);
 
-    if (result)
-        result = extract_packed_buffer(pbuf, &operand->def_display, sizeof(ImmOperandDisplay), true);
+        g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
 
-    if (result)
-        result = extract_packed_buffer(pbuf, &operand->display, sizeof(ImmOperandDisplay), true);
+        result = extract_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true);
 
-    if (result)
-        result = extract_packed_buffer(pbuf, &operand->misc, sizeof(uint8_t), false);
+        if (result)
+            result = extract_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true);
+
+        if (result)
+            result = extract_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true);
+
+        if (result)
+            result = extract_packed_buffer(pbuf, &extra->flags, sizeof(uint8_t), false);
+
+        g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
+    }
 
     return result;
 
@@ -1542,6 +1699,7 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto
 {
     bool result;                            /* Bilan à retourner           */
     GArchOperandClass *parent;              /* Classe parente à consulter  */
+    immop_obj_extra *extra;                 /* Données insérées à modifier */
 
     parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
 
@@ -1551,16 +1709,25 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto
         result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true);
 
     if (result)
-        result = extend_packed_buffer(pbuf, &operand->size, sizeof(MemoryDataSize), true);
+    {
+        extra = GET_IMM_OP_EXTRA(operand);
 
-    if (result)
-        result = extend_packed_buffer(pbuf, &operand->def_display, sizeof(ImmOperandDisplay), true);
+        g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
 
-    if (result)
-        result = extend_packed_buffer(pbuf, &operand->display, sizeof(ImmOperandDisplay), true);
+        result = extend_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true);
 
-    if (result)
-        result = extend_packed_buffer(pbuf, &operand->misc, sizeof(uint8_t), false);
+        if (result)
+            result = extend_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true);
+
+        if (result)
+            result = extend_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true);
+
+        if (result)
+            result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ImmOpFlag), true);
+
+        g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+
+    }
 
     return result;
 
@@ -1757,17 +1924,21 @@ static void g_known_imm_operand_finalize(GKnownImmOperand *operand)
 GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)
 {
     GKnownImmOperand *result;               /* Remplacement à retourner    */
+    immop_obj_extra *src;                   /* Données insérées à consulter*/
+    immop_obj_extra *dest;                  /* Données insérées à modifier */
 
     result = g_object_new(G_TYPE_KNOWN_IMM_OPERAND, NULL);
 
     result->parent.raw = old->raw;
 
-    result->parent.size = old->size;
-    result->parent.def_display = old->def_display;
-    result->parent.display = old->display;
-    result->parent.misc = old->misc;
+    src = GET_IMM_OP_EXTRA(old);
+    dest = GET_IMM_OP_EXTRA(&result->parent);
+
+    g_bit_lock(&src->lock, HOLE_LOCK_BIT);
+
+    *dest = *src;
 
-    result->alt_text = strdup(alt);
+    g_bit_unlock(&src->lock, HOLE_LOCK_BIT);
 
     return G_ARCH_OPERAND(result);
 
-- 
cgit v0.11.2-87-g4458