diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/disass/output.c | 8 | ||||
-rw-r--r-- | src/arch/processor-int.h | 19 | ||||
-rw-r--r-- | src/arch/processor.c | 171 | ||||
-rw-r--r-- | src/arch/processor.h | 29 | ||||
-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 |
8 files changed, 497 insertions, 9 deletions
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 063280c..8e74d1c 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -83,6 +83,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, GLineGenerator *generator; /* Générateur de contenu ajouté*/ const vmpa2t *saddr; /* Adresse de symbole */ int compared; /* Bilan d'une comparaison */ + char *errmsg; /* Description d'une erreur */ SymbolType stype; /* Type de symbole trouvé */ vmpa2t intro_addr; /* Adresse de début de code */ vmpa2t outro_addr; /* Adresse de fin de code */ @@ -220,6 +221,13 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, _("Unable to find a proper location for symbol '%s' @ 0x%08x"), g_binary_symbol_get_label(symbols[sym_index]), get_phy_addr(saddr)); + asprintf(&errmsg, _("Unable to find a proper location for symbol '%s'"), + g_binary_symbol_get_label(symbols[sym_index])); + + g_arch_processor_add_error(proc, APE_LABEL, saddr, errmsg); + + free(errmsg); + _missing++; if (++sym_index == sym_count) diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h index 0a95fde..a308bb8 100644 --- a/src/arch/processor-int.h +++ b/src/arch/processor-int.h @@ -59,6 +59,16 @@ typedef GArchInstruction * (* disass_instr_fc) (const GArchProcessor *, GProcCon +/* Description d'une erreur */ +typedef struct _proc_error +{ + ArchProcessingError type; /* Type d'erreur */ + + vmpa2t addr; /* Localisation du problème */ + char *desc; /* Description du soucis */ + +} proc_error; + /* Couverture d'un groupe d'instructions */ struct _instr_coverage { @@ -70,8 +80,6 @@ struct _instr_coverage }; - - /* Définition générique d'un processeur d'architecture (instance) */ struct _GArchProcessor { @@ -92,6 +100,13 @@ struct _GArchProcessor gint locked; /* Statut d'accès à la liste */ #endif + proc_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 + instr_coverage *coverages; /* Liste de couvertures */ size_t cov_allocated; /* Taille de la liste allouée */ size_t cov_count; /* Taille de la liste utilisée */ diff --git a/src/arch/processor.c b/src/arch/processor.c index 38c39e6..21b6c49 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -27,6 +27,7 @@ #include <assert.h> #include <malloc.h> #include <stdlib.h> +#include <string.h> @@ -129,10 +130,17 @@ static void g_arch_processor_class_init(GArchProcessorClass *klass) static void g_arch_processor_init(GArchProcessor *proc) { + g_mutex_init(&proc->mutex); #ifndef DEBUG g_atomic_int_set(&proc->locked, 0); #endif - g_mutex_init(&proc->mutex); + + proc->errors = NULL; + proc->error_count = 0; + g_mutex_init(&proc->error_mutex); +#ifndef DEBUG + g_atomic_int_set(&proc->error_locked, 0); +#endif proc->coverages = NULL; proc->cov_allocated = 0; @@ -157,6 +165,8 @@ static void g_arch_processor_dispose(GArchProcessor *proc) { g_mutex_clear(&proc->mutex); + g_mutex_clear(&proc->error_mutex); + G_OBJECT_CLASS(g_arch_processor_parent_class)->dispose(G_OBJECT(proc)); } @@ -176,6 +186,18 @@ static void g_arch_processor_dispose(GArchProcessor *proc) static void g_arch_processor_finalize(GArchProcessor *proc) { + size_t i; /* Boucle de parcours */ + + 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_OBJECT_CLASS(g_arch_processor_parent_class)->finalize(G_OBJECT(proc)); } @@ -498,6 +520,153 @@ GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *proc, s /* ---------------------------------------------------------------------------------- */ +/* CONSERVATION DES SOUCIS DURANT LE CHARGEMENT */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : proc = 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_arch_processor_lock_unlock_errors(GArchProcessor *proc, bool state) +{ + if (state) + { + g_mutex_lock(&proc->error_mutex); + g_atomic_int_set(&proc->error_locked, 1); + } + else + { + g_atomic_int_set(&proc->error_locked, 0); + g_mutex_unlock(&proc->error_mutex); + } + +} + + +/****************************************************************************** +* * +* Paramètres : proc = 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_arch_processor_add_error(GArchProcessor *proc, ArchProcessingError type, const vmpa2t *addr, const char *desc) +{ + proc_error *error; /* Raccourci de confort */ + + g_arch_processor_lock_errors(proc); + + proc->errors = realloc(proc->errors, ++proc->error_count * sizeof(proc_error)); + + error = &proc->errors[proc->error_count - 1]; + + error->type = type; + + copy_vmpa(&error->addr, addr); + + if (desc != NULL) + error->desc = strdup(desc); + else + error->desc = NULL; + + g_arch_processor_unlock_errors(proc); + +} + + +/****************************************************************************** +* * +* Paramètres : proc = 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_arch_processor_count_errors(GArchProcessor *proc) +{ + size_t result; /* Quantité à retourner */ + + assert(g_atomic_int_get(&proc->error_locked) == 1); + + result = proc->error_count; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : proc = 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_arch_processor_get_error(GArchProcessor *proc, size_t index, ArchProcessingError *type, vmpa2t *addr, char **desc) +{ + bool result; /* Bilan à retourner */ + proc_error *error; /* Raccourci de confort */ + + assert(g_atomic_int_get(&proc->error_locked) == 1); + + result = (index < proc->error_count); + + assert(result); + + if (result) + { + error = &proc->errors[index]; + + *type = error->type; + + copy_vmpa(addr, &error->addr); + + if (error->desc != NULL) + *desc = strdup(error->desc); + else + *desc = NULL; + + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ /* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */ /* ---------------------------------------------------------------------------------- */ diff --git a/src/arch/processor.h b/src/arch/processor.h index 2a8a8c1..87c0738 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -98,6 +98,35 @@ GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *, size_ +/* ------------------ CONSERVATION DES SOUCIS DURANT LE CHARGEMENT ------------------ */ + + +/* Types d'erreurs détectées */ +typedef enum _ArchProcessingError +{ + APE_DISASSEMBLY = ((0 << 2) | (1 << 0)),/* Code non reconnu */ + APE_LABEL = ((1 << 2) | (1 << 0)) /* Etiquette non référencée */ + +} ArchProcessingError; + + +/* Protège ou lève la protection de l'accès aux erreurs. */ +void g_arch_processor_lock_unlock_errors(GArchProcessor *, bool); + +#define g_arch_processor_lock_errors(p) g_arch_processor_lock_unlock_errors(p, true) +#define g_arch_processor_unlock_errors(p) g_arch_processor_lock_unlock_errors(p, false) + +/* Etend la liste des soucis détectés avec de nouvelles infos. */ +void g_arch_processor_add_error(GArchProcessor *, ArchProcessingError, const vmpa2t *, const char *); + +/* Indique le nombre d'erreurs relevées au niveau assembleur. */ +size_t g_arch_processor_count_errors(GArchProcessor *); + +/* Fournit les éléments concernant un soucis détecté. */ +bool g_arch_processor_get_error(GArchProcessor *, size_t, ArchProcessingError *, vmpa2t *, char **); + + + /* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ 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)); } |