summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2021-08-20 22:31:12 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2021-08-20 22:31:12 (GMT)
commit9ed9405f37244832570f48b42dced1c92704ba3d (patch)
tree095f04c29bf06d3b692866dae490b405ca6f82e4 /src
parent40e1d396f2393d4444ce7e13462803dbc555a4fa (diff)
Prepare architecture processors for serialization.
Diffstat (limited to 'src')
-rw-r--r--src/arch/processor.c419
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;
+
+}