summaryrefslogtreecommitdiff
path: root/src/debug
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-09-06 15:47:08 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-09-06 15:47:08 (GMT)
commit3173b904d5d56a8b5e6bf549c97e3fc49da6c5ba (patch)
treef5ea74177fcbc05558b85b9f2e6db36aa1ca3b86 /src/debug
parentef3b996ad359e0da5e93184dab9200fad9105faf (diff)
Provided some methods to interact with a GDB server.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@110 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/debug')
-rwxr-xr-xsrc/debug/Makefile.am2
-rw-r--r--src/debug/remgdb/Makefile.am18
-rw-r--r--src/debug/remgdb/gdb.c248
-rw-r--r--src/debug/remgdb/gdb.h61
-rw-r--r--src/debug/remgdb/packet.c383
-rw-r--r--src/debug/remgdb/packet.h82
-rw-r--r--src/debug/remgdb/stream-int.h74
-rw-r--r--src/debug/remgdb/stream.c357
-rw-r--r--src/debug/remgdb/stream.h65
-rw-r--r--src/debug/remgdb/tcp.c261
-rw-r--r--src/debug/remgdb/tcp.h56
11 files changed, 1606 insertions, 1 deletions
diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am
index caea642..3f98a9a 100755
--- a/src/debug/Makefile.am
+++ b/src/debug/Makefile.am
@@ -13,4 +13,4 @@ AM_CPPFLAGS =
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS = ptrace
+SUBDIRS = ptrace remgdb
diff --git a/src/debug/remgdb/Makefile.am b/src/debug/remgdb/Makefile.am
new file mode 100644
index 0000000..ab6715d
--- /dev/null
+++ b/src/debug/remgdb/Makefile.am
@@ -0,0 +1,18 @@
+
+lib_LIBRARIES = libdebugremgdb.a
+
+libdebugremgdb_a_SOURCES = \
+ gdb.h gdb.c \
+ packet.h packet.c \
+ stream-int.h \
+ stream.h stream.c \
+ tcp.h tcp.c
+
+libdebugremgdb_a_CFLAGS = $(AM_CFLAGS)
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CPPFLAGS =
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/src/debug/remgdb/gdb.c b/src/debug/remgdb/gdb.c
new file mode 100644
index 0000000..068cf26
--- /dev/null
+++ b/src/debug/remgdb/gdb.c
@@ -0,0 +1,248 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gdb.c - débogage à l'aide de gdb.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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"
+
+#if 0
+
+
+/* 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 *);
+
+
+
+/* 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 : debugger = débogueur à lancer. *
+* *
+* Description : Met en marche le débogueur utilisant gdb. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_gdb_debugger_run(GGdbDebugger *debugger)
+{
+ GError *error; /* Bilan de création de thread */
+
+ if (debugger->options == NULL)
+ debugger->options = create_gdb_options_from_binary(G_BINARY_DEBUGGER(debugger)->binary);
+
+ if (debugger->options == NULL)
+ return false;
+
+
+
+
+ if (!g_thread_create((GThreadFunc)gdb_thread, debugger, FALSE, &error))
+ {
+ printf ("Failed to create the thread: %s\n", error->message);
+ }
+
+
+ /*
+ printf("Start Debugger with bin :: %p\n", G_BINARY_DEBUGGER_GET_IFACE(debugger)->binary);
+
+ g_signal_emit_by_name(debugger, "debugger-stopped", (uint64_t)0xdeadbeaf);
+ */
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : debugger = débogueur à relancer. *
+* *
+* Description : Remet en marche le débogueur utilisant gdb(). *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+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 gdb(). *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_gdb_debugger_kill(GGdbDebugger *debugger)
+{
+ 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);
+
+ return true;
+
+}
+
+#endif
+
+
+
+
+
+
+#include "tcp.h"
+
+
+
+
+
+
+
+
+
+
+
+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
new file mode 100644
index 0000000..2812afd
--- /dev/null
+++ b/src/debug/remgdb/gdb.h
@@ -0,0 +1,61 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gdb.h - prototypes pour le débogage à l'aide de gdb.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 "../debuggers.h"
+
+#if 0
+
+#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 gdb (instance) */
+typedef struct _GGdbDebugger GGdbDebugger;
+
+/* Débogueur utilisant 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);
+
+#endif
+
+
+
+void test_gdb(void);
+
+
+
+#endif /* _DEBUG_REMGDB_GDB_H */
diff --git a/src/debug/remgdb/packet.c b/src/debug/remgdb/packet.c
new file mode 100644
index 0000000..3fd3cba
--- /dev/null
+++ b/src/debug/remgdb/packet.c
@@ -0,0 +1,383 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * packet.c - manipulation des paquets de données GDB.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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(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
new file mode 100644
index 0000000..30be43e
--- /dev/null
+++ b/src/debug/remgdb/packet.h
@@ -0,0 +1,82 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * packet.h - prototypes pour la manipulation des paquets de données GDB.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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(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
new file mode 100644
index 0000000..bdfe11a
--- /dev/null
+++ b/src/debug/remgdb/stream-int.h
@@ -0,0 +1,74 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * stream-int.h - prototypes internes pour la gestion des connexions aux serveurs GDB.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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
new file mode 100644
index 0000000..2b487ad
--- /dev/null
+++ b/src/debug/remgdb/stream.c
@@ -0,0 +1,357 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * stream.c - gestion des connexions aux serveurs GDB.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 *);
+
+/* 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)
+{
+ stream->free_mutex = g_mutex_new();
+
+ stream->recv_cond = g_cond_new();
+ stream->recv_mutex = g_mutex_new();
+
+}
+
+
+/******************************************************************************
+* *
+* 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 */
+ GError *error; /* Bilan de création de thread */
+
+ result = true;
+
+ if (!g_thread_create((GThreadFunc)gdb_stream_thread, stream, FALSE, &error))
+ result = false;
+
+ 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);
+
+ 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))
+ {
+ 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;
+
+ }
+
+ }
+
+ 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
new file mode 100644
index 0000000..7373f39
--- /dev/null
+++ b/src/debug/remgdb/stream.h
@@ -0,0 +1,65 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * stream.h - prototypes pour la gestion des connexions aux serveurs GDB.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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
new file mode 100644
index 0000000..fa97f8c
--- /dev/null
+++ b/src/debug/remgdb/tcp.c
@@ -0,0 +1,261 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * tcp.c - gestion des connexions TCP aux serveurs GDB.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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"
+
+
+
+/* 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 : - *
+* *
+******************************************************************************/
+
+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;
+
+}
+
+
+/******************************************************************************
+* *
+* 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);
+ 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
new file mode 100644
index 0000000..2536b64
--- /dev/null
+++ b/src/debug/remgdb/tcp.h
@@ -0,0 +1,56 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * tcp.h - prototypes pour la gestion des connexions TCP aux serveurs GDB.
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 */