summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-08-07 21:50:38 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-08-07 21:50:38 (GMT)
commita9328553fc558bca2e75f2c93b35acc5518d9568 (patch)
treece15e5259df278d386683dac217ec2b4a86e7c94 /src
parent5f55377ff6c014d513f13b76ec5faf56c31da478 (diff)
Stored all errors detected when loading and disassembling a binary file.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/disass/output.c8
-rw-r--r--src/arch/processor-int.h19
-rw-r--r--src/arch/processor.c171
-rw-r--r--src/arch/processor.h29
-rw-r--r--src/format/format-int.h18
-rw-r--r--src/format/format.c219
-rw-r--r--src/format/format.h28
-rw-r--r--src/format/preload.c14
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));
}