From 296b4ed15fd074f80266e1d22ef4ade7ee11905e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 2 Feb 2020 21:38:58 +0100
Subject: Relied on flags for raw instructions.

---
 plugins/pychrysalide/arch/constants.c   | 122 ++++++++++++++++++++++++++++++++
 plugins/pychrysalide/arch/constants.h   |   6 ++
 plugins/pychrysalide/arch/instruction.c |  40 +----------
 plugins/pychrysalide/arch/raw.c         |  94 +++++++++++++++++++-----
 plugins/pychrysalide/arch/raw.h         |   3 +
 src/arch/instruction.c                  |  39 ++++++++++
 src/arch/instruction.h                  |  11 ++-
 src/arch/raw.c                          |  43 ++++++-----
 src/arch/raw.h                          |   8 +++
 9 files changed, 294 insertions(+), 72 deletions(-)

diff --git a/plugins/pychrysalide/arch/constants.c b/plugins/pychrysalide/arch/constants.c
index 241b009..e4055c0 100644
--- a/plugins/pychrysalide/arch/constants.c
+++ b/plugins/pychrysalide/arch/constants.c
@@ -25,6 +25,7 @@
 #include "constants.h"
 
 
+#include <arch/raw.h>
 #include <arch/vmpa.h>
 
 
@@ -36,6 +37,86 @@
 *                                                                             *
 *  Paramètres  : type = type dont le dictionnaire est à compléter.            *
 *                                                                             *
+*  Description : Définit les constantes relatives aux instructions.           *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_arch_instruction_constants(PyTypeObject *type)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *values;                       /* Groupe de valeurs à établir */
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "NONE", AIF_NONE);
+    if (result) result = add_const_to_group(values, "ROUTINE_START", AIF_ROUTINE_START);
+    if (result) result = add_const_to_group(values, "RETURN_POINT", AIF_RETURN_POINT);
+    if (result) result = add_const_to_group(values, "CALL", AIF_CALL);
+    if (result) result = add_const_to_group(values, "LOW_USER", AIF_LOW_USER);
+    if (result) result = add_const_to_group(values, "HIGH_USER", AIF_HIGH_USER);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group_to_type(type, true, "ArchInstrFlag", values,
+                                            "Flags for some instruction properties.");
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "FETCH", IPH_FETCH);
+    if (result) result = add_const_to_group(values, "LINK", IPH_LINK);
+    if (result) result = add_const_to_group(values, "POST", IPH_POST);
+    if (result) result = add_const_to_group(values, "COUNT", IPH_COUNT);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group_to_type(type, false, "InstrProcessHook", values,
+                                            "Kind of hook for instruction processing after disassembling.");
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "EXEC_FLOW", ILT_EXEC_FLOW);
+    if (result) result = add_const_to_group(values, "JUMP", ILT_JUMP);
+    if (result) result = add_const_to_group(values, "CASE_JUMP", ILT_CASE_JUMP);
+    if (result) result = add_const_to_group(values, "JUMP_IF_TRUE", ILT_JUMP_IF_TRUE);
+    if (result) result = add_const_to_group(values, "JUMP_IF_FALSE", ILT_JUMP_IF_FALSE);
+    if (result) result = add_const_to_group(values, "LOOP", ILT_LOOP);
+    if (result) result = add_const_to_group(values, "CALL", ILT_CALL);
+    if (result) result = add_const_to_group(values, "CATCH_EXCEPTION", ILT_CATCH_EXCEPTION);
+    if (result) result = add_const_to_group(values, "REF", ILT_REF);
+    if (result) result = add_const_to_group(values, "COUNT", ILT_COUNT);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group_to_type(type, false, "InstructionLinkType", values,
+                                            "Kind of link between two instructions.");
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type dont le dictionnaire est à compléter.            *
+*                                                                             *
 *  Description : Définit les constantes relatives aux emplacements.           *
 *                                                                             *
 *  Retour      : true en cas de succès de l'opération, false sinon.           *
@@ -68,3 +149,44 @@ bool define_arch_vmpa_constants(PyTypeObject *type)
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type dont le dictionnaire est à compléter.            *
+*                                                                             *
+*  Description : Définit les constantes relatives aux instructions brutes.    *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_raw_instruction_constants(PyTypeObject *type)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *values;                       /* Groupe de valeurs à établir */
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "PADDING", RIF_PADDING);
+    if (result) result = add_const_to_group(values, "STRING", RIF_STRING);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group_to_type(type, true, "RawInstrFlag", values,
+                                            "Flags for some instruction properties.\n"
+                                            "\n"
+                                            "They can be seen as an extension of" \
+                                            " pychrysalide.arch.ArchInstruction.ArchInstrFlag");
+
+ exit:
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/arch/constants.h b/plugins/pychrysalide/arch/constants.h
index 5273bbd..0be832b 100644
--- a/plugins/pychrysalide/arch/constants.h
+++ b/plugins/pychrysalide/arch/constants.h
@@ -31,9 +31,15 @@
 
 
 
