From 6183dcf34a45b7250b63add608c02e96bf53e096 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 21 Jun 2020 22:21:00 +0200
Subject: Reorganized the code for target operands.

---
 plugins/arm/v7/post.c                          |   2 +-
 plugins/dalvik/post.c                          |   2 +-
 plugins/pychrysalide/analysis/constants.c      |  58 ++
 plugins/pychrysalide/analysis/constants.h      |   3 +
 plugins/pychrysalide/arch/operands/Makefile.am |   1 +
 plugins/pychrysalide/arch/operands/module.c    |   2 +
 plugins/pychrysalide/arch/operands/target.c    | 483 +++++++++++++++++
 plugins/pychrysalide/arch/operands/target.h    |  48 ++
 src/analysis/disass/links.c                    |   2 +-
 src/arch/Makefile.am                           |   1 -
 src/arch/instructions/raw.c                    |   2 +-
 src/arch/operands/Makefile.am                  |   2 +
 src/arch/operands/target-int.h                 |  58 ++
 src/arch/operands/target.c                     | 683 ++++++++++++++++++++++++
 src/arch/operands/target.h                     |  70 +++
 src/arch/post.c                                |   2 +-
 src/arch/storage.c                             |   2 +-
 src/arch/target.c                              | 707 -------------------------
 src/arch/target.h                              |  70 ---
 src/core/processors.c                          |   3 +-
 20 files changed, 1416 insertions(+), 785 deletions(-)
 create mode 100644 plugins/pychrysalide/arch/operands/target.c
 create mode 100644 plugins/pychrysalide/arch/operands/target.h
 create mode 100644 src/arch/operands/target-int.h
 create mode 100644 src/arch/operands/target.c
 create mode 100644 src/arch/operands/target.h
 delete mode 100644 src/arch/target.c
 delete mode 100644 src/arch/target.h

diff --git a/plugins/arm/v7/post.c b/plugins/arm/v7/post.c
index 649b462..c1c299f 100644
--- a/plugins/arm/v7/post.c
+++ b/plugins/arm/v7/post.c
@@ -24,8 +24,8 @@
 #include "post.h"
 
 
-#include <arch/target.h>
 #include <arch/operands/immediate.h>
+#include <arch/operands/target.h>
 
 
 
diff --git a/plugins/dalvik/post.c b/plugins/dalvik/post.c
index 7ba7a1d..4066c80 100644
--- a/plugins/dalvik/post.c
+++ b/plugins/dalvik/post.c
@@ -27,8 +27,8 @@
 #include <assert.h>
 
 
-#include <arch/target.h>
 #include <arch/operands/immediate.h>
+#include <arch/operands/target.h>
 
 
 
