diff options
Diffstat (limited to 'src/format/format.c')
-rw-r--r-- | src/format/format.c | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/src/format/format.c b/src/format/format.c index f8fe13a..d126236 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -33,6 +33,7 @@ #include "preload.h" #include "../arch/processor.h" #include "../common/sort.h" +#include "../core/demanglers.h" #include "../plugins/pglist.h" @@ -49,6 +50,12 @@ static void g_binary_format_dispose(GBinFormat *); /* Procède à la libération totale de la mémoire. */ static void g_binary_format_finalize(GBinFormat *); +/* Charge les plages de couvertures depuis une mémoire tampon. */ +static bool g_binary_format_load_start_points(GBinFormat *, packed_buffer_t *); + +/* Sauvegarde les points de départ enregistrés pour un format. */ +static bool g_binary_format_store_start_points(GBinFormat *, packed_buffer_t *); + /* ---------------------- RASSEMBLEMENT ET GESTION DE SYMBOLES ---------------------- */ @@ -65,6 +72,30 @@ static bool __g_binary_format_find_symbol(const GBinFormat *, const void *, __co +/* ------------------ CONSERVATION DES SOUCIS DURANT LE CHARGEMENT ------------------ */ + + +/* Charge les erreurs de chargement depuis une mémoire tampon. */ +static bool g_binary_format_load_errors(GBinFormat *, packed_buffer_t *); + +/* Sauvegarde les erreurs de chargement dans une mémoire tampon. */ +static bool g_binary_format_store_errors(GBinFormat *, packed_buffer_t *); + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Charge un format depuis une mémoire tampon. */ +static bool g_binary_format_load(GBinFormat *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un format dans une mémoire tampon. */ +static bool g_binary_format_store(GBinFormat *, GObjectStorage *, packed_buffer_t *); + + + + + /* Indique le type défini pour un format binaire générique. */ G_DEFINE_TYPE(GBinFormat, g_binary_format, G_TYPE_KNOWN_FORMAT); @@ -84,12 +115,18 @@ G_DEFINE_TYPE(GBinFormat, g_binary_format, G_TYPE_KNOWN_FORMAT); static void g_binary_format_class_init(GBinFormatClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GKnownFormatClass *known; /* Version de classe parente */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_format_dispose; object->finalize = (GObjectFinalizeFunc)g_binary_format_finalize; + known = G_KNOWN_FORMAT_CLASS(klass); + + known->load = (load_known_fc)g_binary_format_load; + known->store = (load_known_fc)g_binary_format_store; + g_signal_new("symbol-added", G_TYPE_BIN_FORMAT, G_SIGNAL_RUN_LAST, @@ -411,6 +448,101 @@ void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, DisassPr /****************************************************************************** * * +* 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_binary_format_load_start_points(GBinFormat *format, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + DisassPriorityLevel i; /* Boucle de parcours #1 */ + uleb128_t count; /* Quantité de points présents */ + size_t k; /* Boucle de parcours #2 */ + uleb128_t value; /* Valeur ULEB128 à charger */ + + result = true; + + g_rw_lock_writer_lock(&format->pt_lock); + + for (i = 0; i < DPL_COUNT && result; i++) + { + result = unpack_uleb128(&count, pbuf); + if (!result) break; + + format->pt_allocated[i] = count; + format->pt_count[i] = count; + + format->start_points[i] = calloc(format->pt_count[i], sizeof(virt_t)); + + for (k = 0; k < format->pt_count[i] && result; k++) + { + result = unpack_uleb128(&value, pbuf); + if (!result) break; + + format->start_points[i][k] = value; + + } + + } + + g_rw_lock_writer_unlock(&format->pt_lock); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde les points de départ enregistrés pour un format. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_format_store_start_points(GBinFormat *format, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + DisassPriorityLevel i; /* Boucle de parcours #1 */ + size_t count; /* Quantité de points présents */ + size_t k; /* Boucle de parcours #2 */ + + result = true; + + g_rw_lock_writer_lock(&format->pt_lock); + + for (i = 0; i < DPL_COUNT && result; i++) + { + count = format->pt_count[i]; + + result = pack_uleb128((uleb128_t []){ count }, pbuf); + + for (k = 0; k < count && result; k++) + result = pack_uleb128((uleb128_t []){ format->start_points[i][k] }, pbuf); + + } + + g_rw_lock_writer_unlock(&format->pt_lock); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = description de l'exécutable à consulter. * * ctx = contexte de désassemblage à préparer. * * status = barre de statut à tenir informée. * @@ -1546,3 +1678,243 @@ bool g_binary_format_get_error(GBinFormat *format, size_t index, BinaryFormatErr return result; } + + +/****************************************************************************** +* * +* Paramètres : format = format de binaire concerné 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_binary_format_load_errors(GBinFormat *format, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + uleb128_t value; /* Valeur ULEB128 à charger */ + size_t i; /* Boucle de parcours */ + fmt_error *error; /* Raccourci de confort */ + rle_string str; /* Chaîne à charger */ + + g_binary_format_lock_errors(format); + + result = unpack_uleb128(&value, pbuf); + if (!result) goto exit; + + format->error_count = value; + + format->errors = calloc(format->error_count, sizeof(fmt_error)); + + for (i = 0; i < format->error_count && result; i++) + { + error = &format->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_binary_format_unlock_errors(format); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = format de binaire concerné 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_binary_format_store_errors(GBinFormat *format, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + fmt_error *error; /* Raccourci de confort */ + rle_string str; /* Chaîne à conserver */ + + g_binary_format_lock_errors(format); + + result = pack_uleb128((uleb128_t []){ format->error_count }, pbuf); + + for (i = 0; i < format->error_count && result; i++) + { + error = &format->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_binary_format_unlock_errors(format); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * +* * +* Description : Charge un format depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_format_load(GBinFormat *format, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + fmt_extra_data_t *extra; /* Données insérées à consulter*/ + uleb128_t value; /* Valeur ULEB128 à charger */ + rle_string str; /* Chaîne à charger */ + + extra = GET_BIN_FORMAT_EXTRA(format); + + LOCK_GOBJECT_EXTRA(extra); + + result = unpack_uleb128(&value, pbuf); + + if (result) + extra->flags = value; + + UNLOCK_GOBJECT_EXTRA(extra); + + if (result) + result = g_binary_format_load_start_points(format, pbuf); + + if (result) + { + setup_empty_rle_string(&str); + + result = unpack_rle_string(&str, pbuf); + + if (result) + result = (get_rle_string(&str) != NULL); + + if (result) + format->demangler = get_compiler_demangler_for_key(get_rle_string(&str)); + + if (result) + result = (format->demangler != NULL); + + exit_rle_string(&str); + + } + + + + + + if (result) + result = g_binary_format_load_errors(format, pbuf); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un format dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_format_store(GBinFormat *format, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + fmt_extra_data_t *extra; /* Données insérées à consulter*/ + char *key; /* Désignation du décodeur */ + rle_string str; /* Chaîne à conserver */ + + extra = GET_BIN_FORMAT_EXTRA(format); + + LOCK_GOBJECT_EXTRA(extra); + + result = pack_uleb128((uleb128_t []){ extra->flags }, pbuf); + + UNLOCK_GOBJECT_EXTRA(extra); + + if (result) + result = g_binary_format_store_start_points(format, pbuf); + + if (result) + { + key = g_compiler_demangler_get_key(format->demangler); + init_dynamic_rle_string(&str, key); + + result = pack_rle_string(&str, pbuf); + + exit_rle_string(&str); + + } + + + + + + + if (result) + result = g_binary_format_store_errors(format, pbuf); + + return result; + +} |