+/* Définit les constantes relatives aux instructions. */
+bool define_arch_instruction_constants(PyTypeObject *);
+
 /* Définit les constantes relatives aux emplacements. */
 bool define_arch_vmpa_constants(PyTypeObject *);
 
+/* Définit les constantes relatives aux instructions brutes. */
+bool define_raw_instruction_constants(PyTypeObject *);
+
 
 
 #endif  /* _PLUGINS_PYCHRYSALIDE_ARCH_CONSTANTS_H */
diff --git a/plugins/pychrysalide/arch/instruction.c b/plugins/pychrysalide/arch/instruction.c
index 757949a..3b3033f 100644
--- a/plugins/pychrysalide/arch/instruction.c
+++ b/plugins/pychrysalide/arch/instruction.c
@@ -35,6 +35,7 @@
 #include <plugins/dt.h>
 
 
+#include "constants.h"
 #include "operand.h"
 #include "vmpa.h"
 #include "../access.h"
@@ -149,9 +150,6 @@ static int py_arch_instruction_set_range(PyObject *, PyObject *, void *);
 /* Fournit le nom humain de l'instruction manipulée. */
 static PyObject *py_arch_instruction_get_keyword(PyObject *, void *);
 
-/* Définit les constantes pour les instructions. */
-static bool py_arch_instruction_define_constants(PyTypeObject *);
-
 
 
 /* ---------------------------------------------------------------------------------- */
@@ -839,40 +837,6 @@ static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *unused)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        *
-*                                                                             *
-*  Description : Définit les constantes pour les instructions.                *
-*                                                                             *
-*  Retour      : true en cas de succès de l'opération, false sinon.           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool py_arch_instruction_define_constants(PyTypeObject *obj_type)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    result = true;
-
-    result &= PyDict_AddULongMacro(obj_type, ILT_EXEC_FLOW);
-    result &= PyDict_AddULongMacro(obj_type, ILT_JUMP);
-    result &= PyDict_AddULongMacro(obj_type, ILT_CASE_JUMP);
-    result &= PyDict_AddULongMacro(obj_type, ILT_JUMP_IF_TRUE);
-    result &= PyDict_AddULongMacro(obj_type, ILT_JUMP_IF_FALSE);
-    result &= PyDict_AddULongMacro(obj_type, ILT_LOOP);
-    result &= PyDict_AddULongMacro(obj_type, ILT_CALL);
-    result &= PyDict_AddULongMacro(obj_type, ILT_CATCH_EXCEPTION);
-    result &= PyDict_AddULongMacro(obj_type, ILT_REF);
-    result &= PyDict_AddULongMacro(obj_type, ILT_COUNT);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : -                                                            *
 *                                                                             *
 *  Description : Fournit un accès à une définition de type à diffuser.        *
@@ -989,7 +953,7 @@ bool ensure_python_arch_instruction_is_registered(void)
                                            &PyGObject_Type, get_python_line_generator_type(), NULL))
             return false;
 
-        if (!py_arch_instruction_define_constants(type))
+        if (!define_arch_instruction_constants(type))
             return false;
 
     }
diff --git a/plugins/pychrysalide/arch/raw.c b/plugins/pychrysalide/arch/raw.c
index 318eb6b..da6f759 100644
--- a/plugins/pychrysalide/arch/raw.c
+++ b/plugins/pychrysalide/arch/raw.c
@@ -31,23 +31,29 @@
 #include <arch/raw.h>
 
 
+#include "constants.h"
 #include "instruction.h"
 #include "../access.h"
 #include "../helpers.h"
 
 
 
+#define RAW_INSTRUCTION_DOC                                                     \
+    "The RawInstruction object handles data which is not (yet?) disassembled"   \
+    " as code in a binary."
+
+
 /* Indique si le contenu de l'instruction est du bourrage. */
-static PyObject *py_arch_instruction_is_padding(PyObject *, void *);
+static PyObject *py_raw_instruction_get_padding(PyObject *, void *);
 
 /* Marque l'instruction comme ne contenant que du bourrage. */
