summaryrefslogtreecommitdiff
path: root/src/debug/remgdb/packet.c
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/remgdb/packet.c
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/remgdb/packet.c')
-rw-r--r--src/debug/remgdb/packet.c383
1 files changed, 383 insertions, 0 deletions
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);
+
+}