diff options
Diffstat (limited to 'src/glibext/tpmem.c')
-rw-r--r-- | src/glibext/tpmem.c | 224 |
1 files changed, 79 insertions, 145 deletions
diff --git a/src/glibext/tpmem.c b/src/glibext/tpmem.c index 0703aeb..14b5e33 100644 --- a/src/glibext/tpmem.c +++ b/src/glibext/tpmem.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * tpmem.c - mémorisation des types d'objets mis en cache * - * Copyright (C) 2020 Cyrille Bagard + * Copyright (C) 2020-2025 Cyrille Bagard * * This file is part of Chrysalide. * @@ -25,59 +25,14 @@ #include <assert.h> -#include <stdint.h> -#include "../db/misc/rlestr.h" -#include "../../arch/operands/target.h" -#include "../../core/logs.h" +#include "tpmem-int.h" +#include "../common/szbin.h" +#include "../core/logs.h" -/* Conservation d'une référence sur un type */ -typedef struct _gtype_ref_info_t -{ - GType gtype; /* Type pour la GLib */ - gpointer gclass; /* Lien vers sa classe */ - - /** - * La GLib n'est pas très claire sur la taille de GType : - * - * #if GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG || !defined __cplusplus - * typedef gsize GType; - * #else // for historic reasons, C++ links against gulong GTypes - * typedef gulong GType; - * #endif - * - * Et : - * - * typedef unsigned $glib_size_type_define gsize; - * - * On prend donc le parti de conserver ces types sous forme de valeurs 64 bits - * lors des enregistrements. - */ - -} gtype_ref_info_t; - -/* Définition d'une mémoire de types d'objets (instance) */ -struct _GTypeMemory -{ - GObject parent; /* A laisser en premier */ - - gtype_ref_info_t *gtypes; /* Types des objets reconnus */ - size_t count; /* Quantité de ces objets */ - GMutex mutex; /* Contrôle d'accès à la liste */ - -}; - -/* Définition d'une mémoire de types d'objets (classe) */ -struct _GTypeMemoryClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - /* Initialise la classe des mémoires de types d'objets. */ static void g_type_memory_class_init(GTypeMemoryClass *); @@ -85,10 +40,10 @@ static void g_type_memory_class_init(GTypeMemoryClass *); static void g_type_memory_init(GTypeMemory *); /* Supprime toutes les références externes. */ -static void g_type_memory_dispose(GTypeMemory *); +static void g_type_memory_dispose(GObject *); /* Procède à la libération totale de la mémoire. */ -static void g_type_memory_finalize(GTypeMemory *); +static void g_type_memory_finalize(GObject *); @@ -114,8 +69,8 @@ static void g_type_memory_class_init(GTypeMemoryClass *klass) object = G_OBJECT_CLASS(klass); - object->dispose = (GObjectFinalizeFunc/* ! */)g_type_memory_dispose; - object->finalize = (GObjectFinalizeFunc)g_type_memory_finalize; + object->dispose = g_type_memory_dispose; + object->finalize = g_type_memory_finalize; } @@ -143,7 +98,7 @@ static void g_type_memory_init(GTypeMemory *tpmem) /****************************************************************************** * * -* Paramètres : tpmem = instance d'objet GLib à traiter. * +* Paramètres : object = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * @@ -153,10 +108,13 @@ static void g_type_memory_init(GTypeMemory *tpmem) * * ******************************************************************************/ -static void g_type_memory_dispose(GTypeMemory *tpmem) +static void g_type_memory_dispose(GObject *object) { + GTypeMemory *tpmem; /* Version spécialisée */ uint64_t i; /* Boucle de parcours */ + tpmem = G_TYPE_MEMORY(object); + g_mutex_lock(&tpmem->mutex); for (i = 0; i < tpmem->count; i++) @@ -167,14 +125,14 @@ static void g_type_memory_dispose(GTypeMemory *tpmem) g_mutex_clear(&tpmem->mutex); - G_OBJECT_CLASS(g_type_memory_parent_class)->dispose(G_OBJECT(tpmem)); + G_OBJECT_CLASS(g_type_memory_parent_class)->dispose(object); } /****************************************************************************** * * -* Paramètres : tpmem = instance d'objet GLib à traiter. * +* Paramètres : object = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * @@ -184,12 +142,16 @@ static void g_type_memory_dispose(GTypeMemory *tpmem) * * ******************************************************************************/ -static void g_type_memory_finalize(GTypeMemory *tpmem) +static void g_type_memory_finalize(GObject *object) { + GTypeMemory *tpmem; /* Version spécialisée */ + + tpmem = G_TYPE_MEMORY(object); + if (tpmem->gtypes != NULL) free(tpmem->gtypes); - G_OBJECT_CLASS(g_type_memory_parent_class)->finalize(G_OBJECT(tpmem)); + G_OBJECT_CLASS(g_type_memory_parent_class)->finalize(object); } @@ -220,7 +182,7 @@ GTypeMemory *g_type_memory_new(void) /****************************************************************************** * * * Paramètres : tpmem = mémoire à compléter. * -* pbuf = zone tampon à lire. * +* fd = flux ouvert en lecture. * * * * Description : Apprend tous les types mémorisés dans un tampon. * * * @@ -230,14 +192,14 @@ GTypeMemory *g_type_memory_new(void) * * ******************************************************************************/ -bool g_type_memory_load_types(GTypeMemory *tpmem, packed_buffer_t *pbuf) +bool g_type_memory_load(GTypeMemory *tpmem, int fd) { bool result; /* Bilan à enregistrer */ uleb128_t count; /* Nombre d'éléments détectés */ uleb128_t i; /* Boucle de parcours */ - rle_string str; /* Chaîne à charger */ + sized_binary_t str; /* Chaîne à charger */ - result = unpack_uleb128(&count, pbuf); + result = load_uleb128(&count, fd); if (result) { @@ -248,35 +210,27 @@ bool g_type_memory_load_types(GTypeMemory *tpmem, packed_buffer_t *pbuf) assert(tpmem->gtypes == NULL); tpmem->gtypes = calloc(count, sizeof(gtype_ref_info_t)); - setup_empty_rle_string(&str); - for (i = 0; i < tpmem->count && result; i++) { - result = unpack_rle_string(&str, pbuf); + result = load_sized_binary_as_string(&str, fd); if (!result) break; - if (get_rle_string(&str) == NULL) - { - exit_rle_string(&str); - break; - } - - tpmem->gtypes[i].gtype = g_type_from_name(get_rle_string(&str)); + tpmem->gtypes[i].gtype = g_type_from_name(str.data); result = (tpmem->gtypes[i].gtype != 0); if (!result) - log_variadic_message(LMT_ERROR, "Unknown type: '%s'", get_rle_string(&str)); + log_variadic_message(LMT_ERROR, "Unknown type: '%s'", str.data); else tpmem->gtypes[i].gclass = g_type_class_ref(tpmem->gtypes[i].gtype); - exit_rle_string(&str); + exit_sized_binary(&str); } - } + g_mutex_unlock(&tpmem->mutex); - g_mutex_unlock(&tpmem->mutex); + } return result; @@ -285,38 +239,40 @@ bool g_type_memory_load_types(GTypeMemory *tpmem, packed_buffer_t *pbuf) /****************************************************************************** * * -* Paramètres : tpmem = mémoire à manipuler. * -* pbuf = zone tampon à venir lire. * +* Paramètres : tpmem = mémoire à consulter. * +* fd = flux ouvert en écriture. * * * -* Description : Crée une nouvelle instance d'objet à partir de son type. * +* Description : Enregistre tous les types mémorisés dans un tampon. * * * -* Retour : Instance issue de l'opération ou NULL. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -GObject *g_type_memory_create_object(GTypeMemory *tpmem, packed_buffer_t *pbuf) +bool g_type_memory_store(GTypeMemory *tpmem, int fd) { - GObject *result; /* Nouvelle instance à renvoyer*/ - uleb128_t index; /* Indice du point d'insertion */ - bool status; /* Bilan d'une récupération */ + bool result; /* Bilan à enregistrer */ + uint64_t i; /* Boucle de parcours */ + const gchar *name; /* Désignation d'un type */ + sized_binary_t str; /* Chaîne à conserver */ - result = NULL; + g_mutex_lock(&tpmem->mutex); - status = unpack_uleb128(&index, pbuf); + result = store_uleb128((uleb128_t []){ tpmem->count }, fd); - if (status) + for (i = 0; i < tpmem->count && result; i++) { - g_mutex_lock(&tpmem->mutex); + name = g_type_name(tpmem->gtypes[i].gtype); - if (index < tpmem->count) - result = g_object_new(tpmem->gtypes[index].gtype, NULL); + setup_sized_binary_from_static_string(&str, name); - g_mutex_unlock(&tpmem->mutex); + store_sized_binary_as_string(&str, fd); } + g_mutex_unlock(&tpmem->mutex); + return result; } @@ -325,60 +281,35 @@ GObject *g_type_memory_create_object(GTypeMemory *tpmem, packed_buffer_t *pbuf) /****************************************************************************** * * * Paramètres : tpmem = mémoire à manipuler. * -* obj = instance dont le type est à mémoriser. * -* pbuf = zone tampon à remplir. [OUT] * +* fd = flux ouvert en lecture. * * * -* Description : Sauvegarde le type d'un objet instancié. * +* Description : Crée une nouvelle instance d'objet à partir de son type. * * * -* Retour : Bilan de l'opération. * +* Retour : Instance issue de l'opération ou NULL. * * * * Remarques : - * * * ******************************************************************************/ -bool g_type_memory_store_object_gtype(GTypeMemory *tpmem, GObject *obj, packed_buffer_t *pbuf) +GObject *g_type_memory_create_object_from_gtype(GTypeMemory *tpmem, int fd) { - bool result; /* Bilan à retourner */ - GType gtype; /* Type à enregistrer */ - size_t index; /* Indice du point d'insertion */ - - gtype = G_TYPE_FROM_INSTANCE(obj); + GObject *result; /* Nouvelle instance à renvoyer*/ + uleb128_t index; /* Indice du point d'insertion */ + bool status; /* Bilan d'une récupération */ - /** - * Pour quelques explications sur l'esquive suivante, se rapporter aux - * commentaires de g_target_operand_unserialize(). - * - * Dans la situation présente, on ne doit pas enregistrer le type dans le tampon, - * car l'opérande va relancer l'opération entière (avec un opérande temporaire), - * ce qui conduirait à l'enregistrement de deux types successifs dans les données. - */ + result = NULL; - if (gtype == G_TYPE_TARGET_OPERAND) - result = true; + status = load_uleb128(&index, fd); - else + if (status) { g_mutex_lock(&tpmem->mutex); - for (index = 0; index < tpmem->count; index++) - if (tpmem->gtypes[index].gtype == gtype) - break; - - if (index == tpmem->count) - { - tpmem->gtypes = realloc(tpmem->gtypes, ++tpmem->count * sizeof(gtype_ref_info_t)); - - assert(tpmem->count > 0); - - tpmem->gtypes[index].gtype = gtype; - tpmem->gtypes[index].gclass = g_type_class_ref(gtype); - - } + if (index < tpmem->count) + result = g_object_new(tpmem->gtypes[index].gtype, NULL); g_mutex_unlock(&tpmem->mutex); - result = pack_uleb128((uleb128_t []){ index }, pbuf); - } return result; @@ -388,10 +319,11 @@ bool g_type_memory_store_object_gtype(GTypeMemory *tpmem, GObject *obj, packed_b /****************************************************************************** * * -* Paramètres : tpmem = mémoire à consulter. * -* pbuf = zone tampon à remplir. [OUT] * +* Paramètres : tpmem = mémoire à manipuler. * +* obj = instance dont le type est à mémoriser. * +* fd = flux ouvert en écriture. * * * -* Description : Enregistre tous les types mémorisés dans un tampon. * +* Description : Sauvegarde le type d'un objet instancié. * * * * Retour : Bilan de l'opération. * * * @@ -399,31 +331,33 @@ bool g_type_memory_store_object_gtype(GTypeMemory *tpmem, GObject *obj, packed_b * * ******************************************************************************/ -bool g_type_memory_store_types(GTypeMemory *tpmem, packed_buffer_t *pbuf) +bool g_type_memory_store_object_gtype(GTypeMemory *tpmem, GObject *obj, int fd) { - bool result; /* Bilan à enregistrer */ - uint64_t i; /* Boucle de parcours */ - const gchar *name; /* Désignation d'un type */ - rle_string str; /* Chaîne à conserver */ + bool result; /* Bilan à retourner */ + GType gtype; /* Type à enregistrer */ + size_t index; /* Indice du point d'insertion */ + + gtype = G_TYPE_FROM_INSTANCE(obj); g_mutex_lock(&tpmem->mutex); - result = pack_uleb128((uleb128_t []){ tpmem->count }, pbuf); + for (index = 0; index < tpmem->count; index++) + if (tpmem->gtypes[index].gtype == gtype) + break; - for (i = 0; i < tpmem->count && result; i++) + if (index == tpmem->count) { - name = g_type_name(tpmem->gtypes[i].gtype); - - init_static_rle_string(&str, name); + tpmem->gtypes = realloc(tpmem->gtypes, ++tpmem->count * sizeof(gtype_ref_info_t)); - result = pack_rle_string(&str, pbuf); - - exit_rle_string(&str); + tpmem->gtypes[index].gtype = gtype; + tpmem->gtypes[index].gclass = g_type_class_ref(gtype); } g_mutex_unlock(&tpmem->mutex); + result = store_uleb128((uleb128_t []){ index }, fd); + return result; } |