diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-08-07 21:50:38 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-08-07 21:50:38 (GMT) |
commit | a9328553fc558bca2e75f2c93b35acc5518d9568 (patch) | |
tree | ce15e5259df278d386683dac217ec2b4a86e7c94 /src/format | |
parent | 5f55377ff6c014d513f13b76ec5faf56c31da478 (diff) |
Stored all errors detected when loading and disassembling a binary file.
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/format-int.h | 18 | ||||
-rw-r--r-- | src/format/format.c | 219 | ||||
-rw-r--r-- | src/format/format.h | 28 | ||||
-rw-r--r-- | src/format/preload.c | 14 |
4 files changed, 273 insertions, 6 deletions
diff --git a/src/format/format-int.h b/src/format/format-int.h index d50b053..0ab0e85 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -47,6 +47,17 @@ typedef void (* format_decompile_fc) (const GBinFormat *, void/*GCodeBuffer*/ *, #define EXTRA_POINT_BLOCK 100 +/* Description d'une erreur */ +typedef struct _fmt_error +{ + BinaryFormatError type; /* Type d'erreur */ + + vmpa2t addr; /* Localisation du problème */ + char *desc; /* Description du soucis */ + +} fmt_error; + + /* Format binaire générique (instance) */ struct _GBinFormat { @@ -74,6 +85,13 @@ struct _GBinFormat size_t def_source; /* Fichier source principal */ format_decompile_fc decompile; /* Décompilation d'un fichier */ + fmt_error *errors; /* Liste d'erreurs rencontrées */ + size_t error_count; /* Taille de cette liste */ + GMutex error_mutex; /* Verrou pour l'accès */ +#ifndef NDEBUG + gint error_locked; /* Statut d'accès à la liste */ +#endif + }; /* Format binaire générique (classe) */ diff --git a/src/format/format.c b/src/format/format.c index 5d845e4..293e5da 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -50,6 +50,12 @@ static void g_binary_format_class_init(GBinFormatClass *); /* Initialise une instance de format binaire générique. */ static void g_binary_format_init(GBinFormat *); +/* Supprime toutes les références externes. */ +static void g_binary_format_dispose(GBinFormat *); + +/* Procède à la libération totale de la mémoire. */ +static void g_binary_format_finalize(GBinFormat *); + /* Retire un symbole de la collection du format binaire. */ static void _g_binary_format_remove_symbol(GBinFormat *, size_t); @@ -79,6 +85,12 @@ G_DEFINE_TYPE(GBinFormat, g_binary_format, G_TYPE_OBJECT); static void g_binary_format_class_init(GBinFormatClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_format_dispose; + object->finalize = (GObjectFinalizeFunc)g_binary_format_finalize; } @@ -103,14 +115,70 @@ static void g_binary_format_init(GBinFormat *format) g_rw_lock_init(&format->syms_lock); + format->errors = NULL; + format->error_count = 0; + g_mutex_init(&format->error_mutex); +#ifndef DEBUG + g_atomic_int_set(&format->error_locked, 0); +#endif + } +/****************************************************************************** +* * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_format_dispose(GBinFormat *format) +{ + g_object_unref(format->info); + + g_rw_lock_clear(&format->syms_lock); -/* FIXME : g_object_unref(format->info); */ + g_mutex_clear(&format->error_mutex); -/* FIXME : g_rw_lock_clear(&format->syms_lock);*/ + G_OBJECT_CLASS(g_binary_format_parent_class)->dispose(G_OBJECT(format)); +} + + +/****************************************************************************** +* * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_format_finalize(GBinFormat *format) +{ + size_t i; /* Boucle de parcours */ + + if (format->errors != NULL) + { + for (i = 0; i < format->error_count; i++) + if (format->errors[i].desc != NULL) + free(format->errors[i].desc); + + free(format->errors); + + } + + G_OBJECT_CLASS(g_binary_format_parent_class)->finalize(G_OBJECT(format)); + +} /****************************************************************************** @@ -964,3 +1032,150 @@ void g_binary_format_decompile(const GBinFormat *format, GCodeBuffer *buffer, co } #endif + + + +/* ---------------------------------------------------------------------------------- */ +/* CONSERVATION DES SOUCIS DURANT LE CHARGEMENT */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : format = architecture à manipuler. * +* state = nouvel état de l'accès aux erreurs relevées. * +* * +* Description : Protège ou lève la protection de l'accès aux erreurs. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_lock_unlock_errors(GBinFormat *format, bool state) +{ + if (state) + { + g_mutex_lock(&format->error_mutex); + g_atomic_int_set(&format->error_locked, 1); + } + else + { + g_atomic_int_set(&format->error_locked, 0); + g_mutex_unlock(&format->error_mutex); + } + +} + + +/****************************************************************************** +* * +* Paramètres : format = architecture concernée par la procédure. * +* index = indice du problème visé. * +* type = type d'erreur retrouvée. * +* addr = localisation associée. * +* desc = éventuelle description humaine de description. * +* * +* Description : Etend la liste des soucis détectés avec de nouvelles infos. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_add_error(GBinFormat *format, BinaryFormatError type, const vmpa2t *addr, const char *desc) +{ + fmt_error *error; /* Raccourci de confort */ + + g_binary_format_lock_errors(format); + + format->errors = realloc(format->errors, ++format->error_count * sizeof(fmt_error)); + + error = &format->errors[format->error_count - 1]; + + error->type = type; + + copy_vmpa(&error->addr, addr); + + if (desc != NULL) + error->desc = strdup(desc); + else + error->desc = NULL; + + g_binary_format_unlock_errors(format); + +} + + +/****************************************************************************** +* * +* Paramètres : format = architecture à consulter durant la procédure. * +* * +* Description : Indique le nombre d'erreurs relevées au niveau assembleur. * +* * +* Retour : Nombre d'erreurs en stock. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_binary_format_count_errors(GBinFormat *format) +{ + size_t result; /* Quantité à retourner */ + + assert(g_atomic_int_get(&format->error_locked) == 1); + + result = format->error_count; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = architecture concernée par la procédure. * +* index = indice du problème visé. * +* type = type d'erreur retrouvée. [OUT] * +* addr = localisation associée. [OUT] * +* desc = éventuelle description humaine de description. [OUT]* +* * +* Description : Fournit les éléments concernant un soucis détecté. * +* * +* Retour : Validité des informations renseignées. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_format_get_error(GBinFormat *format, size_t index, BinaryFormatError *type, vmpa2t *addr, char **desc) +{ + bool result; /* Bilan à retourner */ + fmt_error *error; /* Raccourci de confort */ + + assert(g_atomic_int_get(&format->error_locked) == 1); + + result = (index < format->error_count); + + assert(result); + + if (result) + { + error = &format->errors[index]; + + *type = error->type; + + copy_vmpa(addr, &error->addr); + + if (error->desc != NULL) + *desc = strdup(error->desc); + else + *desc = NULL; + + } + + return result; + +} diff --git a/src/format/format.h b/src/format/format.h index ec78236..3c1bbea 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -105,4 +105,32 @@ const char * const *g_binary_format_get_source_files(const GBinFormat *, size_t +/* ------------------ CONSERVATION DES SOUCIS DURANT LE CHARGEMENT ------------------ */ + + +/* Types d'erreurs détectées */ +typedef enum _BinaryFormatError +{ + BFE_STRUCTURE = ((0 << 2) | (0 << 0)) /* Code non reconnu */ + +} BinaryFormatError; + + +/* Protège ou lève la protection de l'accès aux erreurs. */ +void g_binary_format_lock_unlock_errors(GBinFormat *, bool); + +#define g_binary_format_lock_errors(p) g_binary_format_lock_unlock_errors(p, true) +#define g_binary_format_unlock_errors(p) g_binary_format_lock_unlock_errors(p, false) + +/* Etend la liste des soucis détectés avec de nouvelles infos. */ +void g_binary_format_add_error(GBinFormat *, BinaryFormatError, const vmpa2t *, const char *); + +/* Indique le nombre d'erreurs relevées au niveau assembleur. */ +size_t g_binary_format_count_errors(GBinFormat *); + +/* Fournit les éléments concernant un soucis détecté. */ +bool g_binary_format_get_error(GBinFormat *, size_t, BinaryFormatError *, vmpa2t *, char **); + + + #endif /* _FORMAT_FORMAT_H */ diff --git a/src/format/preload.c b/src/format/preload.c index 7f7a435..cddc60e 100644 --- a/src/format/preload.c +++ b/src/format/preload.c @@ -105,14 +105,18 @@ static void g_preload_info_init(GPreloadInfo *info) static void g_preload_info_dispose(GPreloadInfo *info) { + size_t count; /* Borne de parcours */ + size_t i; /* Boucle de parcours */ GArchInstruction *instr; /* Instruction à libérer */ GDbComment *comment; /* Commentaire à libérer */ g_preload_info_lock_instructions(info); - while (_g_preload_info_count_instructions(info) > 0) + count = _g_preload_info_count_instructions(info); + + for (i = 0; i < count; i++) { - instr = _g_preload_info_grab_instruction(info, 0); + instr = _g_preload_info_grab_instruction(info, i); g_object_unref(G_OBJECT(instr)); } @@ -122,9 +126,11 @@ static void g_preload_info_dispose(GPreloadInfo *info) g_preload_info_lock_comments(info); - while (_g_preload_info_count_comments(info) > 0) + count = _g_preload_info_count_comments(info); + + for (i = 0; i < count; i++) { - comment = _g_preload_info_grab_comment(info, 0); + comment = _g_preload_info_grab_comment(info, i); g_object_unref(G_OBJECT(comment)); } |