diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/formats.c | 198 | ||||
-rw-r--r-- | src/core/formats.h | 15 |
2 files changed, 152 insertions, 61 deletions
diff --git a/src/core/formats.c b/src/core/formats.c index 9ff31b2..891fc12 100644 --- a/src/core/formats.c +++ b/src/core/formats.c @@ -29,41 +29,99 @@ #include <string.h> +#include "../format/dwarf/dwarf.h" +#include "../format/dwarf/v2/dwarf.h" +#include "../format/dwarf/v3/dwarf.h" +#include "../format/dwarf/v4/dwarf.h" #include "../format/elf/elf.h" +/* Eléments pour détection */ +typedef struct _format_matcher_t +{ + format_match_fc func; /* Recherche de correspondance */ + +} format_matcher_t; + + /* Caractéristiques d'un processeur */ -typedef struct _format_t +typedef struct _format_loader_t { char *key; /* Clef pour un accès rapide */ char *name; /* Désignation humaine */ - format_match_fc is_matching; /* Recherche de correspondance */ - format_load_fc load; /* Procédure de chargement */ + format_load_fc func; /* Procédure de chargement */ -} format_t; +} format_loader_t; +/* Mémorisation des détections de format enregistrées */ +static format_matcher_t *_formats_matchers = NULL; +static size_t _formats_matchers_count = 0; + /* Mémorisation des types de formats enregistrés */ -static format_t *_formats_definitions = NULL; -static size_t _formats_definitions_count = 0; +static format_loader_t *_formats_loaders = NULL; +static size_t _formats_loaders_count = 0; /* Verrou pour des accès atomiques */ -/* ... */ +static GRWLock _formats_lock; /* Retrouve l'enregistrement correspondant à une architecture. */ -static format_t *find_format_by_key(const char *); +static format_loader_t *find_format_by_key(const char *); + + + +/****************************************************************************** +* * +* Paramètres : func = procédure de détection à utiliser. * +* * +* Description : Enregistre un détection de format(s) binaire(s). * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_format_matcher(format_match_fc func) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + format_matcher_t *new; /* Nouvel élément à définir */ + + g_rw_lock_writer_lock(&_formats_lock); + + for (i = 0; i < _formats_matchers_count; i++) + if (_formats_matchers[i].func == func) + break; + + result = (i == _formats_matchers_count); + + if (result) + { + _formats_matchers = (format_matcher_t *)realloc(_formats_matchers, + ++_formats_matchers_count * sizeof(format_matcher_t)); + new = &_formats_matchers[_formats_matchers_count - 1]; + + new->func = func; + + } + + g_rw_lock_writer_unlock(&_formats_lock); + + return result; + +} /****************************************************************************** * * -* Paramètres : key = désignation rapide et interne d'un format. * -* name = désignation humaine au format de binaire. * -* is_matching = procédure de détection associée. * -* load = procédure de chargement associée. * +* Paramètres : key = désignation rapide et interne d'un format. * +* name = désignation humaine au format de binaire. * +* func = procédure de chargement associée. * * * * Description : Enregistre un format de contenu binaire donné. * * * @@ -73,28 +131,37 @@ static format_t *find_format_by_key(const char *); * * ******************************************************************************/ -bool register_format_type(const char *key, const char *name, format_match_fc is_matching, format_load_fc load) +bool register_format_loader(const char *key, const char *name, format_load_fc func) { - format_t *new; /* Nouvel élément à définir */ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + format_loader_t *new; /* Nouvel élément à définir */ - /* TODO : if find()... -> unref(), ret false */ + g_rw_lock_writer_lock(&_formats_lock); - /* TODO : lock */ + for (i = 0; i < _formats_loaders_count; i++) + if (strcmp(_formats_loaders[i].key, key) == 0 && strcmp(_formats_loaders[i].name, name) == 0) + break; + + result = (i == _formats_loaders_count); + + if (result) + { + _formats_loaders = (format_loader_t *)realloc(_formats_loaders, + ++_formats_loaders_count * sizeof(format_loader_t)); - _formats_definitions = (format_t *)realloc(_formats_definitions, - ++_formats_definitions_count * sizeof(format_t)); + new = &_formats_loaders[_formats_loaders_count - 1]; - new = &_formats_definitions[_formats_definitions_count - 1]; + new->key = strdup(key); + new->name = strdup(name); - new->key = strdup(key); - new->name = strdup(name); + new->func = func; - new->is_matching = is_matching; - new->load = load; + } - /* TODO : unlock */ + g_rw_lock_writer_unlock(&_formats_lock); - return true; + return result; } @@ -117,7 +184,24 @@ bool load_hard_coded_formats_definitions(void) result = true; - result &= register_format_type("elf", "Executable and Linkable Format", elf_is_matching, g_elf_format_new); + /* Détections */ + + result &= register_format_matcher(dwarf_is_matching); + + result &= register_format_matcher(elf_is_matching); + + /* Chargements */ + + result &= register_format_loader("dwarf_v2", "Debugging With Arbitrary Record Formats (v2)", + g_dwarfv2_format_new); + + result &= register_format_loader("dwarf_v3", "Debugging With Arbitrary Record Formats (v3)", + g_dwarfv3_format_new); + + result &= register_format_loader("dwarf_v4", "Debugging With Arbitrary Record Formats (v4)", + g_dwarfv4_format_new); + + result &= register_format_loader("elf", "Executable and Linkable Format", g_elf_format_new); return result; @@ -140,17 +224,23 @@ void unload_formats_definitions(void) { size_t i; /* Boucle de parcours */ - for (i = 0; i < _formats_definitions_count; i++) + if (_formats_matchers != NULL) + free(_formats_matchers); + + _formats_matchers = NULL; + _formats_matchers_count = 0; + + for (i = 0; i < _formats_loaders_count; i++) { - free(_formats_definitions[i].key); - free(_formats_definitions[i].name); + free(_formats_loaders[i].key); + free(_formats_loaders[i].name); } - if (_formats_definitions != NULL) - free(_formats_definitions); + if (_formats_loaders != NULL) + free(_formats_loaders); - _formats_definitions = NULL; - _formats_definitions_count = 0; + _formats_loaders = NULL; + _formats_loaders_count = 0; } @@ -167,9 +257,9 @@ void unload_formats_definitions(void) * * ******************************************************************************/ -static format_t *find_format_by_key(const char *key) +static format_loader_t *find_format_by_key(const char *key) { - format_t *result; /* Trouvaille à retourner */ + format_loader_t *result; /* Trouvaille à retourner */ size_t i; /* Boucle de parcours */ /** @@ -179,9 +269,9 @@ static format_t *find_format_by_key(const char *key) result = NULL; if (key != NULL) - for (i = 0; i < _formats_definitions_count; i++) - if (strcmp(_formats_definitions[i].key, key) == 0) - result = &_formats_definitions[i]; + for (i = 0; i < _formats_loaders_count; i++) + if (strcmp(_formats_loaders[i].key, key) == 0) + result = &_formats_loaders[i]; return result; @@ -203,9 +293,9 @@ static format_t *find_format_by_key(const char *key) const char *get_binary_format_name(const char *key) { const char *result; /* Description à retourner */ - format_t *def; /* Définition d'architecture */ + format_loader_t *def; /* Définition d'architecture */ - /* TODO : lock */ + g_rw_lock_reader_lock(&_formats_lock); def = find_format_by_key(key); @@ -214,7 +304,7 @@ const char *get_binary_format_name(const char *key) else result = def->name; - /* TODO : unlock */ + g_rw_lock_reader_unlock(&_formats_lock); return result; @@ -224,6 +314,7 @@ const char *get_binary_format_name(const char *key) /****************************************************************************** * * * Paramètres : content = contenu binaire à parcourir. * +* parent = éventuel format exécutable déjà chargé. * * * * Description : Identifie un format binaire par son contenu. * * * @@ -233,26 +324,21 @@ const char *get_binary_format_name(const char *key) * * ******************************************************************************/ -const char *find_matching_format(GBinContent *content) +const char *find_matching_format(GBinContent *content, GExeFormat *parent) { const char *result; /* Identifiant à retourner */ size_t i; /* Boucle de parcours */ - format_t *def; /* Définition d'architecture */ result = NULL; - /* TODO : lock */ + g_rw_lock_reader_lock(&_formats_lock); - for (i = 0; i < _formats_definitions_count && result == NULL; i++) + for (i = 0; i < _formats_matchers_count && result == NULL; i++) { - def = &_formats_definitions[i]; - - if (def->is_matching(content)) - result = def->key; - + result = _formats_matchers[i].func(content, parent); } - /* TODO : unlock */ + g_rw_lock_reader_unlock(&_formats_lock); return result; @@ -272,21 +358,21 @@ const char *find_matching_format(GBinContent *content) * * ******************************************************************************/ -GBinFormat *load_new_named_format(const char *key, GBinContent *content) +GBinFormat *load_new_named_format(const char *key, GBinContent *content, GExeFormat *parent) { GBinFormat *result; /* Instance à retourner */ - format_t *def; /* Définition d'architecture */ + format_loader_t *def; /* Définition d'architecture */ - /* TODO : lock */ + g_rw_lock_reader_lock(&_formats_lock); def = find_format_by_key(key); if (def == NULL) result = NULL; else - result = def->load(content); + result = def->func(content, parent); - /* TODO : unlock */ + g_rw_lock_reader_unlock(&_formats_lock); return result; diff --git a/src/core/formats.h b/src/core/formats.h index bc16f01..8857217 100644 --- a/src/core/formats.h +++ b/src/core/formats.h @@ -30,17 +30,22 @@ #include "../format/format.h" +#include "../format/executable.h" + /* Indication à propos du support d'un format */ -typedef bool (* format_match_fc) (GBinContent *); +typedef const char * (* format_match_fc) (GBinContent *, GExeFormat *); /* Méthode de chargement d'un format */ -typedef GBinFormat * (* format_load_fc) (GBinContent *); +typedef GBinFormat * (* format_load_fc) (GBinContent *, GExeFormat *); + +/* Enregistre un détection de format(s) binaire(s). */ +bool register_format_matcher(format_match_fc); /* Enregistre un format de contenu binaire donné. */ -bool register_format_type(const char *, const char *, format_match_fc, format_load_fc); +bool register_format_loader(const char *, const char *, format_load_fc); /* Charge les définitions de formats "natifs". */ bool load_hard_coded_formats_definitions(void); @@ -52,10 +57,10 @@ void unload_formats_definitions(void); const char *get_binary_format_name(const char *); /* Identifie un format binaire par son contenu. */ -const char *find_matching_format(GBinContent *); +const char *find_matching_format(GBinContent *, GExeFormat *); /* Charge le format binaire correspondant à un type. */ -GBinFormat *load_new_named_format(const char *, GBinContent *); +GBinFormat *load_new_named_format(const char *, GBinContent *, GExeFormat *); |