From 9ed9405f37244832570f48b42dced1c92704ba3d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 21 Aug 2021 00:31:12 +0200 Subject: Prepare architecture processors for serialization. --- src/arch/processor.c | 419 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 405 insertions(+), 14 deletions(-) diff --git a/src/arch/processor.c b/src/arch/processor.c index 59af6cd..1fbc14b 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -35,6 +35,8 @@ #include "instruction-int.h" #include "processor-int.h" +#include "../analysis/db/misc/rlestr.h" +#include "../analysis/storage/serialize-int.h" #include "../common/sort.h" #include "../core/logs.h" #include "../glibext/chrysamarshal.h" @@ -62,6 +64,9 @@ static void g_arch_processor_class_init(GArchProcessorClass *); /* Initialise une instance de processeur d'architecture. */ static void g_arch_processor_init(GArchProcessor *); +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_arch_processor_serializable_init(GSerializableObjectInterface *); + /* Supprime toutes les références externes. */ static void g_arch_processor_dispose(GArchProcessor *); @@ -73,10 +78,26 @@ static GProcContext *_g_arch_processor_get_context(const GArchProcessor *); +/* ------------------ CONSERVATION DES SOUCIS DURANT LE CHARGEMENT ------------------ */ + + +/* Procède à la libération totale de la mémoire. */ +static void g_arch_processor_finalize_errors(GArchProcessor *); + +/* Charge les erreurs de chargement depuis une mémoire tampon. */ +static bool g_arch_processor_load_errors(GArchProcessor *, packed_buffer_t *); + +/* Sauvegarde les erreurs de chargement dans une mémoire tampon. */ +static bool g_arch_processor_store_errors(GArchProcessor *, packed_buffer_t *); + + /* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ +/* Procède à la libération totale de la mémoire. */ +static void g_arch_processor_finalize_coverages(GArchProcessor *); + /* Démarre la définition d'un nouveau groupe d'instructions. */ static void g_arch_processor_add_new_coverage(GArchProcessor *, GArchInstruction *, size_t); @@ -92,17 +113,35 @@ static void g_arch_processor_merge_coverages(GArchProcessor *, instr_coverage *, /* Met à jour une série de groupes d'instructions. */ static void g_arch_processor_update_coverages(GArchProcessor *, instr_coverage *, bool); +/* Charge les plages de couvertures depuis une mémoire tampon. */ +static bool g_arch_processor_load_coverages(GArchProcessor *, packed_buffer_t *); + +/* Sauvegarde les plages de couvertures dans une mémoire tampon. */ +static bool g_arch_processor_store_coverages(GArchProcessor *, packed_buffer_t *); + /* Recherche rapidement un indice d'instruction via une adresse. */ static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool, size_t *); +/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_arch_processor_load(GArchProcessor *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_arch_processor_store(GArchProcessor *, GObjectStorage *, packed_buffer_t *); + + /* Indique le type défini pour un processeur d'architecture. */ -G_DEFINE_TYPE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_CODE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_processor_serializable_init)); + /****************************************************************************** @@ -174,6 +213,26 @@ static void g_arch_processor_init(GArchProcessor *proc) /****************************************************************************** * * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de sérialisation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_processor_serializable_init(GSerializableObjectInterface *iface) +{ + iface->load = (load_serializable_object_cb)g_arch_processor_load; + iface->store = (store_serializable_object_cb)g_arch_processor_store; + +} + + +/****************************************************************************** +* * * Paramètres : proc = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * @@ -224,23 +283,12 @@ static void g_arch_processor_dispose(GArchProcessor *proc) static void g_arch_processor_finalize(GArchProcessor *proc) { - size_t i; /* Boucle de parcours */ - if (proc->instructions != NULL) free(proc->instructions); - if (proc->errors != NULL) - { - for (i = 0; i < proc->error_count; i++) - if (proc->errors[i].desc != NULL) - free(proc->errors[i].desc); - - free(proc->errors); + g_arch_processor_finalize_errors(proc); - } - - if (proc->coverages != NULL) - free(proc->coverages); + g_arch_processor_finalize_coverages(proc); G_OBJECT_CLASS(g_arch_processor_parent_class)->finalize(G_OBJECT(proc)); @@ -923,6 +971,41 @@ GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *proc, s /****************************************************************************** * * +* Paramètres : proc = architecture à manipuler. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_processor_finalize_errors(GArchProcessor *proc) +{ + size_t i; /* Boucle de parcours */ + proc_error *error; /* Raccourci de confort */ + + if (proc->errors != NULL) + { + for (i = 0; i < proc->error_count; i++) + { + error = &proc->errors[i]; + + if (error->desc != NULL) + free(error->desc); + + } + + free(proc->errors); + + } + +} + + +/****************************************************************************** +* * * Paramètres : proc = architecture à manipuler. * * state = nouvel état de l'accès aux erreurs relevées. * * * @@ -1066,6 +1149,118 @@ bool g_arch_processor_get_error(GArchProcessor *proc, size_t index, ArchProcessi } +/****************************************************************************** +* * +* Paramètres : proc = architecture concernée par la procédure. * +* pbuf = zone tampon à vider. * +* * +* Description : Charge les erreurs de chargement depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arch_processor_load_errors(GArchProcessor *proc, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + uleb128_t value; /* Valeur ULEB128 à charger */ + size_t i; /* Boucle de parcours */ + proc_error *error; /* Raccourci de confort */ + rle_string str; /* Chaîne à charger */ + + g_arch_processor_lock_errors(proc); + + result = unpack_uleb128(&value, pbuf); + if (!result) goto exit; + + proc->error_count = value; + + proc->errors = calloc(proc->error_count, sizeof(proc_error)); + + for (i = 0; i < proc->error_count && result; i++) + { + error = &proc->errors[i]; + + result = unpack_uleb128(&value, pbuf); + if (!result) break; + + error->type = value; + + result = unpack_vmpa(&error->addr, pbuf); + if (!result) break; + + setup_empty_rle_string(&str); + + result = unpack_rle_string(&str, pbuf); + if (!result) break; + + if (get_rle_string(&str) != NULL) + error->desc = strdup(get_rle_string(&str)); + + exit_rle_string(&str); + + } + + exit: + + g_arch_processor_unlock_errors(proc); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : proc = architecture concernée par la procédure. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde les erreurs de chargement dans une mémoire tampon.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arch_processor_store_errors(GArchProcessor *proc, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + proc_error *error; /* Raccourci de confort */ + rle_string str; /* Chaîne à conserver */ + + g_arch_processor_lock_errors(proc); + + result = pack_uleb128((uleb128_t []){ proc->error_count }, pbuf); + + for (i = 0; i < proc->error_count && result; i++) + { + error = &proc->errors[i]; + + result = pack_uleb128((uleb128_t []){ error->type }, pbuf); + if (!result) break; + + result = pack_vmpa(&error->addr, pbuf); + if (!result) break; + + init_static_rle_string(&str, error->desc); + + result = pack_rle_string(&str, pbuf); + + exit_rle_string(&str); + + } + + g_arch_processor_unlock_errors(proc); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */ @@ -1074,6 +1269,24 @@ bool g_arch_processor_get_error(GArchProcessor *proc, size_t index, ArchProcessi /****************************************************************************** * * +* Paramètres : proc = architecture à manipuler. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_processor_finalize_coverages(GArchProcessor *proc) +{ + if (proc->coverages != NULL) + free(proc->coverages); + +} +/****************************************************************************** +* * * Paramètres : proc = architecture à comléter par la procédure. * * first = première instruction d'un nouveau groupe. * * start = indice de cette instruction dans l'ensemble global. * @@ -1342,6 +1555,101 @@ static void g_arch_processor_update_coverages(GArchProcessor *proc, instr_covera /****************************************************************************** * * +* Paramètres : proc = architecture concernée par la procédure. * +* pbuf = zone tampon à vider. * +* * +* Description : Charge les plages de couvertures depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arch_processor_load_coverages(GArchProcessor *proc, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + uleb128_t value; /* Valeur ULEB128 à charger */ + size_t i; /* Boucle de parcours */ + instr_coverage *coverage; /* Raccourci de confort */ + + result = unpack_uleb128(&value, pbuf); + if (!result) goto exit; + + proc->cov_allocated = value; + proc->cov_count = value; + + proc->coverages = calloc(proc->cov_count, sizeof(instr_coverage)); + + for (i = 0; i < proc->cov_count && result; i++) + { + coverage = &proc->coverages[i]; + + result = unpack_mrange(&coverage->range, pbuf); + if (!result) break; + + result = unpack_uleb128(&value, pbuf); + if (!result) break; + + coverage->start = value; + + result = unpack_uleb128(&value, pbuf); + if (!result) break; + + coverage->count = value; + + } + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : proc = architecture concernée par la procédure. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde les plages de couvertures dans une mémoire tampon.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arch_processor_store_coverages(GArchProcessor *proc, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + instr_coverage *coverage; /* Raccourci de confort */ + + result = pack_uleb128((uleb128_t []){ proc->cov_count }, pbuf); + + for (i = 0; i < proc->error_count && result; i++) + { + coverage = &proc->coverages[i]; + + result = pack_mrange(&coverage->range, pbuf); + if (!result) break; + + result = pack_uleb128((uleb128_t []){ coverage->start }, pbuf); + if (!result) break; + + result = pack_uleb128((uleb128_t []){ coverage->count }, pbuf); + if (!result) break; + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : proc = processeur recensant diverses instructions. * * addr = position en mémoire ou physique à chercher. * * * @@ -1580,3 +1888,86 @@ instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *pr return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* CONSERVATION ET RECHARGEMENT DES DONNEES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : content = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * +* * +* Description : Charge un contenu depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arch_processor_load(GArchProcessor *proc, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + uleb128_t value; /* Valeur ULEB128 à charger */ + + result = unpack_uleb128(&value, pbuf); + if (!result) goto exit; + + proc->endianness = value; + + + + + + + if (result) + result = g_arch_processor_load_errors(proc, pbuf); + + if (result) + result = g_arch_processor_load_coverages(proc, pbuf); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un contenu dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arch_processor_store(GArchProcessor *proc, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + + result = pack_uleb128((uleb128_t []){ proc->endianness }, pbuf); + + + + + + if (result) + result = g_arch_processor_store_coverages(proc, pbuf); + + if (result) + result = g_arch_processor_store_errors(proc, pbuf); + + return result; + +} -- cgit v0.11.2-87-g4458