diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/processor.c | 419 | 
1 files 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; + +} | 
