From 94fd405bb0c2e6dfa43324b04a336ffb611c58ce Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 19 Mar 2017 14:02:54 +0100
Subject: Provided initial features for debugging using GDB.

---
 ChangeLog                                 |  124 +++
 configure.ac                              |    9 +-
 plugins/pychrysa/Makefile.am              |    4 +-
 plugins/pychrysa/arch/vmpa.c              |   62 ++
 plugins/pychrysa/arch/vmpa.h              |    3 +
 plugins/pychrysa/debug/Makefile.am        |    4 +
 plugins/pychrysa/debug/debugger.c         | 1111 +++++++++++++++++++--
 plugins/pychrysa/debug/debugger.h         |   17 +-
 plugins/pychrysa/debug/gdbrsp/Makefile.am |   15 +
 plugins/pychrysa/debug/gdbrsp/gdb.c       |  165 +++
 plugins/pychrysa/debug/gdbrsp/gdb.h       |   42 +
 plugins/pychrysa/debug/gdbrsp/module.c    |   86 ++
 plugins/pychrysa/debug/gdbrsp/module.h    |   39 +
 plugins/pychrysa/debug/module.c           |   39 +-
 plugins/pychrysa/debug/module.h           |    6 +-
 plugins/pychrysa/format/Makefile.am       |    1 -
 plugins/pychrysa/format/elf/elf.c         |    2 +-
 plugins/pychrysa/format/symbol.c          |    9 +-
 plugins/pychrysa/pychrysa.c               |    2 +
 src/Makefile.am                           |    1 -
 src/analysis/binary.c                     |    1 -
 src/arch/vmpa.c                           |    4 +-
 src/common/endianness.c                   |  220 ++++
 src/common/endianness.h                   |   27 +
 src/common/extstr.c                       |    4 +-
 src/common/xml.c                          |   99 +-
 src/common/xml.h                          |    9 +
 src/debug/Makefile.am                     |    6 +-
 src/debug/break-int.h                     |   64 ++
 src/debug/break.c                         |  489 ++++-----
 src/debug/break.h                         |   90 +-
 src/debug/debugger-int.h                  |  128 ++-
 src/debug/debugger.c                      | 1555 +++++++++++++++++++++++++++--
 src/debug/debugger.h                      |  193 +++-
 src/debug/gdbrsp/Makefile.am              |   24 +
 src/debug/gdbrsp/aops.h                   |   57 ++
 src/debug/gdbrsp/gdb-int.h                |  116 +++
 src/debug/gdbrsp/gdb.c                    | 1524 ++++++++++++++++++++++++++++
 src/debug/gdbrsp/gdb.h                    |   61 ++
 src/debug/gdbrsp/helpers.c                |  224 +++++
 src/debug/gdbrsp/helpers.h                |   62 ++
 src/debug/gdbrsp/helpers_arm.c            |  252 +++++
 src/debug/gdbrsp/helpers_arm.h            |   37 +
 src/debug/gdbrsp/helpers_arm64.c          |   97 ++
 src/debug/gdbrsp/helpers_arm64.h          |   40 +
 src/debug/gdbrsp/packet.c                 |  389 ++++++++
 src/debug/gdbrsp/packet.h                 |   82 ++
 src/debug/gdbrsp/stream-int.h             |   89 ++
 src/debug/gdbrsp/stream.c                 |  696 +++++++++++++
 src/debug/gdbrsp/stream.h                 |   68 ++
 src/debug/gdbrsp/support.c                |  598 +++++++++++
 src/debug/gdbrsp/support.h                |   73 ++
 src/debug/gdbrsp/target.c                 |  950 ++++++++++++++++++
 src/debug/gdbrsp/target.h                 |   72 ++
 src/debug/gdbrsp/tcp.c                    |  280 ++++++
 src/debug/gdbrsp/tcp.h                    |   57 ++
 src/debug/gdbrsp/utils.c                  |  351 +++++++
 src/debug/gdbrsp/utils.h                  |   58 ++
 src/debug/misc.h                          |   37 +
 src/debug/remgdb/Makefile.am              |   17 -
 src/debug/remgdb/gdb.c                    |  363 -------
 src/debug/remgdb/gdb.h                    |   61 --
 src/debug/remgdb/helpers.c                |  139 ---
 src/debug/remgdb/helpers.h                |   61 --
 src/debug/remgdb/packet.c                 |  383 -------
 src/debug/remgdb/packet.h                 |   82 --
 src/debug/remgdb/stream-int.h             |   74 --
 src/debug/remgdb/stream.c                 |  402 --------
 src/debug/remgdb/stream.h                 |   65 --
 src/debug/remgdb/tcp.c                    |  263 -----
 src/debug/remgdb/tcp.h                    |   56 --
 src/gtkext/gtkstatusstack.c               |   10 +
 72 files changed, 10391 insertions(+), 2509 deletions(-)
 create mode 100644 plugins/pychrysa/debug/gdbrsp/Makefile.am
 create mode 100644 plugins/pychrysa/debug/gdbrsp/gdb.c
 create mode 100644 plugins/pychrysa/debug/gdbrsp/gdb.h
 create mode 100644 plugins/pychrysa/debug/gdbrsp/module.c
 create mode 100644 plugins/pychrysa/debug/gdbrsp/module.h
 create mode 100644 src/debug/break-int.h
 create mode 100644 src/debug/gdbrsp/Makefile.am
 create mode 100644 src/debug/gdbrsp/aops.h
 create mode 100644 src/debug/gdbrsp/gdb-int.h
 create mode 100644 src/debug/gdbrsp/gdb.c
 create mode 100644 src/debug/gdbrsp/gdb.h
 create mode 100644 src/debug/gdbrsp/helpers.c
 create mode 100644 src/debug/gdbrsp/helpers.h
 create mode 100644 src/debug/gdbrsp/helpers_arm.c
 create mode 100644 src/debug/gdbrsp/helpers_arm.h
 create mode 100644 src/debug/gdbrsp/helpers_arm64.c
 create mode 100644 src/debug/gdbrsp/helpers_arm64.h
 create mode 100644 src/debug/gdbrsp/packet.c
 create mode 100644 src/debug/gdbrsp/packet.h
 create mode 100644 src/debug/gdbrsp/stream-int.h
 create mode 100644 src/debug/gdbrsp/stream.c
 create mode 100644 src/debug/gdbrsp/stream.h
 create mode 100644 src/debug/gdbrsp/support.c
 create mode 100644 src/debug/gdbrsp/support.h
 create mode 100644 src/debug/gdbrsp/target.c
 create mode 100644 src/debug/gdbrsp/target.h
 create mode 100644 src/debug/gdbrsp/tcp.c
 create mode 100644 src/debug/gdbrsp/tcp.h
 create mode 100644 src/debug/gdbrsp/utils.c
 create mode 100644 src/debug/gdbrsp/utils.h
 create mode 100644 src/debug/misc.h
 delete mode 100644 src/debug/remgdb/Makefile.am
 delete mode 100644 src/debug/remgdb/gdb.c
 delete mode 100644 src/debug/remgdb/gdb.h
 delete mode 100644 src/debug/remgdb/helpers.c
 delete mode 100644 src/debug/remgdb/helpers.h
 delete mode 100644 src/debug/remgdb/packet.c
 delete mode 100644 src/debug/remgdb/packet.h
 delete mode 100644 src/debug/remgdb/stream-int.h
 delete mode 100644 src/debug/remgdb/stream.c
 delete mode 100644 src/debug/remgdb/stream.h
 delete mode 100644 src/debug/remgdb/tcp.c
 delete mode 100644 src/debug/remgdb/tcp.h

diff --git a/ChangeLog b/ChangeLog
index b309cc1..155f8e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,127 @@
+17-03-19  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Extend AC_CONFIG_COMMANDS. Add the Makefiles from the 'plugins/pychrysa/debug',
+	'plugins/pychrysa/debug/gdbrsp' and 'src/debug/gdbrsp' directories. Remove
+	the Makefiles linked to the JDWP.
+
+	* plugins/pychrysa/Makefile.am:
+	Add debug/libpychrysadebug.la to pychrysalide_la_LIBADD. Add debug to
+	SUBDIRS.
+
+	* plugins/pychrysa/arch/vmpa.c:
+	* plugins/pychrysa/arch/vmpa.h:
+	Convert Python objects to vmpa structures.
+
+	* plugins/pychrysa/debug/Makefile.am:
+	Add gdbrsp/libpychrysadebuggdbrsp.la to libpychrysadebug_la_LIBADD and gdbrsp
+	to SUBDIRS.
+
+	* plugins/pychrysa/debug/debugger.c:
+	* plugins/pychrysa/debug/debugger.h:
+	Define Python bindings for debugging.
+
+	* plugins/pychrysa/debug/gdbrsp/Makefile.am:
+	* plugins/pychrysa/debug/gdbrsp/gdb.c:
+	* plugins/pychrysa/debug/gdbrsp/gdb.h:
+	* plugins/pychrysa/debug/gdbrsp/module.c:
+	* plugins/pychrysa/debug/gdbrsp/module.h:
+	New entries: implement bindings for the GDB remote serial protocol.
+
+	* plugins/pychrysa/debug/module.c:
+	* plugins/pychrysa/debug/module.h:
+	Update code.
+
+	* plugins/pychrysa/format/Makefile.am:
+	* plugins/pychrysa/format/elf/elf.c:
+	Typo.
+
+	* plugins/pychrysa/format/symbol.c:
+	Handle symbols without label.
+
+	* plugins/pychrysa/pychrysa.c:
+	Handle the new debug module.
+
+	* src/Makefile.am:
+	Fix libchrysadisass_la_LIBADD.
+
+	* src/analysis/binary.c:
+	* src/arch/vmpa.c:
+	Typo.
+
+	* src/common/endianness.c:
+	* src/common/endianness.h:
+	Deal with endianness in memory.
+
+	* src/common/extstr.c:
+	Fix another bug in strrpl().
+
+	* src/common/xml.c:
+	* src/common/xml.h:
+	Load XML data from memory and get the name of nodes.
+
+	* src/debug/Makefile.am:
+	Add the 'break-int.h' and 'misc.h' files to libdebug_la_SOURCES. Remove
+	jdwp/libdebugjdwp.la from libdebug_la_LIBADD and add gdbrsp/libdebuggdbrsp.la.
+
+	* src/debug/break-int.h:
+	New entry: define raw breakpoints properties.
+
+	* src/debug/break.c:
+	* src/debug/break.h:
+	Update raw breakpoints properties.
+
+	* src/debug/debugger-int.h:
+	* src/debug/debugger.c:
+	* src/debug/debugger.h:
+	Provide initial features for debugging using GDB.
+
+	* src/debug/gdbrsp/Makefile.am:
+	* src/debug/gdbrsp/aops.h:
+	* src/debug/gdbrsp/gdb-int.h:
+	* src/debug/gdbrsp/gdb.c:
+	* src/debug/gdbrsp/gdb.h:
+	* src/debug/gdbrsp/helpers.c:
+	* src/debug/gdbrsp/helpers.h:
+	* src/debug/gdbrsp/helpers_arm.c:
+	* src/debug/gdbrsp/helpers_arm.h:
+	* src/debug/gdbrsp/helpers_arm64.c:
+	* src/debug/gdbrsp/helpers_arm64.h:
+	* src/debug/gdbrsp/packet.c:
+	* src/debug/gdbrsp/packet.h:
+	* src/debug/gdbrsp/stream-int.h:
+	* src/debug/gdbrsp/stream.c:
+	* src/debug/gdbrsp/stream.h:
+	* src/debug/gdbrsp/support.c:
+	* src/debug/gdbrsp/support.h:
+	* src/debug/gdbrsp/target.c:
+	* src/debug/gdbrsp/target.h:
+	* src/debug/gdbrsp/tcp.c:
+	* src/debug/gdbrsp/tcp.h:
+	* src/debug/gdbrsp/utils.c:
+	* src/debug/gdbrsp/utils.h:
+	New entries: provide initial features for debugging using GDB.
+
+	* src/debug/misc.h:
+	Provide initial features for debugging using GDB.
+
+	* src/debug/remgdb/Makefile.am:
+	* src/debug/remgdb/gdb.c:
+	* src/debug/remgdb/gdb.h:
+	* src/debug/remgdb/helpers.c:
+	* src/debug/remgdb/helpers.h:
+	* src/debug/remgdb/packet.c:
+	* src/debug/remgdb/packet.h:
+	* src/debug/remgdb/stream-int.h:
+	* src/debug/remgdb/stream.c:
+	* src/debug/remgdb/stream.h:
+	* src/debug/remgdb/tcp.c:
+	* src/debug/remgdb/tcp.h:
+	Replaced entries.
+
+	* src/gtkext/gtkstatusstack.c:
+	Allow the status bar to be used from Python bindings.
+
 17-03-15  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/area.c:
diff --git a/configure.ac b/configure.ac
index b646361..60cf9c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -309,7 +309,7 @@ AC_SUBST(LIBPYGOBJECT_LIBS)
 
 AC_CONFIG_FILES([stamp-h po/Makefile.in], [echo timestamp > stamp-h])
 
-AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM\nVOID:BOOLEAN,ULONG,ULONG" > src/glibext/chrysamarshal.list])
+AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM\nVOID:BOOLEAN,UINT64\nVOID:BOOLEAN,ULONG,ULONG\nVOID:INT,INT" > src/glibext/chrysamarshal.list])
 
 AC_CONFIG_FILES([Makefile
                  pixmaps/Makefile
@@ -327,6 +327,8 @@ AC_CONFIG_FILES([Makefile
                  plugins/pychrysa/arch/arm/v7/Makefile
                  plugins/pychrysa/common/Makefile
                  plugins/pychrysa/core/Makefile
+                 plugins/pychrysa/debug/Makefile
+                 plugins/pychrysa/debug/gdbrsp/Makefile
                  plugins/pychrysa/format/Makefile
                  plugins/pychrysa/format/dex/Makefile
                  plugins/pychrysa/format/elf/Makefile
@@ -365,10 +367,7 @@ AC_CONFIG_FILES([Makefile
                  src/common/Makefile
                  src/core/Makefile
                  src/debug/Makefile
-                 src/debug/jdwp/Makefile
-                 src/debug/jdwp/misc/Makefile
-                 src/debug/jdwp/sets/Makefile
-                 src/debug/remgdb/Makefile
+                 src/debug/gdbrsp/Makefile
                  src/format/Makefile
                  src/format/dex/Makefile
                  src/format/dwarf/Makefile
diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am
index 7ab98fa..8bc5e0c 100644
--- a/plugins/pychrysa/Makefile.am
+++ b/plugins/pychrysa/Makefile.am
@@ -13,6 +13,7 @@ pychrysalide_la_LIBADD =				\
 	arch/libpychrysaarch.la				\
 	common/libpychrysacommon.la			\
 	core/libpychrysacore.la				\
+	debug/libpychrysadebug.la			\
 	format/libpychrysaformat.la			\
 	glibext/libpychrysaglibext.la		\
 	gtkext/libpychrysagtkext.la			\
@@ -29,5 +30,4 @@ AM_CPPFLAGS = $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(LIBGTK_CFLAGS) $(LIBX
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = analysis arch common core format glibext gtkext gui
-#SUBDIRS = analysis arch common core debug format glibext gtkext gui
+SUBDIRS = analysis arch common core debug format glibext gtkext gui
diff --git a/plugins/pychrysa/arch/vmpa.c b/plugins/pychrysa/arch/vmpa.c
index d747f8d..10acf35 100644
--- a/plugins/pychrysa/arch/vmpa.c
+++ b/plugins/pychrysa/arch/vmpa.c
@@ -729,6 +729,68 @@ PyObject *build_from_internal_vmpa(const vmpa2t *addr)
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  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 adresse n'importe quoi.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_any_to_vmpa(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+    int ret;                                /* Test intermédiaire          */
+    vmpa2t *src;                            /* Modèle de données à copier  */
+    PY_LONG_LONG value;                     /* Valeur de type générique    */
+    int overflow;                           /* Détection d'une grosse val. */
+
+    result = 0;
+
+    /* Si l'objet est au bon format, rien à faire ! */
+
+    ret = PyObject_IsInstance(arg, (PyObject *)get_python_vmpa_type());
+
+    if (ret == 1)
+    {
+        src = get_internal_vmpa(arg);
+        copy_vmpa((vmpa2t *)dst, src);
+
+        result = 1;
+        goto catv_done;
+
+    }
+
+    /* Sinon on demande à Python... */
+
+    value = PyLong_AsLongLongAndOverflow(arg, &overflow);
+
+    if (value == -1 && (overflow == 1 || PyErr_Occurred()))
+        PyErr_Clear();
+
+    else
+    {
+        init_vmpa((vmpa2t *)dst, VMPA_NO_PHYSICAL, value);
+
+        result = 1;
+        goto catv_done;
+
+    }
+
+    PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to vmpa");
+
+ catv_done:
+
+    return result;
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                          DEFINITION D'UNE ZONE EN MEMOIRE                          */
diff --git a/plugins/pychrysa/arch/vmpa.h b/plugins/pychrysa/arch/vmpa.h
index 793f24a..46828f5 100644
--- a/plugins/pychrysa/arch/vmpa.h
+++ b/plugins/pychrysa/arch/vmpa.h
@@ -46,6 +46,9 @@ vmpa2t *get_internal_vmpa(PyObject *);
 /* Convertit une structure de type 'vmpa2t' en objet Python. */
 PyObject *build_from_internal_vmpa(const vmpa2t *);
 
+/* Tente de convertir en adresse n'importe quoi. */
+int convert_any_to_vmpa(PyObject *, void *);
+
 
 
 /* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */
diff --git a/plugins/pychrysa/debug/Makefile.am b/plugins/pychrysa/debug/Makefile.am
index 503d228..8011c49 100644
--- a/plugins/pychrysa/debug/Makefile.am
+++ b/plugins/pychrysa/debug/Makefile.am
@@ -5,6 +5,8 @@ libpychrysadebug_la_SOURCES =		\
 	debugger.h debugger.c			\
 	module.h module.c
 
+libpychrysadebug_la_LIBADD =		\
+	gdbrsp/libpychrysadebuggdbrsp.la
 
 libpychrysadebug_la_LDFLAGS = 
 
@@ -13,3 +15,5 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE
 	-I../../../src
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = gdbrsp
diff --git a/plugins/pychrysa/debug/debugger.c b/plugins/pychrysa/debug/debugger.c
index fb55f65..6f930a4 100644
--- a/plugins/pychrysa/debug/debugger.c
+++ b/plugins/pychrysa/debug/debugger.c
@@ -25,85 +25,741 @@
 #include "debugger.h"
 
 
-#if 0
+#include <assert.h>
 #include <malloc.h>
 #include <pygobject.h>
 
 
-#include "../quirks.h"
+#include <debug/debugger.h>
 
 
+#include "../helpers.h"
+#include "../arch/vmpa.h"
 
-/* Crée un nouvel objet Python de type 'BinaryDebugger'. */
-static PyObject *py_binary_debugger_new(PyTypeObject *, PyObject *, PyObject *);
 
-/*  Fournit les identifiants de tous les threads actifs. */
+
+
+
+/* Fournit les identifiants de tous les threads actifs. */
 static PyObject *py_binary_debugger_list_all_threads(PyObject *, PyObject *);
 
-/* Fournit la pile d'exécution courante via un débogueur. */
-static PyObject *py_binary_debugger_get_frames_stack(PyObject *, PyObject *);
 
 
+/* Lit une valeur de 8 bits à une adresse arbitraire. */
+static PyObject *py_binary_debugger_read_memory_u8(PyObject *, PyObject *);
+
+/* Lit une valeur de 16 bits à une adresse arbitraire. */
+static PyObject *py_binary_debugger_read_memory_u16(PyObject *, PyObject *);
+
+/* Lit une valeur de 32 bits à une adresse arbitraire. */
+static PyObject *py_binary_debugger_read_memory_u32(PyObject *, PyObject *);
+
+/* Lit une valeur de 64 bits à une adresse arbitraire. */
+static PyObject *py_binary_debugger_read_memory_u64(PyObject *, PyObject *);
+
+/* Liste l'ensemble des registres appartenant à un groupe. */
+static PyObject *py_binary_debugger_get_register_names(PyObject *, PyObject *);
+
+/* Indique la taille associée à un registre donné. */
+static PyObject *py_binary_debugger_get_register_size(PyObject *, PyObject *);
+
+/* Lit une valeur de 8 bits à partir d'un registre. */
+static PyObject *py_binary_debugger_read_register_u8(PyObject *, PyObject *);
+
+/* Lit une valeur de 16 bits à partir d'un registre. */
+static PyObject *py_binary_debugger_read_register_u16(PyObject *, PyObject *);
+
+/* Lit une valeur de 32 bits à partir d'un registre. */
+static PyObject *py_binary_debugger_read_register_u32(PyObject *, PyObject *);
+
+/* Lit une valeur de 64 bits à partir d'un registre. */
+static PyObject *py_binary_debugger_read_register_u64(PyObject *, PyObject *);
+
+/* Ecrit une valeur de 8 bits dans un registre. */
+static PyObject *py_binary_debugger_write_register_u8(PyObject *, PyObject *);
+
+/* Ecrit une valeur de 16 bits dans un registre. */
+static PyObject *py_binary_debugger_write_register_u16(PyObject *, PyObject *);
+
+/* Ecrit une valeur de 32 bits dans un registre. */
+static PyObject *py_binary_debugger_write_register_u32(PyObject *, PyObject *);
+
+/* Ecrit une valeur de 64 bits dans un registre. */
+static PyObject *py_binary_debugger_write_register_u64(PyObject *, PyObject *);
+
+
+
+/* Remonte la pile d'appels jusqu'au point courant. */
+static PyObject *py_binary_debugger_get_call_stack(PyObject *, PyObject *);
+
+
+
+/* Ajoute un point d'arrêt basique en mémoire. */
+static PyObject *py_binary_debugger_add_mem_bp(PyObject *, PyObject *);
+
+/* Retire un point d'arrêt basique en mémoire. */
+static PyObject *py_binary_debugger_delete_mem_bp(PyObject *, PyObject *);
+
+
+
+/* Redémarre le processus de débogage. */
+static PyObject *py_binary_debugger_restart(PyObject *, PyObject *);
+
+/* Remet en marche le débogueur courant. */
+static PyObject *py_binary_debugger_resume(PyObject *, PyObject *);
+
+/* Relance l'exécution pour une seule instruction. */
+static PyObject *py_binary_debugger_stepi(PyObject *, PyObject *);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments non utilisés ici.                           *
+*                                                                             *
+*  Description : Fournit les identifiants de tous les threads actifs.         *
+*                                                                             *
+*  Retour      : Liste contenant identifiants et désignations de threads.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_list_all_threads(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    size_t count;                           /* Quantité de threads actifs  */
+    dbg_thread_desc *threads;               /* Liste des threads actifs    */
+    size_t i;                               /* Boucle de parcours          */
+    PyObject *thread;                       /* Détails sur un thread donné */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    threads = g_binary_debugger_list_all_threads(debugger, &count);
+
+    result = PyTuple_New(count);
+
+    for (i = 0; i < count; i++)
+    {
+        thread = PyTuple_New(2);
+        PyTuple_SetItem(result, i, thread);
+
+        PyTuple_SetItem(thread, 0, PyLong_FromLong(threads[i].id));
+        PyTuple_SetItem(thread, 1, PyUnicode_FromString(threads[i].name));
+
+    }
+
+    delete_dbg_thread_desc(threads, count);
+
+    return result;
+
+}
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Lit une valeur de 8 bits à une adresse arbitraire.           *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_memory_u8(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    int ret;                                /* Bilan de lecture des args.  */
+    vmpa2t addr;                            /* Position interne associée   */
+    uint8_t value;                          /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_read_memory_u8(debugger, get_virt_addr(&addr), &value);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong(value);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Lit une valeur de 16 bits à une adresse arbitraire.          *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_memory_u16(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    int ret;                                /* Bilan de lecture des args.  */
+    vmpa2t addr;                            /* Position interne associée   */
+    uint16_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_read_memory_u16(debugger, get_virt_addr(&addr), &value);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong(value);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Lit une valeur de 32 bits à une adresse arbitraire.          *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_memory_u32(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    int ret;                                /* Bilan de lecture des args.  */
+    vmpa2t addr;                            /* Position interne associée   */
+    uint32_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_read_memory_u32(debugger, get_virt_addr(&addr), &value);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong(value);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Lit une valeur de 64 bits à une adresse arbitraire.          *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_memory_u64(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    int ret;                                /* Bilan de lecture des args.  */
+    vmpa2t addr;                            /* Position interne associée   */
+    uint64_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_read_memory_u64(debugger, get_virt_addr(&addr), &value);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong(value);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = instance de débogueur à consulter.                    *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Liste l'ensemble des registres appartenant à un groupe.      *
+*                                                                             *
+*  Retour      : Liste de noms à libérer de la mémoire après utilisation.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_get_register_names(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    const char *group;                      /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    char **list;                            /* Liste de noms de registre   */
+    size_t count;                           /* Taille de cette liste       */
+    size_t i;                               /* Boucle de parcours          */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "|s", &group);
+    if (!ret) return NULL;
+
+    list = g_binary_debugger_get_register_names(debugger, group, &count);
+
+    result = PyTuple_New(count);
+
+    for (i = 0; i < count; i++)
+    {
+        PyTuple_SetItem(result, i, PyUnicode_FromString(list[i]));
+        free(list[i]);
+    }
+
+    if (list != NULL)
+        free(list);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = instance de débogueur à consulter.                    *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Indique la taille associée à un registre donné.              *
+*                                                                             *
+*  Retour      : Taille en bits, ou 0 si le registre n'a pas été trouvé.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_get_register_size(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    unsigned int size;                      /* Taille associée au registre */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "s", &reg);
+    if (!ret) return NULL;
+
+    size = g_binary_debugger_get_register_size(debugger, reg);
+
+    result = PyLong_FromUnsignedLong(size);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Lit une valeur de 8 bits à partir d'un registre.             *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_register_u8(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    uint8_t value;                          /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "s", &reg);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_read_register_u8(debugger, reg, &value);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong(value);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Lit une valeur de 16 bits à partir d'un registre.            *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_register_u16(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    uint16_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "s", &reg);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_read_register_u16(debugger, reg, &value);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong(value);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Lit une valeur de 32 bits à partir d'un registre.            *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_register_u32(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    uint32_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "s", &reg);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_read_register_u32(debugger, reg, &value);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong(value);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Lit une valeur de 64 bits à partir d'un registre.            *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_read_register_u64(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    uint64_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "s", &reg);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_read_register_u64(debugger, reg, &value);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong(value);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Ecrit une valeur de 8 bits dans un registre.                 *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_write_register_u8(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    uint8_t value;                          /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "sB", &reg, &value);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_write_register_u8(debugger, reg, &value);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : type = type de l'objet à instancier.                         *
-*                args = arguments fournis à l'appel.                          *
-*                kwds = arguments de type key=val fournis.                    *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
 *                                                                             *
-*  Description : Crée un nouvel objet Python de type 'BinaryDebugger'.        *
+*  Description : Ecrit une valeur de 16 bits dans un registre.                *
 *                                                                             *
-*  Retour      : Instance Python mise en place.                               *
+*  Retour      : Valeur lue ou None.                                          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_binary_debugger_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static PyObject *py_binary_debugger_write_register_u16(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Instance à retourner        */
-    DebuggerType dtype;                     /* Type de débogueur à créer   */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
     int ret;                                /* Bilan de lecture des args.  */
+    uint16_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "sH", &reg, &value);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_write_register_u16(debugger, reg, &value);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Ecrit une valeur de 32 bits dans un registre.                *
+*                                                                             *
+*  Retour      : Valeur lue ou None.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_write_register_u32(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
     GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    uint32_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
 
-    ret = PyArg_ParseTuple(args, "l", &dtype);
-    if (!ret) Py_RETURN_NONE;
+    ret = PyArg_ParseTuple(args, "sI", &reg, &value);
+    if (!ret) return NULL;
 
-    debugger = g_new_binary_debugger(dtype, NULL/* FIXME */);
+    status = g_binary_debugger_write_register_u32(debugger, reg, &value);
 
-    result = py_binary_debugger_from_c(debugger);
-    g_object_unref(debugger);
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
 
-    return (PyObject *)result;
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : debugger = instance existante GLib.                          *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
 *                                                                             *
-*  Description : Crée un nouvel objet Python de type 'BinaryDebugger'.        *
+*  Description : Ecrit une valeur de 64 bits dans un registre.                *
 *                                                                             *
-*  Retour      : Instance Python mise en place.                               *
+*  Retour      : Valeur lue ou None.                                          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-PyObject *py_binary_debugger_from_c(GBinaryDebugger *debugger)
+static PyObject *py_binary_debugger_write_register_u64(PyObject *self, PyObject *args)
 {
-    PyObject *module;                       /* Module d'appartenance       */
-    PyTypeObject *type;                     /* Type Python correspondant   */
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    char *reg;                              /* Nom du registre à manipuler */
+    int ret;                                /* Bilan de lecture des args.  */
+    uint64_t value;                         /* Valeur lue en mémoire       */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "sK", &reg, &value);
+    if (!ret) return NULL;
 
-    module = PyImport_ImportModule("pychrysalide.debug");
-    type = (PyTypeObject*)PyObject_GetAttrString(module, "BinaryDebugger");
-    Py_DECREF(module);
+    status = g_binary_debugger_write_register_u64(debugger, reg, &value);
 
-    pychrysalide_set_instance_data(G_OBJECT(debugger), type);
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
 
-    return pygobject_new(G_OBJECT(debugger));
+    return result;
 
 }
 
@@ -111,52 +767,96 @@ PyObject *py_binary_debugger_from_c(GBinaryDebugger *debugger)
 
 
 
+
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self = classe représentant un débogueur.                     *
-*                args = arguments fournis à l'appel.                          *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
 *                                                                             *
-*  Description : Fournit les identifiants de tous les threads actifs.         *
+*  Description : Remonte la pile d'appels jusqu'au point courant.             *
 *                                                                             *
-*  Retour      : Object Python représentant le résultat de l'opération.       *
+*  Retour      : Pile d'appels sous forme de liste ou None en cas d'erreur.   *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_binary_debugger_list_all_threads(PyObject *self, PyObject *args)
+static PyObject *py_binary_debugger_get_call_stack(PyObject *self, PyObject *args)
 {
-    PyObject *result;                       /* Trouvailles à retourner     */
-    GBinaryDebugger *debugger;              /* Version native              */
-    char **names;                           /* Noms associés aux threads   */
-    size_t count;                           /* Taille de cette liste       */
-    pid_t *threads;                         /* Liste des threads actifs    */
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    virt_t *callstack;                      /* Pile d'appels obtenue       */
+    size_t size;                            /* Hauteur de cette pile       */
+    bool status;                            /* Bilan de l'opération        */
     size_t i;                               /* Boucle de parcours          */
-    PyObject *thread;                       /* Détails sur un thread donné */
 
     debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
 
-    threads = g_binary_debugger_list_all_threads(debugger, &names, &count);
+    status = g_binary_debugger_get_call_stack(debugger, &callstack, &size);
 
-    result = PyTuple_New(count);
+    if (!status)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
 
-    for (i = 0; i < count; i++)
+    else
     {
-        thread = PyTuple_New(2);
-        PyTuple_SetItem(result, i, thread);
+        result = PyTuple_New(size);
 
-        PyTuple_SetItem(thread, 0, PyLong_FromLong(threads[i]));
-        PyTuple_SetItem(thread, 1, PyString_FromString(names[i]));
+        for (i = 0; i < size; i++)
+            PyTuple_SetItem(result, i, PyLong_FromUnsignedLongLong(callstack[i]));
 
-        free(names[i]);
+        if (callstack != NULL)
+            free(callstack);
 
     }
 
-    if (names != NULL)
-        free(names);
+    return result;
+
+}
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
+*                                                                             *
+*  Description : Ajoute un point d'arrêt basique en mémoire.                  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_add_mem_bp(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    vmpa2t addr;                            /* Position interne associée   */
+    int ret;                                /* Bilan de lecture des args.  */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+    if (!ret) return NULL;
+
+    status = g_binary_debugger_add_memory_breakpoint(debugger, get_virt_addr(&addr));
 
-    if (threads != NULL)
-        free(threads);
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
 
     return result;
 
@@ -165,116 +865,321 @@ static PyObject *py_binary_debugger_list_all_threads(PyObject *self, PyObject *a
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self = classe représentant un débogueur.                     *
-*                args = arguments fournis à l'appel.                          *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments accompagnant l'appel.                       *
 *                                                                             *
-*  Description : Fournit la pile d'exécution courante via un débogueur.       *
+*  Description : Retire un point d'arrêt basique en mémoire.                  *
 *                                                                             *
-*  Retour      : Object Python représentant le résultat de l'opération.       *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_binary_debugger_get_frames_stack(PyObject *self, PyObject *args)
+static PyObject *py_binary_debugger_delete_mem_bp(PyObject *self, PyObject *args)
 {
-    PyObject *result;                       /* Trouvailles à retourner     */
-    GBinaryDebugger *debugger;              /* Version native              */
-    unsigned long thread;                   /* Identifiant du thread visé  */
-    size_t count;                           /* Taille de cette liste       */
-    dbg_frame_t *frames;                    /* Frames courantes trouvées   */
-    size_t i;                               /* Boucle de parcours          */
-    PyObject *frame;                        /* Détails sur une frame       */
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    vmpa2t addr;                            /* Position interne associée   */
+    int ret;                                /* Bilan de lecture des args.  */
+    bool status;                            /* Bilan de l'opération        */
 
     debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
 
-    if (!PyArg_ParseTuple(args, "k", &thread))
-        Py_RETURN_NONE;
+    ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+    if (!ret) return NULL;
 
-    frames = g_binary_debugger_get_frames_stack(debugger, thread, &count);
+    status = g_binary_debugger_delete_memory_breakpoint(debugger, get_virt_addr(&addr));
 
-    result = PyTuple_New(count);
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
 
-    for (i = 0; i < count; i++)
-    {
-        frame = PyTuple_New(1);
-        PyTuple_SetItem(result, i, frame);
+    return result;
+
+}
 
-        PyTuple_SetItem(frame, 0, PyLong_FromUnsignedLongLong(frames[i].addr));
 
-    }
 
-    if (frames != NULL)
-        free(frames);
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments non utilisés ici.                           *
+*                                                                             *
+*  Description : Redémarre le processus de débogage.                          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_restart(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    status = g_binary_debugger_restart(debugger);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
 
     return result;
 
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments non utilisés ici.                           *
+*                                                                             *
+*  Description : Remet en marche le débogueur courant.                        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_debugger_resume(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    status = g_binary_debugger_resume(debugger);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
 
+}
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = arguments non utilisés ici.                           *
 *                                                                             *
-*  Description : Ajoute l'objet 'pychrysalide.debug.BinaryDebugger' au module.*
+*  Description : Relance l'exécution pour une seule instruction.              *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-bool register_python_binary_debugger(PyObject *module)
+static PyObject *py_binary_debugger_stepi(PyObject *self, PyObject *args)
 {
-    PyObject *pygobj_mod;                   /* Module Python-GObject       */
-    int ret;                                /* Bilan d'un appel            */
+    PyObject *result;                       /* Instance à retourner        */
+    GBinaryDebugger *debugger;              /* Version GLib du format      */
+    bool status;                            /* Bilan de l'opération        */
+
+    debugger = G_BINARY_DEBUGGER(pygobject_get(self));
+    assert(debugger != NULL);
+
+    status = g_binary_debugger_stepi(debugger, false);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    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_binary_debugger_type(void)
+{
     static PyMethodDef py_binary_debugger_methods[] = {
         {
-            "list_all_threads", (PyCFunction)py_binary_debugger_list_all_threads,
+            "list_all_threads", py_binary_debugger_list_all_threads,
+            METH_NOARGS,
+            "list_all_threads($self, /)\n--\n\nList all current active threads."
+        },
+        {
+            "read_mem_u8", py_binary_debugger_read_memory_u8,
+            METH_VARARGS,
+            "read_mem_u8($self, addr, /)\n--\n\nRead a 8-bit value from a given address."
+        },
+        {
+            "read_mem_u16", py_binary_debugger_read_memory_u16,
+            METH_VARARGS,
+            "read_mem_u16($self, addr, /)\n--\n\nRead a 16-bit value from a given address."
+        },
+        {
+            "read_mem_u32", py_binary_debugger_read_memory_u32,
+            METH_VARARGS,
+            "read_mem_u32($self, addr, /)\n--\n\nRead a 32-bit value from a given address."
+        },
+        {
+            "read_mem_u64", py_binary_debugger_read_memory_u64,
+            METH_VARARGS,
+            "read_mem_u64($self, addr, /)\n--\n\nRead a 64-bit value from a given address."
+        },
+        {
+            "get_reg_names", py_binary_debugger_get_register_names,
+            METH_VARARGS,
+            "get_reg_names($self, [grp]/)\n--\n\nGet the names of all registers belonging to an optional group."
+        },
+        {
+            "get_reg_size", py_binary_debugger_get_register_size,
+            METH_VARARGS,
+            "get_reg_size($self, name, /)\n--\n\nGet the size of a given register."
+        },
+        {
+            "read_reg_u8", py_binary_debugger_read_register_u8,
+            METH_VARARGS,
+            "read_reg_u8($self, reg, /)\n--\n\nRead a 8-bit value from a named register."
+        },
+        {
+            "read_reg_u16", py_binary_debugger_read_register_u16,
+            METH_VARARGS,
+            "read_reg_u16($self, reg, /)\n--\n\nRead a 16-bit value from a named register."
+        },
+        {
+            "read_reg_u32", py_binary_debugger_read_register_u32,
+            METH_VARARGS,
+            "read_reg_u32($self, reg, /)\n--\n\nRead a 32-bit value from a named register."
+        },
+        {
+            "read_reg_u64", py_binary_debugger_read_register_u64,
+            METH_VARARGS,
+            "read_reg_u64($self, reg, /)\n--\n\nRead a 64-bit value from a named register."
+        },
+        {
+            "write_reg_u8", py_binary_debugger_write_register_u8,
+            METH_VARARGS,
+            "write_reg_u8($self, reg, val, /)\n--\n\nWrite a 8-bit value into a named register."
+        },
+        {
+            "write_reg_u16", py_binary_debugger_write_register_u16,
+            METH_VARARGS,
+            "write_reg_u16($self, reg, val, /)\n--\n\nWrite a 16-bit value into a named register."
+        },
+        {
+            "write_reg_u32", py_binary_debugger_write_register_u32,
+            METH_VARARGS,
+            "write_reg_u32($self, reg, val, /)\n--\n\nWrite a 32-bit value into a named register."
+        },
+        {
+            "write_reg_u64", py_binary_debugger_write_register_u64,
+            METH_VARARGS,
+            "write_reg_u64($self, reg, val, /)\n--\n\nWrite a 64-bit value into a named register."
+        },
+        {
+            "get_call_stack", py_binary_debugger_get_call_stack,
             METH_NOARGS,
-            "List all current active threads."
+            "get_call_stack($self, /)\n--\n\nGet the current call stack."
+        },
+        {
+            "add_mem_bp", py_binary_debugger_add_mem_bp,
+            METH_VARARGS,
+            "add_mem_bp($self, addr, /)\n--\n\nInsert a memory breakpoint at a given address."
         },
         {
-            "get_frames_stack", (PyCFunction)py_binary_debugger_get_frames_stack,
+            "delete_mem_bp", py_binary_debugger_delete_mem_bp,
             METH_VARARGS,
-            "Provide the current callstack using a debugger."
+            "delete_mem_bp($self, addr, /)\n--\n\nRemove a memory breakpoint at a given address."
+        },
+        {
+            "restart", py_binary_debugger_restart,
+            METH_NOARGS,
+            "restart($self, /)\n--\n\nRestart the current debugging session."
+        },
+        {
+            "resume", py_binary_debugger_resume,
+            METH_NOARGS,
+            "resume($self, /)\n--\n\nResume the current debugging session."
         },
+        {
+            "stepi", py_binary_debugger_stepi,
+            METH_NOARGS,
+            "stepi($self, /)\n--\n\nExecute one machine instruction, then stop and return to the debugger."
+        },
+        { NULL }
+    };
+
+    static PyGetSetDef py_binary_debugger_getseters[] = {
         { NULL }
     };
 
     static PyTypeObject py_binary_debugger_type = {
 
-        PyObject_HEAD_INIT(NULL)
+        PyVarObject_HEAD_INIT(NULL, 0)
 
-        .tp_name        = "pychrysalide.debug.BinaryDebugger",
-        .tp_basicsize   = sizeof(PyGObject),
+        .tp_name        = "pychrysalide.analysis.BinaryDebugger",
 
         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 
-        .tp_doc         = "PyChrysalide binary debugger",
+        .tp_doc         = "PyChrysalide loaded binary",
 
         .tp_methods     = py_binary_debugger_methods,
-        .tp_new         = (newfunc)py_binary_debugger_new
+        .tp_getset      = py_binary_debugger_getseters
 
     };
 
-    pygobj_mod = PyImport_ImportModule("gobject");
-    if (pygobj_mod == NULL) return false;
+    return &py_binary_debugger_type;
 
-    py_binary_debugger_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject");
-    Py_DECREF(pygobj_mod);
+}
 
-    if (PyType_Ready(&py_binary_debugger_type) < 0)
-        return false;
 
-    Py_INCREF(&py_binary_debugger_type);
-    ret = PyModule_AddObject(module, "BinaryDebugger", (PyObject *)&py_binary_debugger_type);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.....BinaryDebugger'.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_binary_debugger(PyObject *module)
+{
+    PyTypeObject *py_binary_debugger_type;  /* Type Python 'BinaryDebugger'*/
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_binary_debugger_type = get_python_binary_debugger_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, G_TYPE_BINARY_DEBUGGER, py_binary_debugger_type, &PyGObject_Type))
+        return false;
 
-    return (ret == 0);
+    return true;
 
 }
-#endif
diff --git a/plugins/pychrysa/debug/debugger.h b/plugins/pychrysa/debug/debugger.h
index f2e4e46..97f91ac 100644
--- a/plugins/pychrysa/debug/debugger.h
+++ b/plugins/pychrysa/debug/debugger.h
@@ -22,24 +22,21 @@
  */
 
 
-#ifndef _PLUGINS_PYOIDA_DEBUG_DEBUGGER_H
-#define _PLUGINS_PYOIDA_DEBUG_DEBUGGER_H
+#ifndef _PLUGINS_PYCHRYSALIDE_DEBUG_DEBUGGER_H
+#define _PLUGINS_PYCHRYSALIDE_DEBUG_DEBUGGER_H
 
 
 #include <Python.h>
 #include <stdbool.h>
 
-#if 0
-#include <debug/debugger.h>
 
 
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_binary_debugger_type(void);
 
-/* Crée un nouvel objet Python de type 'BinaryDebugger'. */
-PyObject *py_binary_debugger_from_c(GBinaryDebugger *debugger);
-
-/* Ajoute l'objet 'pychrysalide.debug.BinaryDebugger' au module. */
+/* Prend en charge l'objet 'pychrysalide.debug.BinaryDebugger'. */
 bool register_python_binary_debugger(PyObject *);
-#endif
 
 
-#endif  /* _PLUGINS_PYOIDA_DEBUG_DEBUGGER_H */
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_DEBUG_DEBUGGER_H */
diff --git a/plugins/pychrysa/debug/gdbrsp/Makefile.am b/plugins/pychrysa/debug/gdbrsp/Makefile.am
new file mode 100644
index 0000000..cf7b78a
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES = libpychrysadebuggdbrsp.la
+
+libpychrysadebuggdbrsp_la_SOURCES =		\
+	gdb.h gdb.c							\
+	module.h module.c
+
+
+libpychrysadebuggdbrsp_la_LDFLAGS = 
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+	-I../../../../src
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/pychrysa/debug/gdbrsp/gdb.c b/plugins/pychrysa/debug/gdbrsp/gdb.c
new file mode 100644
index 0000000..cbbf66b
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/gdb.c
@@ -0,0 +1,165 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gdb.c - équivalent Python du fichier "debug/gdbrsp/gdb.c"
+ *
+ * Copyright (C) 2016 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 "gdb.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+
+
+#include <debug/gdbrsp/gdb.h>
+
+
+#include "../debugger.h"
+#include "../../helpers.h"
+#include "../../analysis/binary.h"
+
+
+/* Crée un nouvel objet Python de type 'GdbDebugger'. */
+static PyObject *py_gdb_debugger_new(PyTypeObject *, PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type de l'objet à instancier.                         *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Crée un nouvel objet Python de type 'GdbDebugger'.           *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_gdb_debugger_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    PyObject *binary_obj;                   /* Objet pour le binaire lié   */
+    const char *server;                     /* Nom du serveur à contacter  */
+    unsigned short port;                    /* Port de connexion           */
+    int ret;                                /* Bilan de lecture des args.  */
+    GLoadedBinary *binary;                  /* Binaire chargé en mémoire   */
+    GBinaryDebugger *debugger;              /* Création GLib à transmettre */
+
+    ret = PyArg_ParseTuple(args, "OsH", &binary_obj, &server, &port);
+    if (!ret) return NULL;
+
+    ret = PyObject_IsInstance(binary_obj, (PyObject *)get_python_loaded_binary_type());
+    if (!ret)
+    {
+        PyErr_SetString(PyExc_TypeError, _("The first argument must be an instance of LoadedBinary."));
+        return NULL;
+    }
+
+    binary = G_LOADED_BINARY(pygobject_get(binary_obj));
+
+    debugger = g_gdb_debugger_new(binary, server, port);
+
+    result = pygobject_new(G_OBJECT(debugger));
+
+    g_object_unref(debugger);
+
+    return (PyObject *)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_gdb_debugger_type(void)
+{
+    static PyMethodDef py_gdb_debugger_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_gdb_debugger_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_gdb_debugger_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.debug.gdbrsp.GdbDebugger",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = "PyChrysalide GDB debugger",
+
+        .tp_methods     = py_gdb_debugger_methods,
+        .tp_getset      = py_gdb_debugger_getseters,
+        .tp_new         = (newfunc)py_gdb_debugger_new
+
+    };
+
+    return &py_gdb_debugger_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....gdbrsp.GdbDebugger'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_gdb_debugger(PyObject *module)
+{
+    PyTypeObject *py_gdb_debugger_type;     /* Type Python 'GdbDebugger'   */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_gdb_debugger_type = get_python_gdb_debugger_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, G_TYPE_GDB_DEBUGGER,
+                                      py_gdb_debugger_type, get_python_binary_debugger_type()))
+        return false;
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/debug/gdbrsp/gdb.h b/plugins/pychrysa/debug/gdbrsp/gdb.h
new file mode 100644
index 0000000..c3d1330
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/gdb.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gdb.h - prototypes pour l'équivalent Python du fichier "debug/gdbrsp/gdb.h"
+ *
+ * Copyright (C) 2016 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_PYCHRYSA_DEBUG_GDBRSP_DEBUGGER_H
+#define _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_DEBUGGER_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_gdb_debugger_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.debug.gdbrsp.GdbDebugger'. */
+bool register_python_gdb_debugger(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_DEBUGGER_H */
diff --git a/plugins/pychrysa/debug/gdbrsp/module.c b/plugins/pychrysa/debug/gdbrsp/module.c
new file mode 100644
index 0000000..6e7896c
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/module.c
@@ -0,0 +1,86 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire gdbrsp en tant que module
+ *
+ * Copyright (C) 2012 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 "module.h"
+
+
+#include "gdb.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Ajoute le module 'debug.gdbrsp' au module Python.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_debug_gdbrsp_module_to_python_module(PyObject *super)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Sous-module mis en place    */
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyModuleDef py_chrysalide_gdbrsp_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.debug.gdbrsp",
+        .m_doc = "Python module for Chrysalide.debug.gdbrsp",
+
+        .m_size = -1,
+
+    };
+
+    result = false;
+
+    module = PyModule_Create(&py_chrysalide_gdbrsp_module);
+    if (module == NULL) return false;
+
+    ret = PyState_AddModule(super, &py_chrysalide_gdbrsp_module);
+    if (ret != 0) goto loading_failed;
+
+    ret = _PyImport_FixupBuiltin(module, "pychrysalide.debug.gdbrsp");
+    if (ret != 0) goto loading_failed;
+
+    Py_INCREF(module);
+    ret = PyModule_AddObject(super, "gdbrsp", module);
+    if (ret != 0) goto loading_failed;
+
+    result = true;
+
+    result &= register_python_gdb_debugger(module);
+
+ loading_failed:
+
+    assert(result);
+
+    return result;
+
+}
diff --git a/plugins/pychrysa/debug/gdbrsp/module.h b/plugins/pychrysa/debug/gdbrsp/module.h
new file mode 100644
index 0000000..78e62b0
--- /dev/null
+++ b/plugins/pychrysa/debug/gdbrsp/module.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire gdbrsp en tant que module
+ *
+ * Copyright (C) 2012-2016 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_PYCHRYSA_DEBUG_GDBRSP_MODULE_H
+#define _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'debug.gdbrsp' au module Python. */
+bool add_debug_gdbrsp_module_to_python_module(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_DEBUG_GDBRSP_MODULE_H */
diff --git a/plugins/pychrysa/debug/module.c b/plugins/pychrysa/debug/module.c
index f4b1ff3..db33a13 100644
--- a/plugins/pychrysa/debug/module.c
+++ b/plugins/pychrysa/debug/module.c
@@ -26,6 +26,7 @@
 
 
 #include "debugger.h"
+#include "gdbrsp/module.h"
 
 
 
@@ -43,23 +44,45 @@
 
 bool add_debug_module_to_python_module(PyObject *super)
 {
-    bool result;
-    PyObject *module;
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Sous-module mis en place    */
     int ret;                                /* Bilan d'un appel            */
 
-    static PyMethodDef py_debug_methods[] = {
-        { NULL }
+    static PyModuleDef py_chrysalide_debug_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.debug",
+        .m_doc = "Python module for Chrysalide.debug",
+
+        .m_size = -1,
+
     };
 
-    module = Py_InitModule("pyoida.debug", py_debug_methods);
+    result = false;
+
+    module = PyModule_Create(&py_chrysalide_debug_module);
     if (module == NULL) return false;
 
+    ret = PyState_AddModule(super, &py_chrysalide_debug_module);
+    if (ret != 0) goto loading_failed;
+
+    ret = _PyImport_FixupBuiltin(module, "pychrysalide.debug");
+    if (ret != 0) goto loading_failed;
+
     Py_INCREF(module);
-    ret = PyModule_AddObject(super, "pyoida.debug", module);
+    ret = PyModule_AddObject(super, "debug", module);
+    if (ret != 0) goto loading_failed;
+
+    result = true;
+
+    result &= register_python_binary_debugger(module);
+
+    result &= add_debug_gdbrsp_module_to_python_module(module);
 
-    result = (ret == 0);
+ loading_failed:
 
-    //result &= register_python_binary_debugger(module);
+    assert(result);
 
     return result;
 
diff --git a/plugins/pychrysa/debug/module.h b/plugins/pychrysa/debug/module.h
index 9c17b75..bbd1971 100644
--- a/plugins/pychrysa/debug/module.h
+++ b/plugins/pychrysa/debug/module.h
@@ -22,8 +22,8 @@
  */
 
 
-#ifndef _PLUGINS_PYOIDA_DEBUG_MODULE_H
-#define _PLUGINS_PYOIDA_DEBUG_MODULE_H
+#ifndef _PLUGINS_PYCHRYSA_DEBUG_MODULE_H
+#define _PLUGINS_PYCHRYSA_DEBUG_MODULE_H
 
 
 #include <Python.h>
@@ -36,4 +36,4 @@ bool add_debug_module_to_python_module(PyObject *);
 
 
 
-#endif  /* _PLUGINS_PYOIDA_DEBUG_MODULE_H */
+#endif  /* _PLUGINS_PYCHRYSA_DEBUG_MODULE_H */
diff --git a/plugins/pychrysa/format/Makefile.am b/plugins/pychrysa/format/Makefile.am
index 5733e39..bef87ca 100644
--- a/plugins/pychrysa/format/Makefile.am
+++ b/plugins/pychrysa/format/Makefile.am
@@ -11,7 +11,6 @@ libpychrysaformat_la_LIBADD =			\
 	dex/libpychrysaformatdex.la			\
 	elf/libpychrysaformatelf.la
 
-
 libpychrysaformat_la_LDFLAGS = 
 
 
diff --git a/plugins/pychrysa/format/elf/elf.c b/plugins/pychrysa/format/elf/elf.c
index f8c067f..102c60d 100644
--- a/plugins/pychrysa/format/elf/elf.c
+++ b/plugins/pychrysa/format/elf/elf.c
@@ -198,7 +198,7 @@ bool register_python_elf_format(PyObject *module)
     dict = PyModule_GetDict(module);
 
     if (!register_class_for_pygobject(dict, G_TYPE_ELF_FORMAT,
-                                  py_elf_format_type, get_python_executable_format_type()))
+                                      py_elf_format_type, get_python_executable_format_type()))
         return false;
 
     return true;
diff --git a/plugins/pychrysa/format/symbol.c b/plugins/pychrysa/format/symbol.c
index 44707d1..101b694 100644
--- a/plugins/pychrysa/format/symbol.c
+++ b/plugins/pychrysa/format/symbol.c
@@ -384,7 +384,14 @@ static PyObject *py_binary_symbol_get_label(PyObject *self, void *closure)
     symbol = G_BIN_SYMBOL(pygobject_get(self));
     label = g_binary_symbol_get_label(symbol);
 
-    result = PyUnicode_FromString(label);
+    if (label != NULL)
+        result = PyUnicode_FromString(label);
+
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
 
     return result;
 
diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c
index 60d200d..45e32b4 100644
--- a/plugins/pychrysa/pychrysa.c
+++ b/plugins/pychrysa/pychrysa.c
@@ -46,6 +46,7 @@
 #include "arch/module.h"
 #include "common/module.h"
 #include "core/module.h"
+#include "debug/module.h"
 #include "format/module.h"
 #include "glibext/module.h"
 #include "gtkext/module.h"
@@ -391,6 +392,7 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
     status &= add_arch_module_to_python_module(result);
     status &= add_common_module_to_python_module(result);
     status &= add_core_module_to_python_module(result);
+    status &= add_debug_module_to_python_module(result);
     status &= add_format_module_to_python_module(result);
     status &= add_glibext_module_to_python_module(result);
     status &= add_gtkext_module_to_python_module(result);
diff --git a/src/Makefile.am b/src/Makefile.am
index ad9f22d..4b66cfb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,7 +33,6 @@ libchrysadisass_la_LIBADD =				\
 	analysis/libanalysis.la				\
 	arch/libarch.la						\
 	debug/libdebug.la					\
-	debug/remgdb/libdebugremgdb.la		\
 	format/libformat.la
 
 
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index a6f0a31..79c82f5 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -394,7 +394,6 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch
     char *access;                           /* Chemin d'accès à un élément */
     char *hash;                             /* Empreinte à retrouver       */
     GBinContent *content;                   /* Contenu à référencer        */
-
     xmlXPathObjectPtr xobject;              /* Cible d'une recherche       */
     unsigned int i;                         /* Boucle de parcours          */
 
diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c
index 27262d1..f344101 100644
--- a/src/arch/vmpa.c
+++ b/src/arch/vmpa.c
@@ -422,7 +422,7 @@ static char *_phys_t_to_string(phys_t phys, MemoryDataSize msize, char buffer[VM
         switch (msize)
         {
             case MDS_8_BITS:
-                ret = snprintf(buffer, VMPA_MAX_LEN,"0x%02" PRIx64, phys);
+                ret = snprintf(buffer, VMPA_MAX_LEN, "0x%02" PRIx64, phys);
                 break;
 
             case MDS_16_BITS:
@@ -499,7 +499,7 @@ char *vmpa2_virt_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer
 		switch (msize)
 		{
             case MDS_8_BITS:
-				ret = snprintf(buffer, VMPA_MAX_LEN,"0x%02" PRIx64, addr->virtual);
+				ret = snprintf(buffer, VMPA_MAX_LEN, "0x%02" PRIx64, addr->virtual);
 				break;
 
             case MDS_16_BITS:
diff --git a/src/common/endianness.c b/src/common/endianness.c
index eecb397..ba72f3d 100755
--- a/src/common/endianness.c
+++ b/src/common/endianness.c
@@ -29,6 +29,226 @@
 
 
 
+/* ---------------------------------------------------------------------------------- */
+/*                             CONVERSION ENTRE BOUTISMES                             */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : value  = valeur d'origine à manipuler.                       *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
+*                                                                             *
+*  Retour      : Valeur transformée au besoin.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint16_t swap_u16(const uint16_t *value, SourceEndian endian)
+{
+    uint16_t result;                        /* Valeur à retourner          */
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = *value;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = ((*value >> 0) & 0xff) << 8 | ((*value >> 8) & 0xff) << 0;
+
+#else
+
+#   error "TODO : PDP !"
+
+#endif
+
+            break;
+
+        case SRE_MIDDLE:
+            /* TODO */
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = ((*value >> 0) & 0xff) << 8 | ((*value >> 8) & 0xff) << 0;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = *value;
+
+#else
+
+#   error "TODO : PDP !"
+
+#endif
+
+            break;
+
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : value  = valeur d'origine à manipuler.                       *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
+*                                                                             *
+*  Retour      : Valeur transformée au besoin.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint32_t swap_u32(const uint32_t *value, SourceEndian endian)
+{
+    uint32_t result;                        /* Valeur à retourner          */
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = *value;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = ((*value >>  0) & 0xff) << 24 | ((*value >>  8) & 0xff) << 16
+                   | ((*value >> 16) & 0xff) << 8  | ((*value >> 24) & 0xff) << 0;
+
+#else
+
+#   error "TODO : PDP !"
+
+#endif
+
+            break;
+
+        case SRE_MIDDLE:
+            /* TODO */
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = ((*value >>  0) & 0xff) << 24 | ((*value >>  8) & 0xff) << 16
+                   | ((*value >> 16) & 0xff) << 8  | ((*value >> 24) & 0xff) << 0;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = *value;
+
+#else
+
+#   error "TODO : PDP !"
+
+#endif
+
+            break;
+
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : value  = valeur d'origine à manipuler.                       *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
+*                                                                             *
+*  Retour      : Valeur transformée au besoin.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint64_t swap_u64(const uint64_t *value, SourceEndian endian)
+{
+    uint64_t result;                        /* Valeur à retourner          */
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = *value;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = ((*value >>  0) & 0xff) << 56 | ((*value >>  8) & 0xff) << 48
+                   | ((*value >> 16) & 0xff) << 40 | ((*value >> 24) & 0xff) << 32
+                   | ((*value >> 32) & 0xff) << 24 | ((*value >> 40) & 0xff) << 16
+                   | ((*value >> 48) & 0xff) << 8  | ((*value >> 56) & 0xff) << 0;
+
+#else
+
+#   error "TODO : PDP !"
+
+#endif
+
+            break;
+
+        case SRE_MIDDLE:
+            /* TODO */
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = ((*value >>  0) & 0xff) << 56 | ((*value >>  8) & 0xff) << 48
+                   | ((*value >> 16) & 0xff) << 40 | ((*value >> 24) & 0xff) << 32
+                   | ((*value >> 32) & 0xff) << 24 | ((*value >> 40) & 0xff) << 16
+                   | ((*value >> 48) & 0xff) << 8  | ((*value >> 56) & 0xff) << 0;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = *value;
+
+#else
+
+#   error "TODO : PDP !"
+
+#endif
+
+            break;
+
+
+    }
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           BOUTISME DES ENTREES / SORTIES                           */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
diff --git a/src/common/endianness.h b/src/common/endianness.h
index 2af6493..5ceb2ee 100755
--- a/src/common/endianness.h
+++ b/src/common/endianness.h
@@ -43,6 +43,33 @@ typedef enum _SourceEndian
 } SourceEndian;
 
 
+/* --------------------------- CONVERSION ENTRE BOUTISMES --------------------------- */
+
+
+/* Adapte un nombre sur 16 bits à un boutisme donné. */
+uint16_t swap_u16(const uint16_t *, SourceEndian);
+
+/* Adapte un nombre sur 16 bits à un boutisme donné. */
+uint32_t swap_u32(const uint32_t *, SourceEndian);
+
+/* Adapte un nombre sur 16 bits à un boutisme donné. */
+uint64_t swap_u64(const uint64_t *, SourceEndian);
+
+
+#define from_u16(v, e) swap_u16(v, e)
+#define from_u32(v, e) swap_u32(v, e)
+#define from_u64(v, e) swap_u64(v, e)
+
+
+#define to_u16(v, e) swap_u16(v, e)
+#define to_u32(v, e) swap_u32(v, e)
+#define to_u64(v, e) swap_u64(v, e)
+
+
+
+/* ------------------------- BOUTISME DES ENTREES / SORTIES ------------------------- */
+
+
 /* Lit un nombre non signé sur 4 bits. */
 bool read_u4(uint8_t *, const bin_t *, phys_t *, phys_t, bool *);
 
diff --git a/src/common/extstr.c b/src/common/extstr.c
index 087505a..bd561ba 100644
--- a/src/common/extstr.c
+++ b/src/common/extstr.c
@@ -196,13 +196,13 @@ char *strrpl(char *haystack, const char *needle1, const char *needle2)
             haystack = (char *)realloc(haystack, inlen * sizeof(char *));
             found = haystack + index;
 
-            memmove(found + len2, found + len1, inlen + len2 - index);
+            memmove(found + len2, found + len1, inlen - len2 - index);
 
         }
 
         else if (len2 < len1)
         {
-            memmove(found + len2, found + len1, inlen + len2 - index);
+            memmove(found + len2, found + len1, inlen - index - len1);
 
             inlen -= (len1 - len2);
 
diff --git a/src/common/xml.c b/src/common/xml.c
index cbb7a41..0bd4d86 100644
--- a/src/common/xml.c
+++ b/src/common/xml.c
@@ -45,9 +45,8 @@
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : filename = nom du fichier à ouvrir.                          *
-*                xdoc     = structure XML chargée. [OUT]                      *
-*                context  = contexte à utiliser pour les recherches. [OUT]    *
+*  Paramètres  : xdoc    = structure XML chargée. [OUT]                       *
+*                context = contexte à utiliser pour les recherches. [OUT]     *
 *                                                                             *
 *  Description : Crée un nouveau fichier XML.                                 *
 *                                                                             *
@@ -79,6 +78,41 @@ bool create_new_xml_file(xmlDocPtr *xdoc, xmlXPathContextPtr *context)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : content = données XML présentes en mémoire et à charge.      *
+*                length  = quantité de ces données.                           *
+*                xdoc    = structure XML chargée. [OUT]                       *
+*                context = contexte à utiliser pour les recherches. [OUT]     *
+*                                                                             *
+*  Description : Charge un document XML entièrement en mémoire.               *
+*                                                                             *
+*  Retour      : true si l'opération a pu s'effectuer, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_xml_from_memory(const char *content, size_t length, xmlDocPtr *xdoc, xmlXPathContextPtr *context)
+{
+    *xdoc = xmlReadMemory(content, length, "noname.xml", NULL, 0);
+
+    if (*xdoc == NULL)
+        return false;
+
+    *context = xmlXPathNewContext(*xdoc);
+
+    if (*context == NULL)
+    {
+        xmlFreeDoc(*xdoc);
+        return false;
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : xdoc     = structure XML chargée.                            *
 *                filename = nom du fichier à remplir.                         *
 *                                                                             *
@@ -217,6 +251,65 @@ xmlXPathObjectPtr get_node_xpath_object(xmlXPathContextPtr xpathCtx, const char
 *                                                                             *
 *  Paramètres  : node = noeud dont une propriété est à lire.                  *
 *                                                                             *
+*  Description : Obtient le nom de balise d'un noeud donné.                   *
+*                                                                             *
+*  Retour      : Valeur sous forme de chaîne de caractères ou NULL.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *qck_get_node_name(xmlNodePtr node)
+{
+    char *result;                           /* Valeur en question renvoyée */
+
+    result = NULL;
+
+    if (node != NULL)
+        result = strdup((const char *)node->name);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : xpathCtx = contexte à utiliser pour les recherches.          *
+*                path     = chemin d'accès au noeud visé.                     *
+*                                                                             *
+*  Description : Obtient le nom de balise d'un noeud donné.                   *
+*                                                                             *
+*  Retour      : Valeur sous forme de chaîne de caractères ou NULL.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *get_node_name(xmlXPathContextPtr xpathCtx, const char *path)
+{
+    char *result;                           /* Valeur en question renvoyée */
+    xmlXPathObjectPtr xpathObj;             /* Point de départ XML         */
+
+    result = NULL;
+
+    xpathObj = get_node_xpath_object(xpathCtx, path);
+    if (xpathObj == NULL) return NULL;
+
+    if (xpathObj->nodesetval->nodeNr > 0)
+        result = qck_get_node_name(xpathObj->nodesetval->nodeTab[0]);
+
+    xmlXPathFreeObject(xpathObj);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = noeud dont une propriété est à lire.                  *
+*                                                                             *
 *  Description : Obtient une valeur placée entre <...> et </...>.             *
 *                                                                             *
 *  Retour      : Valeur sous forme de chaîne de caractères ou NULL.           *
diff --git a/src/common/xml.h b/src/common/xml.h
index c3e4b56..ed009c6 100644
--- a/src/common/xml.h
+++ b/src/common/xml.h
@@ -37,6 +37,9 @@
 /* Crée un nouveau fichier XML. */
 bool create_new_xml_file(xmlDocPtr *, xmlXPathContextPtr *);
 
+/*  Charge un document XML entièrement en mémoire. */
+bool load_xml_from_memory(const char *, size_t, xmlDocPtr *, xmlXPathContextPtr *);
+
 /* Sauvegarde une structure XML dans un fichier. */
 bool save_xml_file(xmlDocPtr, const char *);
 
@@ -58,6 +61,12 @@ gboolean open_xml_file(const char *filename, xmlDoc **, xmlXPathContextPtr *);
 /* Obtient de façon encadrée l'accès à un noeud défini. */
 xmlXPathObjectPtr get_node_xpath_object(xmlXPathContextPtr, const char *);
 
+/* Obtient le nom de balise d'un noeud donné. */
+char *qck_get_node_name(xmlNodePtr);
+
+/* Obtient le nom de balise d'un noeud donné. */
+char *get_node_name(xmlXPathContextPtr, const char *);
+
 /* Obtient une valeur placée entre <...> et </...>. */
 char *qck_get_node_text_value(xmlNodePtr);
 
diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am
index b2f4685..f955a5a 100755
--- a/src/debug/Makefile.am
+++ b/src/debug/Makefile.am
@@ -2,16 +2,18 @@
 noinst_LTLIBRARIES = libdebug.la
 
 libdebug_la_SOURCES =					\
+	break-int.h							\
 	break.h break.c						\
 	debugger-int.h						\
 	debugger.h debugger.c				\
+	misc.h								\
 	packet-int.h						\
 	packet.h packet.c					\
 	stream-int.h						\
 	stream.h stream.c
 
 libdebug_la_LIBADD =					\
-	jdwp/libdebugjdwp.la
+	gdbrsp/libdebuggdbrsp.la
 
 libdebug_la_CFLAGS = $(AM_CFLAGS)
 
@@ -20,4 +22,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = jdwp remgdb
+SUBDIRS = gdbrsp
diff --git a/src/debug/break-int.h b/src/debug/break-int.h
new file mode 100644
index 0000000..44b3664
--- /dev/null
+++ b/src/debug/break-int.h
@@ -0,0 +1,64 @@
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * break-int.h - prototypes pour la définition générique interne des points d'arrêt
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_BREAK_INT_H
+#define _DEBUG_BREAK_INT_H
+
+
+#include "break.h"
+
+
+
+/* Traçabilité des poses */
+typedef struct _bp_source
+{
+    RawBpOrigin origin;                     /* Source de la définition     */
+
+    /* Si origin != RBO_USER : */
+
+    dbg_thread_id_t tid;                    /* Identifiant du thread lié   */
+    virt_t previous;                        /* Arrêt officiel d'origine    */
+
+} bp_source;
+
+
+/* Définition d'un point d'arrêt appliqué */
+struct _raw_breakpoint
+{
+    virt_t addr;                            /* Adresse d'application       */
+
+    union
+    {
+        bp_source source;                   /* Origine du point d'arrêt    */
+        bp_source *sources;                 /* Origines du point d'arrêt   */
+    };
+    size_t count;                           /* Nombre de ces origines      */
+
+};
+
+
+/* Initialise le coeur d'un point d'arrêt. */
+void init_raw_breakpoint(raw_breakpoint *, virt_t);
+
+
+
+#endif  /* _DEBUG_BREAK_INT_H */
diff --git a/src/debug/break.c b/src/debug/break.c
index 19eb787..1d4c2d3 100644
--- a/src/debug/break.c
+++ b/src/debug/break.c
@@ -24,114 +24,20 @@
 #include "break.h"
 
 
+#include <assert.h>
 #include <malloc.h>
-#include <string.h>
 
 
-#include "../common/dllist.h"
+#include "break-int.h"
 
 
 
-
-/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */
-
-
-/* Propriétés d'un point d'arrêt (instance) */
-struct _GBreakPoint
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    DL_LIST_ITEM(link);                     /* Maillon de liste chaînée    */
-
-    vmpa_t address;                         /* Adresse où s'arrêter        */
-
-    bool is_enabled;                        /* Statut d'activité           */
-
-};
-
-/* Propriétés d'un point d'arrêt (classe) */
-struct _GBreakPointClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-    /* Signaux */
-
-    void (* changed) (GBreakPoint *);
-
-};
-
-
-#define bp_list_add_tail(new, head) dl_list_add_tail(new, head, GBreakPoint, link)
-#define bp_list_del(item, head) dl_list_del(item, head, GBreakPoint, link)
-#define bp_list_for_each(pos, head) dl_list_for_each(pos, head, GBreakPoint, link)
-#define bp_list_for_each_safe(pos, head, next) dl_list_for_each_safe(pos, head, next, GBreakPoint, link)
-
-
-/* Initialise la classe des propriétés d'un point d'arrêt. */
-static void g_break_point_class_init(GBreakPointClass *);
-
-/* Initialise des propriétés d'un point d'arrêt. */
-static void g_break_point_init(GBreakPoint *);
-
-
-
-
-
-
-/* ---------------------------- GROUPE DE POINTS D'ARRET ---------------------------- */
-
-
-/* Propriétés d'un groupe de points d'arrêt (instance) */
-struct _GBreakGroup
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    char *name;                             /* Désignation humaine         */
-
-    GBreakPoint *points;                    /* Liste de points d'arrêt     */
-
-};
-
-/* Propriétés d'un groupe de points d'arrêt (classe) */
-struct _GBreakGroupClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-    /* Signaux */
-
-    void (* added) (GBreakGroup *, GBreakPoint *);
-    void (* removed) (GBreakGroup *, GBreakPoint *);
-
-};
-
-
-/* Initialise la classe des groupes de points d'arrêt. */
-static void g_break_group_class_init(GBreakGroupClass *);
-
-/* Initialise un groupe de points d'arrêt. */
-static void g_break_group_init(GBreakGroup *);
-
-
-
-
-
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                             GESTION DES POINTS D'ARRET                             */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini pour des propriétés d'un point d'arrêt. */
-G_DEFINE_TYPE(GBreakPoint, g_break_point, G_TYPE_OBJECT);
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
+*  Paramètres  : bp   = point d'arrêt à initialiser.                          *
+*                addr = adresse d'action du point d'arrêt.                    *
 *                                                                             *
-*  Description : Initialise la classe des propriétés d'un point d'arrêt.      *
+*  Description : Initialise le coeur d'un point d'arrêt.                      *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -139,24 +45,20 @@ G_DEFINE_TYPE(GBreakPoint, g_break_point, G_TYPE_OBJECT);
 *                                                                             *
 ******************************************************************************/
 
-static void g_break_point_class_init(GBreakPointClass *klass)
+void init_raw_breakpoint(raw_breakpoint *bp, virt_t addr)
 {
-    g_signal_new("changed",
-                 G_TYPE_BREAK_POINT,
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GBreakPointClass, changed),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__VOID,
-                 G_TYPE_NONE, 0);
+    bp->addr = addr;
+
+    bp->count = 0;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : point = instance à initialiser.                              *
+*  Paramètres  : bp = point d'arrêt à traiter.                                *
 *                                                                             *
-*  Description : Initialise des propriétés d'un point d'arrêt.                *
+*  Description : Libère le coeur d'un point d'arrêt.                          *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -164,135 +66,133 @@ static void g_break_point_class_init(GBreakPointClass *klass)
 *                                                                             *
 ******************************************************************************/
 
-static void g_break_point_init(GBreakPoint *point)
+void fini_raw_breakpoint(raw_breakpoint *bp)
 {
-    DL_LIST_ITEM_INIT(&point->link);
+    if (bp->count > 1)
+        free(bp->sources);
+
+    free(bp);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : address = adresse à laquelle s'arrêter.                      *
+*  Paramètres  : bp = point d'arrêt à consulter.                              *
 *                                                                             *
-*  Description : Construit un nouveau point d'arrêt.                          *
+*  Description : Indique l'adresse du point d'arrêt dans la mémoire ciblée.   *
 *                                                                             *
-*  Retour      : Point d'arrêt mis en place ou NULL en cas d'échec.           *
+*  Retour      : Adresse associée au point d'arrêt.                           *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GBreakPoint *g_break_point_new(vmpa_t address)
+virt_t get_raw_breakpoint_addr(const raw_breakpoint *bp)
 {
-    GBreakPoint *result;                    /* Adresse à retourner         */
-
-    result = g_object_new(G_TYPE_BREAK_POINT, NULL);
-
-    result->address = address;
-
-    return result;
+    return bp->addr;
 
 }
 
 
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : point = instance à consulter.                                *
+*  Paramètres  : bp = point d'arrêt à consulter.                              *
 *                                                                             *
-*  Description : Fournit l'adresse associée à un point d'arrêt.               *
+*  Description : Fournit l'adresse d'origine d'un point d'arrêt de pas à pas. *
 *                                                                             *
-*  Retour      : Adresse associée.                                            *
+*  Retour      : -                                                            *
 *                                                                             *
-*  Remarques   : -                                                            *
+*  Remarques   : Un appel à cette fonction n'est valide que pour un point     *
+*                d'arrêt de type RBO_STEP.                                    *
 *                                                                             *
 ******************************************************************************/
 
-vmpa_t g_break_point_get_address(const GBreakPoint *point)
+virt_t get_raw_breakpoint_prev_addr(const raw_breakpoint *bp)
 {
-    return point->address;
+    virt_t result;                          /* Localisation à retourner    */
+    bool found;                             /* Valide une obtention        */
+    size_t i;                               /* Boucle de parcours          */
 
-}
+    switch (bp->count)
+    {
+        case 1:
+            assert(bp->source.origin == RBO_INTERNAL || bp->source.origin == RBO_STEP);
+            result = bp->source.previous;
+            break;
 
+        default:
 
+            found = false;
 
-/* ---------------------------------------------------------------------------------- */
-/*                              GROUPE DE POINTS D'ARRET                              */
-/* ---------------------------------------------------------------------------------- */
+            for (i = 0; i < bp->count && !found; i++)
+                if (bp->sources[i].origin == RBO_INTERNAL || bp->sources[i].origin == RBO_STEP)
+                {
+                    result = bp->sources[i].previous;
+                    found = true;
+                }
 
+            assert(found);
 
-/* Indique le type défini pour les groupes de points d'errêt. */
-G_DEFINE_TYPE(GBreakGroup, g_break_group, G_TYPE_OBJECT);
+            break;
 
+    }
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des groupes de points d'arrêt.          *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_break_group_class_init(GBreakGroupClass *klass)
-{
-    g_signal_new("added",
-                 G_TYPE_BREAK_GROUP,
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GBreakGroupClass, added),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__OBJECT,
-                 G_TYPE_NONE, 1, G_TYPE_BREAK_POINT);
-
-    g_signal_new("removed",
-                 G_TYPE_BREAK_GROUP,
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GBreakGroupClass, removed),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__OBJECT,
-                 G_TYPE_NONE, 1, G_TYPE_BREAK_POINT);
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : group = instance à initialiser.                              *
+*  Paramètres  : addr = adresse à consulter.                                  *
+*                bp   = point d'arrêt à consulter.                            *
 *                                                                             *
-*  Description : Initialise un groupe de point d'arrêt.                       *
+*  Description : Effectue une comparaison entre adresse et point d'arrêt.     *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Bilan de la comparaison.                                     *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_break_group_init(GBreakGroup *group)
+int compare_raw_breakpoint_with_addr(const virt_t *addr, const raw_breakpoint **bp)
 {
+    int result;                             /* Bilan à retourner           */
+
+    if (*addr < (*bp)->addr)
+        result = -1;
+
+    else if (*addr == (*bp)->addr)
+        result = 0;
+
+    else
+        result = 1;
+
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : -                                                            *
+*  Paramètres  : a = premier point d'arrêt à consulter.                       *
+*                b = second point d'arrêt à consulter.                        *
 *                                                                             *
-*  Description : Construit un nouveau groupe de points d'arrêt.               *
+*  Description : Effectue une comparaison entre deux points d'arrêt.          *
 *                                                                             *
-*  Retour      : Groupe de points d'arrêt mis en place ou NULL en cas d'échec.*
+*  Retour      : Bilan de la comparaison.                                     *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GBreakGroup *g_break_group_new(void)
+int compare_raw_breakpoints(const raw_breakpoint **a, const raw_breakpoint **b)
 {
-    GBreakGroup *result;                    /* Adresse à retourner         */
+    int result;                             /* Bilan à retourner           */
 
-    result = g_object_new(G_TYPE_BREAK_GROUP, NULL);
+    result = compare_raw_breakpoint_with_addr(&(*a)->addr, b);
 
     return result;
 
@@ -301,140 +201,263 @@ GBreakGroup *g_break_group_new(void)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : group = groupe de points d'arrêt à consulter.                *
+*  Paramètres  : bp       = point d'arrêt à manipuler.                        *
+*                origin   = origine de la création du point d'arrêt.          *
+*                tid      = identifiant du thread concerné.                   *
+*                previous = éventuelle adresse précédent celle du point.      *
 *                                                                             *
-*  Description : Fournit la désignation humaine associée à un groupe.         *
+*  Description : Enregistre la source d'un point d'arrêt posé.                *
 *                                                                             *
-*  Retour      : Désignation humaine associée, jamais NULL.                   *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-const char *g_break_group_get_name(const GBreakGroup *group)
+void set_raw_breakpoint_origin(raw_breakpoint *bp, RawBpOrigin origin, dbg_thread_id_t tid, virt_t previous)
 {
-    return group->name;
+#ifndef NDEBUG
+    size_t i;                               /* Boucle de parcours          */
+#endif
+    bp_source *src;                         /* Source à définir            */
+    bp_source tmp;                          /* Copie temporaire            */
+
+#ifndef NDEBUG
+
+    if (bp->count == 1)
+        assert(bp->source.tid != tid || (bp->source.origin & origin) == 0);
+
+    else
+        for (i = 0; i < bp->count; i++)
+            if (bp->source.tid == tid)
+            {
+                assert((bp->sources[i].origin & origin) == 0);
+                break;
+            }
+
+#endif
+
+    bp->count++;
+
+    switch (bp->count)
+    {
+        case 1:
+            src = &bp->source;
+            break;
+
+        case 2:
+            tmp = bp->source;
+            bp->sources = (bp_source *)calloc(2, sizeof(bp_source));
+            bp->sources[0] = tmp;
+            src = &bp->sources[1];
+            break;
+
+        default:
+            bp->sources = (bp_source *)realloc(bp->sources, bp->count * sizeof(bp_source));
+            src = &bp->sources[bp->count - 1];
+            break;
+
+    }
+
+    src->origin = origin;
+    src->tid = tid;
+    src->previous = previous;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : group = groupe de points d'arrêt à modifier.                 *
-*                name  = nouveau nom de scène.                                *
+*  Paramètres  : bp       = point d'arrêt à manipuler.                        *
+*                origin   = origine de la création du point d'arrêt.          *
+*                tid      = identifiant du thread concerné.                   *
+*                previous = éventuelle adresse précédent celle du point.      *
 *                                                                             *
-*  Description : Définit la désignation humaine à associer à un groupe.       *
+*  Description : Oublie la source d'un point d'arrêt posé.                    *
 *                                                                             *
-*  Retour      : Désignation humaine associée, voire NULL.                    *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void g_break_group_set_name(GBreakGroup *group, const char *name)
+void unset_raw_breakpoint_origin(raw_breakpoint *bp, RawBpOrigin origin, dbg_thread_id_t tid)
 {
-    if (group->name != NULL)
-        free(group->name);
+    size_t i;                               /* Boucle de parcours #1       */
+    bp_source tmp;                          /* Copie temporaire            */
+#ifndef NDEBUG
+    size_t j;                               /* Boucle de parcours #2       */
+#endif
 
-    if (name == NULL)
-        group->name = NULL;
+    bool has_same_origin(bp_source *src)
+    {
+        bool result;
 
-    else
-        group->name = strdup(name);
+        result = (src->origin == origin && src->tid == tid);
+
+        return result;
+
+    }
+
+    switch (bp->count)
+    {
+        case 1:
+
+            if (has_same_origin(&bp->source))
+                bp->count = 0;
+
+            break;
+
+        case 2:
+
+            if (has_same_origin(&bp->sources[0]))
+            {
+                assert(!has_same_origin(&bp->sources[1]));
+
+                tmp = bp->sources[1];
+
+                bp->count = 1;
+                free(bp->sources);
+
+                bp->source = tmp;
+
+            }
+
+            else if (has_same_origin(&bp->sources[1]))
+            {
+                assert(!has_same_origin(&bp->sources[0]));
+
+                tmp = bp->sources[0];
+
+                bp->count = 1;
+                free(bp->sources);
+
+                bp->source = tmp;
+
+            }
+
+            break;
+
+        default:
+
+            for (i = 0; i < bp->count; i++)
+            {
+                if (has_same_origin(&bp->sources[i]))
+                {
+                    if ((i + 1) < bp->count)
+                        memmove(&bp->sources[i], &bp->sources[i + 1], (bp->count - i - 1) * sizeof(bp_source));
+
+                    bp->sources = (bp_source *)realloc(bp->sources, --bp->count * sizeof(bp_source));
+
+#ifndef NDEBUG
+                    for (j = i; j < bp->count; j++)
+                        assert(!has_same_origin(&bp->sources[j]));
+#endif
+
+                    break;
+
+                }
+
+            }
+
+            break;
+
+    }
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : group = groupe de points d'arrêt à consulter.                *
-*                addr  = adresse recherchée dans les points d'arrêt.          *
+*  Paramètres  : bp     = point d'arrêt à manipuler.                          *
+*                origin = origine de la création du point d'arrêt.            *
+*                tid    = identifiant du thread concerné.                     *
 *                                                                             *
-*  Description : Indique si une adresse donnée est gérée dans un groupe.      *
+*  Description : Indique si le point d'arrêt correspond à une source donnée.  *
 *                                                                             *
-*  Retour      : true si l'adresse est gérée ici, false sinon.                *
+*  Retour      : Bilan de l'analyse.                                          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-bool g_break_group_has_address(const GBreakGroup *group, vmpa_t addr)
+bool has_raw_breakpoint_origin(const raw_breakpoint *bp, RawBpOrigin origin, dbg_thread_id_t tid)
 {
-    GBreakPoint *iter;                      /* Boucle de parcours          */
+    bool result;                            /* Conclusion à retourner      */
+    size_t i;                               /* Boucle de parcours          */
+
+    if (bp->count == 1)
+        result = (bp->source.tid == tid && (bp->source.origin & origin) != 0);
+
+    else
+    {
+        result = false;
+
+        for (i = 0; i < bp->count && !result; i++)
+            result = (bp->sources[i].tid == tid && (bp->sources[i].origin & origin) != 0);
 
-    bp_list_for_each(iter, group->points)
-        if (g_break_point_get_address(iter) == addr)
-            return true;
+    }
 
-    return false;
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : group = groupe de points d'arrêt à modifier.                 *
-*                addr  = adresse mémoire à faire basculer.                    *
+*  Paramètres  : bp     = point d'arrêt à manipuler.                          *
+*                origin = origine de la création du point d'arrêt.            *
+*                tid    = identifiant du thread concerné.                     *
+*                prev   = adresse d'instruction qui a conduit à des poses.    *
 *                                                                             *
-*  Description : Ajoute ou supprime un point d'arrêt dans un groupe.          *
+*  Description : Indique si le point d'arrêt correspond à une origine donnée. *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Bilan de l'analyse.                                          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void g_break_group_toggle_breakpoint(GBreakGroup *group, vmpa_t addr)
+bool has_raw_breakpoint_previous_address(const raw_breakpoint *bp, RawBpOrigin origin, dbg_thread_id_t tid, virt_t prev)
 {
-    GBreakPoint *iter;                      /* Boucle de parcours          */
-    GBreakPoint *next;                      /* Prochain point de passage   */
+    bool result;                            /* Conclusion à retourner      */
+    size_t i;                               /* Boucle de parcours          */
 
-    /* Suppression d'un éventuel existant */
+    if (bp->count == 1)
+        result = (bp->source.tid == tid && (bp->source.origin & origin) != 0 && bp->source.previous == prev);
 
-    bp_list_for_each_safe(iter, &group->points, next)
-        if (g_break_point_get_address(iter) == addr)
-        {
-            g_signal_emit_by_name(group, "removed", iter);
-
-            bp_list_del(iter, &group->points);
-            g_object_unref(G_OBJECT(iter));
-
-            return;
-
-        }
-
-    /* Si non trouvé, ajout du nouveau point */
+    else
+    {
+        result = false;
 
-    iter = g_break_point_new(addr);
+        for (i = 0; i < bp->count && !result; i++)
+            result = (bp->sources[i].tid == tid && (bp->sources[i].origin & origin) != 0 && bp->sources[i].previous == prev);
 
-    bp_list_add_tail(iter, &group->points);
+    }
 
-    g_signal_emit_by_name(group, "added", iter);
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : group = groupe de points d'arrêt à parcourir.                *
-*                func  = fonction à appeler à chaque point trouvé.            *
-*                data  = éventuelle donnée de l'utilisateur à joindre.        *
+*  Paramètres  : bp = point d'arrêt à consulter.                              *
 *                                                                             *
-*  Description : Parcourt l'ensemble des points d'arrêt d'un groupe donné.    *
+*  Description : Indique si un point d'arrêt a encore une utilité.            *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : true si le point peut être retiré, false sinon.              *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void g_break_group_for_each(GBreakGroup *group, GExtFunc func, gpointer data)
+bool is_breakpoint_useless(const raw_breakpoint *bp)
 {
-    GBreakPoint *iter;                      /* Boucle de parcours          */
+    bool result;                            /* Conclusion à faire remonter */
 
-    /* Suppression d'un éventuel existant */
+    result = (bp->count == 0);
 
-    bp_list_for_each(iter, group->points)
-        func(group, iter, data);
+    return result;
 
 }
diff --git a/src/debug/break.h b/src/debug/break.h
index 5946ad2..77d959a 100644
--- a/src/debug/break.h
+++ b/src/debug/break.h
@@ -25,80 +25,58 @@
 #define _DEBUG_BREAK_H
 
 
-#include <glib-object.h>
-#include <stdbool.h>
+#include "misc.h"
+#include "../arch/vmpa.h"
 
 
-#include "../arch/archbase.h"
-#include "../glibext/proto.h"
 
+/* Origine des points d'arrêt en place */
+typedef enum _RawBpOrigin
+{
+    RBO_INVALID  = (0 << 0),                /* Existance illégale          */
+    RBO_USER     = (1 << 0),                /* Point d'arrêt utilisateur   */
+    //RBO_COMPUTED = (1 << 1),                /* Arrêt sur un point spécial  */
+    RBO_INTERNAL = (1 << 2),                /* Restauration transparente   */
+    RBO_STEP     = (1 << 3),                /* Mise en place éphémère      */
 
+    RBO_COUNT
 
-/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */
+} RawBpOrigin;
 
 
-#define G_TYPE_BREAK_POINT               g_break_point_get_type()
-#define G_BREAK_POINT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_break_point_get_type(), GBreakPoint))
-#define G_IS_BREAK_POINT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_break_point_get_type()))
-#define G_BREAK_POINT_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_break_point_get_type(), GBreakPointIface))
-#define G_BREAK_POINT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BREAK_POINT, GBreakPointClass))
+/* Définition d'un point d'arrêt appliqué */
+typedef struct _raw_breakpoint raw_breakpoint;
 
 
-/* Propriétés d'un point d'arrêt (instance) */
-typedef struct _GBreakPoint GBreakPoint;
+/* Libère le coeur d'un point d'arrêt. */
+void fini_raw_breakpoint(raw_breakpoint *);
 
-/* Propriétés d'un point d'arrêt (classe) */
-typedef struct _GBreakPointClass GBreakPointClass;
+/* Indique l'adresse du point d'arrêt dans la mémoire ciblée. */
+virt_t get_raw_breakpoint_addr(const raw_breakpoint *);
 
+/* Fournit l'adresse d'origine d'un point d'arrêt de pas à pas. */
+virt_t get_raw_breakpoint_prev_addr(const raw_breakpoint *);
 
-/* Indique le type défini pour des propriétés d'un point d'arrêt. */
-GType g_break_point_get_type(void);
+/* Effectue une comparaison entre adresse et point d'arrêt. */
+int compare_raw_breakpoint_with_addr(const virt_t *, const raw_breakpoint **);
 
-/* Construit un nouveau point d'arrêt. */
-GBreakPoint *g_break_point_new(vmpa_t);
+/* Effectue une comparaison entre deux points d'arrêt. */
+int compare_raw_breakpoints(const raw_breakpoint **, const raw_breakpoint **);
 
-/* Fournit l'adresse associée à un point d'arrêt. */
-vmpa_t g_break_point_get_address(const GBreakPoint *);
+/* Enregistre la source d'un point d'arrêt posé. */
+void set_raw_breakpoint_origin(raw_breakpoint *, RawBpOrigin, dbg_thread_id_t, virt_t);
 
+/* Oublie la source d'un point d'arrêt posé. */
+void unset_raw_breakpoint_origin(raw_breakpoint *, RawBpOrigin, dbg_thread_id_t);
 
+/* Indique si le point d'arrêt correspond à une source donnée. */
+bool has_raw_breakpoint_origin(const raw_breakpoint *, RawBpOrigin, dbg_thread_id_t);
 
-/* ---------------------------- GROUPE DE POINTS D'ARRET ---------------------------- */
+/* Indique si le point d'arrêt correspond à une origine donnée. */
+bool has_raw_breakpoint_previous_address(const raw_breakpoint *, RawBpOrigin, dbg_thread_id_t, virt_t);
 
-
-#define G_TYPE_BREAK_GROUP               g_break_group_get_type()
-#define G_BREAK_GROUP(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_break_group_get_type(), GBreakGroup))
-#define G_IS_BREAK_GROUP(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_break_group_get_type()))
-#define G_BREAK_GROUP_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_break_group_get_type(), GBreakGroupIface))
-#define G_BREAK_GROUP_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BREAK_GROUP, GBreakGroupClass))
-
-
-/* Propriétés d'un groupe de points d'arrêt (instance) */
-typedef struct _GBreakGroup GBreakGroup;
-
-/* Propriétés d'un groupe de points d'arrêt (classe) */
-typedef struct _GBreakGroupClass GBreakGroupClass;
-
-
-/* Indique le type défini pour les groupes de points d'errêt. */
-GType g_break_group_get_type(void);
-
-/* Construit un nouveau groupe de points d'arrêt. */
-GBreakGroup *g_break_group_new(void);
-
-/* Fournit la désignation humaine associée à un groupe. */
-const char *g_break_group_get_name(const GBreakGroup *);
-
-/* Définit la désignation humaine à associer à un groupe. */
-void g_break_group_set_name(GBreakGroup *, const char *);
-
-/* Indique si une adresse donnée est gérée dans un groupe. */
-bool g_break_group_has_address(const GBreakGroup *, vmpa_t);
-
-/* Ajoute ou supprime un point d'arrêt dans un groupe. */
-void g_break_group_toggle_breakpoint(GBreakGroup *, vmpa_t);
-
-/* Parcourt l'ensemble des points d'arrêt d'un groupe donné. */
-void g_break_group_for_each(GBreakGroup *, GExtFunc, gpointer);
+/* Indique si un point d'arrêt a encore une utilité. */
+bool is_breakpoint_useless(const raw_breakpoint *);
 
 
 
diff --git a/src/debug/debugger-int.h b/src/debug/debugger-int.h
index 06aa5d3..58153b8 100644
--- a/src/debug/debugger-int.h
+++ b/src/debug/debugger-int.h
@@ -28,7 +28,15 @@
 #include "debugger.h"
 
 
-#include <gtk/gtk.h>
+#include "break.h"
+
+
+
+//#include <gtk/gtk.h>////////////////////////////////////////////
+
+
+
+
 
 
 
@@ -39,16 +47,71 @@ typedef bool (* attach_debugger_fc) (GBinaryDebugger *);
 typedef bool (* basic_debugger_fc) (GBinaryDebugger *);
 
 /* Reprend une procédure de débogage. */
-typedef bool (* resume_debugger_fc) (GBinaryDebugger *);
+//typedef bool (* resume_debugger_fc) (GBinaryDebugger *);
 
 /* Fournit les identifiants de tous les threads actifs. */
-typedef pid_t * (* dbg_list_all_threads_fc) (GBinaryDebugger *, char ***, size_t *);
+//typedef pid_t * (* dbg_list_all_threads_fc) (GBinaryDebugger *, char ***, size_t *);
 
 /* Fournit la liste des frames courantes d'un thread donné. */
-typedef dbg_frame_t * (* dbg_get_frames_stack_fc) (GBinaryDebugger *, pid_t, size_t *);
+//typedef dbg_frame_t * (* dbg_get_frames_stack_fc) (GBinaryDebugger *, pid_t, size_t *);
 
 /* Fournit la valeur des registres de l'architecture. */
-typedef register_value * (* get_register_values_fc) (GBinaryDebugger *, size_t *);
+//typedef register_value * (* get_register_values_fc) (GBinaryDebugger *, size_t *);
+
+
+
+
+
+
+/* Fournit les identifiants de tous les threads actifs. */
+typedef dbg_thread_desc * (* list_all_threads_fc) (GBinaryDebugger *, size_t *);
+
+
+
+
+/* Lit une valeur quelconque à une adresse arbitraire. */
+typedef bool (* read_mem_any_fc) (GBinaryDebugger *, virt_t, size_t, ...);
+
+/* Ecrit une valeur quelconque à une adresse arbitraire. */
+typedef bool (* write_mem_any_fc) (GBinaryDebugger *, virt_t, size_t, ...);
+
+/* Liste l'ensemble des registres appartenant à un groupe. */
+typedef char ** (* get_reg_names_fc) (const GBinaryDebugger *, const char *, size_t *);
+
+/* Indique la taille associée à un registre donné. */
+typedef unsigned int (* get_reg_size_fc) (const GBinaryDebugger *, const char *);
+
+/* Lit une valeur quelconque à partir d'un registre. */
+typedef bool (* read_write_reg_any_fc) (GBinaryDebugger *, const char *, size_t, ...);
+
+
+
+/* Détermine le point d'exécution courant. */
+typedef bool (* get_current_pc_fc) (GBinaryDebugger *, virt_t *);
+
+/* Remonte la pile d'appels jusqu'au point courant. */
+typedef bool (* get_call_stack_fc) (GBinaryDebugger *, virt_t **, size_t *);
+
+
+
+/* Ajoute un point d'arrêt basique en mémoire. */
+typedef raw_breakpoint * (* enable_mem_bp_fc) (GBinaryDebugger *, virt_t);
+
+/* Retire un point d'arrêt basique en mémoire. */
+typedef bool (* disable_mem_bp_fc) (GBinaryDebugger *, raw_breakpoint *);
+
+/* Redémarre le processus de débogage lié à un serveur GDB. */
+typedef bool (* restart_debugger_fc) (GBinaryDebugger *);
+
+/* Remet en marche le débogueur courant. */
+typedef bool (* resume_debugger_fc) (GBinaryDebugger *);
+
+
+
+
+
+
+
 
 
 /* Définition des fonctionnalités d'un débogueur (instance) */
@@ -62,13 +125,13 @@ struct _GBinaryDebugger
 
     basic_debugger_fc run;                  /* Démarre le débogueur        */
     basic_debugger_fc pause;                /* Met en pause le débogueur   */
-    resume_debugger_fc resume;              /* Relance le débogueur        */
     basic_debugger_fc kill;                 /* Tue le débogueur            */
 
-    dbg_list_all_threads_fc all_threads;    /* Liste des threads actifs    */
-    dbg_get_frames_stack_fc frames_stack;   /* Pile des frames courantes   */
 
-    get_register_values_fc get_reg_values;  /* Obtient les valeurs de reg. */
+
+    raw_breakpoint **bpoints;               /* Points d'arrêt posés        */
+    size_t bp_count;                        /* Quantité de ces points posés*/
+    GRWLock bp_lock;                        /* Verrou d'accès à la liste   */
 
 };
 
@@ -78,13 +141,58 @@ struct _GBinaryDebuggerClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
+    list_all_threads_fc all_threads;        /* Liste des threads actifs    */
+
+    read_mem_any_fc read_mem;               /* Lecture d'une valeur XX bits*/
+    read_mem_any_fc write_mem;              /* Ecriture d'une valeur X bits*/
+    get_reg_names_fc get_reg_names;         /* Liste des registres         */
+    get_reg_size_fc get_reg_size;           /* Taille d'un registre donné  */
+    read_write_reg_any_fc read_reg;         /* Lecture de registre XX bits */
+    read_write_reg_any_fc write_reg;        /* Ecriture de registre XX bits*/
+
+    get_current_pc_fc get_current_pc;       /* Obtention du point d'exéc.  */
+    get_call_stack_fc get_call_stack;       /* Obtention de pile d'appels  */
+
+    enable_mem_bp_fc enable_bp;             /* Mise en place d'un arrêt    */
+    disable_mem_bp_fc disable_bp;           /* Retrait d'un point d'arrêt  */
+
+    restart_debugger_fc restart;            /* Redémarre le débogueur      */
+    resume_debugger_fc resume;              /* Relance le débogueur        */
+
     /* Signaux */
 
-    void (* debugger_stopped) (GBinaryDebugger *, uint64_t, uint64_t);
+    void (* signaled) (GBinaryDebugger *, int);
+    void (* exited) (GBinaryDebugger *, int, pid_t);
+    void (* terminated) (GBinaryDebugger *, int, pid_t);
+
+    void (* stopped) (GBinaryDebugger *, virt_t);
+
+
+
+
+    /* Signaux */
 
     void (* debugger_halted) (GBinaryDebugger *, int, vmpa_t, pid_t);
 
+
+
+
+
+    void (* mem_bp_handled) (GBinaryDebugger *, bool, virt_t);
+
 };
 
 
+
+/* ------------------------- MANIPULATION DE L'ETAT COURANT ------------------------- */
+
+
+/* Réagit à un arrêt du flot d'exécution. */
+void on_binary_debugger_stopped(GBinaryDebugger *, virt_t);
+
+/* Réagit à la fin de l'opération de débogage. */
+void on_binary_debugger_finished(GBinaryDebugger *, pid_t);
+
+
+
 #endif  /* _DEBUG_DEBUGGER_INT_H */
diff --git a/src/debug/debugger.c b/src/debug/debugger.c
index 331adc6..0dfe315 100644
--- a/src/debug/debugger.c
+++ b/src/debug/debugger.c
@@ -23,27 +23,70 @@
 
 #include "debugger.h"
 
+
+#include <assert.h>
+#include <inttypes.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+
+#include <i18n.h>
+
+
 #include "debugger-int.h"
-#include "jdwp/debugger.h"
-#include "remgdb/gdb.h"
+#include "../common/sort.h"
 #include "../glibext/chrysamarshal.h"
+#include "../gui/panels/log.h"
 #include "../plugins/pglist.h"
 
 
 
+/* ---------------------------- TRONC COMMUN DE DEBOGAGE ---------------------------- */
+
+
 /* Initialise la classe de base des débogueurs. */
 static void g_binary_debugger_class_init(GBinaryDebuggerClass *);
 
 /* Initialise une instance de base d'un débogueur. */
 static void g_binary_debugger_init(GBinaryDebugger *);
 
+/* Supprime toutes les références externes. */
+static void g_binary_debugger_dispose(GBinaryDebugger *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_binary_debugger_finalize(GBinaryDebugger *);
+
+
+
+/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */
+
+
+/* Active un point d'arrêt à un emplacement de mémoire donné. */
+static bool g_binary_debugger_insert_memory_breakpoint(GBinaryDebugger *, virt_t, RawBpOrigin, dbg_thread_id_t, virt_t);
+
+/* Désactive un point d'arrêt à un emplacement de mémoire donné. */
+static bool g_binary_debugger_remove_memory_breakpoint(GBinaryDebugger *, virt_t);
+
+/* Sème des points d'arrêt sur les instructions suivantes. */
+static bool g_binary_debugger_spread_breakpoints(GBinaryDebugger *, dbg_thread_id_t, virt_t, RawBpOrigin, bool);
+
+/* Retire tous les points d'arrêt issus d'un adresse. */
+static void g_binary_debugger_remove_same_breakpoints(GBinaryDebugger *, dbg_thread_id_t, virt_t, RawBpOrigin);
+
+/* Met à jour les points d'arrêt suite à un arrêt. */
+static bool g_binary_debugger_update_breakpoints_on_stop(GBinaryDebugger *, dbg_thread_id_t, virt_t);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                              TRONC COMMUN DE DEBOGAGE                              */
+/* ---------------------------------------------------------------------------------- */
 
 
 /* Indique le type définit pour une ligne de représentation. */
 G_DEFINE_TYPE(GBinaryDebugger, g_binary_debugger, G_TYPE_OBJECT);
 
 
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : klass = classe à initialiser.                                *
@@ -58,13 +101,46 @@ G_DEFINE_TYPE(GBinaryDebugger, g_binary_debugger, G_TYPE_OBJECT);
 
 static void g_binary_debugger_class_init(GBinaryDebuggerClass *klass)
 {
-    g_signal_new("debugger-stopped",
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_debugger_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_binary_debugger_finalize;
+
+    g_signal_new("signaled",
+                 G_TYPE_BINARY_DEBUGGER,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GBinaryDebuggerClass, signaled),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__INT,
+                 G_TYPE_NONE, 1, G_TYPE_INT);
+
+    g_signal_new("exited",
+                 G_TYPE_BINARY_DEBUGGER,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GBinaryDebuggerClass, exited),
+                 NULL, NULL,
+                 g_cclosure_user_marshal_VOID__INT_INT,
+                 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+
+    g_signal_new("terminated",
                  G_TYPE_BINARY_DEBUGGER,
                  G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GBinaryDebuggerClass, debugger_stopped),
+                 G_STRUCT_OFFSET(GBinaryDebuggerClass, terminated),
                  NULL, NULL,
-                 g_cclosure_user_marshal_VOID__UINT64_UINT64,
-                 G_TYPE_NONE, 2, G_TYPE_UINT64, G_TYPE_UINT64);
+                 g_cclosure_user_marshal_VOID__INT_INT,
+                 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+
+    g_signal_new("stopped",
+                 G_TYPE_BINARY_DEBUGGER,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GBinaryDebuggerClass, stopped),
+                 NULL, NULL,
+                 g_cclosure_user_marshal_VOID__UINT64,
+                 G_TYPE_NONE, 1, G_TYPE_UINT64);
+
+
 
     g_signal_new("halted",
                  G_TYPE_BINARY_DEBUGGER,
@@ -74,6 +150,18 @@ static void g_binary_debugger_class_init(GBinaryDebuggerClass *klass)
                  g_cclosure_user_marshal_VOID__INT_UINT64_INT,
                  G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_UINT64, G_TYPE_INT);
 
+
+
+
+
+    g_signal_new("mem-bp-handled",
+                 G_TYPE_BINARY_DEBUGGER,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GBinaryDebuggerClass, mem_bp_handled),
+                 NULL, NULL,
+                 g_cclosure_user_marshal_VOID__INT_UINT64_INT,
+                 G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_UINT64);
+
 }
 
 
@@ -91,51 +179,64 @@ static void g_binary_debugger_class_init(GBinaryDebuggerClass *klass)
 
 static void g_binary_debugger_init(GBinaryDebugger *debugger)
 {
+    g_rw_lock_init(&debugger->bp_lock);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : type   = type de débigueur choisi pour l'opération.          *
-*                binary = binaire devant être débogué.                        *
+*  Paramètres  : debugger = instance d'objet GLib à traiter.                  *
 *                                                                             *
-*  Description : Crée un nouveau débogueur.                                   *
+*  Description : Supprime toutes les références externes.                     *
 *                                                                             *
-*  Retour      : Composant GObject mis en place ou NULL.                      *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GBinaryDebugger *g_new_binary_debugger(DebuggerType type, GLoadedBinary *binary)
+static void g_binary_debugger_dispose(GBinaryDebugger *debugger)
 {
-    GBinaryDebugger *result;
+    g_object_unref(G_OBJECT(debugger->binary));
 
-    switch (type)
-    {
-        case DGT_JDWP:
-            result = g_java_debugger_new(binary, NULL);
-            break;
+    g_rw_lock_clear(&debugger->bp_lock);
 
-        case DGT_REMOTE_GDB:
-            result = g_gdb_debugger_new(binary, NULL);
-            break;
+    G_OBJECT_CLASS(g_binary_debugger_parent_class)->dispose(G_OBJECT(debugger));
 
-        default:
-            result = NULL;
-            break;
+}
 
-    }
 
-    if (result != NULL)
-        result->binary = binary;
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    return result;
+static void g_binary_debugger_finalize(GBinaryDebugger *debugger)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < debugger->bp_count; i++)
+        fini_raw_breakpoint(debugger->bpoints[i]);
+
+    if (debugger->bpoints != NULL)
+        free(debugger->bpoints);
+
+    G_OBJECT_CLASS(g_binary_debugger_parent_class)->finalize(G_OBJECT(debugger));
 
 }
 
 
+
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : debugger = débogueur à manipuler ici.                        *
@@ -196,11 +297,13 @@ void g_binary_debugger_run(GBinaryDebugger *debugger)
 }
 
 
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : debugger = débogueur à manipuler ici.                        *
 *                                                                             *
-*  Description : Reprend une procédure de débogage.                           *
+*  Description : Tue une procédure de débogage.                               *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -208,18 +311,37 @@ void g_binary_debugger_run(GBinaryDebugger *debugger)
 *                                                                             *
 ******************************************************************************/
 
-void g_binary_debugger_resume(GBinaryDebugger *debugger)
+void g_binary_debugger_kill(GBinaryDebugger *debugger)
 {
-    debugger->resume(debugger);
+    debugger->kill(debugger);
 
 }
 
 
+
+
+
+
+
+
+
+
+
+/* ------------------- MANIPULATION DES DIFFERENTS THREADS ACTIFS ------------------- */
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                     MANIPULATION DES DIFFERENTS THREADS ACTIFS                     */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*  Paramètres  : list  = descriptions à supprimer de la mémoire.              *
+*                count = taille de cette liste.                               *
 *                                                                             *
-*  Description : Tue une procédure de débogage.                               *
+*  Description : Libère la mémoire d'une liste de threads actifs.             *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -227,9 +349,15 @@ void g_binary_debugger_resume(GBinaryDebugger *debugger)
 *                                                                             *
 ******************************************************************************/
 
-void g_binary_debugger_kill(GBinaryDebugger *debugger)
+void delete_dbg_thread_desc(dbg_thread_desc *list, size_t count)
 {
-    debugger->kill(debugger);
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < count; i++)
+        free(list[i].name);
+
+    if (list != NULL)
+        free(list);
 
 }
 
@@ -242,50 +370,212 @@ void g_binary_debugger_kill(GBinaryDebugger *debugger)
 *                                                                             *
 *  Description : Fournit les identifiants de tous les threads actifs.         *
 *                                                                             *
-*  Retour      : Liste des threads décomptés.                                 *
+*  Retour      : Liste des threads décomptés, à libérer de la mémoire ensuite.*
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-pid_t *g_binary_debugger_list_all_threads(GBinaryDebugger *debugger, char ***names, size_t *count)
+dbg_thread_desc *g_binary_debugger_list_all_threads(GBinaryDebugger *debugger, size_t *count)
 {
-    pid_t *result;                          /* Liste à retourner           */
+    dbg_thread_desc *result;                /* Liste à retourner           */
 
-    if (debugger->all_threads != NULL)
-        result = debugger->all_threads(debugger, names, count);
-    else
-        result = NULL;
+    *count = 0;
+
+    result = G_BINARY_DEBUGGER_GET_CLASS(debugger)->all_threads(debugger, count);
+
+    if (result != NULL)
+    {
+        int cmp_dbg_thread_desc(const dbg_thread_desc *a, const dbg_thread_desc *b)
+        {
+            int status;                     /* Bilan à retourner           */
+
+            if (a->id < b->id)
+                status = -1;
+
+            if (a->id > b->id)
+                status = 1;
+
+            else
+                status = -1;
+
+            return status;
+
+        }
+
+        qsort(result, *count, sizeof(dbg_thread_desc), (__compar_fn_t)cmp_dbg_thread_desc);
+
+    }
 
     return result;
 
 }
 
 
+
+
+
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                             ENTREES / SORTIES BASIQUES                             */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : debugger = instance du module de débogage chargé.            *
-*                thread   = thread concerné par l'analyse.                    *
-*                count    = nombre de frames en place. [OUT]                  *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir consulter.         *
+*                value    = emplacement de la valeur lue à conserver. [OUT]   *
 *                                                                             *
-*  Description : Fournit la liste des frames courantes d'un thread donné.     *
+*  Description : Lit une valeur de 8 bits à une adresse arbitraire.           *
 *                                                                             *
-*  Retour      : Liste des frames trouvées.                                   *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-dbg_frame_t *g_binary_debugger_get_frames_stack(GBinaryDebugger *debugger, pid_t thread, size_t *count)
+bool g_binary_debugger_read_memory_u8(GBinaryDebugger *debugger, virt_t addr, uint8_t *value)
 {
-    dbg_frame_t *result;                    /* Liste à retourner           */
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->read_mem(debugger, addr, 8, value);
 
-    if (debugger->frames_stack != NULL)
-        result = debugger->frames_stack(debugger, thread, count);
-    else
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir consulter.         *
+*                value    = emplacement de la valeur lue à conserver. [OUT]   *
+*                                                                             *
+*  Description : Lit une valeur de 16 bits à une adresse arbitraire.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_read_memory_u16(GBinaryDebugger *debugger, virt_t addr, uint16_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->read_mem(debugger, addr, 16, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir consulter.         *
+*                value    = emplacement de la valeur lue à conserver. [OUT]   *
+*                                                                             *
+*  Description : Lit une valeur de 32 bits à une adresse arbitraire.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_read_memory_u32(GBinaryDebugger *debugger, virt_t addr, uint32_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->read_mem(debugger, addr, 32, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir consulter.         *
+*                value    = emplacement de la valeur lue à conserver. [OUT]   *
+*                                                                             *
+*  Description : Lit une valeur de 64 bits à une adresse arbitraire.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_read_memory_u64(GBinaryDebugger *debugger, virt_t addr, uint64_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->read_mem(debugger, addr, 64, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir consulter.         *
+*                value    = emplacement de la valeur lue à conserver. [OUT]   *
+*                len      = taille attendue de la valeur en octets.           *
+*                                                                             *
+*  Description : Lit une valeur de taille quelconque à une adresse arbitraire.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_read_memory_data(GBinaryDebugger *debugger, virt_t addr, uint8_t *value, size_t len)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t iter;                            /* Tête de lecture / écriture  */
+    size_t remaining;                       /* Quantité restant à replacer */
+
+    result = true;
+
+    iter = 0;
+    remaining = len;
+
+    while (result && remaining > 0)
     {
-        *count = 0;
-        result = NULL;
+        if (remaining >= 8)
+        {
+            result = g_binary_debugger_read_memory_u64(debugger, addr + iter, (uint64_t *)&value[iter]);
+
+            iter += 8;
+            remaining -= 8;
+
+        }
+
+        else if (remaining >= 4)
+        {
+            result = g_binary_debugger_read_memory_u32(debugger, addr + iter, (uint32_t *)(&value[iter]));
+
+            iter += 4;
+            remaining -= 4;
+
+        }
+
+        else if (remaining >= 2)
+        {
+            result = g_binary_debugger_read_memory_u16(debugger, addr + iter, (uint16_t *)&value[iter]);
+
+            iter += 2;
+            remaining -= 2;
+
+        }
+
+        else if (remaining >= 1)
+        {
+            result = g_binary_debugger_read_memory_u8(debugger, addr + iter, (uint8_t *)&value[iter]);
+
+            iter += 1;
+            remaining -= 1;
+
+        }
+
+        else
+            assert(false);
+
     }
 
     return result;
@@ -295,19 +585,1164 @@ dbg_frame_t *g_binary_debugger_get_frames_stack(GBinaryDebugger *debugger, pid_t
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : debugger = débogueur à manipuler ici.                        *
-*                count    = nombre de transmissions effetuées.                *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir modifier.          *
+*                value    = emplacement de la valeur à inscrire.              *
+*                                                                             *
+*  Description : Ecrit une valeur de 8 bits à une adresse arbitraire.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_write_memory_u8(GBinaryDebugger *debugger, virt_t addr, const uint8_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->write_mem(debugger, addr, 8, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir modifier.          *
+*                value    = emplacement de la valeur à inscrire.              *
+*                                                                             *
+*  Description : Ecrit une valeur de 16 bits à une adresse arbitraire.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_write_memory_u16(GBinaryDebugger *debugger, virt_t addr, const uint16_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->write_mem(debugger, addr, 16, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir modifier.          *
+*                value    = emplacement de la valeur à inscrire.              *
+*                                                                             *
+*  Description : Ecrit une valeur de 32 bits à une adresse arbitraire.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_write_memory_u32(GBinaryDebugger *debugger, virt_t addr, const uint32_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->write_mem(debugger, addr, 32, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir modifier.          *
+*                value    = emplacement de la valeur à inscrire.              *
 *                                                                             *
-*  Description : Fournit la valeur des registres de l'architecture.           *
+*  Description : Ecrit une valeur de 64 bits à une adresse arbitraire.        *
 *                                                                             *
-*  Retour      : Tableau de valeurs transmises à libérer de la mémoire / NULL.*
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-register_value *g_binary_debugger_get_registers(GBinaryDebugger *debugger, size_t *count)
+bool g_binary_debugger_write_memory_u64(GBinaryDebugger *debugger, virt_t addr, const uint64_t *value)
 {
-    return debugger->get_reg_values(debugger, count);
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->write_mem(debugger, addr, 64, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                addr     = emplacement en mémoire à venir modifier.          *
+*                value    = emplacement de la valeur à incrire.               *
+*                len      = taille de la valeur fournie en octets.            *
+*                                                                             *
+*  Description : Ecrit une valeur de taille quelconque à une adresse donnée.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_write_memory_data(GBinaryDebugger *debugger, virt_t addr, const uint8_t *value, size_t len)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t iter;                            /* Tête de lecture / écriture  */
+    size_t remaining;                       /* Quantité restant à replacer */
+
+    result = true;
+
+    iter = 0;
+    remaining = len;
+
+    while (result && remaining > 0)
+    {
+        if (remaining >= 8)
+        {
+            result = g_binary_debugger_write_memory_u64(debugger, addr + iter, (uint64_t *)&value[iter]);
+
+            iter += 8;
+            remaining -= 8;
+
+        }
+
+        else if (remaining >= 4)
+        {
+            result = g_binary_debugger_write_memory_u32(debugger, addr + iter, (uint32_t *)&value[iter]);
+
+            iter += 4;
+            remaining -= 4;
+
+        }
+
+        else if (remaining >= 2)
+        {
+            result = g_binary_debugger_write_memory_u16(debugger, addr + iter, (uint16_t *)&value[iter]);
+
+            iter += 2;
+            remaining -= 2;
+
+        }
+
+        else if (remaining >= 1)
+        {
+            result = g_binary_debugger_write_memory_u8(debugger, addr + iter, (uint8_t *)&value[iter]);
+
+            iter += 1;
+            remaining -= 1;
+
+        }
+
+        else
+            assert(false);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                group    = éventuel groupe de registres ciblé ou NULL.       *
+*                count    = nombre d'éléments dans la liste de noms. [OUT]    *
+*                                                                             *
+*  Description : Liste l'ensemble des registres appartenant à un groupe.      *
+*                                                                             *
+*  Retour      : Liste de noms à libérer de la mémoire après utilisation.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char **g_binary_debugger_get_register_names(const GBinaryDebugger *debugger, const char *group, size_t *count)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->get_reg_names(debugger, group, count);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                name     = désignation du registre visé.                     *
+*                                                                             *
+*  Description : Indique la taille associée à un registre donné.              *
+*                                                                             *
+*  Retour      : Taille en bits, ou 0 si le registre n'a pas été trouvé.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int g_binary_debugger_get_register_size(const GBinaryDebugger *debugger, const char *name)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->get_reg_size(debugger, name);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                value    =  emplacement de la valeur lue à conserver. [OUT]  *
+*                                                                             *
+*  Description : Lit une valeur de 8 bits à partir d'un registre.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_read_register_u8(GBinaryDebugger *debugger, const char *reg, uint8_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->read_reg(debugger, reg, 8, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                value    =  emplacement de la valeur lue à conserver. [OUT]  *
+*                                                                             *
+*  Description : Lit une valeur de 16 bits à partir d'un registre.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_read_register_u16(GBinaryDebugger *debugger, const char *reg, uint16_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->read_reg(debugger, reg, 16, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                value    =  emplacement de la valeur lue à conserver. [OUT]  *
+*                                                                             *
+*  Description : Lit une valeur de 32 bits à partir d'un registre.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_read_register_u32(GBinaryDebugger *debugger, const char *reg, uint32_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->read_reg(debugger, reg, 32, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                value    =  emplacement de la valeur lue à conserver. [OUT]  *
+*                                                                             *
+*  Description : Lit une valeur de 64 bits à partir d'un registre.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_read_register_u64(GBinaryDebugger *debugger, const char *reg, uint64_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->read_reg(debugger, reg, 64, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                value    =  emplacement de la valeur à écrire.               *
+*                                                                             *
+*  Description : Ecrit une valeur de 8 bits dans un registre.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_write_register_u8(GBinaryDebugger *debugger, const char *reg, const uint8_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->write_reg(debugger, reg, 8, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                value    =  emplacement de la valeur à écrire.               *
+*                                                                             *
+*  Description : Ecrit une valeur de 16 bits dans un registre.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_write_register_u16(GBinaryDebugger *debugger, const char *reg, const uint16_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->write_reg(debugger, reg, 16, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                value    =  emplacement de la valeur à écrire.               *
+*                                                                             *
+*  Description : Ecrit une valeur de 32 bits dans un registre.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_write_register_u32(GBinaryDebugger *debugger, const char *reg, const uint32_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->write_reg(debugger, reg, 32, value);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                value    =  emplacement de la valeur à écrire.               *
+*                                                                             *
+*  Description : Ecrit une valeur de 64 bits dans un registre.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_write_register_u64(GBinaryDebugger *debugger, const char *reg, const uint64_t *value)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->write_reg(debugger, reg, 64, value);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           MANIPULATION DE L'ETAT COURANT                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                pc       = adresse de l'instruction courante. [OUT]          *
+*                                                                             *
+*  Description : Détermine le point d'exécution courant.                      *
+*                                                                             *
+*  Retour      : Bilan de la récupération.                                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_get_current_pc(GBinaryDebugger *debugger, virt_t *pc)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = G_BINARY_DEBUGGER_GET_CLASS(debugger)->get_current_pc(debugger, pc);
+
+    if (!result)
+        log_variadic_message(LMT_WARNING, "Unable to get the current PC!");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                pc       = adresse de l'instruction de retour d'appel. [OUT] *
+*                                                                             *
+*  Description : Détermine l'adresse du premier retour d'appel.               *
+*                                                                             *
+*  Retour      : Bilan de la récupération.                                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_get_return_pc(GBinaryDebugger *debugger, virt_t *pc)
+{
+    bool result;                            /* Bilan à retourner           */
+    virt_t *callstack;                      /* Pile d'appels courante      */
+    size_t size;                            /* Hauteur de cette pile       */
+
+    result = g_binary_debugger_get_call_stack(debugger, &callstack, &size);
+
+    if (result && size > 0)
+        *pc = callstack[size - 1];
+
+    if (callstack != NULL)
+        free(callstack);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                over     = indique si les appels doivent être sautés ou non. *
+*                count    = nombre d'adresses identifiées.                    *
+*                                                                             *
+*  Description : Détermine les prochaines probables instructions exécutées.   *
+*                                                                             *
+*  Retour      : Liste d'adresses à libérer de la mémoire après usage.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *debugger, virt_t pc, bool over, size_t *count)
+{
+    virt_t *result;                         /* Liste à retourner           */
+    GArchProcessor *proc;                   /* Processeur lié au binaire   */
+    vmpa2t addr;                            /* Localisation à cibler       */
+    instr_iter_t *iter;                     /* Parcours local d'adresses   */
+    GArchInstruction *instr;                /* Instruction correspondante  */
+    virt_t ret;                             /* Adresse de retour d'appel   */
+    instr_link_t *dests;                    /* Instr. visées par une autre */
+    size_t dcount;                          /* Nombre de liens de dest.    */
+    size_t i;                               /* Boucle de parcours          */
+    const mrange_t *range;                  /* Emplacement d'instruction   */
+
+    result = NULL;
+    *count = 0;
+
+    proc = g_loaded_binary_get_processor(debugger->binary);
+
+    init_vmpa(&addr, VMPA_NO_PHYSICAL, pc);
+    iter = g_arch_processor_get_iter_from_address(proc, &addr);
+
+    if (iter != NULL)
+    {
+        instr = get_instruction_iterator_current(iter);
+
+        /* Si l'instruction est un retour à l'appelant */
+        if (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
+        {
+            if (g_binary_debugger_get_return_pc(debugger, &ret))
+            {
+                *count = 1;
+                result = (virt_t *)malloc(sizeof(virt_t));
+
+                result[0] = ret;
+
+            }
+
+        }
+
+        /* Sinon on se penche sur ses destinations */
+        else
+        {
+            g_arch_instruction_rlock_dest(instr);
+
+            dcount = g_arch_instruction_get_destinations(instr, &dests);
+
+            for (i = 0; i < dcount; i++)
+                switch (dests[i].type)
+                {
+                    case ILT_EXEC_FLOW:
+                    case ILT_JUMP:
+                    case ILT_CASE_JUMP:
+                    case ILT_JUMP_IF_TRUE:
+                    case ILT_JUMP_IF_FALSE:
+                    case ILT_LOOP:
+
+                        (*count)++;
+                        result = (virt_t *)realloc(result, *count * sizeof(virt_t));
+
+                        range = g_arch_instruction_get_range(dests[i].linked);
+
+                        result[*count - 1] = get_virt_addr(get_mrange_addr(range));
+                        break;
+
+                    case ILT_CALL:
+
+                        if (!over)
+                        {
+                            (*count)++;
+                            result = (virt_t *)realloc(result, *count * sizeof(virt_t));
+
+                            range = g_arch_instruction_get_range(dests[i].linked);
+
+                            result[*count - 1] = get_virt_addr(get_mrange_addr(range));
+
+                        }
+
+                        break;
+
+                    default:
+                        break;
+
+                }
+
+            g_arch_instruction_runlock_dest(instr);
+
+            /* Si tout ça ne donne rien, on se rabat sur l'instruction suivante par défaut */
+            if (*count == 0)
+            {
+                g_object_unref(G_OBJECT(instr));
+
+                instr = get_instruction_iterator_next(iter);
+
+                if (instr != NULL)
+                {
+                    *count = 1;
+                    result = (virt_t *)malloc(sizeof(virt_t));
+
+                    range = g_arch_instruction_get_range(instr);
+
+                    result[0] = get_virt_addr(get_mrange_addr(range));
+
+                }
+
+            }
+
+        }
+
+        if (instr != NULL)
+            g_object_unref(G_OBJECT(instr));
+
+        delete_instruction_iterator(iter);
+
+    }
+
+    g_object_unref(G_OBJECT(proc));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger  = débogueur à consulter.                           *
+*                callstack = pile d'appels reconstituée. [OUT]                *
+*                size      = taille de cette pile. [OUT]                      *
+*                                                                             *
+*  Description : Remonte la pile d'appels jusqu'au point courant.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_get_call_stack(GBinaryDebugger *debugger, virt_t **callstack, size_t *size)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    *callstack = NULL;
+    *size = 0;
+
+    result = G_BINARY_DEBUGGER_GET_CLASS(debugger)->get_call_stack(debugger, callstack, size);
+
+    if (!result)
+    {
+        if (*callstack != NULL)
+            free(*callstack);
+
+        *callstack = NULL;
+        *size = 0;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                pc       = adresse de l'instruction courante.                *
+*                                                                             *
+*  Description : Réagit à un arrêt du flot d'exécution.                       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void on_binary_debugger_stopped(GBinaryDebugger *debugger, virt_t pc)
+{
+    pid_t tid;                              /* Identifiant du thread       */
+    bool auto_resume;                       /* Poursuite automatique ?     */
+
+    tid = 1;    // FIXME
+
+    auto_resume = g_binary_debugger_update_breakpoints_on_stop(debugger, tid, pc);
+
+    if (!auto_resume)
+        g_signal_emit_by_name(debugger, "stopped", pc);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                pid      = éventuel identifiant de processus concerné ou -1. *
+*                                                                             *
+*  Description : Réagit à la fin de l'opération de débogage.                  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void on_binary_debugger_finished(GBinaryDebugger *debugger, pid_t pid)
+{
+
+    /* TODO : libérer de la mémoire tous les BP */
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                             GESTION DES POINTS D'ARRET                             */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                addr     = emplacement du point mémoire à traiter.           *
+*                origin   = origine de la création du point d'arrêt.          *
+*                tid      = identifiant du thread concerné.                   *
+*                previous = éventuelle adresse précédent celle du point.      *
+*                                                                             *
+*  Description : Active un point d'arrêt à un emplacement de mémoire donné.   *
+*                                                                             *
+*  Retour      : true si la demande a été prise en compte, false sinon.       *
+*                                                                             *
+*  Remarques   : L'accès à la liste doit être placée sous la protection de    *
+*                l'appelant.                                                  *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_debugger_insert_memory_breakpoint(GBinaryDebugger *debugger, virt_t addr, RawBpOrigin origin, dbg_thread_id_t tid, virt_t previous)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t index;                           /* Indice de ce point d'arrêt  */
+    bool found;                             /* Présence d'un point d'arrêt */
+    raw_breakpoint *bp;                     /* Point d'arrêt à constituer  */
+
+    result = false;
+
+    found = bsearch_index(&addr, debugger->bpoints, debugger->bp_count, sizeof(raw_breakpoint *),
+                          (__compar_fn_t)compare_raw_breakpoint_with_addr, &index);
+
+    if (found)
+    {
+        bp = debugger->bpoints[index];
+        result = true;
+    }
+
+    else
+    {
+        bp = G_BINARY_DEBUGGER_GET_CLASS(debugger)->enable_bp(debugger, addr);
+
+        if (bp != NULL)
+        {
+            debugger->bpoints = (raw_breakpoint **)qinsert(debugger->bpoints, &debugger->bp_count,
+                                                           sizeof(raw_breakpoint *),
+                                                           (__compar_fn_t)compare_raw_breakpoints, &bp);
+            result = true;
+        }
+
+    }
+
+    if (result)
+        set_raw_breakpoint_origin(bp, origin, tid, previous);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                index    = indice du point à supprimer.                      *
+*                                                                             *
+*  Description : Désactive un point d'arrêt à un emplacement de mémoire donné.*
+*                                                                             *
+*  Retour      : true si la demande a été prise en compte, false sinon.       *
+*                                                                             *
+*  Remarques   : L'accès à la liste doit être placée sous la protection de    *
+*                l'appelant.                                                  *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_debugger_remove_memory_breakpoint(GBinaryDebugger *debugger, size_t index)
+{
+    bool result;                            /* Bilan à retourner           */
+    raw_breakpoint *bp;                     /* Point d'arrêt à manipuler   */
+
+    result = false;
+
+    assert(index < debugger->bp_count);
+
+    bp = debugger->bpoints[index];
+
+    result = G_BINARY_DEBUGGER_GET_CLASS(debugger)->disable_bp(debugger, bp);
+
+    if (result)
+    {
+        debugger->bpoints = (raw_breakpoint **)_qdelete(debugger->bpoints, &debugger->bp_count,
+                                                        sizeof(raw_breakpoint *), index);
+
+        fini_raw_breakpoint(bp);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                tid      = identifiant du thread concerné.                   *
+*                pc       = adresse de l'instruction courante.                *
+*                type     = type de point d'arrêt à insérer.                  *
+*                over     = indique si les appels doivent être sautés ou non. *
+*                                                                             *
+*  Description : Sème des points d'arrêt sur les instructions suivantes.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_debugger_spread_breakpoints(GBinaryDebugger *debugger, dbg_thread_id_t tid, virt_t pc, RawBpOrigin type, bool over)
+{
+    bool result;                            /* Bilan à retourner           */
+    virt_t *next_list;                      /* Liste de points d'arrêts    */
+    size_t next_count;                      /* Taille de cette liste       */
+    GArchProcessor *proc;                   /* Processeur lié au binaire   */
+    size_t i;                               /* Boucle de parcours          */
+    vmpa2t addr;                            /* Format d'adresse complet    */
+    GArchInstruction *instr;                /* Instruction ciblée          */
+    bool valid;                             /* Point d'arrêt pertinent ?   */
+    const char *encoding;                   /* Encodage de l'instruction   */
+
+    result = true;
+
+    next_list = g_binary_debugger_get_next_pcs(debugger, pc, over, &next_count);
+
+    if (next_count == 0)
+        log_variadic_message(LMT_WARNING, "No instruction found to break after 0x%" PRIx64, pc);
+
+    proc = g_loaded_binary_get_processor(debugger->binary);
+
+    /**
+     * Le verrou sur la liste des points est normalement déjà posé.
+     */
+
+    for (i = 0; i < next_count && result; i++)
+    {
+        /**
+         * Des données peuvent suivre du code (typiquement en ARM).
+         * On réalise une validation minimale au préalable donc.
+         */
+
+        init_vmpa(&addr, VMPA_NO_PHYSICAL, next_list[i]);
+        instr = g_arch_processor_find_instr_by_address(proc, &addr);
+
+        if (instr == NULL)
+            valid = false;
+
+        else
+        {
+            encoding = g_arch_instruction_get_encoding(instr);
+
+            valid = strcmp(encoding, _("String")) != 0
+                    && strcmp(encoding, _("Raw")) != 0
+                    && strcmp(encoding, _("Undefined")) != 0;
+
+            g_object_unref(G_OBJECT(instr));
+
+        }
+
+        if (valid)
+            result = g_binary_debugger_insert_memory_breakpoint(debugger, next_list[i], type, tid, pc);
+
+    }
+
+    if (next_list != NULL)
+        free(next_list);
+
+    g_object_unref(G_OBJECT(proc));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                tid      = identifiant du thread concerné.                   *
+*                prev     = adresse d'instruction qui a conduit à des poses.  *
+*                type     = type de point d'arrêt à insérer.                  *
+*                                                                             *
+*  Description : Retire tous les points d'arrêt issus d'un adresse.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_debugger_remove_same_breakpoints(GBinaryDebugger *debugger, dbg_thread_id_t tid, virt_t prev, RawBpOrigin type)
+{
+    size_t i;                               /* Boucle de parcours          */
+    raw_breakpoint *bp;                     /* Confort de l'accès rapide   */
+
+    /**
+     * Le verrou sur la liste des points est normalement déjà posé.
+     */
+
+    for (i = 0; i < debugger->bp_count; i++)
+    {
+        bp = debugger->bpoints[i];
+
+        if (has_raw_breakpoint_previous_address(bp, type, tid, prev))
+            unset_raw_breakpoint_origin(bp, type, tid);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                tid      = identifiant du thread concerné.                   *
+*                pc       = adresse de l'instruction courante.                *
+*                                                                             *
+*  Description : Met à jour les points d'arrêt suite à un arrêt.              *
+*                                                                             *
+*  Retour      : true si l'exécution a été relancée automatiquement.          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_debugger_update_breakpoints_on_stop(GBinaryDebugger *debugger, dbg_thread_id_t tid, virt_t pc)
+{
+    bool result;                            /* Indication à faire remonter */
+    size_t index;                           /* Indice de ce point d'arrêt  */
+    bool found;                             /* Présence d'un point d'arrêt */
+    raw_breakpoint *bp;                     /* Confort de l'accès rapide   */
+    virt_t previous;                        /* Adresse d'origine           */
+    bool status;                            /* Bilan d'un retrait          */
+    size_t i;                               /* Boucle de parcours          */
+    virt_t addr;                            /* Localisation d'un point     */
+
+    result = false;
+
+    g_rw_lock_writer_lock(&debugger->bp_lock);
+
+    found = bsearch_index(&pc, debugger->bpoints, debugger->bp_count, sizeof(raw_breakpoint *),
+                          (__compar_fn_t)compare_raw_breakpoint_with_addr, &index);
+
+    if (found)
+    {
+        bp = debugger->bpoints[index];
+
+        /* S'il s'agissait d'un point d'arrêt à usage interne */
+        if (has_raw_breakpoint_origin(bp, RBO_INTERNAL, tid))
+        {
+            previous = get_raw_breakpoint_prev_addr(bp);
+            assert(previous != VMPA_NO_VIRTUAL);
+
+            g_binary_debugger_remove_same_breakpoints(debugger, tid, previous, RBO_INTERNAL);
+
+            assert(!has_raw_breakpoint_origin(bp, RBO_INTERNAL, tid));
+
+            result = true;
+
+        }
+
+        /* S'il s'agissait d'un arrêt demandé par l'utilisateur */
+        if (has_raw_breakpoint_origin(bp, RBO_USER, tid))
+        {
+            status = G_BINARY_DEBUGGER_GET_CLASS(debugger)->disable_bp(debugger, bp);
+
+            if (!status)
+                log_variadic_message(LMT_ERROR, "Error while removing the breakpoint at 0x%" PRIx64, pc);
+
+            g_binary_debugger_spread_breakpoints(debugger, tid, pc, RBO_INTERNAL, false);
+
+            result = false;
+
+        }
+
+        /* S'il s'agissait d'une progression pas à pas */
+        if (has_raw_breakpoint_origin(bp, RBO_STEP, tid))
+        {
+            previous = get_raw_breakpoint_prev_addr(bp);
+            assert(previous != VMPA_NO_VIRTUAL);
+
+            g_binary_debugger_remove_same_breakpoints(debugger, tid, previous, RBO_STEP);
+
+            assert(!has_raw_breakpoint_origin(bp, RBO_STEP, tid));
+
+            result = false;
+
+        }
+
+        /* En conclusion, on supprime les points inutiles */
+        for (i = 0; i < debugger->bp_count; )
+        {
+            bp = debugger->bpoints[i];
+
+            if (is_breakpoint_useless(bp))
+            {
+                status = g_binary_debugger_remove_memory_breakpoint(debugger, i);
+
+                if (!status)
+                {
+                    addr = get_raw_breakpoint_addr(bp);
+                    log_variadic_message(LMT_ERROR, "Error while removing the breakpoint at 0x%" PRIx64, addr);
+                    i++;
+                }
+
+            }
+
+            else i++;
+
+        }
+
+    }
+
+    g_rw_lock_writer_unlock(&debugger->bp_lock);
+
+    if (result)
+        G_BINARY_DEBUGGER_GET_CLASS(debugger)->resume(debugger);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                addr     = emplacement du point mémoire à traiter.           *
+*                                                                             *
+*  Description : Ajoute un point d'arrêt basique en mémoire.                  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_add_memory_breakpoint(GBinaryDebugger *debugger, virt_t addr)
+{
+    bool result;                            /* Bilan à retourner           */
+    dbg_thread_id_t tid;                    /* Identifiant de thread       */
+
+    tid = 1;/// FIXME
+
+    g_rw_lock_writer_lock(&debugger->bp_lock);
+
+    result = g_binary_debugger_insert_memory_breakpoint(debugger, addr, RBO_USER, tid, VMPA_NO_VIRTUAL);
+
+    g_rw_lock_writer_unlock(&debugger->bp_lock);
+
+    if (result)
+        g_signal_emit_by_name(debugger, "mem-bp-handled", true, addr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                addr     = emplacement du point mémoire à traiter.           *
+*                                                                             *
+*  Description : Retire un point d'arrêt basique en mémoire.                  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_delete_memory_breakpoint(GBinaryDebugger *debugger, virt_t addr)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t index;                           /* Indice de ce point d'arrêt  */
+    raw_breakpoint *bp;                     /* Confort de l'accès rapide   */
+    dbg_thread_id_t tid;                    /* Identifiant de thread       */
+
+    g_rw_lock_writer_lock(&debugger->bp_lock);
+
+    result = bsearch_index(&addr, debugger->bpoints, debugger->bp_count, sizeof(raw_breakpoint *),
+                           (__compar_fn_t)compare_raw_breakpoint_with_addr, &index);
+
+    if (result)
+    {
+        bp = debugger->bpoints[index];
+
+        tid = 1;/// FIXME
+
+        result = has_raw_breakpoint_origin(bp, RBO_USER, tid);
+
+        if (result)
+        {
+            unset_raw_breakpoint_origin(bp, RBO_USER, tid);
+
+            if (is_breakpoint_useless(bp))
+                result = g_binary_debugger_remove_memory_breakpoint(debugger, index);
+
+        }
+
+    }
+
+    g_rw_lock_writer_unlock(&debugger->bp_lock);
+
+    if (result)
+        g_signal_emit_by_name(debugger, "mem-bp-handled", false, addr);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            CONTROLE DU FLOT D'EXECUTION                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à redémarrer.                           *
+*                                                                             *
+*  Description : Redémarre le processus de débogage.                          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_restart(GBinaryDebugger *debugger)
+{
+    return G_BINARY_DEBUGGER_GET_CLASS(debugger)->restart(debugger);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                                                                             *
+*  Description : Remet en marche le débogueur courant.                        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_resume(GBinaryDebugger *debugger)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = G_BINARY_DEBUGGER_GET_CLASS(debugger)->resume(debugger);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                over     = indique si les appels doivent être sautés ou non. *
+*                                                                             *
+*  Description : Relance l'exécution pour une seule instruction.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_debugger_stepi(GBinaryDebugger *debugger, bool over)
+{
+    bool result;                            /* Bilan à retourner           */
+    virt_t pc;                              /* Position courante           */
+    dbg_thread_id_t tid;                    /* Identifiant de thread       */
+
+    result = g_binary_debugger_get_current_pc(debugger, &pc);
+
+    if (result)
+    {
+        tid = 1;/// FIXME
+
+        g_rw_lock_writer_lock(&debugger->bp_lock);
+
+        result = g_binary_debugger_spread_breakpoints(debugger, tid, pc, RBO_STEP, over);
+
+        g_rw_lock_writer_unlock(&debugger->bp_lock);
+
+    }
+
+    if (result)
+        result = G_BINARY_DEBUGGER_GET_CLASS(debugger)->resume(debugger);
+
+    return result;
 
 }
diff --git a/src/debug/debugger.h b/src/debug/debugger.h
index 6553b6d..1050e4e 100644
--- a/src/debug/debugger.h
+++ b/src/debug/debugger.h
@@ -27,51 +27,23 @@
 
 #include <glib-object.h>
 #include <stdint.h>
-#include <sys/types.h>
 
 
+#include "misc.h"
 #include "../analysis/binary.h"
 #include "../arch/archbase.h"
 
 
 
-/* Liste de tous les débogueurs */
-typedef enum _DebuggerType
-{
-    DGT_JDWP,                               /* Utilisation du JDWP         */
-    DGT_REMOTE_GDB,                         /* Utilisation de GDB          */
-    DGT_PTRACE,                             /* Utilisation de ptrace()     */
-
-    DGT_COUNT2/* FIXME */
-
-} DebuggerType;
-
-
-/* Définition d'une frame */
-typedef struct _dbg_frame_t
-{
-
-    vmpa_t addr;                            /* Position dans le code       */
-
-} dbg_frame_t;
-
-
-
-/* Transmission des valeurs des registres */
-typedef struct _register_value
-{
-    const char *name;                       /* Nom à ne pas libérer        */
-    uint64_t value;                         /* Valeur (taille maximale)    */
-
-} register_value;
+/* ---------------------------- TRONC COMMUN DE DEBOGAGE ---------------------------- */
 
 
 #define G_TYPE_BINARY_DEBUGGER              g_binary_debugger_get_type()
 #define G_BINARY_DEBUGGER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_debugger_get_type(), GBinaryDebugger))
 #define G_IS_BINARY_DEBUGGER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_debugger_get_type()))
-#define G_BINARY_DEBUGGER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BINARY_DEBUGGER, GGBinaryDebuggerClass))
+#define G_BINARY_DEBUGGER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BINARY_DEBUGGER, GBinaryDebuggerClass))
 #define G_IS_BINARY_DEBUGGER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BINARY_DEBUGGER))
-#define G_BINARY_DEBUGGER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BINARY_DEBUGGER, GGBinaryDebuggerClass))
+#define G_BINARY_DEBUGGER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BINARY_DEBUGGER, GBinaryDebuggerClass))
 
 
 /* Définition des fonctionnalités d'un débogueur (instance) */
@@ -84,9 +56,6 @@ typedef struct _GBinaryDebuggerClass GBinaryDebuggerClass;
 /* Indique le type définit par la GLib pour le débogueur ptrace(). */
 GType g_binary_debugger_get_type(void);
 
-/* Crée un nouveau débogueur. */
-GBinaryDebugger *g_new_binary_debugger(DebuggerType, GLoadedBinary *);
-
 /* Démarre une procédure de débogage. */
 bool g_binary_debugger_attach(GBinaryDebugger *);
 
@@ -94,19 +63,165 @@ bool g_binary_debugger_attach(GBinaryDebugger *);
 void g_binary_debugger_run(GBinaryDebugger *);
 
 /* Reprend une procédure de débogage. */
-void g_binary_debugger_resume(GBinaryDebugger *);
+//void g_binary_debugger_resume(GBinaryDebugger *);
 
 /* Tue une procédure de débogage. */
 void g_binary_debugger_kill(GBinaryDebugger *);
 
 /* Fournit les identifiants de tous les threads actifs. */
-pid_t *g_binary_debugger_list_all_threads(GBinaryDebugger *, char ***, size_t *);
+//pid_t *g_binary_debugger_list_all_threads(GBinaryDebugger *, char ***, size_t *);
 
 /* Fournit la liste des frames courantes d'un thread donné. */
-dbg_frame_t *g_binary_debugger_get_frames_stack(GBinaryDebugger *, pid_t, size_t *);
+//dbg_frame_t *g_binary_debugger_get_frames_stack(GBinaryDebugger *, pid_t, size_t *);
 
 /* Fournit la valeur des registres de l'architecture. */
-register_value *g_binary_debugger_get_registers(GBinaryDebugger *, size_t *);
+//register_value *g_binary_debugger_get_registers(GBinaryDebugger *, size_t *);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                     MANIPULATION DES DIFFERENTS THREADS ACTIFS                     */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Description humaine à représenter */
+typedef struct _dbg_thread_desc
+{
+    dbg_thread_id_t id;                     /* Identifiant interne         */
+    char *name;                             /* Dénomination humaine        */
+
+} dbg_thread_desc;
+
+
+/* Libère la mémoire d'une liste de threads actifs. */
+void delete_dbg_thread_desc(dbg_thread_desc *, size_t);
+
+/* Fournit les identifiants de tous les threads actifs. */
+dbg_thread_desc *g_binary_debugger_list_all_threads(GBinaryDebugger *, size_t *);
+
+
+
+
+
+
+
+
+
+/* --------------------------- ENTREES / SORTIES BASIQUES --------------------------- */
+
+
+/* Lit une valeur de 8 bits à une adresse arbitraire. */
+bool g_binary_debugger_read_memory_u8(GBinaryDebugger *, virt_t, uint8_t *);
+
+/* Lit une valeur de 16 bits à une adresse arbitraire. */
+bool g_binary_debugger_read_memory_u16(GBinaryDebugger *, virt_t, uint16_t *);
+
+/* Lit une valeur de 32 bits à une adresse arbitraire. */
+bool g_binary_debugger_read_memory_u32(GBinaryDebugger *, virt_t, uint32_t *);
+
+/* Lit une valeur de 64 bits à une adresse arbitraire. */
+bool g_binary_debugger_read_memory_u64(GBinaryDebugger *, virt_t, uint64_t *);
+
+/* Lit une valeur de taille quelconque à une adresse arbitraire. */
+bool g_binary_debugger_read_memory_data(GBinaryDebugger *, virt_t, uint8_t *, size_t);
+
+/* Ecrit une valeur de 8 bits à une adresse arbitraire. */
+bool g_binary_debugger_write_memory_u8(GBinaryDebugger *, virt_t, const uint8_t *);
+
+/* Ecrit une valeur de 16 bits à une adresse arbitraire. */
+bool g_binary_debugger_write_memory_u16(GBinaryDebugger *, virt_t, const uint16_t *);
+
+/* Ecrit une valeur de 32 bits à une adresse arbitraire. */
+bool g_binary_debugger_write_memory_u32(GBinaryDebugger *, virt_t, const uint32_t *);
+
+/* Ecrit une valeur de 64 bits à une adresse arbitraire. */
+bool g_binary_debugger_write_memory_u64(GBinaryDebugger *, virt_t, const uint64_t *);
+
+/* Ecrit une valeur de taille quelconque à une adresse donnée. */
+bool g_binary_debugger_write_memory_data(GBinaryDebugger *, virt_t, const uint8_t *, size_t);
+
+/* Liste l'ensemble des registres appartenant à un groupe. */
+char **g_binary_debugger_get_register_names(const GBinaryDebugger *, const char *, size_t *);
+
+/* Indique la taille associée à un registre donné. */
+unsigned int g_binary_debugger_get_register_size(const GBinaryDebugger *, const char *);
+
+/* Lit une valeur de 8 bits à partir d'un registre. */
+bool g_binary_debugger_read_register_u8(GBinaryDebugger *, const char *, uint8_t *);
+
+/* Lit une valeur de 16 bits à partir d'un registre. */
+bool g_binary_debugger_read_register_u16(GBinaryDebugger *, const char *, uint16_t *);
+
+/* Lit une valeur de 32 bits à partir d'un registre. */
+bool g_binary_debugger_read_register_u32(GBinaryDebugger *, const char *, uint32_t *);
+
+/* Lit une valeur de 64 bits à partir d'un registre. */
+bool g_binary_debugger_read_register_u64(GBinaryDebugger *, const char *, uint64_t *);
+
+/* Ecrit une valeur de 8 bits dans un registre. */
+bool g_binary_debugger_write_register_u8(GBinaryDebugger *, const char *, const uint8_t *);
+
+/* Ecrit une valeur de 16 bits dans un registre. */
+bool g_binary_debugger_write_register_u16(GBinaryDebugger *, const char *, const uint16_t *);
+
+/* Ecrit une valeur de 32 bits dans un registre. */
+bool g_binary_debugger_write_register_u32(GBinaryDebugger *, const char *, const uint32_t *);
+
+/* Ecrit une valeur de 64 bits dans un registre. */
+bool g_binary_debugger_write_register_u64(GBinaryDebugger *, const char *, const uint64_t *);
+
+
+
+/* ------------------------- MANIPULATION DE L'ETAT COURANT ------------------------- */
+
+
+/* Détermine le point d'exécution courant. */
+bool g_binary_debugger_get_current_pc(GBinaryDebugger *, virt_t *);
+
+/* Détermine l'adresse du premier retour d'appel. */
+bool g_binary_debugger_get_return_pc(GBinaryDebugger *, virt_t *);
+
+/* Détermine les prochaines probables instructions exécutées. */
+virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *, virt_t, bool, size_t *);
+
+/* Remonte la pile d'appels jusqu'au point courant. */
+bool g_binary_debugger_get_call_stack(GBinaryDebugger *, virt_t **, size_t *);
+
+
+
+/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */
+
+
+/* Ajoute un point d'arrêt basique en mémoire. */
+bool g_binary_debugger_add_memory_breakpoint(GBinaryDebugger *, virt_t);
+
+/* Retire un point d'arrêt basique en mémoire. */
+bool g_binary_debugger_delete_memory_breakpoint(GBinaryDebugger *, virt_t);
+
+
+
+/* -------------------------- CONTROLE DU FLOT D'EXECUTION -------------------------- */
+
+
+/* Redémarre le processus de débogage. */
+bool g_binary_debugger_restart(GBinaryDebugger *);
+
+/* Remet en marche le débogueur courant. */
+bool g_binary_debugger_resume(GBinaryDebugger *);
+
+/* Relance l'exécution pour une seule instruction. */
+bool g_binary_debugger_stepi(GBinaryDebugger *, bool);
 
 
 
diff --git a/src/debug/gdbrsp/Makefile.am b/src/debug/gdbrsp/Makefile.am
new file mode 100644
index 0000000..fd46f27
--- /dev/null
+++ b/src/debug/gdbrsp/Makefile.am
@@ -0,0 +1,24 @@
+
+noinst_LTLIBRARIES = libdebuggdbrsp.la
+
+libdebuggdbrsp_la_SOURCES =				\
+	aops.h								\
+	gdb-int.h							\
+	gdb.h gdb.c							\
+	helpers.h helpers.c					\
+	helpers_arm.h helpers_arm.c			\
+	helpers_arm64.h helpers_arm64.c		\
+	packet.h packet.c					\
+	stream-int.h						\
+	stream.h stream.c					\
+	support.h support.c					\
+	target.h target.c					\
+	tcp.h tcp.c							\
+	utils.h utils.c
+
+libdebuggdbrsp_la_CFLAGS = $(AM_CFLAGS)
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/src/debug/gdbrsp/aops.h b/src/debug/gdbrsp/aops.h
new file mode 100644
index 0000000..02d4982
--- /dev/null
+++ b/src/debug/gdbrsp/aops.h
@@ -0,0 +1,57 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * aops.h - prototypes pour les compléments utiles à GDB pour l'architecture ARM
+ *
+ * Copyright (C) 2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_AOPS_H
+#define _DEBUG_GDBRSP_AOPS_H
+
+
+#include "gdb.h"
+
+
+
+/* Détermine le point d'exécution courant. */
+typedef bool (* get_pc_fc) (GGdbDebugger *, virt_t *);
+
+/* Remonte la pile d'appels jusqu'au point courant. */
+typedef bool (* compute_call_stack_fc) (const GGdbDebugger *, virt_t **, size_t *);
+
+/* Complète la commande manipulant des points d'arrêt. */
+typedef const char * (* get_bp_kind_fc) (const GGdbDebugger *, virt_t);
+
+/* Construit une instruction provoquant un arrêt d'exécution. */
+typedef const uint8_t * (* get_bp_data_fc) (const GGdbDebugger *, virt_t, size_t *);
+
+
+/* Procédures spécifiques pour une architecture */
+typedef struct _gdb_arch_ops
+{
+    get_pc_fc get_pc;                       /* Obtention du point d'exéc.  */
+    compute_call_stack_fc compute_cstack;   /* Calcule la pile d'appels    */
+    get_bp_kind_fc get_bp_kind;             /* Fournit le type d'un point  */
+    get_bp_data_fc get_bp_data;             /* Code d'un point d'arrêt     */
+
+} gdb_arch_ops;
+
+
+
+#endif  /* _DEBUG_GDBRSP_AOPS_H */
diff --git a/src/debug/gdbrsp/gdb-int.h b/src/debug/gdbrsp/gdb-int.h
new file mode 100644
index 0000000..5055fbf
--- /dev/null
+++ b/src/debug/gdbrsp/gdb-int.h
@@ -0,0 +1,116 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gdb.h - prototypes pour le débogage à l'aide de gdb.
+ *
+ * Copyright (C) 2009-2012 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_GDB_INT_H
+#define _DEBUG_GDBRSP_GDB_INT_H
+
+
+#include "aops.h"
+#include "gdb.h"
+#include "stream.h"
+#include "support.h"
+#include "target.h"
+#include "../break-int.h"
+#include "../debugger-int.h"
+
+
+
+
+
+
+
+
+
+
+/* Définition d'un point d'arrêt appliqué */
+typedef struct _gdb_breakpoint
+{
+    raw_breakpoint raw;                     /* A laisser en premier        */
+
+    bool is_z;                              /* Usage de commande dédiée ?  */
+
+    union
+    {
+        const char *kind;                   /* Précision de taille         */
+
+        struct
+        {
+            uint8_t memory[16];             /* Données d'origine remplacées*/
+            size_t len;                     /* Quantité de ces données     */
+        };
+
+    };
+
+} gdb_breakpoint;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Débogueur utilisant un serveur GDB (instance) */
+struct _GGdbDebugger
+{
+    GBinaryDebugger parent;                 /* A laisser en premier        */
+
+    SourceEndian endian;                    /* Boutisme du format          */
+    MemoryDataSize msize;                   /* Taille des adresses         */
+
+    const gdb_arch_ops *ops;                /* Opérations spécifiques      */
+
+    GGdbStream *stream;                     /* Flux de communication       */
+    GGdbSupport *support;                   /* Configuration à adopter     */
+    GGdbTarget *target;                     /* Architecture ciblée par GDB */
+
+};
+
+
+/* Débogueur utilisant un serveur GDB (classe) */
+struct _GGdbDebuggerClass
+{
+    GBinaryDebuggerClass parent;            /* A laisser en premier        */
+
+};
+
+
+
+/* ------------------------ ACCUEIL D'EVENEMENTS ASYNCHRONES ------------------------ */
+
+
+/* Réagit à la réception d'un signal par le programme étudié. */
+void g_gdb_debugger_receive_signal_reply(GGdbDebugger *, int);
+
+/* Réagit à la sortie d'exécution d'un programme étudié. */
+void g_gdb_debugger_receive_exit_reply(GGdbDebugger *, int, pid_t);
+
+
+
+#endif  /* _DEBUG_GDBRSP_GDB_INT_H */
diff --git a/src/debug/gdbrsp/gdb.c b/src/debug/gdbrsp/gdb.c
new file mode 100644
index 0000000..37a7a73
--- /dev/null
+++ b/src/debug/gdbrsp/gdb.c
@@ -0,0 +1,1524 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gdb.c - débogage à l'aide de gdb.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "gdb.h"
+
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+
+#include "gdb-int.h"
+#include "helpers.h"
+#include "helpers_arm.h"
+#include "helpers_arm64.h"
+#include "tcp.h"
+#include "utils.h"
+#include "../../common/cpp.h"
+#include "../../format/format.h"
+
+
+
+
+
+
+
+
+/* Initialise la classe du débogueur utilisant gdb. */
+static void g_gdb_debugger_class_init(GGdbDebuggerClass *);
+
+/* Procède à l'initialisation du débogueur utilisant gdb. */
+static void g_gdb_debugger_init(GGdbDebugger *);
+
+/* Supprime toutes les références externes. */
+static void g_gdb_debugger_dispose(GGdbDebugger *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_gdb_debugger_finalize(GGdbDebugger *);
+
+
+/* Met en marche le débogueur utilisant un serveur GDB. */
+static bool g_gdb_debugger_run(GGdbDebugger *);
+
+/* Remet en marche le débogueur utilisant un serveur GDB. */
+//static bool g_gdb_debugger_resume(GGdbDebugger *);
+
+/* Tue le débogueur utilisant un serveur GDB. */
+static bool g_gdb_debugger_kill(GGdbDebugger *);
+
+
+
+
+
+
+/* --------------------------- ENTREES / SORTIES BASIQUES --------------------------- */
+
+
+/* Lit une valeur quelconque à une adresse arbitraire.  */
+static bool g_gdb_debugger_read_memory(GGdbDebugger *, virt_t, size_t, ...);
+
+/* Ecrit une valeur quelconque à une adresse arbitraire.  */
+static bool g_gdb_debugger_write_memory(GGdbDebugger *, virt_t, size_t, ...);
+
+/* Liste l'ensemble des registres appartenant à un groupe. */
+static char **g_gdb_debugger_get_register_names(const GGdbDebugger *, const char *, size_t *);
+
+/* Indique la taille associée à un registre donné. */
+static unsigned int g_gdb_debugger_get_register_size(const GGdbDebugger *, const char *);
+
+/* Effectue la lecture d'un registre donné. */
+static bool g_gdb_debugger_read_register(GGdbDebugger *, const char *, size_t, ...);
+
+/* Effectue l'écriture d'un registre donné. */
+static bool g_gdb_debugger_write_register(GGdbDebugger *, const char *, size_t, ...);
+
+
+
+/* ------------------------- MANIPULATION DE L'ETAT COURANT ------------------------- */
+
+
+/* Détermine le point d'exécution courant. */
+static bool g_gdb_debugger_get_current_pc(GGdbDebugger *, virt_t *);
+
+/* Remonte la pile d'appels jusqu'au point courant. */
+static bool g_gdb_debugger_compute_call_stack(GGdbDebugger *, virt_t **, size_t *);
+
+
+
+/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */
+
+
+/* Ajoute un point d'arrêt basique en mémoire. */
+static gdb_breakpoint *g_gdb_debugger_enable_memory_breakpoint(GGdbDebugger *, virt_t);
+
+/* Retire un point d'arrêt basique en mémoire. */
+static bool g_gdb_debugger_disable_memory_breakpoint(GGdbDebugger *, gdb_breakpoint *);
+
+
+
+/* -------------------------- CONTROLE DU FLOT D'EXECUTION -------------------------- */
+
+
+/* Redémarre le processus de débogage lié à un serveur GDB. */
+static bool g_gdb_debugger_restart(GGdbDebugger *);
+
+/* Remet en marche le débogueur utilisant un serveur GDB. */
+static bool g_gdb_debugger_resume(GGdbDebugger *);
+
+
+
+
+
+
+
+
+
+
+
+
+/* Détermine l'identifiant du thread principal courant. */
+static char *g_gdb_debugger_get_active_thread(GGdbDebugger *);
+
+
+
+
+
+
+/* ------------------------ ACCUEIL D'EVENEMENTS ASYNCHRONES ------------------------ */
+
+
+
+
+
+
+
+
+/* Indique le type défini par la GLib pour le débogueur gdb. */
+G_DEFINE_TYPE(GGdbDebugger, g_gdb_debugger, G_TYPE_BINARY_DEBUGGER);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe de débogueur à initialiser.                   *
+*                                                                             *
+*  Description : Initialise la classe du débogueur utilisant gdb.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_debugger_class_init(GGdbDebuggerClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GBinaryDebuggerClass *parent;           /* Version en classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_debugger_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_gdb_debugger_finalize;
+
+    parent = G_BINARY_DEBUGGER_CLASS(klass);
+
+    parent->read_mem = (read_mem_any_fc)g_gdb_debugger_read_memory;
+    parent->write_mem = (write_mem_any_fc)g_gdb_debugger_write_memory;
+    parent->get_reg_names = (get_reg_names_fc)g_gdb_debugger_get_register_names;
+    parent->get_reg_size = (get_reg_size_fc)g_gdb_debugger_get_register_size;
+    parent->read_reg = (read_write_reg_any_fc)g_gdb_debugger_read_register;
+    parent->write_reg = (read_write_reg_any_fc)g_gdb_debugger_write_register;
+
+    parent->get_current_pc = (get_current_pc_fc)g_gdb_debugger_get_current_pc;
+    parent->get_call_stack = (get_call_stack_fc)g_gdb_debugger_compute_call_stack;
+
+    parent->enable_bp = (enable_mem_bp_fc)g_gdb_debugger_enable_memory_breakpoint;
+    parent->disable_bp = (disable_mem_bp_fc)g_gdb_debugger_disable_memory_breakpoint;
+
+    parent->restart = (restart_debugger_fc)g_gdb_debugger_restart;
+    parent->resume = (resume_debugger_fc)g_gdb_debugger_resume;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = instance de débogueur à préparer.                 *
+*                                                                             *
+*  Description : Procède à l'initialisation du débogueur utilisant gdb.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_debugger_init(GGdbDebugger *debugger)
+{
+    GBinaryDebugger *parent;                /* Instance parente            */
+
+    parent = G_BINARY_DEBUGGER(debugger);
+
+    parent->run = (basic_debugger_fc)g_gdb_debugger_run;
+    //parent->resume = (resume_debugger_fc)g_gdb_debugger_resume;
+    parent->kill = (basic_debugger_fc)g_gdb_debugger_kill;
+
+    //parent->get_reg_values = (get_register_values_fc)get_register_values_using_gdb_debugger;
+
+    //debugger->cond = g_cond_new();
+    //debugger->mutex = g_mutex_new();
+
+
+    // FIXME
+    //debugger->compute_cstack = compute_call_stack_for_arm64;
+    //debugger->fill_mem_bp = fill_memory_breakpoint_cmd_for_arm64;
+
+
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_debugger_dispose(GGdbDebugger *debugger)
+{
+    if (debugger->stream != NULL)
+        g_object_unref(G_OBJECT(debugger->stream));
+
+    if (debugger->support != NULL)
+        g_object_unref(G_OBJECT(debugger->support));
+
+    if (debugger->target != NULL)
+        g_object_unref(G_OBJECT(debugger->target));
+
+    G_OBJECT_CLASS(g_gdb_debugger_parent_class)->dispose(G_OBJECT(debugger));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_debugger_finalize(GGdbDebugger *debugger)
+{
+    G_OBJECT_CLASS(g_gdb_debugger_parent_class)->finalize(G_OBJECT(debugger));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = binaire représenter à déboguer.                     *
+*                server = nom ou adresse du serveur à contacter.              *
+*                port   = port de connexion.                                  *
+*                                                                             *
+*  Description : Crée un débogueur utilisant un serveur GDB distant.          *
+*                                                                             *
+*  Retour      : Instance de débogueur mise en place ou NULL.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinaryDebugger *g_gdb_debugger_new(GLoadedBinary *binary, const char *server, unsigned short port)
+{
+    GGdbDebugger *result;                   /* Débogueur à retourner       */
+    GExeFormat *format;                     /* Format du binaire chargé    */
+    const char *arch;                       /* Architecture d'exécution    */
+    GArchProcessor *proc;                   /* Processeur lié au binaire   */
+    char service[sizeof(XSTR(UINT16_MAX)) + 1]; /* Conversion requise      */
+
+    result = g_object_new(G_TYPE_GDB_DEBUGGER, NULL);
+
+    G_BINARY_DEBUGGER(result)->binary = binary;
+    g_object_ref(G_OBJECT(binary));
+
+    /* Propriétés de la cible */
+
+    format = g_loaded_binary_get_format(binary);
+
+    result->endian = g_binary_format_get_endianness(G_BIN_FORMAT(format));
+
+    arch = g_exe_format_get_target_machine(format);
+
+    if (strcmp(arch, "armv7") == 0)
+        result->ops = get_arm_operations();
+    else
+        result->ops = NULL;
+
+    g_object_unref(G_OBJECT(format));
+
+    if (result->ops == NULL)
+        goto ggdn_error;
+
+    proc = g_loaded_binary_get_processor(binary);
+
+    result->msize = g_arch_processor_get_memory_size(proc);
+
+    g_object_unref(G_OBJECT(proc));
+
+    /* Mise en place des modules auxialiaires */
+
+    snprintf(service, sizeof(service), "%hu", port);
+
+    result->stream = g_gdb_tcp_client_new(server, service, result);
+    if (result->stream == NULL) goto ggdn_error;
+
+    result->support = g_gdb_support_new(result->stream);
+
+    result->target = g_gdb_target_new(result->stream);
+    if (result->target == NULL) goto ggdn_error;
+
+    return G_BINARY_DEBUGGER(result);
+
+ ggdn_error:
+
+    g_object_unref(G_OBJECT(result));
+
+    return NULL;
+
+}
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à lancer.                               *
+*                                                                             *
+*  Description : Met en marche le débogueur utilisant un serveur GDB.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_run(GGdbDebugger *debugger)
+{
+
+
+
+    GGdbPacket *packet;
+
+    bool test;
+
+    const char *data;
+    size_t len;
+
+
+    int sig;
+    vmpa_t addr;
+    pid_t thread;
+
+
+    debugger->stream = g_gdb_tcp_client_new("127.0.0.1", "6666", NULL);
+    if (debugger->stream == NULL) return false;
+
+
+    printf("Connection done !\n");
+
+
+
+    packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "?");
+
+
+    test = g_gdb_stream_send_packet(debugger->stream, packet);
+
+
+
+    printf(" >> Paquet '%s' bien envoyé ? %s\n", "?", test ? "oui" : "non");
+
+
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+    packet = g_gdb_stream_recv_packet(debugger->stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    printf(" << Réception de '%s'\n", data);
+
+
+
+
+
+    get_stop_reply_sig_info(packet, &sig, &addr, &thread, SRE_LITTLE);
+
+    g_signal_emit_by_name(debugger, "halted", sig, addr, thread);
+
+
+
+    return true;
+
+}
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                                                                             *
+*  Description : Tue le débogueur utilisant un serveur GDB.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_kill(GGdbDebugger *debugger)
+{
+
+
+#if 0
+    int ret;                                /* Bilan de l'appel système    */
+
+    ret = kill(debugger->child, SIGKILL);
+    if (ret != 0) perror("kill");
+
+    debugger->child = 0;
+
+    g_mutex_lock(debugger->mutex);
+    debugger->run_again = TRUE;
+    g_cond_signal(debugger->cond);
+    g_mutex_unlock(debugger->mutex);
+#endif
+    return true;
+
+}
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                                                                             *
+*  Description : Détermine l'identifiant du thread principal courant.         *
+*                                                                             *
+*  Retour      : Identifiant du thread actif principal ou NULL en cas d'échec.*
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_gdb_debugger_get_active_thread(GGdbDebugger *debugger)
+{
+    char *result;                           /* Identifiant à renvoyer      */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    bool status;                            /* Bilan d'une communication   */
+    const char *data;                       /* Données reçues à analyser   */
+    const char *start;                      /* Début d'identification      */
+    const char *end;                        /* Fin d'identification        */
+
+    result = NULL;
+
+    /* Envoi de la requête */
+
+    packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "?");
+
+    status = g_gdb_stream_send_packet(debugger->stream, packet);
+
+    if (!status)
+        goto ggdgat_exit;
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(debugger->stream);
+
+    g_gdb_packet_get_data(packet, &data, NULL, NULL);
+
+    start = strstr(data, "thread:");
+    if (start == NULL) goto ggdgat_exit;
+
+    start += sizeof("thread:") - 1 /* '\0' */;
+
+    end = strstr(start, ";");
+    if (end == NULL) goto ggdgat_exit;
+
+    result = strndup(start, end - start);
+
+ ggdgat_exit:
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+    return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                             ENTREES / SORTIES BASIQUES                             */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                addr     = emplacement en mémoire à venir consulter.         *
+*                size     = taille des données mises en jeu.                  *
+*                ...      = emplacement de la valeur lue à conserver. [OUT]   *
+*                                                                             *
+*  Description : Lit une valeur quelconque à une adresse arbitraire.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_read_memory(GGdbDebugger *debugger, virt_t addr, size_t size, ...)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    char cmd[1 + VMPA_MAX_LEN + 3];         /* Commande à émettre          */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;                             /* Quantité de données reçues  */
+    va_list ap;                             /* Liste variable d'arguments  */
+    uint8_t *val8;                          /* Valeur sur 8 bits           */
+    uint16_t *val16;                        /* Valeur sur 16 bits          */
+    uint16_t conv16;                        /* Valeur adaptée sur 16 bits  */
+    uint32_t *val32;                        /* Valeur sur 32 bits          */
+    uint32_t conv32;                        /* Valeur adaptée sur 32 bits  */
+    uint64_t *val64;                        /* Valeur sur 64 bits          */
+    uint64_t conv64;                        /* Valeur adaptée sur 64 bits  */
+
+    /* Envoi de la requête */
+
+    cmd[0] = 'm';
+
+    result = translate_virt_to_hex(debugger, addr, &cmd[1]);
+
+    switch (size)
+    {
+        case 8:
+            strcat(cmd, ",1");
+            break;
+
+        case 16:
+            strcat(cmd, ",2");
+            break;
+
+        case 32:
+            strcat(cmd, ",4");
+            break;
+
+        case 64:
+            strcat(cmd, ",8");
+            break;
+
+        default:
+            assert(false);
+            result = false;
+            goto ggdrm_exit;
+            break;
+
+    }
+
+    packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, cmd);
+
+    result = g_gdb_stream_send_packet(debugger->stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+    if (!result)
+        goto ggdrm_exit;
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(debugger->stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    if (is_error_code(data, len))
+    {
+        result = false;
+        goto ggdrm_error;
+    }
+
+    va_start(ap, size);
+
+    switch (size)
+    {
+        case 8:
+            val8 = va_arg(ap, uint8_t *);
+            result = hex_to_u8(data, val8);
+            break;
+
+        case 16:
+            val16 = va_arg(ap, uint16_t *);
+            result = hex_to_u16(data, &conv16);
+            *val16 = from_u16(&conv16, debugger->endian);
+            break;
+
+        case 32:
+            val32 = va_arg(ap, uint32_t *);
+            result = hex_to_u32(data, &conv32);
+            *val32 = from_u32(&conv32, debugger->endian);
+            break;
+
+        case 64:
+            val64 = va_arg(ap, uint64_t *);
+            result = hex_to_u64(data, &conv64);
+            *val64 = from_u64(&conv64, debugger->endian);
+            break;
+
+        default:
+            assert(false);
+            result = false;
+            break;
+
+    }
+
+    va_end(ap);
+
+ ggdrm_error:
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+ ggdrm_exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler.                            *
+*                addr     = emplacement en mémoire à venir consulter.         *
+*                size     = taille des données mises en jeu.                  *
+*                ...      = emplacement de la valeur lue à conserver. [OUT]   *
+*                                                                             *
+*  Description : Lit une valeur quelconque à une adresse arbitraire.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_write_memory(GGdbDebugger *debugger, virt_t addr, size_t size, ...)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    char cmd[1 + 3 * VMPA_MAX_LEN + 3];     /* Commande à émettre          */
+    va_list ap;                             /* Liste variable d'arguments  */
+    const uint8_t *val8;                    /* Valeur sur 8 bits           */
+    const uint16_t *val16;                  /* Valeur sur 16 bits          */
+    uint16_t conv16;                        /* Valeur adaptée sur 16 bits  */
+    const uint32_t *val32;                  /* Valeur sur 32 bits          */
+    uint32_t conv32;                        /* Valeur adaptée sur 32 bits  */
+    const uint64_t *val64;                  /* Valeur sur 64 bits          */
+    uint64_t conv64;                        /* Valeur adaptée sur 64 bits  */
+    char hexval[17];                        /* Valeur sous forme hexa      */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;                             /* Quantité de données reçues  */
+
+    /* Envoi de la requête */
+
+    cmd[0] = 'M';
+
+    result = translate_virt_to_hex(debugger, addr, &cmd[1]);
+
+    va_start(ap, size);
+
+    switch (size)
+    {
+        case 8:
+            val8 = va_arg(ap, uint8_t *);
+            result = u8_to_hex(val8, hexval);
+
+            strcat(cmd, ",1:");
+            strcat(cmd, hexval);
+            break;
+
+        case 16:
+            val16 = va_arg(ap, uint16_t *);
+            conv16 = to_u16(val16, debugger->endian);
+            result = u16_to_hex(&conv16, hexval);
+
+            strcat(cmd, ",2:");
+            strcat(cmd, hexval);
+            break;
+
+        case 32:
+            val32 = va_arg(ap, uint32_t *);
+            conv32 = to_u32(val32, debugger->endian);
+            result = u32_to_hex(&conv32, hexval);
+
+            strcat(cmd, ",4:");
+            strcat(cmd, hexval);
+            break;
+
+        case 64:
+            val64 = va_arg(ap, uint64_t *);
+            conv64 = to_u64(val64, debugger->endian);
+            result = u16_to_hex(&conv64, hexval);
+
+            strcat(cmd, ",8:");
+            strcat(cmd, hexval);
+            break;
+
+        default:
+            assert(false);
+            result = false;
+            break;
+
+    }
+
+    if (!result)
+        goto ggdwm_exit;
+
+    packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, cmd);
+
+    result = g_gdb_stream_send_packet(debugger->stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+    if (!result)
+        goto ggdwm_exit;
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(debugger->stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    if (len == 3 && data[0] == 'E')
+    {
+        result = false;
+        goto ggdrm_error;
+    }
+
+ ggdrm_error:
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+ ggdwm_exit:
+
+    va_end(ap);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                group    = éventuel groupe de registres ciblé ou NULL.       *
+*                count    = nombre d'éléments dans la liste de noms. [OUT]    *
+*                                                                             *
+*  Description : Liste l'ensemble des registres appartenant à un groupe.      *
+*                                                                             *
+*  Retour      : Liste de noms à libérer de la mémoire après utilisation.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char **g_gdb_debugger_get_register_names(const GGdbDebugger *debugger, const char *group, size_t *count)
+{
+    return g_gdb_target_get_register_names(debugger->target, group, count);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                name     = désignation du registre visé.                     *
+*                                                                             *
+*  Description : Indique la taille associée à un registre donné.              *
+*                                                                             *
+*  Retour      : Taille en bits, ou 0 si le registre n'a pas été trouvé.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static unsigned int g_gdb_debugger_get_register_size(const GGdbDebugger *debugger, const char *name)
+{
+    return g_gdb_target_get_register_size(debugger->target, name);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                size     = taille des données mises en jeu.                  *
+*                ...      = emplacement de la valeur lue à conserver. [OUT]   *
+*                                                                             *
+*  Description : Effectue la lecture d'un registre donné.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_read_register(GGdbDebugger *debugger, const char *reg, size_t size, ...)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    va_list ap;                             /* Liste variable d'arguments  */
+    uint8_t *val8;                          /* Valeur sur 8 bits           */
+    uint16_t *val16;                        /* Valeur sur 16 bits          */
+    uint32_t *val32;                        /* Valeur sur 32 bits          */
+    uint64_t *val64;                        /* Valeur sur 64 bits          */
+
+    va_start(ap, size);
+
+    switch (size)
+    {
+        case 8:
+            val8 = va_arg(ap, uint8_t *);
+            result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian,
+                                                reg, 8, val8);
+            break;
+
+        case 16:
+            val16 = va_arg(ap, uint16_t *);
+            result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian,
+                                                reg, 16, val16);
+            break;
+
+        case 32:
+            val32 = va_arg(ap, uint32_t *);
+            result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian,
+                                                reg, 32, val32);
+            break;
+
+        case 64:
+            val64 = va_arg(ap, uint64_t *);
+            result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian,
+                                                reg, 64, val64);
+            break;
+
+        default:
+            assert(false);
+            result = false;
+            break;
+
+    }
+
+    va_end(ap);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler.                            *
+*                reg      = désignation humaine du register à consulter.      *
+*                size     = taille des données mises en jeu.                  *
+*                ...      = emplacement de la valeur à écrire.                *
+*                                                                             *
+*  Description : Effectue l'écriture d'un registre donné.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_write_register(GGdbDebugger *debugger, const char *reg, size_t size, ...)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    va_list ap;                             /* Liste variable d'arguments  */
+    const uint8_t *val8;                    /* Valeur sur 8 bits           */
+    const uint16_t *val16;                  /* Valeur sur 16 bits          */
+    const uint32_t *val32;                  /* Valeur sur 32 bits          */
+    const uint64_t *val64;                  /* Valeur sur 64 bits          */
+
+    va_start(ap, size);
+
+    switch (size)
+    {
+        case 8:
+            val8 = va_arg(ap, const uint8_t *);
+            result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian,
+                                                 reg, 8, val8);
+            break;
+
+        case 16:
+            val16 = va_arg(ap, const uint16_t *);
+            result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian,
+                                                 reg, 16, val16);
+            break;
+
+        case 32:
+            val32 = va_arg(ap, const uint32_t *);
+            result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian,
+                                                 reg, 32, val32);
+            break;
+
+        case 64:
+            val64 = va_arg(ap, const uint64_t *);
+            result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian,
+                                                 reg, 64, val64);
+            break;
+
+        default:
+            assert(false);
+            result = false;
+            break;
+
+    }
+
+    va_end(ap);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           MANIPULATION DE L'ETAT COURANT                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                pc       = adresse de l'instruction courante. [OUT]          *
+*                                                                             *
+*  Description : Détermine le point d'exécution courant.                      *
+*                                                                             *
+*  Retour      : Bilan de la récupération.                                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_get_current_pc(GGdbDebugger *debugger, virt_t *pc)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = debugger->ops->get_pc(debugger, pc);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger  = débogueur à consulter.                           *
+*                callstack = pile d'appels reconstituée. [OUT]                *
+*                size      = taille de cette pile. [OUT]                      *
+*                                                                             *
+*  Description : Remonte la pile d'appels jusqu'au point courant.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_compute_call_stack(GGdbDebugger *debugger, virt_t **callstack, size_t *size)
+{
+    bool result;                            /* Bilan global à retourner    */
+
+    if (debugger->ops->compute_cstack != NULL)
+        result = debugger->ops->compute_cstack(debugger, callstack, size);
+
+    else
+        result = false;
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                             GESTION DES POINTS D'ARRET                             */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                addr     = emplacement du point mémoire à traiter.           *
+*                                                                             *
+*  Description : Ajoute un point d'arrêt basique en mémoire.                  *
+*                                                                             *
+*  Retour      : Structure de suivi mise en place pour l'occasion, voire NULL.*
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gdb_breakpoint *g_gdb_debugger_enable_memory_breakpoint(GGdbDebugger *debugger, virt_t addr)
+{
+    gdb_breakpoint *result;                 /* Nouveau suivi à retourner   */
+    char cmd[3 + VMPA_MAX_LEN + 3];         /* Commande à émettre          */
+    bool status;                            /* Bilan d'une opération       */
+    const char *kind;                       /* Taille spécifique du point  */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;                             /* Quantité de données reçues  */
+    GBinaryDebugger *dbg;                   /* Autre version du débogueur  */
+    const uint8_t *bp;                      /* Données du point d'arrêt    */
+    size_t bp_len;                          /* Quantité de ces données     */
+    uint8_t memory[16];                     /* Sauvegarde de la mémoire    */
+
+    result = NULL;
+
+    /* Si l'utilisation de la commande dédiée est possible */
+    if (1)  //////// TODO
+    {
+        /* Envoi de la requête */
+
+        strcpy(cmd, "Z0,");
+
+        status = translate_virt_to_hex(debugger, addr, &cmd[3]);
+
+        if (!status)
+            goto ggdemb_exit;
+
+        kind = debugger->ops->get_bp_kind(debugger, addr);
+
+        if (kind == NULL)
+            goto ggdemb_exit;
+
+        strcat(cmd, kind);
+
+        packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+        g_gdb_packet_start_new_command(packet);
+        g_gdb_packet_append(packet, cmd);
+
+        status = g_gdb_stream_send_packet(debugger->stream, packet);
+
+        g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+        if (!status)
+            goto ggdemb_exit;
+
+        /* Réception de la réponse */
+
+        packet = g_gdb_stream_recv_packet(debugger->stream);
+
+        g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+        if (is_error_code(data, len))
+        {
+            g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+            goto ggdemb_fallback;
+        }
+
+        if (strcmp(data, "OK") != 0)
+        {
+            g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+            goto ggdemb_fallback;
+        }
+
+        g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+        /* Constitution d'un dossier de suivi */
+
+        result = (gdb_breakpoint *)malloc(sizeof(gdb_breakpoint));
+
+        result->is_z = true;
+
+        result->kind = kind;
+
+    }
+
+    else
+    {
+
+ ggdemb_fallback:
+
+        dbg = G_BINARY_DEBUGGER(debugger);
+
+        /* Détermination du point d'arrêt */
+
+        bp = debugger->ops->get_bp_data(debugger, addr, &bp_len);
+
+        assert(bp_len <= 16);
+
+        /* Sauvegarde de la mémoire courante */
+
+        status = g_binary_debugger_read_memory_data(dbg, addr, memory, bp_len);
+
+        if (!status) goto ggdemb_exit;
+
+        /* Application du point d'arrêt */
+
+        status = g_binary_debugger_write_memory_data(dbg, addr, bp, bp_len);
+
+        if (!status) goto ggdemb_exit;
+
+        /* Constitution d'un dossier de suivi */
+
+        result = (gdb_breakpoint *)malloc(sizeof(gdb_breakpoint));
+
+        result->is_z = false;
+
+        memcpy(result->memory, memory, bp_len);
+        result->len = bp_len;
+
+    }
+
+    init_raw_breakpoint((raw_breakpoint *)result, addr);
+
+ ggdemb_exit:
+
+    return result;
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                bp       = point d'arrêt à traiter.                          *
+*                                                                             *
+*  Description : Retire un point d'arrêt basique de la mémoire ciblée.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_disable_memory_breakpoint(GGdbDebugger *debugger, gdb_breakpoint *bp)
+{
+    bool result;                            /* Bilan à retourner           */
+    char cmd[3 + VMPA_MAX_LEN + 3];         /* Commande à émettre          */
+    bool status;                            /* Bilan d'une opération       */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;                             /* Quantité de données reçues  */
+    GBinaryDebugger *dbg;                   /* Autre version du débogueur  */
+
+    result = false;
+
+    /* Si l'utilisation de la commande dédiée est requise */
+    if (bp->is_z)
+    {
+        /* Envoi de la requête */
+
+        strcpy(cmd, "z0,");
+
+        status = translate_virt_to_hex(debugger, bp->raw.addr, &cmd[3]);
+
+        if (!status)
+            goto ggddmb_exit;
+
+        strcat(cmd, bp->kind);
+
+        packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+        g_gdb_packet_start_new_command(packet);
+        g_gdb_packet_append(packet, cmd);
+
+        status = g_gdb_stream_send_packet(debugger->stream, packet);
+
+        g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+        if (!status)
+            goto ggddmb_exit;
+
+        /* Réception de la réponse */
+
+        packet = g_gdb_stream_recv_packet(debugger->stream);
+
+        g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+        if (is_error_code(data, len))
+        {
+            g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+            goto ggddmb_exit;
+        }
+
+        if (strcmp(data, "OK") != 0)
+        {
+            g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+            goto ggddmb_exit;
+        }
+
+        g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+        result = true;
+
+    }
+
+    else
+    {
+        dbg = G_BINARY_DEBUGGER(debugger);
+
+        result = g_binary_debugger_write_memory_data(dbg, bp->raw.addr, bp->memory, bp->len);
+
+    }
+
+ ggddmb_exit:
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            CONTROLE DU FLOT D'EXECUTION                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à redémarrer.                           *
+*                                                                             *
+*  Description : Redémarre le processus de débogage lié à un serveur GDB.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_restart(GGdbDebugger *debugger)
+{
+    bool result;                            /* Bilan à retourner           */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    return true;
+    /* Envoi de la requête */
+
+    packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "R00");
+
+    result = g_gdb_stream_send_packet(debugger->stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à relancer.                             *
+*                                                                             *
+*  Description : Remet en marche le débogueur utilisant un serveur GDB.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_debugger_resume(GGdbDebugger *debugger)
+{
+    bool result;                            /* Bilan à retourner           */
+    //char *id;                               /* Identifiant de thread       */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    //const char *data;                       /* Données reçues à analyser   */
+
+    static bool _twice = false;
+
+
+    if (!_twice && 0)
+    {
+
+    packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "$QPassSignals:e;10;14;17;1a;1b;1c;21;24;25;2c;4c;");
+
+    result = g_gdb_stream_send_packet(debugger->stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+    if (!result)
+        goto ggdhmb_exit;
+
+    }
+
+
+
+
+
+
+    /* Envoi de la requête */
+
+    /*
+    id = g_gdb_debugger_get_active_thread(debugger);
+    if (id == NULL) return false;
+
+    printf("ID : %s\n", id);
+    */
+
+    /*
+    id = g_gdb_support_get_id(debugger->support);
+    if (id == NULL) return false;
+
+    printf("ID : %s\n", id);
+    */
+
+    packet = g_gdb_stream_get_free_packet(debugger->stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "vCont;c:-1");
+    //g_gdb_packet_append(packet, "vCont;c:p256f.-1");
+
+
+    /*
+    if (_twice)
+    {
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "vCont;c:p");
+    g_gdb_packet_append(packet, id);
+    g_gdb_packet_append(packet, ".");
+    g_gdb_packet_append(packet, id);
+    }
+    else
+    {
+        _twice = true;
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "vCont;c:p");
+    g_gdb_packet_append(packet, id);
+    g_gdb_packet_append(packet, ".-1");
+    }
+    */
+
+
+
+
+
+    result = g_gdb_stream_send_packet(debugger->stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+
+    if (!result)
+        goto ggdhmb_exit;
+
+    /* Réception de la réponse */
+    /*
+    packet = g_gdb_stream_recv_packet(debugger->stream);
+
+    g_gdb_packet_get_data(packet, &data, NULL, NULL);
+
+    printf("Ack cont...\n");
+
+    //result = (strcmp(data, "OK") == 0);
+
+    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
+    */
+ ggdhmb_exit:
+
+    _twice = true;
+
+    return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          ACCUEIL D'EVENEMENTS ASYNCHRONES                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = instance liée à un débogueur GDB à manipuler.     *
+*                signum   = indentifiant du signal concerné.                  *
+*                                                                             *
+*  Description : Réagit à la réception d'un signal par le programme étudié.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_debugger_receive_signal_reply(GGdbDebugger *debugger, int signum)
+{
+    virt_t pc;                              /* Position courante du CPU    */
+    bool status;                            /* Bilan d'une opération       */
+    GBinaryDebugger *base;                  /* Version basique du débogueur*/
+
+    base = G_BINARY_DEBUGGER(debugger);
+
+    status = g_binary_debugger_get_current_pc(base, &pc);
+
+    if (!status)
+        pc = VMPA_NO_VIRTUAL;
+
+    on_binary_debugger_stopped(base, pc);
+
+    g_signal_emit_by_name(debugger, "signaled", signum);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = instance liée à un débogueur GDB à manipuler.     *
+*                status   = indication d'état à la sortie.                    *
+*                pid      = éventuel identifiant de processus concerné ou -1. *
+*                                                                             *
+*  Description : Réagit à la sortie d'exécution d'un programme étudié.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_debugger_receive_exit_reply(GGdbDebugger *debugger, int status, pid_t pid)
+{
+    GBinaryDebugger *base;                  /* Version basique du débogueur*/
+
+    base = G_BINARY_DEBUGGER(debugger);
+
+    on_binary_debugger_finished(base, pid);
+
+    g_signal_emit_by_name(debugger, "exited", status, pid);
+
+}
diff --git a/src/debug/gdbrsp/gdb.h b/src/debug/gdbrsp/gdb.h
new file mode 100644
index 0000000..7faa044
--- /dev/null
+++ b/src/debug/gdbrsp/gdb.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gdb.h - prototypes pour le débogage à l'aide de gdb.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_GDB_H
+#define _DEBUG_GDBRSP_GDB_H
+
+
+#include <glib-object.h>
+
+
+#include "../debugger.h"
+
+
+
+#define G_TYPE_GDB_DEBUGGER            (g_gdb_debugger_get_type())
+#define G_GDB_DEBUGGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_DEBUGGER, GGdbDebugger))
+#define G_IS_GDB_DEBUGGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_DEBUGGER))
+#define G_GDB_DEBUGGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass))
+#define G_IS_GDB_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_DEBUGGER))
+#define G_GDB_DEBUGGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass))
+
+
+/* Débogueur utilisant un serveur GDB (instance) */
+typedef struct _GGdbDebugger GGdbDebugger;
+
+/* Débogueur utilisant un serveur GDB (classe) */
+typedef struct _GGdbDebuggerClass GGdbDebuggerClass;
+
+
+/* Indique le type défini par la GLib pour le débogueur gdb. */
+GType g_gdb_debugger_get_type(void);
+
+/* Crée un débogueur utilisant un serveur GDB distant. */
+GBinaryDebugger *g_gdb_debugger_new(GLoadedBinary *, const char *, unsigned short);
+
+
+void test_gdb(void);
+
+
+
+#endif  /* _DEBUG_GDBRSP_GDB_H */
diff --git a/src/debug/gdbrsp/helpers.c b/src/debug/gdbrsp/helpers.c
new file mode 100644
index 0000000..296d642
--- /dev/null
+++ b/src/debug/gdbrsp/helpers.c
@@ -0,0 +1,224 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers.c - assistanat dans la manipulation des paquets GDB
+ *
+ * Copyright (C) 2010-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "helpers.h"
+
+
+#include <regex.h>
+#include <string.h>
+
+
+#include "gdb-int.h"
+#include "utils.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                addr     = emplacement en mémoire à venir consulter.         *
+*                out      = zone d'impression en hexadécimal. [OUT]           *
+*                                                                             *
+*  Description : Traduit une adresse en chaîne hexadécimale pour GDB.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool translate_virt_to_hex(const GGdbDebugger *debugger, virt_t addr, char *out)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    uint8_t conv8;                          /* Valeur adaptée sur 8 bits   */
+    uint16_t conv16;                        /* Valeur adaptée sur 16 bits  */
+    uint32_t conv32;                        /* Valeur adaptée sur 32 bits  */
+    uint64_t conv64;                        /* Valeur adaptée sur 64 bits  */
+    char hexval[17];                        /* Valeur sous forme hexa      */
+    bool got_msn;                           /* Obtention d'un quartet ?    */
+    size_t i;                               /* Boucle de parcours          */
+
+    /* Conversion */
+
+    switch (debugger->msize)
+    {
+        case MDS_8_BITS:
+            conv8 = addr;
+            result = u8_to_hex(&conv8, hexval);
+            break;
+
+        case MDS_16_BITS:
+            conv16 = addr;
+            conv16 = to_u16(&conv16, SRE_BIG);
+            result = u16_to_hex(&conv16, hexval);
+            break;
+
+        case MDS_32_BITS:
+            conv32 = addr;
+            conv32 = to_u32(&conv32, SRE_BIG);
+            result = u32_to_hex(&conv32, hexval);
+            break;
+
+        case MDS_64_BITS:
+            conv64 = addr;
+            conv64 = to_u64(&conv64, SRE_BIG);
+            result = u64_to_hex(&conv64, hexval);
+            break;
+
+        default:
+            result = false;
+            break;
+
+    }
+
+    /* On saute les zéros préliminaires... */
+
+    if (result)
+    {
+        got_msn = false;
+
+        for (i = 0; i < 17; i++)
+        {
+            if (!got_msn)
+            {
+                if (hexval[i] == '0')
+                    continue;
+                else
+                    got_msn = true;
+            }
+
+            *out = hexval[i];
+            out++;
+
+        }
+
+        *out = '\0';
+
+    }
+
+    return result;
+
+}
+
+
+
+
+
+
+
+
+/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : packet = paquet de deonnées à interpréter.                   *
+*                sig    = identifiant du signal source. [OUT]                 *
+*                addr   = adresse de l'instruction courante. [OUT]            *
+*                thread = identifiant du thread concerné. [OUT]               *
+*                endian = boutisme de la plateforme ciblée.                   *
+*                                                                             *
+*  Description : Récupère les informations liées à un arrêt suite à signal.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : Les données sont la forme :                                  *
+*                T0505:00000000;04:a08de6bf;08:505878b7;thread:50dc;          *
+*                                                                             *
+******************************************************************************/
+
+bool get_stop_reply_sig_info(const GGdbPacket *packet, int *sig, vmpa_t *addr, pid_t *thread, SourceEndian endian)
+{
+    const char *data;                       /* Données brutes du paquet    */
+    size_t length;                          /* Quantité de ces données     */
+    uint8_t index;                          /* Indice de 8 bits quelconque */
+    size_t pos;                             /* Tête de lecture courante    */
+    regex_t preg;                           /* Expression régulière        */
+    int ret;                                /* Bilan d'un appel            */
+    regmatch_t pmatch[3];                   /* Zones remarquées            */
+    size_t key_len;                         /* Taille de l'indicatif       */
+
+    *addr = 0ull;
+
+    g_gdb_packet_get_data(packet, &data, &length, NULL);
+
+    pos = 1;
+
+    /* Lecture du numéro du signal */
+
+    if (!strtou8(&index, data, &pos, length, SRE_LITTLE))
+        return false;
+
+    *sig = index;
+
+    /* Reste des informations */
+
+    ret = regcomp(&preg, "([^:]+):([^;]+);", REG_EXTENDED | REG_ICASE);
+    if (ret != 0) return false;
+
+    for (ret = regexec(&preg, &data[pos], 3, pmatch, 0);
+         ret != REG_NOMATCH;
+         ret = regexec(&preg, &data[pos], 3, pmatch, 0))
+    {
+        key_len = pmatch[1].rm_eo - pmatch[1].rm_so;
+
+        /* Indication sur le thread */
+        if (key_len == strlen("thread")
+            && strncmp(&data[pos + pmatch[1].rm_so], "thread", key_len) == 0)
+        {
+
+            /* TODO printf("Thread found !\n"); */
+
+        }
+
+        /* Valeur de registre ? */
+        else if (key_len == 2)
+        {
+            if (!strtou8(&index, data, (size_t []) { pos + pmatch[1].rm_so }, length, SRE_LITTLE))
+                return false;
+
+            if (index != 8 /* FIXME */)
+                goto next_field;
+
+            if (!strtou32(addr, data, (size_t []) { pos + pmatch[2].rm_so }, length, SRE_LITTLE/* FIXME */))
+                return false;
+
+        }
+
+    next_field:
+        pos += pmatch[0].rm_eo;
+
+    }
+
+    regfree(&preg);
+
+    return (*addr != 0ull);
+
+}
+
+
+
diff --git a/src/debug/gdbrsp/helpers.h b/src/debug/gdbrsp/helpers.h
new file mode 100644
index 0000000..5f5f301
--- /dev/null
+++ b/src/debug/gdbrsp/helpers.h
@@ -0,0 +1,62 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers.h - prototypes pour un assistanat dans la manipulation des paquets GDB
+ *
+ * Copyright (C) 2010-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_HELPERS_H
+#define _DEBUG_GDBRSP_HELPERS_H
+
+
+#include "gdb.h"
+#include "packet.h"
+
+
+
+/* Traduit une adresse en chaîne hexadécimale pour GDB. */
+bool translate_virt_to_hex(const GGdbDebugger *, virt_t, char *);
+
+
+
+
+
+
+/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */
+
+
+/* Récupère les informations liées à un arrêt suite à signal. */
+bool get_stop_reply_sig_info(const GGdbPacket *, int *, vmpa_t *, pid_t *, SourceEndian);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            PAQUETS DES REPONSES D'ARRET                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+
+
+
+
+
+
+
+
+#endif  /* _DEBUG_GDBRSP_HELPERS_H */
diff --git a/src/debug/gdbrsp/helpers_arm.c b/src/debug/gdbrsp/helpers_arm.c
new file mode 100644
index 0000000..e2491ae
--- /dev/null
+++ b/src/debug/gdbrsp/helpers_arm.c
@@ -0,0 +1,252 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers_arm.c - compléments utiles à GDB pour l'architecture ARM
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "helpers_arm.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "gdb-int.h"
+
+
+
+/* Détermine le point d'exécution courant. */
+static bool get_arm_pc(GGdbDebugger *, virt_t *);
+
+/* Remonte la pile d'appels jusqu'au point courant. */
+static bool compute_call_stack_for_arm(const GGdbDebugger *, virt_t **, size_t *);
+
+/* Complète la commande manipulant des points d'arrêt. */
+static const char *get_breakpoint_kind_for_arm(const GGdbDebugger *, virt_t);
+
+/* Construit une instruction provoquant un arrêt d'exécution. */
+static const uint8_t *get_arm_breakpoint_data(const GGdbDebugger *, virt_t, size_t *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit les fonctions adaptées aux opérations pour ARM.      *
+*                                                                             *
+*  Retour      : Opérations spécifiques adaptées à ARM.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const gdb_arch_ops *get_arm_operations(void)
+{
+    static const gdb_arch_ops arm_ops = {
+
+        .get_pc = get_arm_pc,
+        .compute_cstack = compute_call_stack_for_arm,
+        .get_bp_kind = get_breakpoint_kind_for_arm,
+        .get_bp_data = get_arm_breakpoint_data
+
+    };
+
+    return &arm_ops;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à consulter.                            *
+*                pc       = adresse de l'instruction courante. [OUT]          *
+*                                                                             *
+*  Description : Détermine le point d'exécution courant.                      *
+*                                                                             *
+*  Retour      : Bilan de la récupération.                                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool get_arm_pc(GGdbDebugger *debugger, virt_t *pc)
+{
+    bool result;                            /* Bilan à retourner           */
+    uint32_t value;
+
+    result = g_binary_debugger_read_register_u32(G_BINARY_DEBUGGER(debugger), "pc", &value);
+
+    if (result)
+        *pc = value;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger  = débogueur à consulter.                           *
+*                callstack = pile d'appels reconstituée. [OUT]                *
+*                size      = taille de cette pile. [OUT]                      *
+*                                                                             *
+*  Description : Remonte la pile d'appels jusqu'au point courant.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool compute_call_stack_for_arm(const GGdbDebugger *debugger, virt_t **callstack, size_t *size)
+{
+    bool result;                            /* Bilan global à retourner    */
+    GBinaryDebugger *base;                  /* Version basique d'instance  */
+    uint32_t lr;                            /* Retour de fonction          */
+    uint32_t fp;                            /* Pointeur de cadre à suivre  */
+
+    base = G_BINARY_DEBUGGER(debugger);
+
+    result = g_binary_debugger_read_register_u32(base, "lr", &lr);
+
+    if (result && lr != 0)
+    {
+        *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t));
+
+        (*callstack)[*size - 1] = lr;
+
+    }
+
+    result &= g_binary_debugger_read_register_u32(base, "r11", &fp);
+
+    while (result && fp != 0)
+    {
+        /**
+         * fp[-0] : pc sauvegardé
+         * fp[-1] : lr sauvegardé
+         * fp[-2] : sp précédent
+         * fp[-3] : fp précédent
+         */
+
+        result = g_binary_debugger_read_memory_u32(base, fp - 2 * sizeof(uint32_t), &lr);
+        if (!result) break;
+
+        if (lr != 0)
+        {
+            *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t));
+
+            (*callstack)[*size - 1] = lr;
+
+        }
+
+        result = g_binary_debugger_read_memory_u32(base, fp - 4 * sizeof(uint32_t), &fp);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                virt     = emplacement du point mémoire à traiter.           *
+*                                                                             *
+*  Description : Complète la commande manipulant des points d'arrêt.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const char *get_breakpoint_kind_for_arm(const GGdbDebugger *debugger, virt_t virt)
+{
+    const char *result;                     /* Indication à retourner      */
+    GArchProcessor *proc;                   /* Processeur lié au binaire   */
+    vmpa2t addr;                            /* Format d'adresse complet    */
+    GArchInstruction *instr;                /* Instruction ciblée          */
+    const char *encoding;                   /* Encodage de l'instruction   */
+
+    proc = g_loaded_binary_get_processor(G_BINARY_DEBUGGER(debugger)->binary);
+
+    init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+    instr = g_arch_processor_find_instr_by_address(proc, &addr);
+
+    if (instr == NULL)
+        result = NULL;
+
+    else
+    {
+        encoding = g_arch_instruction_get_encoding(instr);
+
+        if (strcmp(encoding, "Thumb/16") == 0)
+            result = ",2";
+
+        if (strcmp(encoding, "Thumb/32") == 0)
+            result = ",3";
+
+        if (strcmp(encoding, "ARM") == 0)
+            result = ",4";
+
+        else
+            result = NULL;
+
+        g_object_unref(G_OBJECT(instr));
+
+    }
+
+    g_object_unref(G_OBJECT(proc));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                addr     = emplacement du point mémoire à traiter.           *
+*                len      = quantité de mémoire à remplacer. [OUT]            *
+*                                                                             *
+*  Description : Construit une instruction provoquant un arrêt d'exécution.   *
+*                                                                             *
+*  Retour      : Définition du point d'arrêt à placer à l'adresse donnée.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const uint8_t *get_arm_breakpoint_data(const GGdbDebugger *debugger, virt_t addr, size_t *len)
+{
+    const uint8_t *result;                  /* Données à placer en mémoire */
+
+    /* Version point d'arrêt */
+    static const uint32_t bkpt_code[] = { 0xe1200070 };
+
+    *len = sizeof(bkpt_code);;
+
+    result = (const uint8_t *)bkpt_code;
+
+    return result;
+
+}
diff --git a/src/debug/gdbrsp/helpers_arm.h b/src/debug/gdbrsp/helpers_arm.h
new file mode 100644
index 0000000..70977bc
--- /dev/null
+++ b/src/debug/gdbrsp/helpers_arm.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers_arm.h - prototypes pour les compléments utiles à GDB pour l'architecture ARM
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_HELPERS_ARM_H
+#define _DEBUG_GDBRSP_HELPERS_ARM_H
+
+
+#include "aops.h"
+
+
+
+/* Fournit les fonctions adaptées aux opérations pour ARM. */
+const gdb_arch_ops *get_arm_operations(void);
+
+
+
+#endif  /* _DEBUG_GDBRSP_HELPERS_ARM_H */
diff --git a/src/debug/gdbrsp/helpers_arm64.c b/src/debug/gdbrsp/helpers_arm64.c
new file mode 100644
index 0000000..6807662
--- /dev/null
+++ b/src/debug/gdbrsp/helpers_arm64.c
@@ -0,0 +1,97 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers_arm64.c - compléments utiles à GDB pour l'architecture AArch64
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "helpers_arm64.h"
+
+
+#include <malloc.h>
+
+
+#include "gdb-int.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger  = débogueur à consulter.                           *
+*                callstack = pile d'appels reconstituée. [OUT]                *
+*                size      = taille de cette pile. [OUT]                      *
+*                                                                             *
+*  Description : Remonte la pile d'appels jusqu'au point courant.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool compute_call_stack_for_arm64(GGdbDebugger *debugger, virt_t **callstack, size_t *size)
+{
+    bool result;                            /* Bilan global à retourner    */
+    GBinaryDebugger *base;                  /* Version basique d'instance  */
+    uint64_t fp;                            /* Pointeur de cadre à suivre  */
+    uint64_t previous;                      /* Appel de fonction précédent */
+
+    base = G_BINARY_DEBUGGER(debugger);
+
+    result = g_binary_debugger_read_register_u64(base, "x29", &fp);
+
+    while (result && fp != 0)
+    {
+        result = g_binary_debugger_read_memory_u64(base, fp + sizeof(uint64_t), &previous);
+        if (!result) break;
+
+        *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t));
+
+        (*callstack)[*size - 1] = previous;
+
+        result = g_binary_debugger_read_memory_u64(base, fp, &fp);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : debugger = débogueur à manipuler ici.                        *
+*                addr     = emplacement du point mémoire à traiter.           *
+*                cmd      = commande en cours de constitution. [OUT]          *
+*                                                                             *
+*  Description : Complète la commande manipulant des points d'arrêt.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool fill_memory_breakpoint_cmd_for_arm64(GGdbDebugger *debugger, virt_t addr, char *cmd)
+{
+    strcat(cmd, ",4");
+
+    return true;
+
+}
diff --git a/src/debug/gdbrsp/helpers_arm64.h b/src/debug/gdbrsp/helpers_arm64.h
new file mode 100644
index 0000000..80f9312
--- /dev/null
+++ b/src/debug/gdbrsp/helpers_arm64.h
@@ -0,0 +1,40 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers_arm64.h - prototypes pour les compléments utiles à GDB pour l'architecture AArch64
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_HELPERS_ARM64_H
+#define _DEBUG_GDBRSP_HELPERS_ARM64_H
+
+
+#include "gdb.h"
+
+
+
+/* Remonte la pile d'appels jusqu'au point courant. */
+bool compute_call_stack_for_arm64(GGdbDebugger *, virt_t **, size_t *);
+
+/* Complète la commande manipulant des points d'arrêt. */
+bool fill_memory_breakpoint_cmd_for_arm64(GGdbDebugger *, virt_t, char *);
+
+
+
+#endif  /* _DEBUG_GDBRSP_HELPERS_ARM64_H */
diff --git a/src/debug/gdbrsp/packet.c b/src/debug/gdbrsp/packet.c
new file mode 100644
index 0000000..4a70a79
--- /dev/null
+++ b/src/debug/gdbrsp/packet.c
@@ -0,0 +1,389 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * packet.c - manipulation des paquets de données GDB.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "packet.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../../common/dllist.h"
+
+
+
+/* Répresentation d'un paquet GDB (instance) */
+struct _GGdbPacket
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    DL_LIST_ITEM(link);                     /* Lien vers les autres        */
+
+    char *buffer;                           /* Données à traiter           */
+    size_t len;                             /* Quantité de ces données     */
+    size_t allocated;                       /* Taille du tampon            */
+
+    uint8_t checksum;                       /* Empreinte de contrôle       */
+
+};
+
+
+/* Répresentation d'un paquet GDB (classe) */
+struct _GGdbPacketClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des représentations des paquets GDB. */
+static void g_gdb_packet_class_init(GGdbPacketClass *);
+
+/* Initialise une instance de représentation de paquet GDB. */
+static void g_gdb_packet_init(GGdbPacket *);
+
+
+
+/* Indique le type défini pour une répresentation de paquet GDB. */
+G_DEFINE_TYPE(GGdbPacket, g_gdb_packet, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des représentations des paquets GDB.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_packet_class_init(GGdbPacketClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : packet = instance à initialiser.                             *
+*                                                                             *
+*  Description : Initialise une instance de représentation de paquet GDB.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_packet_init(GGdbPacket *packet)
+{
+    DL_LIST_ITEM_INIT(&packet->link);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une représentation de paquet GDB.                       *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGdbPacket *g_gdb_packet_new(void)
+{
+    GGdbPacket *result;                     /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_GDB_PACKET, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : packet = paquet à préparer pour une émission.                *
+*                                                                             *
+*  Description : Prépare un paquet pour un envoi prochain.                    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_packet_start_new_command(GGdbPacket *packet)
+{
+    if (packet->allocated == 0)
+    {
+        packet->allocated = 1;
+        packet->buffer = (char *)calloc(packet->allocated, sizeof(char));
+    }
+
+    packet->buffer[0] = '\0';
+    packet->len = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : packet = paquet à préparer pour une émission.                *
+*                string = chaîne à inclure dans le paquet.                    *
+*                                                                             *
+*  Description : Complète un paquet pour un envoi prochain.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_packet_append(GGdbPacket *packet, const char *string)
+{
+    size_t len;                             /* Taille de la chaîne donnée  */
+
+    len = strlen(string);
+
+    /* Si la place n'est pas assez grande */
+    if ((packet->len + len + 1) > packet->allocated)
+    {
+        packet->buffer = (char *)realloc(packet->buffer, (packet->len + len + 1) * sizeof(char));
+        packet->allocated = packet->len + len + 1;
+    }
+
+
+    memcpy(packet->buffer + packet->len, string, len + 1);
+    //strcat(packet->buffer, string);
+
+    packet->len += len;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : packet = paquet à analyser.                                  *
+*                                                                             *
+*  Description : Détermine l'empreinte des données d'un paquet GDB.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_packet_compute_checksum(GGdbPacket *packet)
+{
+    int sum;                                /* Valeur cumulée des données  */
+    size_t i;                               /* Boucle de parcours          */
+
+    sum = 0;
+
+    for (i = 0; i < packet->len; i++)
+        sum += packet->buffer[i];
+
+    packet->checksum = sum % 256;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : packet   = paquet à analyser.                                *
+*                checksum = contrôle d'intégrité à retrouver.                 *
+*                                                                             *
+*  Description : Contrôle l'intégrité des données d'un paquet GDB.            *
+*                                                                             *
+*  Retour      : Bilan de la vérification.                                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_gdb_packet_verify_checksum(GGdbPacket *packet, uint8_t checksum)
+{
+    g_gdb_packet_compute_checksum(packet);
+
+    return checksum == packet->checksum;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : packet = paquet à décoder et/ou décompresser.                *
+*                                                                             *
+*  Description : Décode et/ou décompresse un paquet GDB.                      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_gdb_packet_decode(GGdbPacket *packet)
+{
+    bool result;                            /* Bilan à retourner           */
+    char *buffer;                           /* Données transcrites         */
+    size_t allocated;                       /* Quantité de données gérées  */
+    size_t i;                               /* Boucle de parcours          */
+    size_t k;                               /* Point d'insertion           */
+    size_t repeat;                          /* Nombre de répétitions       */
+
+    result = true;
+
+    allocated = packet->len + 1;
+    buffer = (char *)calloc(allocated, sizeof(char));
+
+    for (i = 0, k = 0; i < packet->len && result; i++)
+        switch (packet->buffer[i])
+        {
+            case '#':
+            case '$':
+                result = false;
+                break;
+
+            case '*':
+
+                if (++i == packet->len || k == 0)
+                {
+                    result = false;
+                    break;
+                }
+
+                repeat = packet->buffer[i] - ' ' + 3;
+
+                allocated += repeat;
+                buffer = (char *)realloc(buffer, allocated * sizeof(char));
+
+                memset(&buffer[k], buffer[k - 1], repeat);
+                k += repeat;
+
+                break;
+
+            case '}':
+
+                if (++i == packet->len)
+                {
+                    result = false;
+                    break;
+                }
+
+                buffer[k++] = packet->buffer[i] ^ 0x20;
+
+                break;
+
+            default:
+                buffer[k++] = packet->buffer[i];
+                break;
+
+        }
+
+    if (packet->buffer != NULL)
+        free(packet->buffer);
+
+    buffer[k] = '\0';
+
+    packet->buffer = buffer;
+    packet->len = k;
+    packet->allocated = allocated;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : packet   = paquet à analyser.                                *
+*                data     = données contenues dans le paquet. [OUT]           *
+*                len      = quantité de ces données ou NULL. [OUT]            *
+*                checksum = contrôle d'intégrité des données ou NULL. [OUT]   *
+*                                                                             *
+*  Description : Fournit le contenu du paquet.                                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_packet_get_data(const GGdbPacket *packet, const char **data, size_t *len, uint8_t *checksum)
+{
+    *data = packet->buffer;
+
+    if (len != NULL)
+        *len = packet->len;
+
+    if (checksum != NULL)
+        *checksum = packet->checksum;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = liste de paquets à compléter.                         *
+*                item = paquet à ajouter à la liste.                          *
+*                                                                             *
+*  Description : Ajoute un paquet à une liste de paquets.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_packet_push(GGdbPacket **list, GGdbPacket *item)
+{
+    dl_list_push(item, list, GGdbPacket, link);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = liste de paquets à consulter.                         *
+*                                                                             *
+*  Description : Retire et fournit le premier élément d'une liste de paquets. *
+*                                                                             *
+*  Retour      : Elément dépilé de la liste de paquets.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGdbPacket *g_gdb_packet_pop(GGdbPacket **list)
+{
+    return dl_list_pop(list, GGdbPacket, link);
+
+}
diff --git a/src/debug/gdbrsp/packet.h b/src/debug/gdbrsp/packet.h
new file mode 100644
index 0000000..2e8abb7
--- /dev/null
+++ b/src/debug/gdbrsp/packet.h
@@ -0,0 +1,82 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * packet.h - prototypes pour la manipulation des paquets de données GDB.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_PACKET_H
+#define _DEBUG_GDBRSP_PACKET_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+
+
+#define G_TYPE_GDB_PACKET               g_gdb_packet_get_type()
+#define G_GDB_PACKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_packet_get_type(), GGdbPacket))
+#define G_IS_GDB_PACKET(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_packet_get_type()))
+#define G_GDB_PACKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_PACKET, GGdbPacketClass))
+#define G_IS_GDB_PACKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_PACKET))
+#define G_GDB_PACKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_PACKET, GGdbPacketClass))
+
+
+/* Répresentation d'un paquet GDB (instance) */
+typedef struct _GGdbPacket GGdbPacket;
+
+/* Répresentation d'un paquet GDB (classe) */
+typedef struct _GGdbPacketClass GGdbPacketClass;
+
+
+
+/* Indique le type défini pour une répresentation de paquet GDB. */
+GType g_gdb_packet_get_type(void);
+
+/* Crée une représentation de paquet GDB. */
+GGdbPacket *g_gdb_packet_new(void);
+
+/* Prépare un paquet pour un envoi prochain. */
+void g_gdb_packet_start_new_command(GGdbPacket *);
+
+/* Complète un paquet pour un envoi prochain. */
+void g_gdb_packet_append(GGdbPacket *, const char *);
+
+/* Détermine l'empreinte des données d'un paquet GDB. */
+void g_gdb_packet_compute_checksum(GGdbPacket *);
+
+/* Contrôle l'intégrité des données d'un paquet GDB. */
+bool g_gdb_packet_verify_checksum(GGdbPacket *, uint8_t);
+
+/* Décode et/ou décompresse un paquet GDB. */
+bool g_gdb_packet_decode(GGdbPacket *);
+
+/* Fournit le contenu du paquet. */
+void g_gdb_packet_get_data(const GGdbPacket *, const char **, size_t *, uint8_t *);
+
+/* Ajoute un paquet à une liste de paquets. */
+void g_gdb_packet_push(GGdbPacket **, GGdbPacket *);
+
+/* Retire et fournit le premier élément d'une liste de paquets. */
+GGdbPacket *g_gdb_packet_pop(GGdbPacket **);
+
+
+
+#endif  /* _DEBUG_GDBRSP_PACKET_H */
diff --git a/src/debug/gdbrsp/stream-int.h b/src/debug/gdbrsp/stream-int.h
new file mode 100644
index 0000000..db61d13
--- /dev/null
+++ b/src/debug/gdbrsp/stream-int.h
@@ -0,0 +1,89 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * stream-int.h - prototypes internes pour la gestion des connexions aux serveurs GDB.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_STREAM_INT_H
+#define _DEBUG_GDBRSP_STREAM_INT_H
+
+
+#include "gdb.h"
+#include "stream.h"
+
+
+
+/* Envoie des données à un serveur GDB. */
+typedef bool (* send_gdb_data_fc) (GGdbStream *, const char *, size_t);
+
+/* Réceptionne un octet de donnée d'un serveur GDB. */
+typedef bool (* recv_gdb_byte_fc) (GGdbStream *, char *);
+
+
+/* Flux de communication avec un serveur GDB (instance) */
+struct _GGdbStream
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    int fd;                                 /* Flux ouvert en L./E.        */
+
+    GGdbDebugger *owner;                    /* Propriétaire du flux        */
+
+    send_gdb_data_fc send_data;             /* Envoi d'un paquet GDB       */
+    recv_gdb_byte_fc recv_byte;             /* Réception d'un paquet GDB   */
+
+    GThread *listening;                     /* Thread pour les réceptions  */
+
+    GGdbPacket *free_packets;               /* Liste des disponibles       */
+    GMutex free_mutex;                      /* Accès à la liste            */
+
+    GGdbPacket *recv_packets;               /* Liste des paquets reçus     */
+    GCond recv_cond;                        /* Attente de disponibilité    */
+    GMutex recv_mutex;                      /* Accès à la liste            */
+
+    GGdbPacket *status_packets;             /* Liste des paquets d'état    */
+    GCond status_cond;                      /* Attente de disponibilité    */
+    GMutex status_mutex;                    /* Accès à la liste            */
+
+
+
+
+    bool skip_ack;
+
+    bool want_status;
+
+
+};
+
+
+/* Flux de communication avec un serveur GDB (classe) */
+struct _GGdbStreamClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Lance l'écoute d'un flux de communication avec GDB. */
+bool g_gdb_stream_listen(GGdbStream *);
+
+
+
+#endif  /* _DEBUG_GDBRSP_STREAM_INT_H */
diff --git a/src/debug/gdbrsp/stream.c b/src/debug/gdbrsp/stream.c
new file mode 100644
index 0000000..979ed9b
--- /dev/null
+++ b/src/debug/gdbrsp/stream.c
@@ -0,0 +1,696 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * stream.c - gestion des connexions aux serveurs GDB.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "stream.h"
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <glib/gthread.h>
+#include <sys/select.h>
+
+
+#include "gdb-int.h"
+#include "stream-int.h"
+#include "utils.h"
+#include "../../common/dllist.h"
+#include "../../gui/panels/log.h"
+
+
+
+/* Initialise la classe des flux de communication avec GDB. */
+static void g_gdb_stream_class_init(GGdbStreamClass *);
+
+/* Initialise une instance de flux de communication avec GDB. */
+static void g_gdb_stream_init(GGdbStream *);
+
+/* Supprime toutes les références externes. */
+static void g_gdb_stream_dispose(GGdbStream *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_gdb_stream_finalize(GGdbStream *);
+
+/* Envoie un acquittement pour la dernière réception. */
+static bool gdb_stream_ack(GGdbStream *);
+
+/* Ecoute une connexion à un serveur GDB. */
+static void *gdb_stream_thread(GGdbStream *);
+
+/* Reste en alerte quant au changement de statut de l'exécution. */
+static void *gdb_stream_status_thread(GGdbStream *);
+
+/* Réceptionne un paquet d'un serveur GDB. */
+static bool g_gdb_stream_read_packet(GGdbStream *, GGdbPacket *);
+
+
+
+/* Indique le type défini pour un flux de communication avec un serveur GDB. */
+G_DEFINE_TYPE(GGdbStream, g_gdb_stream, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des flux de communication avec GDB.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_stream_class_init(GGdbStreamClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_stream_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_gdb_stream_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = instance à initialiser.                             *
+*                                                                             *
+*  Description : Initialise une instance de flux de communication avec GDB.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_stream_init(GGdbStream *stream)
+{
+    g_mutex_init(&stream->free_mutex);
+
+    g_cond_init(&stream->recv_cond);
+    g_mutex_init(&stream->recv_mutex);
+
+    g_cond_init(&stream->status_cond);
+    g_mutex_init(&stream->status_mutex);
+
+    stream->skip_ack = false;
+
+    stream->want_status = false;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_stream_dispose(GGdbStream *stream)
+{
+    g_object_unref(G_OBJECT(stream->owner));
+
+
+    /* TODO... */
+
+
+    G_OBJECT_CLASS(g_gdb_stream_parent_class)->dispose(G_OBJECT(stream));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_stream_finalize(GGdbStream *stream)
+{
+
+    /* TODO */
+
+
+    G_OBJECT_CLASS(g_gdb_stream_parent_class)->finalize(G_OBJECT(stream));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = instance à modifier.                                *
+*                                                                             *
+*  Description : Ne participe plus aux acquitements de paquets.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_stream_do_not_ack(GGdbStream *stream)
+{
+    stream->skip_ack = true;
+
+}
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = instance à réellement lancer.                       *
+*                                                                             *
+*  Description : Lance l'écoute d'un flux de communication avec GDB.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_gdb_stream_listen(GGdbStream *stream)
+{
+    bool result;                            /* Bilan final à retourner     */
+
+    result = true;
+
+    if (!g_thread_new("chrysalide_gdb_stream", (GThreadFunc)gdb_stream_thread, stream))
+        result = false;
+
+    if (!g_thread_new("chrysalide_gdb_status", (GThreadFunc)gdb_stream_status_thread, stream))
+        result = false;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = encadrement associée à l'opération.                 *
+*                                                                             *
+*  Description : Envoie un acquittement pour la dernière réception.           *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool gdb_stream_ack(GGdbStream *stream)
+{
+    ///
+    //return true;
+
+    bool result;                            /* Bilan à retourner           */
+    GGdbPacket *packet;                     /* Paquet à envoyer            */
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "+");
+
+    result = g_gdb_stream_send_packet(stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = encadrement associée à l'opération.                 *
+*                                                                             *
+*  Description : Ecoute une connexion à un serveur GDB.                       *
+*                                                                             *
+*  Retour      : ???                                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void *gdb_stream_thread(GGdbStream *stream)
+{
+    fd_set rfds;                            /* Liste des flux à surveiller */
+    int ret;                                /* Bilan d'un appel            */
+    GGdbPacket *packet;                     /* Nouveau paquet reçu         */
+
+
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;                             /* Quantité de ces données     */
+
+
+
+    while (1)
+    {
+        FD_ZERO(&rfds);
+        FD_SET(stream->fd, &rfds);
+
+        ret = select(stream->fd + 1, &rfds, NULL, NULL, NULL);
+
+        switch (ret)
+        {
+            case -1:
+                perror("select()");
+                break;
+
+            case 0:
+                break;
+
+            default:
+
+                packet = g_gdb_stream_get_free_packet(stream);
+
+                g_gdb_packet_start_new_command(packet);
+
+                if (g_gdb_stream_read_packet(stream, packet))
+                {
+                    /* Acquittement ? */
+                    if (!stream->skip_ack)
+                    {
+                        if (!gdb_stream_ack(stream)) goto bad_recv;
+                    }
+
+
+                    /* On conserve le résultat ? */
+
+
+                    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+
+                    //printf("---------------------------\n");
+                    //printf(">> want status ? %d\n", stream->want_status);
+                    //printf(">> got '%s'\n", data);
+
+
+                    if (len >= 1)
+                    {
+                        if (stream->want_status)
+                            stream->want_status = false;
+
+                        else if (index("STWX", data[0]) != NULL)
+                        {
+                            g_mutex_lock(&stream->status_mutex);
+                            g_gdb_packet_push(&stream->status_packets, packet);
+                            g_mutex_unlock(&stream->status_mutex);
+
+                            g_cond_signal(&stream->status_cond);
+
+                            break;
+                        }
+
+                        // else message inconnu -> log_message() !
+
+                    }
+
+
+
+
+                    g_mutex_lock(&stream->recv_mutex);
+                    g_gdb_packet_push(&stream->recv_packets, packet);
+                    g_mutex_unlock(&stream->recv_mutex);
+
+                    g_cond_signal(&stream->recv_cond);
+
+                }
+
+                else
+                    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+                break;
+
+ bad_recv:
+
+                printf("bad things happend...\n");
+
+                g_gdb_stream_mark_packet_as_free(stream, packet);
+
+                break;
+
+        }
+
+    }
+
+
+    printf("Oh noes....\n");
+
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = encadrement associée à l'opération.                 *
+*                                                                             *
+*  Description : Reste en alerte quant au changement de statut de l'exécution.*
+*                                                                             *
+*  Retour      : ???                                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void *gdb_stream_status_thread(GGdbStream *stream)
+{
+    GGdbPacket *packet;                     /* Nouveau paquet reçu         */
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;                             /* Quantité de ces données     */
+    bool malformed;                         /* Echec d'interprétation      */
+    uint8_t byte;                           /* Valeur quelconque sur 8 bits*/
+    bool ret;                               /* Bilan d'un appel            */
+
+    while (1)
+    {
+        /* Réception d'un nouveau paquet de statut */
+
+        g_mutex_lock(&stream->status_mutex);
+
+        if (dl_list_empty(stream->status_packets))
+            g_cond_wait(&stream->status_cond, &stream->status_mutex);
+
+        packet = g_gdb_packet_pop(&stream->status_packets);
+
+        g_mutex_unlock(&stream->status_mutex);
+
+        /* Traitement du paquet reçu */
+
+        g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+        malformed = false;
+
+        switch (data[0])
+        {
+            case 'S':
+
+                ret = read_fixed_byte(data + 1, len - 1, &byte);
+
+                if (!ret)
+                {
+                    malformed = true;
+                    goto gsst_processed;
+                }
+
+                g_gdb_debugger_receive_signal_reply(stream->owner, byte);
+                break;
+
+            case 'T':
+                assert(false);  // TODO
+                break;
+
+            case 'W':
+
+                ret = read_fixed_byte(data + 1, len - 1, &byte);
+
+                if (!ret)
+                {
+                    malformed = true;
+                    goto gsst_processed;
+                }
+
+
+                // TODO : ";process:pid"
+
+
+                printf("Program exited (status=%hhu)\n", byte);
+
+
+                g_gdb_debugger_receive_exit_reply(stream->owner, byte, -1);
+
+
+                // log_message en cas de mauvais format...
+
+
+                break;
+
+
+            default:
+                assert(false);
+                break;
+
+        }
+
+ gsst_processed:
+
+        if (malformed && true/* TODO : config->show_... */)
+            log_variadic_message(LMT_WARNING, "Malformed GDB status reply: '%s'", data);
+
+        g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    }
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = flux de communication avec GDB à consulter.         *
+*                                                                             *
+*  Description : Fournit un paquet prêt à emploi.                             *
+*                                                                             *
+*  Retour      : Paquet prêt à emploi.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGdbPacket *g_gdb_stream_get_free_packet(GGdbStream *stream)
+{
+    GGdbPacket *result;                     /* Paquet à retourner          */
+
+    g_mutex_lock(&stream->free_mutex);
+
+    if (dl_list_empty(stream->free_packets))
+        result = g_gdb_packet_new();
+
+    else
+        result = g_gdb_packet_pop(&stream->free_packets);
+
+    g_mutex_unlock(&stream->free_mutex);
+
+    // ???
+    //g_gdb_packet_start_new_command(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = flux de communication avec GDB à mettre à jour.     *
+*                packet = paquet à considérer comme disponible.               *
+*                                                                             *
+*  Description : Place un paquet en attente d'une future utilisation.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_gdb_stream_mark_packet_as_free(GGdbStream *stream, GGdbPacket *packet)
+{
+    //// Utile ?
+    g_gdb_packet_start_new_command(packet);
+
+
+    g_mutex_lock(&stream->free_mutex);
+
+    g_gdb_packet_push(&stream->free_packets, packet);
+
+    g_mutex_unlock(&stream->free_mutex);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = flux ouvert en lecture  à utiliser.                 *
+*                packet = données à recevoir.                                 *
+*                                                                             *
+*  Description : Réceptionne un paquet d'un serveur GDB.                      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_stream_read_packet(GGdbStream *stream, GGdbPacket *packet)
+{
+    bool result;                            /* Bilan à renvoyer            */
+    char tmp[3];                            /* Tampon de réception         */
+    uint8_t checksum;                       /* Contrôle d'intégrité        */
+
+    do
+    {
+        result = stream->recv_byte(stream, tmp);
+        if (tmp[0] != '+') break;
+    }
+    while (0);
+
+    if (tmp[0] != '$') return false;
+
+    tmp[1] = '\0';
+
+    while ((result = stream->recv_byte(stream, tmp)))
+    {
+        //printf(" .. '%c'\n", tmp[0]);
+
+        if (tmp[0] == '#') break;
+        else g_gdb_packet_append(packet, tmp);
+    }
+
+    if (result)
+    {
+        result = stream->recv_byte(stream, &tmp[0]);
+        result &= stream->recv_byte(stream, &tmp[1]);
+
+        tmp[2] = 0;
+        checksum = strtol(tmp, NULL, 16);
+
+    }
+
+    if (result)
+        result = g_gdb_packet_verify_checksum(packet, checksum);
+
+    if (result)
+        result = g_gdb_packet_decode(packet);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = flux ouvert en écriture à mettre à jour.            *
+*                packet = données à transmettre.                              *
+*                                                                             *
+*  Description : Envoie un paquet à un serveur GDB.                           *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+#include <string.h>
+bool g_gdb_stream_send_packet(GGdbStream *stream, GGdbPacket *packet)
+{
+    bool result;                            /* Bilan à renvoyer            */
+    const char *data;                       /* Données à envoyer           */
+    size_t len;                             /* Quantité de ces données     */
+    uint8_t checksum;                       /* Contrôle d'intégrité        */
+    char tmp[3];                            /* Impression du checksum      */
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+#if 1
+    /* Ack ? */
+    if (len == 1 && data[0] == '+')
+        result = stream->send_data(stream, "+", 1);
+
+    else
+#endif
+    {
+
+    result = stream->send_data(stream, "$", 1);
+    //result = stream->send_data(stream, "+$", 2);
+
+    g_gdb_packet_compute_checksum(packet);
+    g_gdb_packet_get_data(packet, &data, &len, &checksum);
+
+
+    if (len == 1 && data[0] == '?')
+        stream->want_status = true;
+
+    /*
+    if (memcmp(data, "vCont;c", strlen("vCont;c")) == 0)
+        stream->want_status = true;
+    */
+
+
+
+    result &= stream->send_data(stream, data, len);
+
+    result = stream->send_data(stream, "#", 1);
+
+    snprintf(tmp, 3, "%02hhx", checksum);
+    result &= stream->send_data(stream, tmp, 2);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = flux de communication avec GDB à consulter.         *
+*                                                                             *
+*  Description : Fournit un paquet reçu d'un serveur GDB.                     *
+*                                                                             *
+*  Retour      : Paquet GDB.                                                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGdbPacket *g_gdb_stream_recv_packet(GGdbStream *stream)
+{
+    GGdbPacket *result;                     /* Paquet à retourner          */
+
+    g_mutex_lock(&stream->recv_mutex);
+
+    if (dl_list_empty(stream->recv_packets))
+        g_cond_wait(&stream->recv_cond, &stream->recv_mutex);
+
+    result = g_gdb_packet_pop(&stream->recv_packets);
+
+    g_mutex_unlock(&stream->recv_mutex);
+
+    return result;
+
+}
diff --git a/src/debug/gdbrsp/stream.h b/src/debug/gdbrsp/stream.h
new file mode 100644
index 0000000..b4b483d
--- /dev/null
+++ b/src/debug/gdbrsp/stream.h
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * stream.h - prototypes pour la gestion des connexions aux serveurs GDB.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_STREAM_H
+#define _DEBUG_GDBRSP_STREAM_H
+
+
+#include "packet.h"
+
+
+
+#define G_TYPE_GDB_STREAM               g_gdb_stream_get_type()
+#define G_GDB_STREAM(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_stream_get_type(), GGdbStream))
+#define G_IS_GDB_STREAM(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_stream_get_type()))
+#define G_GDB_STREAM_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_STREAM, GGdbStreamClass))
+#define G_IS_GDB_STREAM_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_STREAM))
+#define G_GDB_STREAM_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_STREAM, GGdbStreamClass))
+
+
+/* Flux de communication avec un serveur GDB (instance) */
+typedef struct _GGdbStream GGdbStream;
+
+/* Flux de communication avec un serveur GDB (classe) */
+typedef struct _GGdbStreamClass GGdbStreamClass;
+
+
+
+/* Indique le type défini pour un flux de communication avec un serveur GDB. */
+GType g_gdb_stream_get_type(void);
+
+/* Ne participe plus aux acquitements de paquets. */
+void g_gdb_stream_do_not_ack(GGdbStream *);
+
+/* Fournit un paquet prêt à emploi. */
+GGdbPacket *g_gdb_stream_get_free_packet(GGdbStream *);
+
+/* Place un paquet en attente d'une future utilisation. */
+void g_gdb_stream_mark_packet_as_free(GGdbStream *, GGdbPacket *);
+
+/* Envoie un paquet à un serveur GDB. */
+bool g_gdb_stream_send_packet(GGdbStream *, GGdbPacket *);
+
+/* Fournit un paquet reçu d'un serveur GDB. */
+GGdbPacket *g_gdb_stream_recv_packet(GGdbStream *);
+
+
+
+#endif  /* _DEBUG_GDBRSP_STREAM_H */
diff --git a/src/debug/gdbrsp/support.c b/src/debug/gdbrsp/support.c
new file mode 100644
index 0000000..5086540
--- /dev/null
+++ b/src/debug/gdbrsp/support.c
@@ -0,0 +1,598 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * support.c - conformité dans l'interfaçage client/serveur
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "support.h"
+
+
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/* Indications quant à l'interfaçage client/serveur GDB (instance) */
+struct _GGdbSupport
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    unsigned long packet_size;              /* Taille maximale d'un paquet */
+
+    bool os_data;
+
+
+    bool extended_mode;                     /* Mode étendu présent & actif */
+
+
+    char *id;
+
+};
+
+/* Indications quant à l'interfaçage client/serveur GDB (classe) */
+struct _GGdbSupportClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des détails d'interfaçage GDB. */
+static void g_gdb_support_class_init(GGdbSupportClass *);
+
+/* Procède à l'initialisation des détails d'interfaçage GDB. */
+static void g_gdb_support_init(GGdbSupport *);
+
+/* Supprime toutes les références externes. */
+static void g_gdb_support_dispose(GGdbSupport *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_gdb_support_finalize(GGdbSupport *);
+
+/* Lit une valeur booléenne à partir des détails du serveur. */
+static bool g_gdb_support_read_bool(GGdbSupport *, const char *, const char *, bool *);
+
+/* Lit une valeur longue à partir des détails du serveur. */
+static bool g_gdb_support_read_ulong(GGdbSupport *, const char *, const char *, unsigned long *);
+
+
+
+/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */
+G_DEFINE_TYPE(GGdbSupport, g_gdb_support, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe de débogueur à initialiser.                   *
+*                                                                             *
+*  Description : Initialise la classe des détails d'interfaçage GDB.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_support_class_init(GGdbSupportClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_support_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_gdb_support_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : support = instance de débogueur à préparer.                  *
+*                                                                             *
+*  Description : Procède à l'initialisation des détails d'interfaçage GDB.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_support_init(GGdbSupport *support)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : support = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_support_dispose(GGdbSupport *support)
+{
+    G_OBJECT_CLASS(g_gdb_support_parent_class)->dispose(G_OBJECT(support));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : support = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_support_finalize(GGdbSupport *support)
+{
+    G_OBJECT_CLASS(g_gdb_support_parent_class)->finalize(G_OBJECT(support));
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#include <string.h>
+
+static char *build_id(GGdbStream *stream)
+{
+    char *result;                           /* Identifiant à renvoyer      */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    bool status;                            /* Bilan d'une communication   */
+    const char *data;                       /* Données reçues à analyser   */
+    const char *start;                      /* Début d'identification      */
+    const char *end;                        /* Fin d'identification        */
+
+    result = NULL;
+
+    /* Envoi de la requête */
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "?");
+
+    status = g_gdb_stream_send_packet(stream, packet);
+
+    if (!status)
+        goto ggdgat_exit;
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, NULL, NULL);
+
+    start = strstr(data, "thread:");
+    if (start == NULL) goto ggdgat_exit;
+
+    start += sizeof("thread:") - 1 /* '\0' */;
+
+    end = strstr(start, ";");
+    if (end == NULL) goto ggdgat_exit;
+
+    result = strndup(start, end - start);
+
+ ggdgat_exit:
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    return result;
+
+}
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = flux de communication ouvert avec le débogueur.     *
+*                                                                             *
+*  Description : Crée une définition des détails d'interfaçage GDB.           *
+*                                                                             *
+*  Retour      : Instance de détails mise en place ou NULL.                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGdbSupport *g_gdb_support_new(GGdbStream *stream)
+{
+    GGdbSupport *result;                    /* Débogueur à retourner       */
+    GGdbPacket *packet;                     /* Paquet de communication GDB */
+
+
+    //goto end;
+
+    //goto skip;
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters");
+    g_gdb_packet_append(packet, "qSupported");
+
+    g_gdb_packet_append(packet, "qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+");
+
+
+    bool test;
+
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;
+
+    test = g_gdb_stream_send_packet(stream, packet);
+
+
+
+    printf(" >> Paquet '%s' bien envoyé ? %s\n", "qSupported", test ? "oui" : "non");
+
+
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    printf(" << Réception de '%s'\n", data);
+
+
+
+
+    result = g_object_new(G_TYPE_GDB_SUPPORT, NULL);
+
+
+
+    /* Découpage des éléments de réponse */
+
+    char *answer;                           /* Réponse modifiable          */
+    char *save;                             /* Sauvegarde de position      */
+    char *token;                            /* Elément de réponse cerné    */
+
+    answer = strdup(data);
+
+    for (token = strtok_r(answer, ";", &save);
+         token != NULL;
+         token = strtok_r(NULL, ";", &save))
+    {
+
+
+        printf("TOKEN :: %s\n", token);
+
+        if (g_gdb_support_read_ulong(result, token, "PacketSize", &result->packet_size))
+            continue;
+
+        if (g_gdb_support_read_bool(result, token, "qXfer:osdata:read", &result->os_data))
+        {
+            printf(" -->> %d\n", result->os_data);
+            continue;
+        }
+
+
+
+
+    }
+
+    free(answer);
+
+
+
+    /**
+     * Première chose : plus d'acquitement !
+     *
+     * Dans les faits, c'est impossible à gérer en asynchrone. Par exemple :
+     *
+     *  C> vCont;c
+     *  C> g           Txx... <S
+     *
+     * Si le client envoie une commande en même temps que le serveur envoie
+     * quelque chose, le serveur attend dans tous les cas un acquitement.
+     * Donc il va consommer les données envoyées par le client jusqu'à y
+     * trouver ce qu'il cherche.
+     */
+
+    /* Envoi de la requête */
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "QStartNoAckMode");
+
+    test = g_gdb_stream_send_packet(stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    if (!test)
+        goto ggsn_error;
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, NULL, NULL);
+
+    if (strcmp(data, "OK") != 0)
+        goto ggsn_error;
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    /* Désactivation des acquitements */
+
+    g_gdb_stream_do_not_ack(stream);
+
+    /**
+     * Passage en mode étendu. C'est obligatoire pour pouvoir redémarrer un
+     * programme débogué.
+     */
+
+    /* Envoi de la requête */
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "!");
+
+    test = g_gdb_stream_send_packet(stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    if (!test)
+        goto ggsn_error;
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, NULL, NULL);
+
+    result->extended_mode = (strcmp(data, "OK") == 0);
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+
+
+
+    result->id = build_id(stream);
+
+
+
+#if 0
+    //end:
+
+#define CMD "?"
+
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters");
+    g_gdb_packet_append(packet, CMD);
+
+
+    test = g_gdb_stream_send_packet(stream, packet);
+
+
+
+    printf(" >> Paquet '%s' bien envoyé ? %s\n", CMD, test ? "oui" : "non");
+
+
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    printf(" << [pkt = %p ] Réception de '%s' (len=%d)\n", packet, data, (int)len);
+
+
+#endif
+
+
+
+    // qfThreadInfo
+
+
+#undef CMD
+
+    //#define CMD "qXfer:threads:read::0,1fff"
+    //#define CMD "qXfer:btrace:read:all:0,1fff"
+    //#define CMD "g"
+    //#define CMD "m400000,8"
+#define CMD "qsThreadInfo"
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters");
+    g_gdb_packet_append(packet, CMD);
+
+
+    test = g_gdb_stream_send_packet(stream, packet);
+
+
+
+    printf(" >> Paquet '%s' bien envoyé ? %s\n", CMD, test ? "oui" : "non");
+
+
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    printf(" << [pkt = %p ] Réception de '%s' (len=%d)\n", packet, data, (int)len);
+
+
+
+
+
+
+
+
+
+
+
+    return result;
+
+ ggsn_error:
+
+
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : support = ensemble de détails à préciser.                    *
+*                raw     = données brutes à parcourir.                        *
+*                name    = désignation de la valeur recherchée.               *
+*                value   = emplacement de la valeur à inscrire.               *
+*                                                                             *
+*  Description : Lit une valeur booléenne à partir des détails du serveur.    *
+*                                                                             *
+*  Retour      : true en cas d'affectation, false dans tous les autres cas.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_support_read_bool(GGdbSupport *support, const char *raw, const char *name, bool *value)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t rlen;                            /* Taille de l'ensemble        */
+    size_t nlen;                            /* Taille du nom               */
+
+    rlen = strlen(raw);
+    nlen = strlen(name);
+
+    if ((nlen + 1) != rlen)
+        return false;
+
+    if (strncmp(raw, name, nlen) != 0)
+        return false;
+
+    switch (raw[nlen])
+    {
+        case '+':
+            *value = true;
+            result = true;
+            break;
+
+        case '-':
+        case '?':
+            *value = false;
+            result = true;
+            break;
+
+        default:
+            result = false;
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : support = ensemble de détails à préciser.                    *
+*                raw     = données brutes à parcourir.                        *
+*                name    = désignation de la valeur recherchée.               *
+*                value   = emplacement de la valeur à inscrire.               *
+*                                                                             *
+*  Description : Lit une valeur longue à partir des détails du serveur.       *
+*                                                                             *
+*  Retour      : true en cas d'affectation, false dans tous les autres cas.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_support_read_ulong(GGdbSupport *support, const char *raw, const char *name, unsigned long *value)
+{
+    size_t rlen;                            /* Taille de l'ensemble        */
+    size_t nlen;                            /* Taille du nom               */
+    unsigned long v;                        /* Valeur récupérée à assigner */
+
+    rlen = strlen(raw);
+    nlen = strlen(name);
+
+    if (strncmp(raw, name, nlen) != 0)
+        return false;
+
+    if (raw[nlen] != '=')
+        return false;
+
+    v = strtoul(raw + nlen + 1, NULL, 16);
+
+    if (v == ULONG_MAX/* && errno == ERANGE*/)
+        return false;
+
+    *value = v;
+
+    return true;
+
+}
+
+
+
+
+
+
+char *g_gdb_support_get_id(const GGdbSupport *support)
+{
+    return support->id;
+
+}
+
+
+
+
+
diff --git a/src/debug/gdbrsp/support.h b/src/debug/gdbrsp/support.h
new file mode 100644
index 0000000..6b4ab63
--- /dev/null
+++ b/src/debug/gdbrsp/support.h
@@ -0,0 +1,73 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * support.h - prototypes pour la conformité dans l'interfaçage client/serveur
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_SUPPORT_H
+#define _DEBUG_GDBRSP_SUPPORT_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "stream.h"
+
+
+
+#define G_TYPE_GDB_SUPPORT            (g_gdb_support_get_type())
+#define G_GDB_SUPPORT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_SUPPORT, GGdbSupport))
+#define G_IS_GDB_SUPPORT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_SUPPORT))
+#define G_GDB_SUPPORT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_SUPPORT, GGdbSupportClass))
+#define G_IS_GDB_SUPPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_SUPPORT))
+#define G_GDB_SUPPORT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_SUPPORT, GGdbSupportClass))
+
+
+/* Indications quant à l'interfaçage client/serveur GDB (instance) */
+typedef struct _GGdbSupport GGdbSupport;
+
+/* Indications quant à l'interfaçage client/serveur GDB (classe) */
+typedef struct _GGdbSupportClass GGdbSupportClass;
+
+
+/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */
+GType g_gdb_support_get_type(void);
+
+/* Crée une définition des détails d'interfaçage GDB. */
+GGdbSupport *g_gdb_support_new(GGdbStream *);
+
+
+
+
+
+
+
+char *g_gdb_support_get_id(const GGdbSupport *support);
+
+
+
+
+
+
+
+
+
+#endif  /* _DEBUG_GDBRSP_SUPPORT_H */
diff --git a/src/debug/gdbrsp/target.c b/src/debug/gdbrsp/target.c
new file mode 100644
index 0000000..d6edf6c
--- /dev/null
+++ b/src/debug/gdbrsp/target.c
@@ -0,0 +1,950 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * target.c - gestion des éléments propres à l'architecture reconnue par GDB
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "target.h"
+
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "utils.h"
+#include "../../common/cpp.h"
+#include "../../common/extstr.h"
+#include "../../common/xml.h"
+
+
+
+/* Définitions de registres */
+
+typedef struct _arch_register_t
+{
+    char *name;                             /* Nom de registre             */
+    unsigned int size;                      /* Taille en bits              */
+
+} arch_register_t;
+
+typedef struct _target_cpu_t
+{
+    char *label;                            /* Désignation de l'ensemble   */
+
+    arch_register_t *regs;                  /* Définition des registres    */
+    unsigned int count;                     /* Quantité de ces définitions */
+
+} target_cpu_t;
+
+
+/* Indications quant à l'interfaçage client/serveur GDB (instance) */
+struct _GGdbTarget
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    target_cpu_t **defs;                    /* Liste de définitions        */
+    size_t count;                           /* Taille de cette même liste  */
+
+    bool read_single_register;              /* Lecture spécifique permise ?*/
+    bool write_single_register;             /* Ecriture spécifique valide ?*/
+
+};
+
+/* Indications quant à l'interfaçage client/serveur GDB (classe) */
+struct _GGdbTargetClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des détails d'interfaçage GDB. */
+static void g_gdb_target_class_init(GGdbTargetClass *);
+
+/* Procède à l'initialisation des détails d'interfaçage GDB. */
+static void g_gdb_target_init(GGdbTarget *);
+
+/* Supprime toutes les références externes. */
+static void g_gdb_target_dispose(GGdbTarget *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_gdb_target_finalize(GGdbTarget *);
+
+/* Charge la définition d'un groupe de registres. */
+static bool g_gdb_target_load_register_definition(GGdbTarget *, GGdbStream *, const char *);
+
+/* Recherche l'indice correspondant à un registre donné. */
+static bool g_gdb_target_find_register_index(const GGdbTarget *, const char *, unsigned int *);
+
+/* Recherche la position correspondant à un registre donné. */
+static bool g_gdb_target_find_register_offset(const GGdbTarget *, unsigned int, size_t *);
+
+
+
+/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */
+G_DEFINE_TYPE(GGdbTarget, g_gdb_target, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe de débogueur à initialiser.                   *
+*                                                                             *
+*  Description : Initialise la classe des détails d'interfaçage GDB.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_target_class_init(GGdbTargetClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_target_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_gdb_target_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = instance de débogueur à préparer.                   *
+*                                                                             *
+*  Description : Procède à l'initialisation des détails d'interfaçage GDB.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_target_init(GGdbTarget *target)
+{
+    target->defs = NULL;
+    target->count = 0;
+
+    target->read_single_register = true;
+    target->write_single_register = true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_target_dispose(GGdbTarget *target)
+{
+    G_OBJECT_CLASS(g_gdb_target_parent_class)->dispose(G_OBJECT(target));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_target_finalize(GGdbTarget *target)
+{
+    G_OBJECT_CLASS(g_gdb_target_parent_class)->finalize(G_OBJECT(target));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : stream = flux de communication ouvert avec le débogueur.     *
+*                                                                             *
+*  Description : Crée une définition des détails d'interfaçage GDB.           *
+*                                                                             *
+*  Retour      : Instance de détails mise en place ou NULL.                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGdbTarget *g_gdb_target_new(GGdbStream *stream)
+{
+    GGdbTarget *result;                     /* Débogueur à retourner       */
+    GGdbPacket *packet;                     /* Paquet de communication GDB */
+    bool status;                            /* Bilan d'une communication   */
+
+    const char *data;                       /* Données reçues du serveur   */
+    size_t len;                             /* Quantité de ces données     */
+    char *xmldata;                          /* Données modifiables         */
+    xmlDocPtr xdoc;                         /* Document XML récupéré       */
+    xmlXPathContextPtr context;             /* COntexte d'analyse associé  */
+    xmlXPathObjectPtr xobject;              /* Cible d'une recherche       */
+    unsigned int i;                         /* Boucle de parcours          */
+    char *access;                           /* Chemin d'accès à un élément */
+    char *xmlref;                           /* Référence de définitions    */
+
+
+
+
+    result = NULL;
+
+
+    //goto end;
+
+    //goto skip;
+
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    //g_gdb_packet_append(packet, "qTargeted:multiprocess+;xmlRegisters");
+    g_gdb_packet_append(packet, "qXfer:features:read:target.xml:0,3fff");
+
+    //g_gdb_packet_append(packet, "qTargeted:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContTargeted+;QThreadEvents+;no-resumed+");
+
+
+
+    status = g_gdb_stream_send_packet(stream, packet);
+    if (!status) goto ggtn_failed;
+
+
+
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    printf(" << Réception de '%s'\n", data);
+
+    /* Marqueur de fin placé au début ?! */
+    if (data[0] != 'l')
+        goto ggtn_failed;
+
+    xmldata = strdup(data + 1);
+
+    /**
+     * On cherche à éviter la déconvenue suivante avec la libxml2 :
+     *
+     *    noname.xml:12: namespace error : Namespace prefix xi on include is not defined
+     *      <xi:include href="aarch64-core.xml"/>
+     */
+
+    xmldata = strrpl(xmldata, "xi:include", "include");
+
+    if (!load_xml_from_memory(xmldata, len - 1, &xdoc, &context))
+        goto ggtn_failed;
+
+
+    result = g_object_new(G_TYPE_GDB_TARGET, NULL);
+
+
+    xobject = get_node_xpath_object(context, "/target/include");
+
+    for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
+    {
+        asprintf(&access, "/target/include[position()=%u]", i + 1);
+
+        xmlref = get_node_prop_value(context, access, "href");
+
+        free(access);
+
+        if (xmlref != NULL)
+        {
+            printf("REF>> %s\n", xmlref);
+            /*static bool */g_gdb_target_load_register_definition(result, stream, xmlref);
+
+            free(xmlref);
+
+        }
+
+    }
+
+    if(xobject != NULL)
+        xmlXPathFreeObject(xobject);
+
+    close_xml_file(xdoc, context);
+
+    free(xmldata);
+
+
+
+
+
+
+
+
+
+
+    //result = g_object_new(G_TYPE_GDB_TARGET, NULL);
+
+
+ ggtn_failed:
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = ensemble d'informations liées à l'architecture.     *
+*                stream = flux de communication ouvert avec le débogueur.     *
+*                name   = désignation des définitions de registres à charger. *
+*                                                                             *
+*  Description : Charge la définition d'un groupe de registres.               *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_target_load_register_definition(GGdbTarget *target, GGdbStream *stream, const char *name)
+{
+    bool result;                            /* Bilan à retourner           */
+    GGdbPacket *packet;                     /* Paquet de communication GDB */
+    bool status;                            /* Bilan d'une communication   */
+    const char *data;                       /* Données reçues du serveur   */
+    size_t len;                             /* Quantité de ces données     */
+    xmlDocPtr xdoc;                         /* Document XML récupéré       */
+    xmlXPathContextPtr context;             /* COntexte d'analyse associé  */
+    xmlXPathObjectPtr xobject;              /* Cible d'une recherche       */
+    target_cpu_t *def;                      /* Nouvelle définition à lire  */
+    unsigned int i;                         /* Boucle de parcours          */
+    char *access;                           /* Chemin d'accès à un élément */
+    char *type;                             /* Espèce de définition        */
+
+    result = false;
+
+    /* Envoi de la requête */
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+
+    g_gdb_packet_append(packet, "qXfer:features:read:");
+    g_gdb_packet_append(packet, name);
+    g_gdb_packet_append(packet, ":0,3fff");
+
+    status = g_gdb_stream_send_packet(stream, packet);
+    if (!status) goto ggtlrd_failed;
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    //printf(">>>> '%s'\n", data);
+
+    /* Marqueur de fin placé au début ?! */
+    if (data[0] != 'l')
+        goto ggtlrd_failed;
+
+    if (!load_xml_from_memory(data + 1, len - 1, &xdoc, &context))
+        goto ggtlrd_failed;
+
+    /* Chargement des définitions */
+
+    xobject = get_node_xpath_object(context, "/feature/*");
+
+    def = (target_cpu_t *)calloc(1, sizeof(target_cpu_t));
+
+    def->count = XPATH_OBJ_NODES_COUNT(xobject);
+    def->regs = (arch_register_t *)calloc(def->count, sizeof(arch_register_t));
+
+    for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
+    {
+        asprintf(&access, "/feature/*[position()=%u]", i + 1);
+
+        type = get_node_name(context, access);
+
+        if (strcmp(type, "reg") == 0)
+        {
+            def->regs[i].name = get_node_prop_value(context, access, "name");
+            def->regs[i].size = atoi(get_node_prop_value(context, access, "bitsize"));
+
+            //printf("load reg '%s' (%u)\n", def->regs[i].name, def->regs[i].size);
+
+        }
+
+        free(type);
+
+        free(access);
+
+    }
+
+    if(xobject != NULL)
+        xmlXPathFreeObject(xobject);
+
+    close_xml_file(xdoc, context);
+
+    /* Intégration finale */
+
+    target->defs = (target_cpu_t **)realloc(target->defs, ++target->count * sizeof(target_cpu_t *));
+
+    target->defs[target->count - 1] = def;
+
+ ggtlrd_failed:
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = ensemble d'informations liées à l'architecture.     *
+*                group  = éventuel groupe de registres ciblé ou NULL.         *
+*                count  = nombre d'éléments dans la liste de noms. [OUT]      *
+*                                                                             *
+*  Description : Liste l'ensemble des registres appartenant à un groupe.      *
+*                                                                             *
+*  Retour      : Liste de noms à libérer de la mémoire après utilisation.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char **g_gdb_target_get_register_names(const GGdbTarget *target, const char *group, size_t *count)
+{
+    char **result;                          /* Désignations à retourner    */
+    unsigned int i;                         /* Boucle de parcours #1       */
+    const target_cpu_t *rgrp;               /* Groupe de registres         */
+    unsigned int j;                         /* Boucle de parcours #2       */
+
+    result = NULL;
+
+    for (i = 0; i < target->count && result == NULL; i++)
+    {
+        rgrp = target->defs[i];
+
+        if (group != NULL)
+        {
+            if (strcmp(rgrp->label, group) != 0)
+                continue;
+        }
+
+        *count = rgrp->count;
+
+        result = (char **)calloc(*count, sizeof(char *));
+
+        for (j = 0; j < *count; j++)
+            result[j] = strdup(rgrp->regs[j].name);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = ensemble d'informations liées à l'architecture.     *
+*                name   = désignation du registre visé.                       *
+*                                                                             *
+*  Description : Indique la taille associée à un registre donné.              *
+*                                                                             *
+*  Retour      : Taille en bits, ou 0 si le registre n'a pas été trouvé.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int g_gdb_target_get_register_size(const GGdbTarget *target, const char *name)
+{
+    unsigned int result;                    /* Taille en bits  à retourner */
+    unsigned int i;                         /* Boucle de parcours #1       */
+    const target_cpu_t *rgrp;               /* Groupe de registres         */
+    unsigned int j;                         /* Boucle de parcours #2       */
+
+    result = 0;
+
+    for (i = 0; i < target->count && result == 0; i++)
+    {
+        rgrp = target->defs[i];
+
+        for (j = 0; j < rgrp->count; j++)
+            if (strcmp(rgrp->regs[j].name, name) == 0)
+                result = rgrp->regs[j].size;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = ensemble d'informations liées à l'architecture.     *
+*                reg    = désignation humaine du register à consulter.        *
+*                index  = indice correspondant au registre pour GDB. [OUT]    *
+*                                                                             *
+*  Description : Recherche l'indice correspondant à un registre donné.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération : trouvaille ou échec ?                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_target_find_register_index(const GGdbTarget *target, const char *reg, unsigned int *index)
+{
+    bool result;                            /* Bilan à retourner           */
+    unsigned int i;                         /* Boucle de parcours #1       */
+    unsigned int j;                         /* Boucle de parcours #2       */
+
+    result = false;
+
+    *index = 0;
+
+    for (i = 0; i < target->count && !result; i++)
+        for (j = 0; j < target->defs[i]->count && !result; j++)
+        {
+            if (strcmp(target->defs[i]->regs[j].name, reg) == 0)
+                result = true;
+            else
+                (*index)++;
+        }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = ensemble d'informations liées à l'architecture.     *
+*                index  = indice correspondant au registre pour GDB.          *
+*                offset = position de valeur du registre dans du texte. [OUT] *
+*                                                                             *
+*  Description : Recherche la position correspondant à un registre donné.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération : trouvaille ou échec ?                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_target_find_register_offset(const GGdbTarget *target, unsigned int index, size_t *offset)
+{
+    unsigned int i;                         /* Boucle de parcours #1       */
+    unsigned int j;                         /* Boucle de parcours #2       */
+
+    *offset = 0;
+
+    for (i = 0; i < target->count && index > 0; i++)
+        for (j = 0; j < target->defs[i]->count && index > 0; j++)
+        {
+            assert(target->defs[i]->regs[j].size % 4 == 0);
+
+            *offset += target->defs[i]->regs[j].size / 4;
+
+            index--;
+
+        }
+
+    return (index == 0);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = ensemble d'informations liées à l'architecture.     *
+*                stream = flux de communication ouvert avec le débogueur.     *
+*                endian = boutisme de la cible.                               *
+*                reg    = désignation humaine du register à consulter.        *
+*                size   = taille des données mises en jeu.                    *
+*                ...    = emplacement de la valeur lue à conserver. [OUT]     *
+*                                                                             *
+*  Description : Effectue la lecture d'un registre donné.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_gdb_target_read_register(GGdbTarget *target, GGdbStream *stream, SourceEndian endian, const char *reg, size_t size, ...)
+{
+    bool result;                            /* Bilan à retourner           */
+    unsigned int index;                     /* Indice du registre ciblé    */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    char cmd[sizeof(XSTR(UINT_MAX)) + 1];   /* Elément de requête          */
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;                             /* Quantité de ces données     */
+    const char *raw;                        /* Début de zone à relire      */
+    size_t offset;                          /* Position dans la masse      */
+    va_list ap;                             /* Liste variable d'arguments  */
+    uint8_t *val8;                          /* Valeur sur 8 bits           */
+    uint16_t *val16;                        /* Valeur sur 16 bits          */
+    uint16_t conv16;                        /* Valeur adaptée sur 16 bits  */
+    uint32_t *val32;                        /* Valeur sur 32 bits          */
+    uint32_t conv32;                        /* Valeur adaptée sur 32 bits  */
+    uint64_t *val64;                        /* Valeur sur 64 bits          */
+    uint64_t conv64;                        /* Valeur adaptée sur 64 bits  */
+
+    result = g_gdb_target_find_register_index(target, reg, &index);
+    if (!result) goto ggtrr_error;
+
+    /**
+     * Essai avec la méthode précise.
+     */
+
+    if (!target->read_single_register)
+        goto read_all_register_fallback;
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "p");
+
+    snprintf(cmd, sizeof(cmd), "%x", index);
+    g_gdb_packet_append(packet, cmd);
+
+    result = g_gdb_stream_send_packet(stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    if (!result)
+        goto ggtrr_error;
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    if (len != 0 && !is_error_code(data, len))
+        raw = data;
+
+    else
+    {
+        target->read_single_register = false;
+
+        g_gdb_stream_mark_packet_as_free(stream, packet);
+
+ read_all_register_fallback:
+
+        /**
+         * Utilisation de la méthode de masse au besoin...
+         */
+
+        packet = g_gdb_stream_get_free_packet(stream);
+
+        g_gdb_packet_start_new_command(packet);
+        g_gdb_packet_append(packet, "g");
+
+        result = g_gdb_stream_send_packet(stream, packet);
+
+        g_gdb_stream_mark_packet_as_free(stream, packet);
+
+        if (!result)
+            goto ggtrr_error;
+
+        /* Réception de la réponse */
+
+        packet = g_gdb_stream_recv_packet(stream);
+
+        g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+        result = g_gdb_target_find_register_offset(target, index, &offset);
+
+        if (!result || offset > len)
+            goto ggtrr_exit;
+
+        raw = data + offset;
+        len -= offset;
+
+    }
+
+    /* Lecture finale de la valeur recherchée */
+
+    va_start(ap, size);
+
+    switch (size)
+    {
+        case 8:
+            val8 = va_arg(ap, uint8_t *);
+            result = hex_to_u8(raw, val8);
+            break;
+
+        case 16:
+            val16 = va_arg(ap, uint16_t *);
+            result = hex_to_u16(raw, &conv16);
+            *val16 = from_u16(&conv16, endian);
+            break;
+
+        case 32:
+            val32 = va_arg(ap, uint32_t *);
+            result = hex_to_u32(raw, &conv32);
+            *val32 = from_u32(&conv32, endian);
+            break;
+
+        case 64:
+            val64 = va_arg(ap, uint64_t *);
+            result = hex_to_u64(raw, &conv64);
+            *val64 = from_u64(&conv64, endian);
+            break;
+
+        default:
+            assert(false);
+            result = false;
+            break;
+
+    }
+
+    va_end(ap);
+
+ ggtrr_exit:
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+ ggtrr_error:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = ensemble d'informations liées à l'architecture.     *
+*                stream = flux de communication ouvert avec le débogueur.     *
+*                endian = boutisme de la cible.                               *
+*                reg    = désignation humaine du register à consulter.        *
+*                size   = taille des données mises en jeu.                    *
+*                ...    = emplacement de la valeur à écrire.                  *
+*                                                                             *
+*  Description : Effectue l'écriture d'un registre donné.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_gdb_target_write_register(GGdbTarget *target, GGdbStream *stream, SourceEndian endian, const char *reg, size_t size, ...)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    va_list ap;                             /* Liste variable d'arguments  */
+    const uint8_t *val8;                    /* Valeur sur 8 bits           */
+    const uint16_t *val16;                  /* Valeur sur 16 bits          */
+    uint16_t conv16;                        /* Valeur adaptée sur 16 bits  */
+    const uint32_t *val32;                  /* Valeur sur 32 bits          */
+    uint32_t conv32;                        /* Valeur adaptée sur 32 bits  */
+    const uint64_t *val64;                  /* Valeur sur 64 bits          */
+    uint64_t conv64;                        /* Valeur adaptée sur 64 bits  */
+    char hexval[17];                        /* Valeur sous forme hexa      */
+    unsigned int index;                     /* Indice du registre ciblé    */
+    GGdbPacket *packet;                     /* Paquet de communication     */
+    char cmd[sizeof(XSTR(UINT_MAX)) + 1];   /* Elément de requête          */
+    const char *data;                       /* Données reçues à analyser   */
+    size_t len;                             /* Quantité de ces données     */
+    char *new;                              /* Nouvelles valeurs générales */
+    size_t offset;                          /* Position dans la masse      */
+
+    /* Tronc commun : récupération de la valeur */
+
+    va_start(ap, size);
+
+    switch (size)
+    {
+        case 8:
+            val8 = va_arg(ap, uint8_t *);
+            result = u8_to_hex(val8, hexval);
+            break;
+
+        case 16:
+            val16 = va_arg(ap, uint16_t *);
+            conv16 = to_u16(val16, endian);
+            result = u16_to_hex(&conv16, hexval);
+            break;
+
+        case 32:
+            val32 = va_arg(ap, uint32_t *);
+            conv32 = to_u32(val32, endian);
+            result = u32_to_hex(&conv32, hexval);
+            break;
+
+        case 64:
+            val64 = va_arg(ap, uint64_t *);
+            conv64 = to_u64(val64, endian);
+            result = u16_to_hex(&conv64, hexval);
+            break;
+
+        default:
+            assert(false);
+            result = false;
+            break;
+
+    }
+
+    va_end(ap);
+
+    if (!result)
+        goto ggtwr_error;
+
+    /* Préparation de la suite */
+
+    result = g_gdb_target_find_register_index(target, reg, &index);
+    if (!result) goto ggtwr_error;
+
+    /**
+     * Essai avec la méthode précise.
+     */
+
+    if (!target->write_single_register)
+        goto write_all_register_fallback;
+
+    packet = g_gdb_stream_get_free_packet(stream);
+
+    g_gdb_packet_start_new_command(packet);
+    g_gdb_packet_append(packet, "P");
+
+    snprintf(cmd, sizeof(cmd), "%x", index);
+    g_gdb_packet_append(packet, cmd);
+
+    g_gdb_packet_append(packet, "=");
+
+    g_gdb_packet_append(packet, hexval);
+
+    result = g_gdb_stream_send_packet(stream, packet);
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+    if (!result)
+        goto ggtwr_error;
+
+    /* Réception de la réponse */
+
+    packet = g_gdb_stream_recv_packet(stream);
+
+    g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+    if (is_error_code(data, len) || strcmp(data, "OK") != 0)
+    {
+        target->write_single_register = false;
+
+        g_gdb_stream_mark_packet_as_free(stream, packet);
+
+ write_all_register_fallback:
+
+        /**
+         * Utilisation de la méthode de masse au besoin...
+         */
+
+        /* Lecture de l'ensemble des registres */
+
+        packet = g_gdb_stream_get_free_packet(stream);
+
+        g_gdb_packet_start_new_command(packet);
+        g_gdb_packet_append(packet, "g");
+
+        result = g_gdb_stream_send_packet(stream, packet);
+
+        g_gdb_stream_mark_packet_as_free(stream, packet);
+
+        if (!result)
+            goto ggtwr_error;
+
+        /* Réception de la réponse et mise à jour */
+
+        packet = g_gdb_stream_recv_packet(stream);
+
+        g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+        result = g_gdb_target_find_register_offset(target, index, &offset);
+
+        if (!result || offset > len)
+            goto ggtwr_exit;
+
+        new = (char *)malloc(len);
+
+        memcpy(new, data, len);
+        memcpy(new + offset, hexval, strlen(hexval));
+
+        g_gdb_stream_mark_packet_as_free(stream, packet);
+
+        /* Ecrasement de tous les registres */
+
+        packet = g_gdb_stream_get_free_packet(stream);
+
+        g_gdb_packet_start_new_command(packet);
+        g_gdb_packet_append(packet, "G");
+
+        g_gdb_packet_append(packet, new);
+        free(new);
+
+        result = g_gdb_stream_send_packet(stream, packet);
+
+        g_gdb_stream_mark_packet_as_free(stream, packet);
+
+        if (!result)
+            goto ggtwr_error;
+
+        /* Réception de la réponse */
+
+        packet = g_gdb_stream_recv_packet(stream);
+
+        g_gdb_packet_get_data(packet, &data, &len, NULL);
+
+        result = (!is_error_code(data, len) && strcmp(data, "OK") == 0);
+
+    }
+
+ ggtwr_exit:
+
+    g_gdb_stream_mark_packet_as_free(stream, packet);
+
+ ggtwr_error:
+
+    return result;
+
+}
diff --git a/src/debug/gdbrsp/target.h b/src/debug/gdbrsp/target.h
new file mode 100644
index 0000000..805ff49
--- /dev/null
+++ b/src/debug/gdbrsp/target.h
@@ -0,0 +1,72 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * target.h - prototypes pour la gestion des éléments propres à l'architecture reconnue par GDB
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_TARGET_H
+#define _DEBUG_GDBRSP_TARGET_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "stream.h"
+#include "../../common/endianness.h"
+
+
+
+#define G_TYPE_GDB_TARGET            (g_gdb_target_get_type())
+#define G_GDB_TARGET(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_TARGET, GGdbTarget))
+#define G_IS_GDB_TARGET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_TARGET))
+#define G_GDB_TARGET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_TARGET, GGdbTargetClass))
+#define G_IS_GDB_TARGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_TARGET))
+#define G_GDB_TARGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_TARGET, GGdbTargetClass))
+
+
+/* Indications quant à l'interfaçage client/serveur GDB (instance) */
+typedef struct _GGdbTarget GGdbTarget;
+
+/* Indications quant à l'interfaçage client/serveur GDB (classe) */
+typedef struct _GGdbTargetClass GGdbTargetClass;
+
+
+/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */
+GType g_gdb_target_get_type(void);
+
+/* Crée une définition des détails d'interfaçage GDB. */
+GGdbTarget *g_gdb_target_new(GGdbStream *);
+
+/* Liste l'ensemble des registres appartenant à un groupe. */
+char **g_gdb_target_get_register_names(const GGdbTarget *, const char *, size_t *);
+
+/* Indique la taille associée à un registre donné. */
+unsigned int g_gdb_target_get_register_size(const GGdbTarget *, const char *);
+
+/* Effectue la lecture d'un registre donné. */
+bool g_gdb_target_read_register(GGdbTarget *, GGdbStream *, SourceEndian, const char *, size_t, ...);
+
+/* Effectue l'écriture d'un registre donné. */
+bool g_gdb_target_write_register(GGdbTarget *, GGdbStream *, SourceEndian, const char *, size_t, ...);
+
+
+
+#endif  /* _DEBUG_GDBRSP_TARGET_H */
diff --git a/src/debug/gdbrsp/tcp.c b/src/debug/gdbrsp/tcp.c
new file mode 100644
index 0000000..d6a1ef8
--- /dev/null
+++ b/src/debug/gdbrsp/tcp.c
@@ -0,0 +1,280 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tcp.c - gestion des connexions TCP aux serveurs GDB.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "tcp.h"
+
+
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+
+#include "stream-int.h"
+
+
+#include "../../common/net.h"
+
+
+/* Flux de communication TCP avec un serveur GDB (instance) */
+struct _GGdbTcpClient
+{
+    GGdbStream parent;                      /* A laisser en premier        */
+
+};
+
+
+/* Flux de communication TCP avec un serveur GDB (classe) */
+struct _GGdbTcpClientClass
+{
+    GGdbStreamClass parent;                 /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des flux de communication TCP avec GDB. */
+static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *);
+
+/* Initialise une instance de flux de communication avec GDB. */
+static void g_gdb_tcp_client_init(GGdbTcpClient *);
+
+/* Ouvre une connexion TCP à un serveur GDB. */
+//static int connect_via_tcp(const char *, const char *);
+
+/* Envoie des données à un serveur GDB. */
+static bool g_gdb_tcp_client_send_data(GGdbTcpClient *, const char *, size_t);
+
+/* Réceptionne un octet de donnée d'un serveur GDB. */
+static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *, char *);
+
+
+
+/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */
+G_DEFINE_TYPE(GGdbTcpClient, g_gdb_tcp_client, G_TYPE_GDB_STREAM);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des flux de communication TCP avec GDB. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : client = instance à initialiser.                             *
+*                                                                             *
+*  Description : Initialise une instance de flux de communication avec GDB.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_gdb_tcp_client_init(GGdbTcpClient *client)
+{
+    GGdbStream *stream;                     /* Version parente             */
+
+    stream = G_GDB_STREAM(client);
+
+    stream->send_data = (send_gdb_data_fc)g_gdb_tcp_client_send_data;
+    stream->recv_byte = (recv_gdb_byte_fc)g_gdb_tcp_client_recv_byte;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : server = nom ou adresse du serveur à contacter.              *
+*                port   = port de connexion.                                  *
+*                                                                             *
+*  Description : Ouvre une connexion TCP à un serveur GDB.                    *
+*                                                                             *
+*  Retour      : Flux ouvert en lecture/écriture ou -1 en cas d'échec.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+#if 0
+static int connect_via_tcp(const char *server, const char *port)
+{
+    int result;                             /* Bilan à retourner           */
+    struct addrinfo hints;                  /* Type de connexion souhaitée */
+    struct addrinfo *infos;                 /* Informations disponibles    */
+    int ret;                                /* Bilan d'un appel            */
+    struct addrinfo *iter;                  /* Boucle de parcours          */
+    struct sockaddr_in addr;                /* Infos de connexion distante */
+
+    memset(&hints, 0, sizeof(struct addrinfo));
+
+    hints.ai_family = AF_UNSPEC;        /* IPv4 ou IPv6 */
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = 0;
+    hints.ai_protocol = 0;              /* N'importe quel protocole */
+
+    ret = getaddrinfo(server, port, &hints, &infos);
+    if (ret != 0)
+    {
+        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
+        return -1;
+    }
+
+    for (iter = infos; iter != NULL; iter = iter->ai_next)
+    {
+        result = socket(iter->ai_family, iter->ai_socktype, iter->ai_protocol);
+        if (result == -1) continue;
+
+        ret = connect(result, iter->ai_addr, iter->ai_addrlen);
+        if (ret == 0) break;
+
+        perror("connect");
+        close(result);
+
+    }
+
+    freeaddrinfo(infos);
+
+    if (iter == NULL) return -1;
+
+    ret = getpeername(result, (struct sockaddr *)&addr, (socklen_t []){ sizeof(struct sockaddr_in) });
+    if (ret == -1)
+    {
+        perror("getpeername");
+        close(result);
+        return -1;
+    }
+
+    printf("Connecté à %s:%hd\n", server, ntohs(addr.sin_port));
+
+    return result;
+
+}
+#endif
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : server = nom ou adresse du serveur à contacter.              *
+*                port   = port de connexion.                                  *
+*                owner  = débogueur tributaire du canal de communication.     *
+*                                                                             *
+*  Description : Crée une nouvelle connexion TCP à un serveur GDB.            *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GGdbStream *g_gdb_tcp_client_new(const char *server, const char *port, GGdbDebugger *owner)
+{
+    GGdbTcpClient *result;                  /* Structure à retourner       */
+    int sock;                               /* Flux ouvert à construire    */
+
+    sock = connect_via_tcp(server, port, NULL);
+    if (sock == -1) return NULL;
+
+    result = g_object_new(G_TYPE_GDB_TCP_CLIENT, NULL);
+
+    G_GDB_STREAM(result)->fd = sock;
+
+    G_GDB_STREAM(result)->owner = owner;
+    g_object_ref(G_OBJECT(owner));
+
+    if (!g_gdb_stream_listen(G_GDB_STREAM(result)))
+        goto ggtcn_error;
+
+    return G_GDB_STREAM(result);
+
+ ggtcn_error:
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : client = flux ouvert en écriture à utiliser.                 *
+*                data   = données à envoyer.                                  *
+*                len    = quantité de ces données.                            *
+*                                                                             *
+*  Description : Envoie des données à un serveur GDB.                         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_tcp_client_send_data(GGdbTcpClient *client, const char *data, size_t len)
+{
+    ssize_t sent;                           /* Quantité de données envoyée */
+
+    sent = send(G_GDB_STREAM(client)->fd, data, len, 0);
+
+    //printf("  sent '%s'\n", data);
+    //printf("  sent ? %d vs %d\n", (int)sent, (int)len);
+
+    return (sent == len);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : client = flux ouvert en lecture à utiliser.                  *
+*                data   = donnée à recevoir.                                  *
+*                                                                             *
+*  Description : Réceptionne un octet de donnée d'un serveur GDB.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *client, char *data)
+{
+    ssize_t got;                            /* Quantité de données reçue   */
+
+    got = recv(G_GDB_STREAM(client)->fd, data, 1, 0);
+
+    //printf("  got ? %d vs %d -> %c (0x%02hhx\n", (int)got, (int)1, *data, *data);
+
+    return (got == 1);
+
+}
diff --git a/src/debug/gdbrsp/tcp.h b/src/debug/gdbrsp/tcp.h
new file mode 100644
index 0000000..18d6c33
--- /dev/null
+++ b/src/debug/gdbrsp/tcp.h
@@ -0,0 +1,57 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tcp.h - prototypes pour la gestion des connexions TCP aux serveurs GDB.
+ *
+ * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_TCP_H
+#define _DEBUG_GDBRSP_TCP_H
+
+
+#include "gdb.h"
+#include "stream.h"
+
+
+
+#define G_TYPE_GDB_TCP_CLIENT               g_gdb_tcp_client_get_type()
+#define G_GDB_TCP_CLIENT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_tcp_client_get_type(), GGdbTcpClient))
+#define G_IS_GDB_TCP_CLIENT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_tcp_client_get_type()))
+#define G_GDB_TCP_CLIENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_TCP_CLIENT, GGdbTcpClientClass))
+#define G_IS_GDB_TCP_CLIENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_TCP_CLIENT))
+#define G_GDB_TCP_CLIENT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_TCP_CLIENT, GGdbTcpClientClass))
+
+
+/* Flux de communication TCP avec un serveur GDB (instance) */
+typedef struct _GGdbTcpClient GGdbTcpClient;
+
+/* Flux de communication TCP avec un serveur GDB (classe) */
+typedef struct _GGdbTcpClientClass GGdbTcpClientClass;
+
+
+
+/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */
+GType g_gdb_tcp_client_get_type(void);
+
+/* Crée une nouvelle connexion TCP à un serveur GDB. */
+GGdbStream *g_gdb_tcp_client_new(const char *, const char *, GGdbDebugger *);
+
+
+
+#endif  /* _DEBUG_GDBRSP_TCP_H */
diff --git a/src/debug/gdbrsp/utils.c b/src/debug/gdbrsp/utils.c
new file mode 100644
index 0000000..8c4cb8a
--- /dev/null
+++ b/src/debug/gdbrsp/utils.c
@@ -0,0 +1,351 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * utils.h - fonctions qui simplifient la vie dans les interactions avec un serveur GDB
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "utils.h"
+
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : data = données à inspecter.                                  *
+*                len  = quantité de ces données.                              *
+*                                                                             *
+*  Description : Indique si les données correspondent à un code d'erreur.     *
+*                                                                             *
+*  Retour      : Bilan de l'analyse.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool is_error_code(const char *data, size_t len)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = (len == 3);
+
+    if (result)
+        result = (data[0] == 'E' && isdigit(data[1]) && isdigit(data[2]));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : data = données à analyser.                                   *
+*                size = taille de ces données.                                *
+*                byte = statut de sortie d'un programme. [OUT]                *
+*                                                                             *
+*  Description : Relit une valeur sur 8 bits et deux lettres.                 *
+*                                                                             *
+*  Retour      : Bilan de la lecture.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool read_fixed_byte(const char *data, size_t len, uint8_t *byte)
+{
+    bool result;                            /* Bilan à retourner           */
+    const char *iter;                       /* Boucle de parcours #1       */
+    size_t i;                               /* Boucle de parcours #2       */
+    uint8_t nibble;                         /* Valeur affichée             */
+
+    result = true;
+
+    len = MIN(2, len);
+
+    for (i = 0, iter = data; i < len && result; i++, iter++)
+    {
+        switch (*iter)
+        {
+            case '0' ... '9':
+                nibble = *iter - '0';
+                break;
+
+            case 'a' ... 'f':
+                nibble = *iter - 'a' + 10;
+                break;
+
+            case 'A' ... 'F':
+                nibble = *iter - 'A' + 10;
+                break;
+
+            default:
+                result = false;
+                break;
+
+        }
+
+        if (i == 0)
+            *byte = (nibble << 4);
+        else
+            *byte |= nibble;
+
+    }
+
+    if (result)
+        result = (i == 2);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hex   = tampon d'origine assez grand.                        *
+*                size  = taille de la valeur à considérer pour les travaux.   *
+*                value = valeur sur XX bits à transcrire. [OUT]               *
+*                                                                             *
+*  Description : Traduit en valeur sur XX bits une forme textuelle.           *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool hex_to_any_u(const char *hex, size_t size, ...)
+{
+    bool result;                            /* Bilan à retourner           */
+    va_list ap;                             /* Gestion de l'inconnue       */
+    uint8_t *value8;                        /* Valeur sur 8 bits           */
+    uint16_t *value16;                      /* Valeur sur 16 bits          */
+    uint32_t *value32;                      /* Valeur sur 32 bits          */
+    uint64_t *value64;                      /* Valeur sur 64 bits          */
+    uint8_t *iter;                          /* Boucle de parcours #1       */
+    size_t i;                               /* Boucle de parcours #2       */
+    char nibble;                            /* Valeur à afficher           */
+
+    result = false;
+
+    /* Récupération de la destination */
+
+    va_start(ap, size);
+
+    switch (size)
+    {
+        case 1:
+            value8 = va_arg(ap, uint8_t *);
+            iter = value8;
+            break;
+
+        case 2:
+            value16 = va_arg(ap, uint16_t *);
+            iter = (uint8_t *)value16;
+            break;
+
+        case 4:
+            value32 = va_arg(ap, uint32_t *);
+            iter = (uint8_t *)value32;
+            break;
+
+        case 8:
+            value64 = va_arg(ap, uint64_t *);
+            iter = (uint8_t *)value64;
+            break;
+
+        default:
+            goto done;
+            break;
+
+    }
+
+    /* Lecture de la valeur */
+
+    for (i = 0; i < size; i++, iter++)
+    {
+        *iter = 0;
+
+        nibble = hex[i * 2];
+
+        switch (nibble)
+        {
+            case '0' ... '9':
+                *iter = (nibble - '0') << 4;
+                break;
+
+            case 'a' ... 'f':
+                *iter = (nibble - 'a' + 0xa) << 4;
+                break;
+
+            case 'A' ... 'F':
+                *iter = (nibble - 'A' + 0xa) << 4;
+                break;
+
+            default:
+                goto done;
+                break;
+
+        }
+
+        nibble = hex[i * 2 + 1];
+
+        switch (nibble)
+        {
+            case '0' ... '9':
+                *iter |= (nibble - '0');
+                break;
+
+            case 'a' ... 'f':
+                *iter |= (nibble - 'a' + 0xa);
+                break;
+
+            case 'A' ... 'F':
+                *iter |= (nibble - 'A' + 0xa);
+                break;
+
+            default:
+                goto done;
+                break;
+
+        }
+
+    }
+
+    result = (i == size);
+
+ done:
+
+    va_end(ap);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : size  = taille de la valeur à considérer pour les travaux.   *
+*                hex   = tampon de destination assez grand.                   *
+*                value = valeur sur XX bits à transcrire. [OUT]               *
+*                                                                             *
+*  Description : Traduit une valeur sur XX bits en forme textuelle.           *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool any_u_to_hex(size_t size, char hex[17], ...)
+{
+    bool result;                            /* Bilan à retourner           */
+    va_list ap;                             /* Gestion de l'inconnue       */
+    uint8_t *value8;                        /* Valeur sur 8 bits           */
+    uint16_t *value16;                      /* Valeur sur 16 bits          */
+    uint32_t *value32;                      /* Valeur sur 32 bits          */
+    uint64_t *value64;                      /* Valeur sur 64 bits          */
+    size_t i;                               /* Boucle de parcours #1       */
+    const uint8_t *iter;                    /* Boucle de parcours #2       */
+    uint8_t nibble;                         /* Valeur à retenir            */
+
+    result = true;
+
+    /* Récupération de la destination */
+
+    va_start(ap, hex);
+
+    switch (size)
+    {
+        case 1:
+            value8 = va_arg(ap, uint8_t *);
+            iter = (const uint8_t *)value8;
+            break;
+
+        case 2:
+            value16 = va_arg(ap, uint16_t *);
+            iter = (const uint8_t *)value16;
+            break;
+
+        case 4:
+            value32 = va_arg(ap, uint32_t *);
+            iter = (const uint8_t *)value32;
+            break;
+
+        case 8:
+            value64 = va_arg(ap, uint64_t *);
+            iter = (const uint8_t *)value64;
+            break;
+
+        default:
+            result = false;
+            goto done;
+            break;
+
+    }
+
+    /* Lecture de la valeur */
+
+    for (i = 0; i < size; i++, iter++)
+    {
+        nibble = (*iter & 0xf0) >> 4;
+
+        switch (nibble)
+        {
+            case 0x0 ... 0x9:
+                hex[i * 2] = '0' + nibble;
+                break;
+
+            case 0xa ... 0xf:
+                hex[i * 2] = 'A' + nibble - 0xa;
+                break;
+
+        }
+
+        nibble = (*iter & 0x0f);
+
+        switch (nibble)
+        {
+            case 0x0 ... 0x9:
+                hex[i * 2 + 1] = '0' + nibble;
+                break;
+
+            case 0xa ... 0xf:
+                hex[i * 2 + 1] = 'A' + nibble - 0xa;
+                break;
+
+        }
+
+    }
+
+    hex[size * 2] = '\0';
+
+ done:
+
+    va_end(ap);
+
+    return result;
+
+}
diff --git a/src/debug/gdbrsp/utils.h b/src/debug/gdbrsp/utils.h
new file mode 100644
index 0000000..a67df46
--- /dev/null
+++ b/src/debug/gdbrsp/utils.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * utils.h - prototypes pour les fonctions qui simplifient la vie dans les interactions avec un serveur GDB
+ *
+ * Copyright (C) 2016 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_GDBRSP_UTILS_H
+#define _DEBUG_GDBRSP_UTILS_H
+
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+
+
+/* Indique si les données correspondent à un code d'erreur. */
+bool is_error_code(const char *, size_t);
+
+/* Relit une valeur sur 8 bits et deux lettres. */
+bool read_fixed_byte(const char *, size_t, uint8_t *);
+
+/* Traduit en valeur sur XX bits une forme textuelle. */
+bool hex_to_any_u(const char *, size_t, ...);
+
+#define hex_to_u8(h, v)  hex_to_any_u(h, 1, v)
+#define hex_to_u16(h, v) hex_to_any_u(h, 2, v)
+#define hex_to_u32(h, v) hex_to_any_u(h, 4, v)
+#define hex_to_u64(h, v) hex_to_any_u(h, 8, v)
+
+/* Traduit une valeur sur XX bits en forme textuelle. */
+bool any_u_to_hex(size_t, char [17], ...);
+
+#define u8_to_hex(v, h)  any_u_to_hex(1, h, v)
+#define u16_to_hex(v, h) any_u_to_hex(2, h, v)
+#define u32_to_hex(v, h) any_u_to_hex(4, h, v)
+#define u64_to_hex(v, h) any_u_to_hex(8, h, v)
+
+
+
+#endif  /* _DEBUG_GDBRSP_UTILS_H */
diff --git a/src/debug/misc.h b/src/debug/misc.h
new file mode 100644
index 0000000..dd9492a
--- /dev/null
+++ b/src/debug/misc.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * misc.h - prototypes pour les définitions communes et génériques liées au débogage
+ *
+ * Copyright (C) 2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _DEBUG_MISC_H
+#define _DEBUG_MISC_H
+
+
+#include <stdint.h>
+
+
+
+/* Couverture maximale des identifiants */
+typedef uint64_t dbg_thread_id_t;
+
+
+
+#endif  /* _DEBUG_MISC_H */
diff --git a/src/debug/remgdb/Makefile.am b/src/debug/remgdb/Makefile.am
deleted file mode 100644
index 47e5fdc..0000000
--- a/src/debug/remgdb/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-
-noinst_LTLIBRARIES = libdebugremgdb.la
-
-libdebugremgdb_la_SOURCES =				\
-	gdb.h gdb.c							\
-	helpers.h helpers.c					\
-	packet.h packet.c					\
-	stream-int.h						\
-	stream.h stream.c					\
-	tcp.h tcp.c
-
-libdebugremgdb_la_CFLAGS = $(AM_CFLAGS)
-
-
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/src/debug/remgdb/gdb.c b/src/debug/remgdb/gdb.c
deleted file mode 100644
index 728eee6..0000000
--- a/src/debug/remgdb/gdb.c
+++ /dev/null
@@ -1,363 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gdb.c - débogage à l'aide de gdb.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "gdb.h"
-
-
-#include "../debugger-int.h"
-
-
-
-#include "helpers.h"
-#include "tcp.h"
-
-
-
-
-/* Débogueur utilisant un serveur GDB (instance) */
-struct _GGdbDebugger
-{
-    GBinaryDebugger parent;                 /* A laisser en premier        */
-
-    GGdbStream *stream;                     /* Flux de communication       */
-
-
-#if 0
-    GCond *cond;                            /* Poursuite du déroulement    */
-    GMutex *mutex;                          /* Accès à la condition        */
-
-    ptrace_options *options;                /* Configuration du débogage   */
-
-    pid_t child;                            /* Processus suivi lancé       */
-
-    gboolean run_again;                     /* Reprise du débogage         */
-#endif
-};
-
-/* Débogueur utilisant un serveur GDB (classe) */
-struct _GGdbDebuggerClass
-{
-    GBinaryDebuggerClass parent;            /* A laisser en premier        */
-
-};
-
-
-
-
-
-/* Initialise la classe du débogueur utilisant gdb. */
-static void g_gdb_debugger_class_init(GGdbDebuggerClass *);
-
-/* Procède à l'initialisation du débogueur utilisant gdb. */
-static void g_gdb_debugger_init(GGdbDebugger *);
-
-
-/* Met en marche le débogueur utilisant un serveur GDB. */
-static bool g_gdb_debugger_run(GGdbDebugger *);
-
-/* Remet en marche le débogueur utilisant un serveur GDB. */
-static bool g_gdb_debugger_resume(GGdbDebugger *);
-
-/* Tue le débogueur utilisant un serveur GDB. */
-static bool g_gdb_debugger_kill(GGdbDebugger *);
-
-
-
-/* Indique le type défini par la GLib pour le débogueur gdb. */
-G_DEFINE_TYPE(GGdbDebugger, g_gdb_debugger, G_TYPE_BINARY_DEBUGGER);
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe de débogueur à initialiser.                   *
-*                                                                             *
-*  Description : Initialise la classe du débogueur utilisant gdb.             *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_gdb_debugger_class_init(GGdbDebuggerClass *klass)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : debugger = instance de débogueur à préparer.                 *
-*                                                                             *
-*  Description : Procède à l'initialisation du débogueur utilisant gdb.       *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_gdb_debugger_init(GGdbDebugger *debugger)
-{
-    GBinaryDebugger *parent;                /* Instance parente            */
-
-    parent = G_BINARY_DEBUGGER(debugger);
-
-    parent->run = (basic_debugger_fc)g_gdb_debugger_run;
-    parent->resume = (resume_debugger_fc)g_gdb_debugger_resume;
-    parent->kill = (basic_debugger_fc)g_gdb_debugger_kill;
-
-    //parent->get_reg_values = (get_register_values_fc)get_register_values_using_gdb_debugger;
-
-    //debugger->cond = g_cond_new();
-    //debugger->mutex = g_mutex_new();
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binary  = binaire représenter à déboguer.                    *
-*                options = paramètres destinés au débogage.                   *
-*                                                                             *
-*  Description : Crée un débogueur utilisant un serveur GDB distant.          *
-*                                                                             *
-*  Retour      : Instance de débogueur mise en place ou NULL.                 *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBinaryDebugger *g_gdb_debugger_new(GLoadedBinary *binary, void *options)
-{
-    GBinaryDebugger *result;                /* Débogueur à retourner       */
-
-    result = g_object_new(G_TYPE_GDB_DEBUGGER, NULL);
-
-    return result;
-
-}
-
-
-
-
-
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : debugger = débogueur à lancer.                               *
-*                                                                             *
-*  Description : Met en marche le débogueur utilisant un serveur GDB.         *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_gdb_debugger_run(GGdbDebugger *debugger)
-{
-
-
-
-    GGdbPacket *packet;
-
-    bool test;
-
-    const char *data;
-    size_t len;
-
-
-    int sig;
-    vmpa_t addr;
-    pid_t thread;
-
-
-    debugger->stream = g_gdb_tcp_client_new("127.0.0.1", "6666");
-    if (debugger->stream == NULL) return false;
-
-
-    printf("Connection done !\n");
-
-
-
-    packet = g_gdb_stream_get_free_packet(debugger->stream);
-
-    g_gdb_packet_start_new_command(packet);
-    g_gdb_packet_append(packet, "?");
-
-
-    test = g_gdb_stream_send_packet(debugger->stream, packet);
-
-
-
-    printf(" >> Paquet '%s' bien envoyé ? %s\n", "?", test ? "oui" : "non");
-
-
-
-    g_gdb_stream_mark_packet_as_free(debugger->stream, packet);
-
-    packet = g_gdb_stream_recv_packet(debugger->stream);
-
-    g_gdb_packet_get_data(packet, &data, &len, NULL);
-
-    printf(" << Réception de '%s'\n", data);
-
-
-
-
-
-    get_stop_reply_sig_info(packet, &sig, &addr, &thread, SRE_LITTLE);
-
-    g_signal_emit_by_name(debugger, "halted", sig, addr, thread);
-
-        
-
-
-
-
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : debugger = débogueur à relancer.                             *
-*                                                                             *
-*  Description : Remet en marche le débogueur utilisant un serveur GDB.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_gdb_debugger_resume(GGdbDebugger *debugger)
-{
-
-
-    /*
-    g_mutex_lock(debugger->mutex);
-    debugger->run_again = TRUE;
-    g_cond_signal(debugger->cond);
-    g_mutex_unlock(debugger->mutex);
-    */
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : debugger = débogueur à relancer.                             *
-*                                                                             *
-*  Description : Tue le débogueur utilisant un serveur GDB.                   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_gdb_debugger_kill(GGdbDebugger *debugger)
-{
-
-
-#if 0
-    int ret;                                /* Bilan de l'appel système    */
-
-    ret = kill(debugger->child, SIGKILL);
-    if (ret != 0) perror("kill");
-
-    debugger->child = 0;
-
-    g_mutex_lock(debugger->mutex);
-    debugger->run_again = TRUE;
-    g_cond_signal(debugger->cond);
-    g_mutex_unlock(debugger->mutex);
-#endif
-    return true;
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-void test_gdb(void)
-{
-
-    GGdbStream *stream;
-
-    GGdbPacket *packet;
-
-    bool test;
-
-    const char *data;
-    size_t len;
-
-    printf("GDB !!!!\n");
-
-
-    stream = g_gdb_tcp_client_new("192.168.100.141", "6666");
-
-
-
-    packet = g_gdb_stream_get_free_packet(stream);
-
-    g_gdb_packet_start_new_command(packet);
-    g_gdb_packet_append(packet, "g");
-
-
-    test = g_gdb_stream_send_packet(stream, packet);
-
-
-
-    printf(" >> Paquet '%s' bien envoyé ? %s\n", "g", test ? "oui" : "non");
-
-
-
-    g_gdb_stream_mark_packet_as_free(stream, packet);
-
-    packet = g_gdb_stream_recv_packet(stream);
-
-    g_gdb_packet_get_data(packet, &data, &len, NULL);
-
-    printf(" << Réception de '%s'\n", data);
-
-
-
-
-}
diff --git a/src/debug/remgdb/gdb.h b/src/debug/remgdb/gdb.h
deleted file mode 100644
index 38aa8fe..0000000
--- a/src/debug/remgdb/gdb.h
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gdb.h - prototypes pour le débogage à l'aide de gdb.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _DEBUG_REMGDB_GDB_H
-#define _DEBUG_REMGDB_GDB_H
-
-
-#include <glib-object.h>
-
-
-#include "../debugger.h"
-
-
-
-#define G_TYPE_GDB_DEBUGGER            (g_gdb_debugger_get_type())
-#define G_GDB_DEBUGGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_DEBUGGER, GGdbDebugger))
-#define G_IS_GDB_DEBUGGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_DEBUGGER))
-#define G_GDB_DEBUGGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass))
-#define G_IS_GDB_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_DEBUGGER))
-#define G_GDB_DEBUGGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass))
-
-
-/* Débogueur utilisant un serveur GDB (instance) */
-typedef struct _GGdbDebugger GGdbDebugger;
-
-/* Débogueur utilisant un serveur GDB (classe) */
-typedef struct _GGdbDebuggerClass GGdbDebuggerClass;
-
-
-/* Indique le type défini par la GLib pour le débogueur gdb. */
-GType g_gdb_debugger_get_type(void);
-
-/* Crée un débogueur utilisant un serveur GDB distant. */
-GBinaryDebugger *g_gdb_debugger_new(GLoadedBinary *, void *);
-
-
-void test_gdb(void);
-
-
-
-#endif  /* _DEBUG_REMGDB_GDB_H */
diff --git a/src/debug/remgdb/helpers.c b/src/debug/remgdb/helpers.c
deleted file mode 100644
index bae7f0b..0000000
--- a/src/debug/remgdb/helpers.c
+++ /dev/null
@@ -1,139 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * helpers.c - assistanat dans la manipulation des paquets GDB
- *
- * Copyright (C) 2010-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "helpers.h"
-
-
-#include <regex.h>
-#include <string.h>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */
-
-
-
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : packet = paquet de deonnées à interpréter.                   *
-*                sig    = identifiant du signal source. [OUT]                 *
-*                addr   = adresse de l'instruction courante. [OUT]            *
-*                thread = identifiant du thread concerné. [OUT]               *
-*                endian = boutisme de la plateforme ciblée.                   *
-*                                                                             *
-*  Description : Récupère les informations liées à un arrêt suite à signal.   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : Les données sont la forme :                                  *
-*                T0505:00000000;04:a08de6bf;08:505878b7;thread:50dc;          *
-*                                                                             *
-******************************************************************************/
-
-bool get_stop_reply_sig_info(const GGdbPacket *packet, int *sig, vmpa_t *addr, pid_t *thread, SourceEndian endian)
-{
-    const char *data;                       /* Données brutes du paquet    */
-    size_t length;                          /* Quantité de ces données     */
-    uint8_t index;                          /* Indice de 8 bits quelconque */
-    size_t pos;                             /* Tête de lecture courante    */
-    regex_t preg;                           /* Expression régulière        */
-    int ret;                                /* Bilan d'un appel            */
-    regmatch_t pmatch[3];                   /* Zones remarquées            */
-    size_t key_len;                         /* Taille de l'indicatif       */
-
-    *addr = 0ull;
-
-    g_gdb_packet_get_data(packet, &data, &length, NULL);
-
-    pos = 1;
-
-    /* Lecture du numéro du signal */
-
-    if (!strtou8(&index, data, &pos, length, SRE_LITTLE))
-        return false;
-
-    *sig = index;
-
-    /* Reste des informations */
-
-    ret = regcomp(&preg, "([^:]+):([^;]+);", REG_EXTENDED | REG_ICASE);
-    if (ret != 0) return false;
-
-    for (ret = regexec(&preg, &data[pos], 3, pmatch, 0);
-         ret != REG_NOMATCH;
-         ret = regexec(&preg, &data[pos], 3, pmatch, 0))
-    {
-        key_len = pmatch[1].rm_eo - pmatch[1].rm_so;
-
-        /* Indication sur le thread */
-        if (key_len == strlen("thread")
-            && strncmp(&data[pos + pmatch[1].rm_so], "thread", key_len) == 0)
-        {
-
-            /* TODO printf("Thread found !\n"); */
-
-        }
-
-        /* Valeur de registre ? */
-        else if (key_len == 2)
-        {
-            if (!strtou8(&index, data, (size_t []) { pos + pmatch[1].rm_so }, length, SRE_LITTLE))
-                return false;
-
-            if (index != 8 /* FIXME */)
-                goto next_field;
-
-            if (!strtou32(addr, data, (size_t []) { pos + pmatch[2].rm_so }, length, SRE_LITTLE/* FIXME */))
-                return false;
-
-        }
-
-    next_field:
-        pos += pmatch[0].rm_eo;
-
-    }
-
-    regfree(&preg);
-
-    return (*addr != 0ull);
-
-}
-
-
-
diff --git a/src/debug/remgdb/helpers.h b/src/debug/remgdb/helpers.h
deleted file mode 100644
index d68fc11..0000000
--- a/src/debug/remgdb/helpers.h
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * helpers.h - prototypes pour un assistanat dans la manipulation des paquets GDB
- *
- * Copyright (C) 2010-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _DEBUG_REMGDB_HELPERS_H
-#define _DEBUG_REMGDB_HELPERS_H
-
-
-#include "packet.h"
-
-
-#include "../../arch/archbase.h"
-#include "../../common/endianness.h"
-
-
-
-
-
-
-
-/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */
-
-
-/* Récupère les informations liées à un arrêt suite à signal. */
-bool get_stop_reply_sig_info(const GGdbPacket *, int *, vmpa_t *, pid_t *, SourceEndian);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            PAQUETS DES REPONSES D'ARRET                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-
-
-
-
-
-
-
-
-#endif  /* _DEBUG_REMGDB_HELPERS_H */
diff --git a/src/debug/remgdb/packet.c b/src/debug/remgdb/packet.c
deleted file mode 100644
index 8d798c6..0000000
--- a/src/debug/remgdb/packet.c
+++ /dev/null
@@ -1,383 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * packet.c - manipulation des paquets de données GDB.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "packet.h"
-
-
-#include <malloc.h>
-#include <string.h>
-
-
-#include "../../common/dllist.h"
-
-
-
-/* Répresentation d'un paquet GDB (instance) */
-struct _GGdbPacket
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    DL_LIST_ITEM(link);                     /* Lien vers les autres        */
-
-    char *buffer;                           /* Données à traiter           */
-    size_t len;                             /* Quantité de ces données     */
-    size_t allocated;                       /* Taille du tampon            */
-
-    uint8_t checksum;                       /* Empreinte de contrôle       */
-
-};
-
-
-/* Répresentation d'un paquet GDB (classe) */
-struct _GGdbPacketClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-};
-
-
-/* Initialise la classe des représentations des paquets GDB. */
-static void g_gdb_packet_class_init(GGdbPacketClass *);
-
-/* Initialise une instance de représentation de paquet GDB. */
-static void g_gdb_packet_init(GGdbPacket *);
-
-
-
-/* Indique le type défini pour une répresentation de paquet GDB. */
-G_DEFINE_TYPE(GGdbPacket, g_gdb_packet, G_TYPE_OBJECT);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des représentations des paquets GDB.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_gdb_packet_class_init(GGdbPacketClass *klass)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : packet = instance à initialiser.                             *
-*                                                                             *
-*  Description : Initialise une instance de représentation de paquet GDB.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_gdb_packet_init(GGdbPacket *packet)
-{
-    DL_LIST_ITEM_INIT(&packet->link);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée une représentation de paquet GDB.                       *
-*                                                                             *
-*  Retour      : Adresse de la structure mise en place.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GGdbPacket *g_gdb_packet_new(void)
-{
-    GGdbPacket *result;                     /* Structure à retourner       */
-
-    result = g_object_new(G_TYPE_GDB_PACKET, NULL);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : packet = paquet à préparer pour une émission.                *
-*                                                                             *
-*  Description : Prépare un paquet pour un envoi prochain.                    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_gdb_packet_start_new_command(GGdbPacket *packet)
-{
-    if (packet->allocated == 0)
-    {
-        packet->allocated = 1;
-        packet->buffer = (char *)calloc(packet->allocated, sizeof(char));
-    }
-
-    packet->buffer[0] = '\0';
-    packet->len = 0;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : packet = paquet à préparer pour une émission.                *
-*                string = chaîne à inclure dans le paquet.                    *
-*                                                                             *
-*  Description : Complète un paquet pour un envoi prochain.                   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_gdb_packet_append(GGdbPacket *packet, const char *string)
-{
-    size_t len;                             /* Taille de la chaîne donnée  */
-
-    len = strlen(string);
-
-    /* Si la place n'est pas assez grande */
-    if ((packet->len + len + 1) >= packet->allocated)
-    {
-        packet->buffer = (char *)realloc(packet->buffer, (packet->len + len + 1) * sizeof(char));
-        packet->allocated = packet->len + len + 1;
-    }
-
-    strcat(packet->buffer, string);
-
-    packet->len += len;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : packet = paquet à analyser.                                  *
-*                                                                             *
-*  Description : Détermine l'empreinte des données d'un paquet GDB.           *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_gdb_packet_compute_checksum(GGdbPacket *packet)
-{
-    int sum;                                /* Valeur cumulée des données  */
-    size_t i;                               /* Boucle de parcours          */
-
-    sum = 0;
-
-    for (i = 0; i < packet->len; i++)
-        sum += packet->buffer[i];
-
-    packet->checksum = sum % 256;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : packet   = paquet à analyser.                                *
-*                checksum = contrôle d'intégrité à retrouver.                 *
-*                                                                             *
-*  Description : Contrôle l'intégrité des données d'un paquet GDB.            *
-*                                                                             *
-*  Retour      : Bilan de la vérification.                                    *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_gdb_packet_verify_checksum(GGdbPacket *packet, uint8_t checksum)
-{
-    g_gdb_packet_compute_checksum(packet);
-
-    return checksum == packet->checksum;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : packet = paquet à décoder et/ou décompresser.                *
-*                                                                             *
-*  Description : Décode et/ou décompresse un paquet GDB.                      *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_gdb_packet_decode(GGdbPacket *packet)
-{
-    bool result;                            /* Bilan à retourner           */
-    char *buffer;                           /* Données transcrites         */
-    size_t allocated;                       /* Quantité de données gérées  */
-    size_t i;                               /* Boucle de parcours          */
-    size_t k;                               /* Point d'insertion           */
-    size_t repeat;                          /* Nombre de répétitions       */
-
-    result = true;
-
-    allocated = packet->len + 1;
-    buffer = (char *)calloc(allocated, sizeof(char));
-
-    for (i = 0, k = 0; i < packet->len && result; i++)
-        switch (packet->buffer[i])
-        {
-            case '#':
-            case '$':
-                result = false;
-                break;
-
-            case '*':
-
-                if (++i == packet->len || k == 0)
-                {
-                    result = false;
-                    break;
-                }
-
-                repeat = packet->buffer[i] - ' ' + 3;
-
-                allocated += repeat;
-                buffer = (char *)realloc(buffer, allocated * sizeof(char));
-
-                memset(&buffer[k], buffer[k - 1], repeat);
-                k += repeat;
-
-                break;
-
-            case '}':
-
-                if (++i == packet->len)
-                {
-                    result = false;
-                    break;
-                }
-
-                buffer[k++] = packet->buffer[i] ^ 0x20;
-
-                break;
-
-            default:
-                buffer[k++] = packet->buffer[i];
-                break;
-
-        }
-
-    if (packet->buffer != NULL)
-        free(packet->buffer);
-
-    packet->buffer = buffer;
-    packet->len = k;
-    packet->allocated = allocated;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : packet   = paquet à analyser.                                *
-*                data     = données contenues dans le paquet. [OUT]           *
-*                len      = quantité de ces données. [OUT]                    *
-*                checksum = contrôle d'intégrité des données ou NULL. [OUT]   *
-*                                                                             *
-*  Description : Fournit le contenu du paquet.                                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_gdb_packet_get_data(const GGdbPacket *packet, const char **data, size_t *len, uint8_t *checksum)
-{
-    *data = packet->buffer;
-    *len = packet->len;
-
-    if (checksum != NULL)
-        *checksum = packet->checksum;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list = liste de paquets à compléter.                         *
-*                item = paquet à ajouter à la liste.                          *
-*                                                                             *
-*  Description : Ajoute un paquet à une liste de paquets.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_gdb_packet_push(GGdbPacket **list, GGdbPacket *item)
-{
-    dl_list_push(item, list, GGdbPacket, link);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list = liste de paquets à consulter.                         *
-*                                                                             *
-*  Description : Retire et fournit le premier élément d'une liste de paquets. *
-*                                                                             *
-*  Retour      : Elément dépilé de la liste de paquets.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GGdbPacket *g_gdb_packet_pop(GGdbPacket **list)
-{
-    return dl_list_pop(list, GGdbPacket, link);
-
-}
diff --git a/src/debug/remgdb/packet.h b/src/debug/remgdb/packet.h
deleted file mode 100644
index 9c44108..0000000
--- a/src/debug/remgdb/packet.h
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * packet.h - prototypes pour la manipulation des paquets de données GDB.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _DEBUG_REMGDB_PACKET_H
-#define _DEBUG_REMGDB_PACKET_H
-
-
-#include <glib-object.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-
-
-#define G_TYPE_GDB_PACKET               g_gdb_packet_get_type()
-#define G_GDB_PACKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_packet_get_type(), GGdbPacket))
-#define G_IS_GDB_PACKET(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_packet_get_type()))
-#define G_GDB_PACKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_PACKET, GGdbPacketClass))
-#define G_IS_GDB_PACKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_PACKET))
-#define G_GDB_PACKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_PACKET, GGdbPacketClass))
-
-
-/* Répresentation d'un paquet GDB (instance) */
-typedef struct _GGdbPacket GGdbPacket;
-
-/* Répresentation d'un paquet GDB (classe) */
-typedef struct _GGdbPacketClass GGdbPacketClass;
-
-
-
-/* Indique le type défini pour une répresentation de paquet GDB. */
-GType g_gdb_packet_get_type(void);
-
-/* Crée une représentation de paquet GDB. */
-GGdbPacket *g_gdb_packet_new(void);
-
-/* Prépare un paquet pour un envoi prochain. */
-void g_gdb_packet_start_new_command(GGdbPacket *);
-
-/* Complète un paquet pour un envoi prochain. */
-void g_gdb_packet_append(GGdbPacket *, const char *);
-
-/* Détermine l'empreinte des données d'un paquet GDB. */
-void g_gdb_packet_compute_checksum(GGdbPacket *);
-
-/* Contrôle l'intégrité des données d'un paquet GDB. */
-bool g_gdb_packet_verify_checksum(GGdbPacket *, uint8_t);
-
-/* Décode et/ou décompresse un paquet GDB. */
-bool g_gdb_packet_decode(GGdbPacket *);
-
-/* Fournit le contenu du paquet. */
-void g_gdb_packet_get_data(const GGdbPacket *, const char **, size_t *, uint8_t *);
-
-/* Ajoute un paquet à une liste de paquets. */
-void g_gdb_packet_push(GGdbPacket **, GGdbPacket *);
-
-/* Retire et fournit le premier élément d'une liste de paquets. */
-GGdbPacket *g_gdb_packet_pop(GGdbPacket **);
-
-
-
-#endif  /* _DEBUG_REMGDB_PACKET_H */
diff --git a/src/debug/remgdb/stream-int.h b/src/debug/remgdb/stream-int.h
deleted file mode 100644
index 8ac422d..0000000
--- a/src/debug/remgdb/stream-int.h
+++ /dev/null
@@ -1,74 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * stream-int.h - prototypes internes pour la gestion des connexions aux serveurs GDB.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _DEBUG_REMGDB_STREAM_INT_H
-#define _DEBUG_REMGDB_STREAM_INT_H
-
-
-#include "stream.h"
-
-
-
-/* Envoie des données à un serveur GDB. */
-typedef bool (* send_gdb_data_fc) (GGdbStream *, const char *, size_t);
-
-/* Réceptionne un octet de donnée d'un serveur GDB. */
-typedef bool (* recv_gdb_byte_fc) (GGdbStream *, char *);
-
-
-/* Flux de communication avec un serveur GDB (instance) */
-struct _GGdbStream
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    int fd;                                 /* Flux ouvert en L./E.        */
-
-    send_gdb_data_fc send_data;             /* Envoi d'un paquet GDB       */
-    recv_gdb_byte_fc recv_byte;             /* Réception d'un paquet GDB   */
-
-    GThread *listening;                     /* Thread pour les réceptions  */
-
-    GGdbPacket *free_packets;               /* Liste des disponibles       */
-    GMutex free_mutex;                      /* Accès à la liste            */
-
-    GGdbPacket *recv_packets;               /* Liste des paquets reçus     */
-    GCond recv_cond;                        /* Attente de disponibilité    */
-    GMutex recv_mutex;                      /* Accès à la liste            */
-
-};
-
-
-/* Flux de communication avec un serveur GDB (classe) */
-struct _GGdbStreamClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-};
-
-
-/* Lance l'écoute d'un flux de communication avec GDB. */
-bool g_gdb_stream_listen(GGdbStream *);
-
-
-
-#endif  /* _DEBUG_REMGDB_STREAM_INT_H */
diff --git a/src/debug/remgdb/stream.c b/src/debug/remgdb/stream.c
deleted file mode 100644
index cd303c3..0000000
--- a/src/debug/remgdb/stream.c
+++ /dev/null
@@ -1,402 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * stream.c - gestion des connexions aux serveurs GDB.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "stream.h"
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <glib/gthread.h>
-#include <sys/select.h>
-
-
-#include "stream-int.h"
-#include "../../common/dllist.h"
-
-
-
-/* Initialise la classe des flux de communication avec GDB. */
-static void g_gdb_stream_class_init(GGdbStreamClass *);
-
-/* Initialise une instance de flux de communication avec GDB. */
-static void g_gdb_stream_init(GGdbStream *);
-
-/* Envoie un acquittement pour la dernière réception. */
-static bool gdb_stream_ack(GGdbStream *);
-
-/* Ecoute une connexion à un serveur GDB. */
-static void *gdb_stream_thread(GGdbStream *);
-
-/* Réceptionne un paquet d'un serveur GDB. */
-static bool g_gdb_stream_read_packet(GGdbStream *, GGdbPacket *);
-
-
-
-/* Indique le type défini pour un flux de communication avec un serveur GDB. */
-G_DEFINE_TYPE(GGdbStream, g_gdb_stream, G_TYPE_OBJECT);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des flux de communication avec GDB.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_gdb_stream_class_init(GGdbStreamClass *klass)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = instance à initialiser.                             *
-*                                                                             *
-*  Description : Initialise une instance de flux de communication avec GDB.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_gdb_stream_init(GGdbStream *stream)
-{
-    g_mutex_init(&stream->free_mutex);
-
-    g_cond_init(&stream->recv_cond);
-    g_mutex_init(&stream->recv_mutex);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = instance à réellement lancer.                       *
-*                                                                             *
-*  Description : Lance l'écoute d'un flux de communication avec GDB.          *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_gdb_stream_listen(GGdbStream *stream)
-{
-    bool result;                            /* Bilan final à retourner     */
-
-    result = true;
-
-    if (!g_thread_new("chrysalide_gdb_stream", (GThreadFunc)gdb_stream_thread, stream))
-        result = false;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = encadrement associée à l'opération.                 *
-*                                                                             *
-*  Description : Envoie un acquittement pour la dernière réception.           *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool gdb_stream_ack(GGdbStream *stream)
-{
-    bool result;                            /* Bilan à retourner           */
-    GGdbPacket *packet;                     /* Paquet à envoyer            */
-
-    packet = g_gdb_stream_get_free_packet(stream);
-
-    g_gdb_packet_start_new_command(packet);
-    g_gdb_packet_append(packet, "+");
-
-    result = g_gdb_stream_send_packet(stream, packet);
-
-    g_gdb_stream_mark_packet_as_free(stream, packet);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = encadrement associée à l'opération.                 *
-*                                                                             *
-*  Description : Ecoute une connexion à un serveur GDB.                       *
-*                                                                             *
-*  Retour      : ???                                                          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void *gdb_stream_thread(GGdbStream *stream)
-{
-    fd_set rfds;                            /* Liste des flux à surveiller */
-    int ret;                                /* Bilan d'un appel            */
-    GGdbPacket *packet;                     /* Nouveau paquet reçu         */
-
-    while (1)
-    {
-        FD_ZERO(&rfds);
-        FD_SET(stream->fd, &rfds);
-
-        ret = select(stream->fd + 1, &rfds, NULL, NULL, NULL);
-
-        printf("ret :: %d\n", ret);
-
-        switch (ret)
-        {
-            case -1:
-                perror("select()");
-                break;
-
-            case 0:
-                break;
-
-            default:
-
-                packet = g_gdb_stream_get_free_packet(stream);
-
-                g_gdb_packet_start_new_command(packet);
-
-                if (g_gdb_stream_read_packet(stream, packet))
-                {
-                    /* Acquittement */
-                    if (!gdb_stream_ack(stream)) goto bad_recv;
-
-                    /* On conserve le résultat */
-
-                    g_mutex_lock(&stream->recv_mutex);
-                    g_gdb_packet_push(&stream->recv_packets, packet);
-                    g_mutex_unlock(&stream->recv_mutex);
-
-                    g_cond_signal(&stream->recv_cond);
-
-                }
-
- bad_recv:
-
-                printf("bad things happend...\n");
-
-                g_gdb_stream_mark_packet_as_free(stream, packet);
-
-                break;
-
-        }
-
-    }
-
-    return NULL;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = flux de communication avec GDB à consulter.         *
-*                                                                             *
-*  Description : Fournit un paquet prêt à emploi.                             *
-*                                                                             *
-*  Retour      : Paquet prêt à emploi.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GGdbPacket *g_gdb_stream_get_free_packet(GGdbStream *stream)
-{
-    GGdbPacket *result;                     /* Paquet à retourner          */
-
-    g_mutex_lock(&stream->free_mutex);
-
-    if (dl_list_empty(stream->free_packets))
-        result = g_gdb_packet_new();
-
-    else
-        result = g_gdb_packet_pop(&stream->free_packets);
-
-    g_mutex_unlock(&stream->free_mutex);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = flux de communication avec GDB à mettre à jour.     *
-*                packet = paquet à considérer comme disponible.               *
-*                                                                             *
-*  Description : Place un paquet en attente d'une future utilisation.         *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_gdb_stream_mark_packet_as_free(GGdbStream *stream, GGdbPacket *packet)
-{
-    g_mutex_lock(&stream->free_mutex);
-
-    g_gdb_packet_push(&stream->free_packets, packet);
-
-    g_mutex_unlock(&stream->free_mutex);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = flux ouvert en lecture  à utiliser.                 *
-*                packet = données à recevoir.                                 *
-*                                                                             *
-*  Description : Réceptionne un paquet d'un serveur GDB.                      *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_gdb_stream_read_packet(GGdbStream *stream, GGdbPacket *packet)
-{
-    bool result;                            /* Bilan à renvoyer            */
-    char tmp[3];                            /* Tampon de réception         */
-    uint8_t checksum;                       /* Contrôle d'intégrité        */
-
-    result = stream->recv_byte(stream, tmp);
-
-    if (tmp[0] != '$') return false;
-
-    tmp[1] = '\0';
-
-    while ((result = stream->recv_byte(stream, tmp)))
-    {
-        if (tmp[0] == '#') break;
-        else g_gdb_packet_append(packet, tmp);
-    }
-
-    if (result)
-    {
-        result = stream->recv_byte(stream, &tmp[0]);
-        result &= stream->recv_byte(stream, &tmp[1]);
-
-        tmp[2] = 0;
-        checksum = strtol(tmp, NULL, 16);
-
-    }
-
-    if (result)
-        result = g_gdb_packet_verify_checksum(packet, checksum);
-
-    if (result)
-        result = g_gdb_packet_decode(packet);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = flux ouvert en écriture à mettre à jour.            *
-*                packet = données à transmettre.                              *
-*                                                                             *
-*  Description : Envoie un paquet à un serveur GDB.                           *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_gdb_stream_send_packet(GGdbStream *stream, GGdbPacket *packet)
-{
-    bool result;                            /* Bilan à renvoyer            */
-    const char *data;                       /* Données à envoyer           */
-    size_t len;                             /* Quantité de ces données     */
-    uint8_t checksum;                       /* Contrôle d'intégrité        */
-    char tmp[3];                            /* Impression du checksum      */
-
-    result = stream->send_data(stream, "$", 1);
-
-    g_gdb_packet_compute_checksum(packet);
-    g_gdb_packet_get_data(packet, &data, &len, &checksum);
-
-    result &= stream->send_data(stream, data, len);
-
-    result = stream->send_data(stream, "#", 1);
-
-    snprintf(tmp, 3, "%hhx", checksum);
-    result &= stream->send_data(stream, tmp, 2);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : stream = flux de communication avec GDB à consulter.         *
-*                                                                             *
-*  Description : Fournit un paquet reçu d'un serveur GDB.                     *
-*                                                                             *
-*  Retour      : Paquet GDB.                                                  *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GGdbPacket *g_gdb_stream_recv_packet(GGdbStream *stream)
-{
-    GGdbPacket *result;                     /* Paquet à retourner          */
-
-    g_mutex_lock(&stream->recv_mutex);
-
-    if (dl_list_empty(stream->recv_packets))
-        g_cond_wait(&stream->recv_cond, &stream->recv_mutex);
-
-    result = g_gdb_packet_pop(&stream->recv_packets);
-
-    g_mutex_unlock(&stream->recv_mutex);
-
-    return result;
-
-}
diff --git a/src/debug/remgdb/stream.h b/src/debug/remgdb/stream.h
deleted file mode 100644
index f93ff60..0000000
--- a/src/debug/remgdb/stream.h
+++ /dev/null
@@ -1,65 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * stream.h - prototypes pour la gestion des connexions aux serveurs GDB.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _DEBUG_REMGDB_STREAM_H
-#define _DEBUG_REMGDB_STREAM_H
-
-
-#include "packet.h"
-
-
-
-#define G_TYPE_GDB_STREAM               g_gdb_stream_get_type()
-#define G_GDB_STREAM(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_stream_get_type(), GGdbStream))
-#define G_IS_GDB_STREAM(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_stream_get_type()))
-#define G_GDB_STREAM_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_STREAM, GGdbStreamClass))
-#define G_IS_GDB_STREAM_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_STREAM))
-#define G_GDB_STREAM_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_STREAM, GGdbStreamClass))
-
-
-/* Flux de communication avec un serveur GDB (instance) */
-typedef struct _GGdbStream GGdbStream;
-
-/* Flux de communication avec un serveur GDB (classe) */
-typedef struct _GGdbStreamClass GGdbStreamClass;
-
-
-
-/* Indique le type défini pour un flux de communication avec un serveur GDB. */
-GType g_gdb_stream_get_type(void);
-
-/* Fournit un paquet prêt à emploi. */
-GGdbPacket *g_gdb_stream_get_free_packet(GGdbStream *);
-
-/* Place un paquet en attente d'une future utilisation. */
-void g_gdb_stream_mark_packet_as_free(GGdbStream *, GGdbPacket *);
-
-/* Envoie un paquet à un serveur GDB. */
-bool g_gdb_stream_send_packet(GGdbStream *, GGdbPacket *);
-
-/* Fournit un paquet reçu d'un serveur GDB. */
-GGdbPacket *g_gdb_stream_recv_packet(GGdbStream *);
-
-
-
-#endif  /* _DEBUG_REMGDB_STREAM_H */
diff --git a/src/debug/remgdb/tcp.c b/src/debug/remgdb/tcp.c
deleted file mode 100644
index aa10c54..0000000
--- a/src/debug/remgdb/tcp.c
+++ /dev/null
@@ -1,263 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * tcp.c - gestion des connexions TCP aux serveurs GDB.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "tcp.h"
-
-
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-
-#include "stream-int.h"
-
-
-#include "../../common/net.h"
-
-
-/* Flux de communication TCP avec un serveur GDB (instance) */
-struct _GGdbTcpClient
-{
-    GGdbStream parent;                      /* A laisser en premier        */
-
-};
-
-
-/* Flux de communication TCP avec un serveur GDB (classe) */
-struct _GGdbTcpClientClass
-{
-    GGdbStreamClass parent;                 /* A laisser en premier        */
-
-};
-
-
-/* Initialise la classe des flux de communication TCP avec GDB. */
-static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *);
-
-/* Initialise une instance de flux de communication avec GDB. */
-static void g_gdb_tcp_client_init(GGdbTcpClient *);
-
-/* Ouvre une connexion TCP à un serveur GDB. */
-//static int connect_via_tcp(const char *, const char *);
-
-/* Envoie des données à un serveur GDB. */
-static bool g_gdb_tcp_client_send_data(GGdbTcpClient *, const char *, size_t);
-
-/* Réceptionne un octet de donnée d'un serveur GDB. */
-static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *, char *);
-
-
-
-/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */
-G_DEFINE_TYPE(GGdbTcpClient, g_gdb_tcp_client, G_TYPE_GDB_STREAM);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des flux de communication TCP avec GDB. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *klass)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : client = instance à initialiser.                             *
-*                                                                             *
-*  Description : Initialise une instance de flux de communication avec GDB.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_gdb_tcp_client_init(GGdbTcpClient *client)
-{
-    GGdbStream *stream;                     /* Version parente             */
-
-    stream = G_GDB_STREAM(client);
-
-    stream->send_data = (send_gdb_data_fc)g_gdb_tcp_client_send_data;
-    stream->recv_byte = (recv_gdb_byte_fc)g_gdb_tcp_client_recv_byte;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : server = nom ou adresse du serveur à contacter.              *
-*                port   = port de connexion.                                  *
-*                                                                             *
-*  Description : Ouvre une connexion TCP à un serveur GDB.                    *
-*                                                                             *
-*  Retour      : Flux ouvert en lecture/écriture ou -1 en cas d'échec.        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-#if 0
-static int connect_via_tcp(const char *server, const char *port)
-{
-    int result;                             /* Bilan à retourner           */
-    struct addrinfo hints;                  /* Type de connexion souhaitée */
-    struct addrinfo *infos;                 /* Informations disponibles    */
-    int ret;                                /* Bilan d'un appel            */
-    struct addrinfo *iter;                  /* Boucle de parcours          */
-    struct sockaddr_in addr;                /* Infos de connexion distante */          
-
-    memset(&hints, 0, sizeof(struct addrinfo));
-
-    hints.ai_family = AF_UNSPEC;        /* IPv4 ou IPv6 */
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_flags = 0;
-    hints.ai_protocol = 0;              /* N'importe quel protocole */
-
-    ret = getaddrinfo(server, port, &hints, &infos);
-    if (ret != 0)
-    {
-        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
-        return -1;
-    }
-
-    for (iter = infos; iter != NULL; iter = iter->ai_next)
-    {
-        result = socket(iter->ai_family, iter->ai_socktype, iter->ai_protocol);
-        if (result == -1) continue;
-
-        ret = connect(result, iter->ai_addr, iter->ai_addrlen);
-        if (ret == 0) break;
-
-        perror("connect");
-        close(result);
-
-    }
-
-    freeaddrinfo(infos);
-
-    if (iter == NULL) return -1;
-
-    ret = getpeername(result, (struct sockaddr *)&addr, (socklen_t []){ sizeof(struct sockaddr_in) });
-    if (ret == -1)
-    {
-        perror("getpeername");
-        close(result);
-        return -1;
-    }
-
-    printf("Connecté à %s:%hd\n", server, ntohs(addr.sin_port));
-
-    return result;
-
-}
-#endif
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : server = nom ou adresse du serveur à contacter.              *
-*                port   = port de connexion.                                  *
-*                                                                             *
-*  Description : Crée une nouvelle connexion TCP à un serveur GDB.            *
-*                                                                             *
-*  Retour      : Adresse de la structure mise en place.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GGdbStream *g_gdb_tcp_client_new(const char *server, const char *port)
-{
-    GGdbTcpClient *result;                  /* Structure à retourner       */
-    int sock;                               /* Flux ouvert à construire    */
-
-    sock = connect_via_tcp(server, port, NULL);
-    if (sock == -1) return NULL;
-
-    result = g_object_new(G_TYPE_GDB_TCP_CLIENT, NULL);
-
-    G_GDB_STREAM(result)->fd = sock;
-
-    if (!g_gdb_stream_listen(G_GDB_STREAM(result)))
-        goto ggtcn_error;
-
-    return G_GDB_STREAM(result);
-
- ggtcn_error:
-
-    return NULL;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : client = flux ouvert en écriture à utiliser.                 *
-*                data   = données à envoyer.                                  *
-*                len    = quantité de ces données.                            *
-*                                                                             *
-*  Description : Envoie des données à un serveur GDB.                         *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_gdb_tcp_client_send_data(GGdbTcpClient *client, const char *data, size_t len)
-{
-    return (send(G_GDB_STREAM(client)->fd, data, len, 0) == len);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : client = flux ouvert en lecture à utiliser.                  *
-*                data   = donnée à recevoir.                                  *
-*                                                                             *
-*  Description : Réceptionne un octet de donnée d'un serveur GDB.             *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *client, char *data)
-{
-    return (recv(G_GDB_STREAM(client)->fd, data, 1, 0) == 1);
-
-}
diff --git a/src/debug/remgdb/tcp.h b/src/debug/remgdb/tcp.h
deleted file mode 100644
index 7d40f16..0000000
--- a/src/debug/remgdb/tcp.h
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * tcp.h - prototypes pour la gestion des connexions TCP aux serveurs GDB.
- *
- * Copyright (C) 2009-2017 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _DEBUG_REMGDB_TCP_H
-#define _DEBUG_REMGDB_TCP_H
-
-
-#include "stream.h"
-
-
-
-#define G_TYPE_GDB_TCP_CLIENT               g_gdb_tcp_client_get_type()
-#define G_GDB_TCP_CLIENT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_tcp_client_get_type(), GGdbTcpClient))
-#define G_IS_GDB_TCP_CLIENT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_tcp_client_get_type()))
-#define G_GDB_TCP_CLIENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_TCP_CLIENT, GGdbTcpClientClass))
-#define G_IS_GDB_TCP_CLIENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_TCP_CLIENT))
-#define G_GDB_TCP_CLIENT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_TCP_CLIENT, GGdbTcpClientClass))
-
-
-/* Flux de communication TCP avec un serveur GDB (instance) */
-typedef struct _GGdbTcpClient GGdbTcpClient;
-
-/* Flux de communication TCP avec un serveur GDB (classe) */
-typedef struct _GGdbTcpClientClass GGdbTcpClientClass;
-
-
-
-/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */
-GType g_gdb_tcp_client_get_type(void);
-
-/* Crée une nouvelle connexion TCP à un serveur GDB. */
-GGdbStream *g_gdb_tcp_client_new(const char *, const char *);
-
-
-
-#endif  /* _DEBUG_REMGDB_TCP_H */
diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c
index 51107c5..789661e 100644
--- a/src/gtkext/gtkstatusstack.c
+++ b/src/gtkext/gtkstatusstack.c
@@ -845,6 +845,8 @@ activity_id_t gtk_status_stack_add_activity(GtkStatusStack *stack, const char *m
     progress_info *info;                    /* Informations à consulter    */
     size_t new;                             /* Indice de l'activité créée  */
 
+    if (stack == NULL) return 0;
+
     info = stack->prog_info;
 
     g_mutex_lock(&info->access);
@@ -904,6 +906,8 @@ void gtk_status_stack_extend_activity(GtkStatusStack *stack, activity_id_t id, u
     progress_info *info;                    /* Informations à consulter    */
     size_t i;                               /* Boucle de parcours          */
 
+    if (stack == NULL) return;
+
     info = stack->prog_info;
 
     g_mutex_lock(&info->access);
@@ -941,6 +945,8 @@ void gtk_status_stack_update_activity(GtkStatusStack *stack, activity_id_t id, c
     size_t i;                               /* Boucle de parcours          */
     bool msg_changed;                       /* Changement d'intitulé       */
 
+    if (stack == NULL) return;
+
     info = stack->prog_info;
 
     g_mutex_lock(&info->access);
@@ -1008,6 +1014,8 @@ void gtk_status_stack_update_activity_value(GtkStatusStack *stack, activity_id_t
     progress_status *status;                /* Raccourci de confort        */
     double new;                             /* Nouvelle progression        */
 
+    if (stack == NULL) return;
+
     info = stack->prog_info;
 
     g_mutex_lock(&info->access);
@@ -1061,6 +1069,8 @@ void gtk_status_stack_remove_activity(GtkStatusStack *stack, activity_id_t id)
     progress_info *info;                    /* Informations à consulter    */
     size_t i;                               /* Boucle de parcours          */
 
+    if (stack == NULL) return;
+
     info = stack->prog_info;
 
     g_mutex_lock(&info->access);
-- 
cgit v0.11.2-87-g4458