-static int py_arch_instruction_mark_as_padding(PyObject *, PyObject *, void *);
+static int py_raw_instruction_set_padding(PyObject *, PyObject *, void *);
 
 /* Indique si le contenu de l'instruction est un texte. */
-static PyObject *py_arch_instruction_is_string(PyObject *, void *);
+static PyObject *py_raw_instruction_get_string(PyObject *, void *);
 
 /* Marque l'instruction comme contenant une chaîne de texte. */
-static int py_arch_instruction_mark_as_string(PyObject *, PyObject *, void *);
+static int py_raw_instruction_set_string(PyObject *, PyObject *, void *);
 
 
 
@@ -64,12 +70,18 @@ static int py_arch_instruction_mark_as_string(PyObject *, PyObject *, void *);
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_arch_instruction_is_padding(PyObject *self, void *closure)
+static PyObject *py_raw_instruction_get_padding(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Conversion à retourner      */
     GRawInstruction *instr;                 /* Version native              */
     bool state;                             /* Etat courant à consulter    */
 
+#define RAW_INSTRUCTION_PADDING_ATTRIB PYTHON_GETSET_DEF_FULL   \
+(                                                               \
+    padding, py_raw_instruction,                                \
+    "Report if the instruction is seen as padding."             \
+)
+
     instr = G_RAW_INSTRUCTION(pygobject_get(self));
 
     state = g_raw_instruction_is_padding(instr);
@@ -97,7 +109,7 @@ static PyObject *py_arch_instruction_is_padding(PyObject *self, void *closure)
 *                                                                             *
 ******************************************************************************/
 
-static int py_arch_instruction_mark_as_padding(PyObject *self, PyObject *value, void *closure)
+static int py_raw_instruction_set_padding(PyObject *self, PyObject *value, void *closure)
 {
     bool state;                             /* Nouvel état à définir       */
     GRawInstruction *instr;                 /* Version native              */
@@ -129,12 +141,18 @@ static int py_arch_instruction_mark_as_padding(PyObject *self, PyObject *value,
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_arch_instruction_is_string(PyObject *self, void *closure)
+static PyObject *py_raw_instruction_get_string(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Conversion à retourner      */
     GRawInstruction *instr;                 /* Version native              */
     bool state;                             /* Etat courant à consulter    */
 
+#define RAW_INSTRUCTION_STRING_ATTRIB PYTHON_GETSET_DEF_FULL    \
+(                                                               \
+    string, py_raw_instruction,                                 \
+    "Report if the instruction is seen as a string."            \
+)
+
     instr = G_RAW_INSTRUCTION(pygobject_get(self));
 
     state = g_raw_instruction_is_string(instr);
@@ -162,7 +180,7 @@ static PyObject *py_arch_instruction_is_string(PyObject *self, void *closure)
 *                                                                             *
 ******************************************************************************/
 
-static int py_arch_instruction_mark_as_string(PyObject *self, PyObject *value, void *closure)
+static int py_raw_instruction_set_string(PyObject *self, PyObject *value, void *closure)
 {
     bool state;                             /* Nouvel état à définir       */
     GRawInstruction *instr;                 /* Version native              */
@@ -200,14 +218,8 @@ PyTypeObject *get_python_raw_instruction_type(void)
     };
 
     static PyGetSetDef py_raw_instruction_getseters[] = {
-        {
-            "is_padding", py_arch_instruction_is_padding, py_arch_instruction_mark_as_padding,
-            "Report if the instruction is seen as padding.", NULL
-        },
-        {
-            "is_string", py_arch_instruction_is_string, py_arch_instruction_mark_as_string,
-            "Report if the instruction is seen as a string.", NULL
-        },
+        RAW_INSTRUCTION_PADDING_ATTRIB,
+        RAW_INSTRUCTION_STRING_ATTRIB,
         { NULL }
     };
 
@@ -220,7 +232,7 @@ PyTypeObject *get_python_raw_instruction_type(void)
 
         .tp_flags       = Py_TPFLAGS_DEFAULT,
 
-        .tp_doc         = "PyChrysalide raw instruction for a all architectures.",
+        .tp_doc         = RAW_INSTRUCTION_DOC,
 
         .tp_methods     = py_raw_instruction_methods,
         .tp_getset      = py_raw_instruction_getseters,
@@ -264,8 +276,56 @@ bool ensure_python_raw_instruction_is_registered(void)
         if (!register_class_for_pygobject(dict, G_TYPE_RAW_INSTRUCTION, type, get_python_arch_instruction_type()))
             return false;
 
+        if (!define_raw_instruction_constants(type))
+            return false;
+
     }
 
     return true;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en instruction brute.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_raw_instruction(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_raw_instruction_type());
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to raw instruction");
+            break;
+
+        case 1:
+            *((GRawInstruction **)dst) = G_RAW_INSTRUCTION(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/arch/raw.h b/plugins/pychrysalide/arch/raw.h
index 552db41..c73192e 100644
--- a/plugins/pychrysalide/arch/raw.h
+++ b/plugins/pychrysalide/arch/raw.h
@@ -37,6 +37,9 @@ PyTypeObject *get_python_raw_instruction_type(void);
 /* Prend en charge l'objet 'pychrysalide.arch.RawInstruction'. */
 bool ensure_python_raw_instruction_is_registered(void);
 
+/* Tente de convertir en instruction brute. */
+int convert_to_raw_instruction(PyObject *, void *);
+
 
 
 #endif  /* _PLUGINS_PYCHRYSALIDE_ARCH_RAW_H */
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index d3ac97e..1090138 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -283,6 +283,8 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
     bool result;                            /* Bilan à retourner           */
     instr_obj_extra *extra;                 /* Données insérées à modifier */
 
+    assert(flag <= AIF_HIGH_USER);
+
     extra = GET_ARCH_INSTR_EXTRA(instr);
 
     g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
@@ -300,6 +302,41 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : instr = instruction quelconque à modifier.                   *
+*                flag  = drapeau d'information complémentaire à planter.      *
+*                                                                             *
+*  Description : Retire une information complémentaire à une instruction.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
+{
+    bool result;                            /* Bilan à retourner           */
+    instr_obj_extra *extra;                 /* Données insérées à modifier */
+
+    assert(flag <= AIF_HIGH_USER);
+
+    extra = GET_ARCH_INSTR_EXTRA(instr);
+
+    g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+    extra->flags &= ~flag;
+
+    result = true;
+
+    g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : instr = instruction quelconque à consulter.                  *
 *                flag  = drapeau d'information à rechercher.                  *
 *                                                                             *
@@ -316,6 +353,8 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl
     bool result;                            /* Bilan à retourner           */
     instr_obj_extra *extra;                 /* Données insérées à consulter*/
 
+    assert(flag <= AIF_HIGH_USER);
+
     extra = GET_ARCH_INSTR_EXTRA(instr);
 
     g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 6c04acb..78f0cdb 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -54,12 +54,18 @@ typedef struct _GArchInstructionClass GArchInstructionClass;
 
 
 /* Drapeaux pour informations complémentaires */
+
+#define AIF_USER_BIT 3
+
 typedef enum _ArchInstrFlag
 {
     AIF_NONE            = (0 << 0),         /* Aucune information          */
     AIF_ROUTINE_START   = (1 << 0),         /* Début de routine            */
     AIF_RETURN_POINT    = (1 << 1),         /* Retour de fonction appelée  */
-    AIF_CALL            = (1 << 2)          /* Instruction d'appel         */
+    AIF_CALL            = (1 << 2),         /* Instruction d'appel         */
+
+    AIF_LOW_USER        = (1 << AIF_USER_BIT), /* Premier bit disponible   */
+    AIF_HIGH_USER       = (1 << 14),        /* Dernier bit disponible      */
 
 } ArchInstrFlag;
 
@@ -87,6 +93,9 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *);
 /* Ajoute une information complémentaire à une instruction. */
 bool g_arch_instruction_set_flag(GArchInstruction *, ArchInstrFlag);
 
+/* Retire une information complémentaire à une instruction. */
+bool g_arch_instruction_unset_flag(GArchInstruction *, ArchInstrFlag);
+
 /* Détermine si une instruction possède un fanion particulier. */
 bool g_arch_instruction_has_flag(const GArchInstruction *, ArchInstrFlag);
 
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 9d597fa..243752d 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -46,9 +46,6 @@ struct _GRawInstruction
 {
     GArchInstruction parent;                /* A laisser en premier        */
 
-    bool is_padding;                        /* Bourrage à représenter ?    */
-    bool is_string;                         /* Chaîne de caractères ?      */
-
 };
 
 /* Définition générique d'une instruction brute d'architecture (classe) */
@@ -450,7 +447,7 @@ static const char *g_raw_instruction_get_encoding(const GRawInstruction *instr)
 {
     const char *result;                     /* Description à retourner     */
 
-    if (instr->is_string)
+    if (g_raw_instruction_is_string(instr))
         result = _("String");
     else
         result = _("Raw");
@@ -529,7 +526,7 @@ static bool g_raw_instruction_unserialize(GRawInstruction *instr, GAsmStorage *s
         result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
 
         if (result)
-            instr->is_padding = (boolean == 1 ? true : false);
+            g_raw_instruction_mark_as_padding(instr, (boolean == 1));
 
     }
 
@@ -538,7 +535,7 @@ static bool g_raw_instruction_unserialize(GRawInstruction *instr, GAsmStorage *s
         result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
 
         if (result)
-            instr->is_string = (boolean == 1 ? true : false);
+            g_raw_instruction_mark_as_string(instr, (boolean == 1));
 
     }
 
@@ -573,13 +570,13 @@ static bool g_raw_instruction_serialize(GRawInstruction *instr, GAsmStorage *sto
 
     if (result)
     {
-        boolean = (instr->is_padding ? 1 : 0);
+        boolean = (g_raw_instruction_is_padding(instr) ? 1 : 0);
         result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
     }
 
     if (result)
     {
-        boolean = (instr->is_string ? 1 : 0);
+        boolean = (g_raw_instruction_is_string(instr) ? 1 : 0);
         result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
     }
 
@@ -636,10 +633,10 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
 
     /* Contenu */
 
-    if (instr->is_padding)
+    if (g_raw_instruction_is_padding(instr))
         max_displayed_len = 0;
 
-    else if (instr->is_string)
+    else if (g_raw_instruction_is_string(instr))
         max_displayed_len = 1;
 
     else
@@ -657,7 +654,7 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
 
     g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
 
-    if (instr->is_padding)
+    if (g_raw_instruction_is_padding(instr))
         g_buffer_line_append_text(line, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL);
 
     else
@@ -683,7 +680,7 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
             if (g_imm_operand_get_size(imm) != MDS_8_BITS)
                 goto grip_fallback;
 
-            if (!instr->is_string && g_imm_operand_get_display(imm) != IOD_CHAR)
+            if (!g_raw_instruction_is_string(instr) && g_imm_operand_get_display(imm) != IOD_CHAR)
                 goto grip_fallback;
 
 #ifndef NDEBUG
@@ -794,7 +791,10 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
 
 void g_raw_instruction_mark_as_padding(GRawInstruction *instr, bool is_padding)
 {
-    instr->is_padding = is_padding;
+    if (is_padding)
+        g_arch_instruction_set_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
+    else
+        g_arch_instruction_unset_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
 
 }
 
@@ -814,7 +814,11 @@ void g_raw_instruction_mark_as_padding(GRawInstruction *instr, bool is_padding)
 
 bool g_raw_instruction_is_padding(const GRawInstruction *instr)
 {
-    return instr->is_padding;
+    bool result;                            /* Indication à retourner      */
+
+    result = g_arch_instruction_has_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
+
+    return result;
 
 }
 
@@ -834,7 +838,10 @@ bool g_raw_instruction_is_padding(const GRawInstruction *instr)
 
 void g_raw_instruction_mark_as_string(GRawInstruction *instr, bool is_string)
 {
-    instr->is_string = is_string;
+    if (is_string)
+        g_arch_instruction_set_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
+    else
+        g_arch_instruction_unset_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
 
 }
 
@@ -854,6 +861,10 @@ void g_raw_instruction_mark_as_string(GRawInstruction *instr, bool is_string)
 
 bool g_raw_instruction_is_string(const GRawInstruction *instr)
 {
-    return instr->is_string;
+    bool result;                            /* Indication à retourner      */
+
+    result = g_arch_instruction_has_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
+
+    return result;
 
 }
diff --git a/src/arch/raw.h b/src/arch/raw.h
index aac48ea..a1c3619 100644
--- a/src/arch/raw.h
+++ b/src/arch/raw.h
@@ -66,6 +66,14 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa
 /* Crée une instruction de type 'db/dw/etc' étendue. */
 GArchInstruction *g_raw_instruction_new_array(const GBinContent *, MemoryDataSize, size_t, vmpa2t *, SourceEndian);
 
+/* Drapeaux pour informations complémentaires */
+typedef enum _RawInstrFlag
+{
+    RIF_PADDING = (1 << (AIF_USER_BIT + 0)),/* Données de bourrage         */
+    RIF_STRING  = (1 << (AIF_USER_BIT + 1)),/* Impression en chaîne        */
+
+} RawInstrFlag;
+
 /* Marque l'instruction comme ne contenant que du bourrage. */
 void g_raw_instruction_mark_as_padding(GRawInstruction *, bool);
 
-- 
cgit v0.11.2-87-g4458