diff --git a/plugins/pychrysalide/analysis/constants.c b/plugins/pychrysalide/analysis/constants.c
index 9bc3e9f..dc507dc 100644
--- a/plugins/pychrysalide/analysis/constants.c
+++ b/plugins/pychrysalide/analysis/constants.c
@@ -154,3 +154,61 @@ int convert_to_source_endian(PyObject *arg, void *dst)
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  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 constante MemoryDataSize.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_memory_data_size(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+    unsigned long value;                    /* Valeur transcrite           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 MemoryDataSize");
+            break;
+
+        case 1:
+            value = PyLong_AsUnsignedLong(arg);
+
+            if (value != MDS_UNDEFINED
+                && (value < MDS_4_BITS_UNSIGNED && value > MDS_64_BITS_UNSIGNED)
+                && (value < MDS_4_BITS_SIGNED && value > MDS_64_BITS_SIGNED))
+            {
+                PyErr_SetString(PyExc_TypeError, "invalid value for MemoryDataSize");
+                result = 0;
+            }
+
+            else
+                *((MemoryDataSize *)dst) = value;
+
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/constants.h b/plugins/pychrysalide/analysis/constants.h
index 2ab1f0a..45982bb 100644
--- a/plugins/pychrysalide/analysis/constants.h
+++ b/plugins/pychrysalide/analysis/constants.h
@@ -36,6 +36,9 @@ bool define_analysis_content_constants(PyTypeObject *);
 /* Tente de convertir en constante SourceEndian. */
 int convert_to_source_endian(PyObject *, void *);
 
+/* Tente de convertir en constante MemoryDataSize. */
+int convert_to_memory_data_size(PyObject *, void *);
+
 
 
 #endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/arch/operands/Makefile.am b/plugins/pychrysalide/arch/operands/Makefile.am
index 2074b6b..d4e9838 100644
--- a/plugins/pychrysalide/arch/operands/Makefile.am
+++ b/plugins/pychrysalide/arch/operands/Makefile.am
@@ -9,6 +9,7 @@ libpychrysaarchoperands_la_SOURCES =	\
 	proxy.h proxy.c						\
 	register.h register.c				\
 	rename.h rename.c					\
+	target.h target.c					\
 	targetable.h targetable.c
 
 libpychrysaarchoperands_la_LIBADD = 
diff --git a/plugins/pychrysalide/arch/operands/module.c b/plugins/pychrysalide/arch/operands/module.c
index 15d7835..f1669fb 100644
--- a/plugins/pychrysalide/arch/operands/module.c
+++ b/plugins/pychrysalide/arch/operands/module.c
@@ -33,6 +33,7 @@
 #include "proxy.h"
 #include "register.h"
 #include "rename.h"
+#include "target.h"
 #include "targetable.h"
 #include "../../helpers.h"
 
@@ -106,6 +107,7 @@ bool populate_arch_operands_module(void)
     if (result) result = ensure_python_register_operand_is_registered();
     if (result) result = ensure_python_renamed_operand_is_registered();
     if (result) result = ensure_python_renameable_operand_is_registered();
+    if (result) result = ensure_python_target_operand_is_registered();
     if (result) result = ensure_python_targetable_operand_is_registered();
 
     assert(result);
diff --git a/plugins/pychrysalide/arch/operands/target.c b/plugins/pychrysalide/arch/operands/target.c
new file mode 100644
index 0000000..5cd9f59
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/target.c
@@ -0,0 +1,483 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * target.c - équivalent Python du fichier "arch/operands/target.c"
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "target.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <arch/operands/target-int.h>
+#include <plugins/dt.h>
+
+
+#include "targetable.h"
+#include "../operand.h"
+#include "../../access.h"
+#include "../../helpers.h"
+#include "../../analysis/constants.h"
+#include "../../analysis/content.h"
+#include "../../arch/vmpa.h"
+#include "../../format/format.h"
+
+
+
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Accompagne la création d'une instance dérivée en Python. */
+static PyObject *py_target_operand_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Initialise la classe des descriptions de fichier binaire. */
+static void py_target_operand_init_gclass(GTargetOperandClass *, gpointer);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_target_operand_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* ------------------ OPERANDES CONSTITUANT DE PURS INTERMEDIAIRES ------------------ */
+
+
+/* Tente une résolution de symbole. */
+static PyObject *py_target_operand_resolve(PyObject *, PyObject *);
+
+/* Renseigne la taille de la valeur indiquée à la construction. */
+static PyObject *py_target_operand_get_size(PyObject *, void *);
+
+/* Fournit les indications concernant le symbole associé. */
+static PyObject *py_target_operand_get_symbol(PyObject *, void *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type du nouvel objet à mettre en place.               *
+*                args = éventuelle liste d'arguments.                         *
+*                kwds = éventuel dictionnaire de valeurs mises à disposition. *
+*                                                                             *
+*  Description : Accompagne la création d'une instance dérivée en Python.     *
+*                                                                             *
+*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_target_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Objet à retourner           */
+    PyTypeObject *base;                     /* Type de base à dériver      */
+    bool first_time;                        /* Evite les multiples passages*/
+    GType gtype;                            /* Nouveau type de processeur  */
+    bool status;                            /* Bilan d'un enregistrement   */
+
+    /* Validations diverses */
+
+    base = get_python_target_operand_type();
+
+    if (type == base)
+        goto simple_way;
+
+    /* Mise en place d'un type dédié */
+
+    first_time = (g_type_from_name(type->tp_name) == 0);
+
+    gtype = build_dynamic_type(G_TYPE_TARGET_OPERAND, type->tp_name,
+                               (GClassInitFunc)py_target_operand_init_gclass, NULL, NULL);
+
+    if (first_time)
+    {
+        status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+        if (!status)
+        {
+            result = NULL;
+            goto exit;
+        }
+
+    }
+
+    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ simple_way:
+
+    result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class  = classe à initialiser.                               *
+*                unused = données non utilisées ici.                          *
+*                                                                             *
+*  Description : Initialise la classe des descriptions de fichier binaire.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void py_target_operand_init_gclass(GTargetOperandClass *class, gpointer unused)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = objet à initialiser (théoriquement).                  *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Initialise une instance sur la base du dérivé de GObject.    *
+*                                                                             *
+*  Retour      : 0.                                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_target_operand_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    MemoryDataSize size;                    /* Taille des adresses mémoire */
+    vmpa2t *addr;                           /* Emplacement de symbole      */
+    int ret;                                /* Bilan de lecture des args.  */
+    GTargetOperand *operand;                 /* Opérande à manipuler        */
+
+#define TARGET_OPERAND_DOC                                                  \
+    "The TargetOperand object translates immediate values as symbols.\n"    \
+    "\n"                                                                    \
+    "Instances can be created using the following constructor:\n"           \
+    "\n"                                                                    \
+    "    TargetOperand(size, addr)"                                         \
+    "\n"                                                                    \
+    "Where size is a pychrysalide.analysis.BinContent.MemoryDataSize value" \
+    " describing the size of memory addresses and addr is the location of"  \
+    " a symbol to target, as a pychrysalide.arch.vmpa value."
+
+    /* Récupération des paramètres */
+
+    ret = PyArg_ParseTuple(args, "O&O&", convert_to_memory_data_size, &size, convert_any_to_vmpa, &addr);
+    if (!ret) return -1;
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    /* Eléments de base */
+
+    operand = G_TARGET_OPERAND(pygobject_get(self));
+
+    operand->size = size;
+    copy_vmpa(&operand->addr, addr);
+
+    clean_vmpa_arg(addr);
+
+    return 0;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                    OPERANDES CONSTITUANT DE PURS INTERMEDIAIRES                    */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = serveur à manipuler.                                  *
+*                args = arguments d'appel non utilisés ici.                   *
+*                                                                             *
+*  Description : Tente une résolution de symbole.                             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_target_operand_resolve(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    GBinFormat *format;                     /* Format de binaire reconnu   */
+    int strict;                             /* Perfection attendue ?       */
+    int ret;                                /* Bilan de lecture des args.  */
+    GTargetOperand *operand;                /* Version GLib de l'opérande  */
+    bool status;                            /* Bilan de l'opération        */
+
+#define TARGET_OPERAND_RESOLVE_METHOD PYTHON_METHOD_DEF             \
+(                                                                   \
+    resolve, "$self, format, strict, /",                            \
+    METH_VARARGS, py_target_operand,                                \
+    "Try to resolve the value carried by the operand as the"        \
+    " address of an existing symbol.\n"                             \
+    "\n"                                                            \
+    "The provided format has to be a pychrysalide.format.BinFormat" \
+    " instance and the *strict* argument defines if an offset is"   \
+    " allowed between the value and the symbol's address.\n"        \
+    "\n"                                                            \
+    "The result is True if the resolution is successful, False"     \
+    " otherwise."                                                   \
+)
+
+    ret = PyArg_ParseTuple(args, "O&p", convert_to_binary_format, &format, &strict);
+    if (!ret) return NULL;
+
+    operand = G_TARGET_OPERAND(pygobject_get(self));
+
+    status = g_target_operand_resolve(operand, format, strict);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Renseigne la taille de la valeur indiquée à la construction. *
+*                                                                             *
+*  Retour      : Taille de la valeur représentée en mémoire.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_target_operand_get_size(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Instance Python à retourner */
+    GTargetOperand *operand;                /* Version GLib de l'opérande  */
+    MemoryDataSize size;                    /* Taille à transmettre        */
+
+#define TARGET_OPERAND_SIZE_ATTRIB PYTHON_GET_DEF_FULL                          \
+(                                                                               \
+    size, py_target_operand,                                                    \
+    "Provide the size of the value carried by the operand.\n"                   \
+    "\n"                                                                        \
+    "The result is a pychrysalide.analysis.BinContent.MemoryDataSize value."    \
+)
+
+    operand = G_TARGET_OPERAND(pygobject_get(self));
+
+    size = g_target_operand_get_size(operand);
+
+    result = cast_with_constants_group_from_type(get_python_binary_content_type(), "MemoryDataSize", size);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit les indications concernant le symbole associé.       *
+*                                                                             *
+*  Retour      : Symbole résolu ou NULL si aucun.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_target_operand_get_symbol(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Instance Python à retourner */
+    GTargetOperand *operand;                /* Version GLib de l'opérande  */
+    GBinSymbol *symbol;                     /* Symbole attaché à l'opérande*/
+    phys_t diff;                            /* Décalage avec la base       */
+
+#define TARGET_OPERAND_SYMBOL_ATTRIB PYTHON_GET_DEF_FULL        \
+(                                                               \
+    symbol, py_target_operand,                                  \
+    "Give the resolved symbol linked to the operand.\n"         \
+    "\n"                                                        \
+    "The result is a pychrysalide.format.BinSymbol instance"    \
+    " or None."                                                 \
+)
+
+    operand = G_TARGET_OPERAND(pygobject_get(self));
+
+    symbol = g_target_operand_get_symbol(operand, &diff);
+
+    result = pygobject_new(G_OBJECT(symbol));
+    g_object_unref(symbol);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_target_operand_type(void)
+{
+    static PyMethodDef py_target_operand_methods[] = {
+        TARGET_OPERAND_RESOLVE_METHOD,
+        { NULL }
+    };
+
+    static PyGetSetDef py_target_operand_getseters[] = {
+        TARGET_OPERAND_SIZE_ATTRIB,
+        TARGET_OPERAND_SYMBOL_ATTRIB,
+        { NULL }
+    };
+
+    static PyTypeObject py_target_operand_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.arch.operands.TargetOperand",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = TARGET_OPERAND_DOC,
+
+        .tp_methods     = py_target_operand_methods,
+        .tp_getset      = py_target_operand_getseters,
+
+        .tp_init        = py_target_operand_init,
+        .tp_new         = py_target_operand_new,
+
+    };
+
+    return &py_target_operand_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.arch.ArchOperand'.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_target_operand_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ArchOperand'   */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_target_operand_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.arch.operands");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_targetable_operand_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_TARGET_OPERAND, type, get_python_arch_operand_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 opérande ciblant idéalement un symbole.*
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_target_operand(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_target_operand_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 target operand");
+            break;
+
+        case 1:
+            *((GTargetOperand **)dst) = G_TARGET_OPERAND(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/arch/operands/target.h b/plugins/pychrysalide/arch/operands/target.h
new file mode 100644
index 0000000..8463079
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/target.h
@@ -0,0 +1,48 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * target.h - prototypes pour l'équivalent Python du fichier "arch/operands/target.h"
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_TARGET_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_TARGET_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* ------------------ OPERANDES CONSTITUANT DE PURS INTERMEDIAIRES ------------------ */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_target_operand_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.arch.operands.TargetOperand'. */
+bool ensure_python_target_operand_is_registered(void);
+
+/* Tente de convertir en opérande ciblant idéalement un symbole. */
+int convert_to_target_operand(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_TARGET_H */
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index c4e7076..310da21 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -29,8 +29,8 @@
 
 #include "../../arch/instruction.h"
 #include "../../arch/instructions/raw.h"
-#include "../../arch/target.h"
 #include "../../arch/operands/immediate.h"
+#include "../../arch/operands/target.h"
 #include "../../arch/operands/targetable.h"
 
 
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index a8f9fb0..851570e 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -18,7 +18,6 @@ libarch_la_SOURCES =					\
 	register-int.h						\
 	register.h register.c				\
 	storage.h storage.c					\
-	target.h target.c					\
 	vmpa.h vmpa.c
 
 libarch_la_LIBADD =						\
diff --git a/src/arch/instructions/raw.c b/src/arch/instructions/raw.c
index 7c2535c..05eb886 100644
--- a/src/arch/instructions/raw.c
+++ b/src/arch/instructions/raw.c
@@ -33,8 +33,8 @@
 
 
 #include "../instruction-int.h"
-#include "../target.h"
 #include "../operands/immediate.h"
+#include "../operands/target.h"
 
 
 
diff --git a/src/arch/operands/Makefile.am b/src/arch/operands/Makefile.am
index 74f057d..25b4db2 100644
--- a/src/arch/operands/Makefile.am
+++ b/src/arch/operands/Makefile.am
@@ -11,6 +11,8 @@ libarchoperands_la_SOURCES =			\
 	proxy.h proxy.c						\
 	rename-int.h						\
 	rename.h rename.c					\
+	target-int.h						\
+	target.h target.c					\
 	targetable-int.h					\
 	targetable.h targetable.c
 
diff --git a/src/arch/operands/target-int.h b/src/arch/operands/target-int.h
new file mode 100644
index 0000000..f3ed447
--- /dev/null
+++ b/src/arch/operands/target-int.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * target-int.h - définitions internes propres aux opérandes ciblant un symbole
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_OPERANDS_TARGET_INT_H
+#define _ARCH_OPERANDS_TARGET_INT_H
+
+
+#include "target.h"
+#include "../operand-int.h"
+
+
+
+/* Définition d'un opérande ciblant idéalement un symbole connu (instance) */
+struct _GTargetOperand
+{
+    GArchOperand parent;                    /* Instance parente            */
+
+    MemoryDataSize size;                    /* Taille de l'opérande        */
+    vmpa2t addr;                            /* Adresse de l'élément visé   */
+
+    bool strict;                            /* Résolution stricte          */
+    /* Référence circulaire */
+    GBinSymbol *symbol;                     /* Eventuel symbole associé    */
+    phys_t diff;                            /* Position dans le symbole    */
+
+};
+
+
+/* Définition d'un opérande ciblant idéalement un symbole connu (classe) */
+struct _GTargetOperandClass
+{
+    GArchOperandClass parent;               /* Classe parente              */
+
+};
+
+
+
+#endif  /* _ARCH_OPERANDS_TARGET_INT_H */
diff --git a/src/arch/operands/target.c b/src/arch/operands/target.c
new file mode 100644
index 0000000..d921200
--- /dev/null
+++ b/src/arch/operands/target.c
@@ -0,0 +1,683 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * target.c - opérandes ciblant un symbole
+ *
+ * Copyright (C) 2014-2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "target.h"
+
+
+#include <assert.h>
+#include <inttypes.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+
+#include "immediate.h"
+#include "target-int.h"
+#include "targetable-int.h"
+#include "../../analysis/routine.h"
+#include "../../common/extstr.h"
+#include "../../format/format.h"
+#include "../../format/strsym.h"
+#include "../../glibext/gbinarycursor.h"
+
+
+
+/* Initialise la classe des opérandes ciblant des symboles. */
+static void g_target_operand_class_init(GTargetOperandClass *);
+
+/* Initialise la classe des opérandes ciblant des symboles. */
+static void g_target_operand_init(GTargetOperand *);
+
+/* Procède à l'initialisation de l'interface de ciblage. */
+static void g_target_operand_targetable_interface_init(GTargetableOperandInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_target_operand_dispose(GTargetOperand *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_target_operand_finalize(GTargetOperand *);
+
+/* Compare un opérande avec un autre. */
+static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *);
+
+/* Traduit un opérande en version humainement lisible. */
+static void g_target_operand_print(const GTargetOperand *, GBufferLine *);
+
+/* Construit un petit résumé concis de l'opérande. */
+static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *);
+
+
+
+/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+
+
+/* Charge un opérande depuis une mémoire tampon. */
+static bool g_target_operand_unserialize(GTargetOperand *, GAsmStorage *, GBinFormat *, packed_buffer *);
+
+/* Sauvegarde un opérande dans une mémoire tampon. */
+static bool g_target_operand_serialize(const GTargetOperand *, GAsmStorage *, packed_buffer *);
+
+
+
+/* ----------------------- INTERFACE DE CIBLAGE POUR OPERANDE ----------------------- */
+
+
+/* Obtient l'adresse de la cible visée par un opérande. */
+static bool g_target_operand_get_addr(const GTargetOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *);
+
+
+
+/* Indique le type défini pour un opérande de valeur numérique. */
+G_DEFINE_TYPE_WITH_CODE(GTargetOperand, g_target_operand, G_TYPE_ARCH_OPERAND,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_target_operand_targetable_interface_init));
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des opérandes ciblant des symboles.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_target_operand_class_init(GTargetOperandClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GArchOperandClass *operand;             /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+    operand = G_ARCH_OPERAND_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_target_operand_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_target_operand_finalize;
+
+    operand->compare = (operand_compare_fc)g_target_operand_compare;
+    operand->print = (operand_print_fc)g_target_operand_print;
+    operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip;
+
+    operand->unserialize = (unserialize_operand_fc)g_target_operand_unserialize;
+    operand->serialize = (serialize_operand_fc)g_target_operand_serialize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise la classe des opérandes ciblant des symboles.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_target_operand_init(GTargetOperand *operand)
+{
+    operand->size = MDS_UNDEFINED;
+    init_vmpa(&operand->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+    operand->strict = true;
+    operand->symbol = NULL;
+    operand->diff = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de ciblage.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_target_operand_targetable_interface_init(GTargetableOperandInterface *iface)
+{
+    iface->get_addr = (get_targetable_addr_fc)g_target_operand_get_addr;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_target_operand_dispose(GTargetOperand *operand)
+{
+    G_OBJECT_CLASS(g_target_operand_parent_class)->dispose(G_OBJECT(operand));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_target_operand_finalize(GTargetOperand *operand)
+{
+    G_OBJECT_CLASS(g_target_operand_parent_class)->finalize(G_OBJECT(operand));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = cmp_vmpa(&a->addr, &b->addr);
+    if (result != 0) goto gtoc_done;
+
+    if (a->size < b->size)
+    {
+        result = -1;
+        goto gtoc_done;
+    }
+    else if (a->size > b->size)
+    {
+        result = 1;
+        goto gtoc_done;
+    }
+
+    if (a->symbol == NULL && b->symbol != NULL)
+    {
+        result = -1;
+        goto gtoc_done;
+    }
+    else if (a->symbol != NULL && b->symbol == NULL)
+    {
+        result = 1;
+        goto gtoc_done;
+    }
+    else if (a->symbol != NULL && b->symbol != NULL)
+    {
+        result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol },
+                                     (const GBinSymbol *[]) { b->symbol });
+        if (result != 0) goto gtoc_done;
+    }
+
+    if (a->diff < b->diff)
+    {
+        result = -1;
+        goto gtoc_done;
+    }
+    else if (a->diff > b->diff)
+    {
+        result = 1;
+        goto gtoc_done;
+    }
+
+    result = 0;
+
+ gtoc_done:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = opérande à traiter.                                *
+*                line    = ligne tampon où imprimer l'opérande donné.         *
+*                                                                             *
+*  Description : Traduit un opérande en version humainement lisible.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *line)
+{
+    char *label;                            /* Etiquette liée à un symbole */
+    vmpa2t tmp;                             /* Coquille vide pour argument */
+    VMPA_BUFFER(value);                     /* Adresse brute à imprimer    */
+    size_t len;                             /* Taille de l'élément inséré  */
+
+    label = g_binary_symbol_get_label(operand->symbol);
+
+    if (operand->symbol != NULL && label != NULL)
+    {
+        if (operand->diff > 0)
+            g_buffer_line_append_text(line, BLC_MAIN, "<", 1, RTT_LTGT, NULL);
+
+        g_buffer_line_append_text(line, BLC_MAIN, label, strlen(label), RTT_LABEL, G_OBJECT(operand));
+
+        if (operand->diff > 0)
+        {
+            g_buffer_line_append_text(line, BLC_MAIN, "+", 1, RTT_SIGNS, G_OBJECT(operand));
+
+            init_vmpa(&tmp, operand->diff, VMPA_NO_VIRTUAL);
+            vmpa2_phys_to_string(&tmp, MDS_4_BITS, value, &len);
+
+            g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand));
+
+            g_buffer_line_append_text(line, BLC_MAIN, ">", 1, RTT_LTGT, NULL);
+
+        }
+
+    }
+    else
+    {
+        vmpa2_to_string(&operand->addr, operand->size, value, &len);
+
+        g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand));
+
+    }
+
+    if (label != NULL)
+        free(label);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : size = taille des adresse mémoire virtuelles.                *
+*                addr = localisation d'un élément à retrouver.                *
+*                                                                             *
+*  Description : Crée un opérande réprésentant une valeur numérique.          *
+*                                                                             *
+*  Retour      : Instruction mise en place.                                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)
+{
+    GTargetOperand *result;                 /* Opérande à retourner        */
+
+    result = g_object_new(G_TYPE_TARGET_OPERAND, NULL);
+
+    assert(size != MDS_UNDEFINED);
+
+    result->size = size;
+    copy_vmpa(&result->addr, addr);
+
+    return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = opérande à consulter.                              *
+*                binary  = informations relatives au binaire chargé.          *
+*                                                                             *
+*  Description : Construit un petit résumé concis de l'opérande.              *
+*                                                                             *
+*  Retour      : Chaîne de caractères à libérer après usage ou NULL.          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const GLoadedBinary *binary)
+{
+    char *result;                           /* Description à retourner     */
+    SymbolType stype;                       /* Type de symbole identifié   */
+    const mrange_t *srange;                 /* Emplacement du symbole      */
+    GBufferCache *cache;                    /* Tampon de désassemblage     */
+    GLineCursor *cursor;                    /* Emplacement dans un tampon  */
+    size_t index;                           /* Indice de ligne à traiter   */
+    GBufferLine *line;                      /* Ligne présente à l'adresse  */
+
+    result = NULL;
+
+    if (operand->symbol != NULL && operand->diff == 0)
+    {
+        stype = g_binary_symbol_get_stype(operand->symbol);
+
+        switch (stype)
+        {
+            case STP_ROUTINE:
+            case STP_ENTRY_POINT:
+                result = g_binary_routine_build_tooltip(G_BIN_ROUTINE(operand->symbol), binary);
+                break;
+
+            case STP_RO_STRING:
+            case STP_DYN_STRING:
+
+                srange = g_binary_symbol_get_range(operand->symbol);
+
+                cache = g_loaded_binary_get_disassembly_cache(binary);
+
+                cursor = g_binary_cursor_new();
+                g_binary_cursor_update(G_BINARY_CURSOR(cursor), get_mrange_addr(srange));
+
+                index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
+
+                g_object_unref(G_OBJECT(cursor));
+
+                index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
+
+                line = g_buffer_cache_find_line_by_index(cache, index);
+
+                if (line != NULL)
+                {
+                    result = g_buffer_line_get_text(line, BLC_ASSEMBLY, BLC_COUNT, true);
+                    g_object_unref(G_OBJECT(line));
+                }
+
+                g_object_unref(G_OBJECT(cache));
+
+                break;
+
+            default:
+                break;
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = structure dont le contenu est à consulter.         *
+*                                                                             *
+*  Description : Renseigne la taille de la valeur indiquée à la construction. *
+*                                                                             *
+*  Retour      : Taille de la valeur représentée en mémoire.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+MemoryDataSize g_target_operand_get_size(const GTargetOperand *operand)
+{
+    return operand->size;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = opérande dont le contenu est à raffiner. [OUT]     *
+*                format  = format du binaire d'origine à consulter.           *
+*                strict  = indique la perfection attendue de la résolution.   *
+*                                                                             *
+*  Description : Tente une résolution de symbole.                             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool strict)
+{
+    bool result;                            /* Bilan à retourner           */
+    GBinSymbol *symbol;                     /* Facilités d'accès au symbole*/
+    char *label;                            /* Désignation de la chaîne    */
+#ifndef NDEBUG
+    const mrange_t *range;                  /* Couverture du symbole       */
+#endif
+
+    operand->strict = strict;
+
+    result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff);
+
+    assert(!result || !strict || (strict && operand->diff == 0));
+
+    /**
+     * Si plusieurs chaînes se suivent, la seconde et les suivantes bénéficient
+     * d'une étiquette si et seulement si elles sont détachées des précédentes
+     * par un octet nul.
+     *
+     * S'il y a juste un retour à la ligne ("\n"), alors aucune séparation n'est
+     * considérée, et le bloc de chaînes est uniforme.
+     *
+     * Aussi, si une référence renvoie vers une ligne de ce bloc, alors on
+     * attribue à cette ligne une étiquette propre.
+     */
+
+    if (result && operand->diff == 0)
+    {
+        symbol = operand->symbol;
+
+        if (G_IS_STR_SYMBOL(symbol))
+        {
+            label = g_binary_symbol_get_label(symbol);
+
+            if (label != NULL)
+                free(label);
+
+            else
+            {
+#ifndef NDEBUG
+                range = g_binary_symbol_get_range(symbol);
+
+                assert(cmp_vmpa(&operand->addr, get_mrange_addr(range)) == 0);
+#endif
+
+                g_string_symbol_build_label(G_STR_SYMBOL(symbol), format);
+
+            }
+
+        }
+
+    }
+
+    /* Référence circulaire */
+    if (operand->symbol != NULL)
+        g_object_unref(operand->symbol);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = opérande dont le contenu est à raffiner.           *
+*                diff    = décalage entre le symbole et l'adresse initiale.   *
+*                                                                             *
+*  Description : Fournit les indications concernant le symbole associé.       *
+*                                                                             *
+*  Retour      : Symbole résolu ou NULL si aucun.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *diff)
+{
+    GBinSymbol *result;                     /* Symbole associé à retourner */
+
+    if (diff != NULL)
+        *diff = operand->diff;
+
+    result = operand->symbol;
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = opérande d'assemblage à constituer.                *
+*                storage = mécanisme de sauvegarde à manipuler.               *
+*                format  = format binaire chargé associé à l'architecture.    *
+*                pbuf    = zone tampon à remplir.                             *
+*                                                                             *
+*  Description : Charge un opérande depuis une mémoire tampon.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    assert(false);
+
+    /**
+     * Comme ce type d'opérande peut générer de nouveaux symboles lorsque
+     * sa résolution échoue, il faut appeler ces résolutions dans les contextes
+     * d'origine.
+     *
+     * Ces contextes sont généralement le lieu de conversions de valeurs immédiates
+     * en valeurs de cibles, donc la sérialisation de l'opérande conduit à
+     * la sauvegarde d'un opérande de valeur immédiate de subsitution.
+     *
+     * La désérialisation est donc prise en compte par ce dernier type d'opérande.
+     */
+
+    result = false;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = opérande d'assemblage à consulter.                 *
+*                storage = mécanisme de sauvegarde à manipuler.               *
+*                pbuf    = zone tampon à remplir.                             *
+*                                                                             *
+*  Description : Sauvegarde un opérande dans une mémoire tampon.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorage *storage, packed_buffer *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    GArchOperand *original;                 /* Opérande d'origine          */
+
+    /**
+     * Pour les architectures sans mémoire virtuelle, la valeur est portée
+     * par la position physique.
+     */
+
+    if (has_virt_addr(&operand->addr))
+        original = g_imm_operand_new_from_value(operand->size, get_virt_addr(&operand->addr));
+    else
+        original = g_imm_operand_new_from_value(operand->size, get_phy_addr(&operand->addr));
+
+    result = g_arch_operand_store(original, storage, pbuf);
+
+    g_object_unref(G_OBJECT(original));
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         INTERFACE DE CIBLAGE POUR OPERANDE                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = operande à consulter.                              *
+*                src     = localisation de l'instruction mère.                *
+*                format  = format reconnu pour le binaire chargé.             *
+*                proc    = architecture associée à ce même binaire.           *
+*                addr    = localisation de la cible. [OUT]                    *
+*                                                                             *
+*  Description : Obtient l'adresse de la cible visée par un opérande.         *
+*                                                                             *
+*  Retour      : true si la cible est valide, false sinon.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_target_operand_get_addr(const GTargetOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    copy_vmpa(addr, &operand->addr);
+
+    return result;
+
+}
diff --git a/src/arch/operands/target.h b/src/arch/operands/target.h
new file mode 100644
index 0000000..8810efa
--- /dev/null
+++ b/src/arch/operands/target.h
@@ -0,0 +1,70 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * target.h - prototypes pour les opérandes ciblant un symbole
+ *
+ * Copyright (C) 2014-2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_OPERANDS_TARGET_H
+#define _ARCH_OPERANDS_TARGET_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "../archbase.h"
+#include "../operand.h"
+#include "../vmpa.h"
+
+
+
+#define G_TYPE_TARGET_OPERAND            g_target_operand_get_type()
+#define G_TARGET_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TARGET_OPERAND, GTargetOperand))
+#define G_IS_TARGET_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TARGET_OPERAND))
+#define G_TARGET_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TARGET_OPERAND, GTargetOperandClass))
+#define G_IS_TARGET_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TARGET_OPERAND))
+#define G_TARGET_OPERAND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TARGET_OPERAND, GTargetOperandClass))
+
+
+/* Définition d'un opérande ciblant idéalement un symbole connu (instance) */
+typedef struct _GTargetOperand GTargetOperand;
+
+/* Définition d'un opérande ciblant idéalement un symbole connu (classe) */
+typedef struct _GTargetOperandClass GTargetOperandClass;
+
+
+/* Indique le type défini pour un opérande d'architecture. */
+GType g_target_operand_get_type(void);
+
+/* Crée un opérande réprésentant une valeur numérique. */
+GArchOperand *g_target_operand_new(MemoryDataSize, const vmpa2t *);
+
+/* Renseigne la taille de la valeur indiquée à la construction. */
+MemoryDataSize g_target_operand_get_size(const GTargetOperand *);
+
+/* Tente une résolution de symbole. */
+bool g_target_operand_resolve(GTargetOperand *, GBinFormat *, bool);
+
+/* Fournit les indications concernant le symbole associé. */
+GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *, phys_t *);
+
+
+
+#endif  /* _ARCH_OPERANDS_TARGET_H */
diff --git a/src/arch/post.c b/src/arch/post.c
index 11fecf5..6f6392d 100644
--- a/src/arch/post.c
+++ b/src/arch/post.c
@@ -28,8 +28,8 @@
 
 
 #include "processor.h"
-#include "target.h"
 #include "operands/immediate.h"
+#include "operands/target.h"
 #include "../analysis/routine.h"
 
 
diff --git a/src/arch/storage.c b/src/arch/storage.c
index 217d327..0995f4d 100644
--- a/src/arch/storage.c
+++ b/src/arch/storage.c
@@ -33,7 +33,7 @@
 
 
 #include "instruction.h"
-#include "target.h"
+#include "operands/target.h"
 #include "../common/compression.h"
 #include "../common/extstr.h"
 #include "../common/pathname.h"
diff --git a/src/arch/target.c b/src/arch/target.c
deleted file mode 100644
index 65fef30..0000000
--- a/src/arch/target.c
+++ /dev/null
@@ -1,707 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * target.c - opérandes ciblant un symbole
- *
- * Copyright (C) 2014-2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "target.h"
-
-
-#include <assert.h>
-#include <inttypes.h>
-#include <malloc.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-
-#include "operand-int.h"
-#include "operands/immediate.h"
-#include "operands/targetable-int.h"
-#include "../analysis/routine.h"
-#include "../common/extstr.h"
-#include "../format/format.h"
-#include "../format/strsym.h"
-#include "../glibext/gbinarycursor.h"
-
-
-
-/* Définition d'un opérande ciblant idéalement un symbole connu (instance) */
-struct _GTargetOperand
-{
-    GArchOperand parent;                    /* Instance parente            */
-
-    MemoryDataSize size;                    /* Taille de l'opérande        */
-    vmpa2t addr;                            /* Adresse de l'élément visé   */
-
-    bool strict;                            /* Résolution stricte          */
-    /* Référence circulaire */
-    GBinSymbol *symbol;                     /* Eventuel symbole associé    */
-    phys_t diff;                            /* Position dans le symbole    */
-
-};
-
-
-/* Définition d'un opérande ciblant idéalement un symbole connu (classe) */
-struct _GTargetOperandClass
-{
-    GArchOperandClass parent;               /* Classe parente              */
-
-};
-
-
-/* Initialise la classe des opérandes ciblant des symboles. */
-static void g_target_operand_class_init(GTargetOperandClass *);
-
-/* Initialise la classe des opérandes ciblant des symboles. */
-static void g_target_operand_init(GTargetOperand *);
-
-/* Procède à l'initialisation de l'interface de ciblage. */
-static void g_target_operand_targetable_interface_init(GTargetableOperandInterface *);
-
-/* Supprime toutes les références externes. */
-static void g_target_operand_dispose(GTargetOperand *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_target_operand_finalize(GTargetOperand *);
-
-/* Compare un opérande avec un autre. */
-static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *);
-
-/* Traduit un opérande en version humainement lisible. */
-static void g_target_operand_print(const GTargetOperand *, GBufferLine *);
-
-/* Construit un petit résumé concis de l'opérande. */
-static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *);
-
-
-
-/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
-
-
-/* Charge un opérande depuis une mémoire tampon. */
-static bool g_target_operand_unserialize(GTargetOperand *, GAsmStorage *, GBinFormat *, packed_buffer *);
-
-/* Sauvegarde un opérande dans une mémoire tampon. */
-static bool g_target_operand_serialize(const GTargetOperand *, GAsmStorage *, packed_buffer *);
-
-
-
-/* ----------------------- INTERFACE DE CIBLAGE POUR OPERANDE ----------------------- */
-
-
-/* Obtient l'adresse de la cible visée par un opérande. */
-static bool g_target_operand_get_addr(const GTargetOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *);
-
-
-
-/* Indique le type défini pour un opérande de valeur numérique. */
-G_DEFINE_TYPE_WITH_CODE(GTargetOperand, g_target_operand, G_TYPE_ARCH_OPERAND,
-                        G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_target_operand_targetable_interface_init));
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des opérandes ciblant des symboles.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_target_operand_class_init(GTargetOperandClass *klass)
-{
-    GObjectClass *object;                   /* Autre version de la classe  */
-    GArchOperandClass *operand;             /* Version de classe parente   */
-
-    object = G_OBJECT_CLASS(klass);
-    operand = G_ARCH_OPERAND_CLASS(klass);
-
-    object->dispose = (GObjectFinalizeFunc/* ! */)g_target_operand_dispose;
-    object->finalize = (GObjectFinalizeFunc)g_target_operand_finalize;
-
-    operand->compare = (operand_compare_fc)g_target_operand_compare;
-    operand->print = (operand_print_fc)g_target_operand_print;
-    operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip;
-
-    operand->unserialize = (unserialize_operand_fc)g_target_operand_unserialize;
-    operand->serialize = (serialize_operand_fc)g_target_operand_serialize;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = instance à initialiser.                            *
-*                                                                             *
-*  Description : Initialise la classe des opérandes ciblant des symboles.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_target_operand_init(GTargetOperand *operand)
-{
-    operand->size = MDS_UNDEFINED;
-    init_vmpa(&operand->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
-
-    operand->strict = true;
-    operand->symbol = NULL;
-    operand->diff = 0;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : iface = interface GLib à initialiser.                        *
-*                                                                             *
-*  Description : Procède à l'initialisation de l'interface de ciblage.        *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_target_operand_targetable_interface_init(GTargetableOperandInterface *iface)
-{
-    iface->get_addr = (get_targetable_addr_fc)g_target_operand_get_addr;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = instance d'objet GLib à traiter.                   *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_target_operand_dispose(GTargetOperand *operand)
-{
-    G_OBJECT_CLASS(g_target_operand_parent_class)->dispose(G_OBJECT(operand));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = instance d'objet GLib à traiter.                   *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_target_operand_finalize(GTargetOperand *operand)
-{
-    G_OBJECT_CLASS(g_target_operand_parent_class)->finalize(G_OBJECT(operand));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  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_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b)
-{
-    int result;                             /* Bilan à retourner           */
-
-    result = cmp_vmpa(&a->addr, &b->addr);
-    if (result != 0) goto gtoc_done;
-
-    if (a->size < b->size)
-    {
-        result = -1;
-        goto gtoc_done;
-    }
-    else if (a->size > b->size)
-    {
-        result = 1;
-        goto gtoc_done;
-    }
-
-    if (a->symbol == NULL && b->symbol != NULL)
-    {
-        result = -1;
-        goto gtoc_done;
-    }
-    else if (a->symbol != NULL && b->symbol == NULL)
-    {
-        result = 1;
-        goto gtoc_done;
-    }
-    else if (a->symbol != NULL && b->symbol != NULL)
-    {
-        result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol },
-                                     (const GBinSymbol *[]) { b->symbol });
-        if (result != 0) goto gtoc_done;
-    }
-
-    if (a->diff < b->diff)
-    {
-        result = -1;
-        goto gtoc_done;
-    }
-    else if (a->diff > b->diff)
-    {
-        result = 1;
-        goto gtoc_done;
-    }
-
-    result = 0;
-
- gtoc_done:
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = opérande à traiter.                                *
-*                line    = ligne tampon où imprimer l'opérande donné.         *
-*                                                                             *
-*  Description : Traduit un opérande en version humainement lisible.          *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *line)
-{
-    char *label;                            /* Etiquette liée à un symbole */
-    vmpa2t tmp;                             /* Coquille vide pour argument */
-    VMPA_BUFFER(value);                     /* Adresse brute à imprimer    */
-    size_t len;                             /* Taille de l'élément inséré  */
-
-    label = g_binary_symbol_get_label(operand->symbol);
-
-    if (operand->symbol != NULL && label != NULL)
-    {
-        if (operand->diff > 0)
-            g_buffer_line_append_text(line, BLC_MAIN, "<", 1, RTT_LTGT, NULL);
-
-        g_buffer_line_append_text(line, BLC_MAIN, label, strlen(label), RTT_LABEL, G_OBJECT(operand));
-
-        if (operand->diff > 0)
-        {
-            g_buffer_line_append_text(line, BLC_MAIN, "+", 1, RTT_SIGNS, G_OBJECT(operand));
-
-            init_vmpa(&tmp, operand->diff, VMPA_NO_VIRTUAL);
-            vmpa2_phys_to_string(&tmp, MDS_4_BITS, value, &len);
-
-            g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand));
-
-            g_buffer_line_append_text(line, BLC_MAIN, ">", 1, RTT_LTGT, NULL);
-
-        }
-
-    }
-    else
-    {
-        vmpa2_to_string(&operand->addr, operand->size, value, &len);
-
-        g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_LABEL, G_OBJECT(operand));
-
-    }
-
-    if (label != NULL)
-        free(label);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : size = taille des adresse mémoire virtuelles.                *
-*                addr = localisation d'un élément à retrouver.                *
-*                                                                             *
-*  Description : Crée un opérande réprésentant une valeur numérique.          *
-*                                                                             *
-*  Retour      : Instruction mise en place.                                   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)
-{
-    GTargetOperand *result;                 /* Opérande à retourner        */
-
-    result = g_object_new(G_TYPE_TARGET_OPERAND, NULL);
-
-    assert(size != MDS_UNDEFINED);
-
-    result->size = size;
-    copy_vmpa(&result->addr, addr);
-
-    return G_ARCH_OPERAND(result);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = opérande à consulter.                              *
-*                binary  = informations relatives au binaire chargé.          *
-*                                                                             *
-*  Description : Construit un petit résumé concis de l'opérande.              *
-*                                                                             *
-*  Retour      : Chaîne de caractères à libérer après usage ou NULL.          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const GLoadedBinary *binary)
-{
-    char *result;                           /* Description à retourner     */
-    SymbolType stype;                       /* Type de symbole identifié   */
-    const mrange_t *srange;                 /* Emplacement du symbole      */
-    GBufferCache *cache;                    /* Tampon de désassemblage     */
-    GLineCursor *cursor;                    /* Emplacement dans un tampon  */
-    size_t index;                           /* Indice de ligne à traiter   */
-    GBufferLine *line;                      /* Ligne présente à l'adresse  */
-
-    result = NULL;
-
-    if (operand->symbol != NULL && operand->diff == 0)
-    {
-        stype = g_binary_symbol_get_stype(operand->symbol);
-
-        switch (stype)
-        {
-            case STP_ROUTINE:
-            case STP_ENTRY_POINT:
-                result = g_binary_routine_build_tooltip(G_BIN_ROUTINE(operand->symbol), binary);
-                break;
-
-            case STP_RO_STRING:
-            case STP_DYN_STRING:
-
-                srange = g_binary_symbol_get_range(operand->symbol);
-
-                cache = g_loaded_binary_get_disassembly_cache(binary);
-
-                cursor = g_binary_cursor_new();
-                g_binary_cursor_update(G_BINARY_CURSOR(cursor), get_mrange_addr(srange));
-
-                index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
-
-                g_object_unref(G_OBJECT(cursor));
-
-                index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
-
-                line = g_buffer_cache_find_line_by_index(cache, index);
-
-                if (line != NULL)
-                {
-                    result = g_buffer_line_get_text(line, BLC_ASSEMBLY, BLC_COUNT, true);
-                    g_object_unref(G_OBJECT(line));
-                }
-
-                g_object_unref(G_OBJECT(cache));
-
-                break;
-
-            default:
-                break;
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = structure dont le contenu est à consulter.         *
-*                                                                             *
-*  Description : Renseigne la taille de la valeur indiquée à la construction. *
-*                                                                             *
-*  Retour      : Taille de la valeur représentée en mémoire.                  *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-MemoryDataSize g_target_operand_get_size(const GTargetOperand *operand)
-{
-    return operand->size;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = opérande dont le contenu est à raffiner. [OUT]     *
-*                format  = format du binaire d'origine à consulter.           *
-*                strict  = indique la perfection attendue de la résolution.   *
-*                                                                             *
-*  Description : Tente une résolution de symbole.                             *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool strict)
-{
-    bool result;                            /* Bilan à retourner           */
-    GBinSymbol *symbol;                     /* Facilités d'accès au symbole*/
-    char *label;                            /* Désignation de la chaîne    */
-#ifndef NDEBUG
-    const mrange_t *range;                  /* Couverture du symbole       */
-#endif
-
-    operand->strict = strict;
-
-    result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff);
-
-    assert(!result || !strict || (strict && operand->diff == 0));
-
-    /**
-     * Si plusieurs chaînes se suivent, la seconde et les suivantes bénéficient
-     * d'une étiquette si et seulement si elles sont détachées des précédentes
-     * par un octet nul.
-     *
-     * S'il y a juste un retour à la ligne ("\n"), alors aucune séparation n'est
-     * considérée, et le bloc de chaînes est uniforme.
-     *
-     * Aussi, si une référence renvoie vers une ligne de ce bloc, alors on
-     * attribue à cette ligne une étiquette propre.
-     */
-
-    if (result && operand->diff == 0)
-    {
-        symbol = operand->symbol;
-
-        if (G_IS_STR_SYMBOL(symbol))
-        {
-            label = g_binary_symbol_get_label(symbol);
-
-            if (label != NULL)
-                free(label);
-
-            else
-            {
-#ifndef NDEBUG
-                range = g_binary_symbol_get_range(symbol);
-
-                assert(cmp_vmpa(&operand->addr, get_mrange_addr(range)) == 0);
-#endif
-
-                g_string_symbol_build_label(G_STR_SYMBOL(symbol), format);
-
-            }
-
-        }
-
-    }
-
-    /* Référence circulaire */
-    if (operand->symbol != NULL)
-        g_object_unref(operand->symbol);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = opérande dont le contenu est à raffiner.           *
-*                diff    = décalage entre le symbole et l'adresse initiale.   *
-*                                                                             *
-*  Description : Fournit les indications concernant le symbole associé.       *
-*                                                                             *
-*  Retour      : Symbole résolu ou NULL si aucun.                             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *diff)
-{
-    GBinSymbol *result;                     /* Symbole associé à retourner */
-
-    if (diff != NULL)
-        *diff = operand->diff;
-
-    result = operand->symbol;
-
-    if (result != NULL)
-        g_object_ref(G_OBJECT(result));
-
-    return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = opérande d'assemblage à constituer.                *
-*                storage = mécanisme de sauvegarde à manipuler.               *
-*                format  = format binaire chargé associé à l'architecture.    *
-*                pbuf    = zone tampon à remplir.                             *
-*                                                                             *
-*  Description : Charge un opérande depuis une mémoire tampon.                *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    assert(false);
-
-    /**
-     * Comme ce type d'opérande peut générer de nouveaux symboles lorsque
-     * sa résolution échoue, il faut appeler ces résolutions dans les contextes
-     * d'origine.
-     *
-     * Ces contextes sont généralement le lieu de conversions de valeurs immédiates
-     * en valeurs de cibles, donc la sérialisation de l'opérande conduit à
-     * la sauvegarde d'un opérande de valeur immédiate de subsitution.
-     *
-     * La désérialisation est donc prise en compte par ce dernier type d'opérande.
-     */
-
-    result = false;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = opérande d'assemblage à consulter.                 *
-*                storage = mécanisme de sauvegarde à manipuler.               *
-*                pbuf    = zone tampon à remplir.                             *
-*                                                                             *
-*  Description : Sauvegarde un opérande dans une mémoire tampon.              *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorage *storage, packed_buffer *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    GArchOperand *original;                 /* Opérande d'origine          */
-
-    /**
-     * Pour les architectures sans mémoire virtuelle, la valeur est portée
-     * par la position physique.
-     */
-
-    if (has_virt_addr(&operand->addr))
-        original = g_imm_operand_new_from_value(operand->size, get_virt_addr(&operand->addr));
-    else
-        original = g_imm_operand_new_from_value(operand->size, get_phy_addr(&operand->addr));
-
-    result = g_arch_operand_store(original, storage, pbuf);
-
-    g_object_unref(G_OBJECT(original));
-
-    return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                         INTERFACE DE CIBLAGE POUR OPERANDE                         */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : operand = operande à consulter.                              *
-*                src     = localisation de l'instruction mère.                *
-*                format  = format reconnu pour le binaire chargé.             *
-*                proc    = architecture associée à ce même binaire.           *
-*                addr    = localisation de la cible. [OUT]                    *
-*                                                                             *
-*  Description : Obtient l'adresse de la cible visée par un opérande.         *
-*                                                                             *
-*  Retour      : true si la cible est valide, false sinon.                    *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_target_operand_get_addr(const GTargetOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    result = true;
-
-    copy_vmpa(addr, &operand->addr);
-
-    return result;
-
-}
diff --git a/src/arch/target.h b/src/arch/target.h
deleted file mode 100644
index 1e72ad8..0000000
--- a/src/arch/target.h
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * target.h - prototypes pour les opérandes ciblant un symbole
- *
- * Copyright (C) 2014-2018 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ARCH_TARGET_H
-#define _ARCH_TARGET_H
-
-
-#include <glib-object.h>
-#include <stdbool.h>
-
-
-#include "archbase.h"
-#include "operand.h"
-#include "vmpa.h"
-
-
-
-#define G_TYPE_TARGET_OPERAND            g_target_operand_get_type()
-#define G_TARGET_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TARGET_OPERAND, GTargetOperand))
-#define G_IS_TARGET_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TARGET_OPERAND))
-#define G_TARGET_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TARGET_OPERAND, GTargetOperandClass))
-#define G_IS_TARGET_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TARGET_OPERAND))
-#define G_TARGET_OPERAND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TARGET_OPERAND, GTargetOperandClass))
-
-
-/* Définition d'un opérande ciblant idéalement un symbole connu (instance) */
-typedef struct _GTargetOperand GTargetOperand;
-
-/* Définition d'un opérande ciblant idéalement un symbole connu (classe) */
-typedef struct _GTargetOperandClass GTargetOperandClass;
-
-
-/* Indique le type défini pour un opérande d'architecture. */
-GType g_target_operand_get_type(void);
-
-/* Crée un opérande réprésentant une valeur numérique. */
-GArchOperand *g_target_operand_new(MemoryDataSize, const vmpa2t *);
-
-/* Renseigne la taille de la valeur indiquée à la construction. */
-MemoryDataSize g_target_operand_get_size(const GTargetOperand *);
-
-/* Tente une résolution de symbole. */
-bool g_target_operand_resolve(GTargetOperand *, GBinFormat *, bool);
-
-/* Fournit les indications concernant le symbole associé. */
-GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *, phys_t *);
-
-
-
-#endif  /* _ARCH_TARGET_H */
diff --git a/src/core/processors.c b/src/core/processors.c
index 81f7494..3211009 100644
--- a/src/core/processors.c
+++ b/src/core/processors.c
@@ -29,11 +29,11 @@
 #include <string.h>
 
 
-#include "../arch/target.h"
 #include "../arch/instructions/raw.h"
 #include "../arch/instructions/undefined.h"
 #include "../arch/operands/immediate.h"
 #include "../arch/operands/register.h"
+#include "../arch/operands/target.h"
 
 
 
@@ -78,6 +78,7 @@ void register_arch_gtypes(void)
 
     g_type_ensure(G_TYPE_IMM_OPERAND);
     g_type_ensure(G_TYPE_REGISTER_OPERAND);
+    g_type_ensure(G_TYPE_TARGET_OPERAND);
 
 }
 
-- 
cgit v0.11.2-87-g4458