summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-08-12 19:05:31 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-08-12 19:05:31 (GMT)
commit4b2f65ed2125cd7b6ef598cf02738f6c839d8935 (patch)
treede62e9daaafe63248c45202004758e91b7341cc5 /src/core
parentb5c6bcea25b1b840fd6c8e89a4a3c9fbd83ba84b (diff)
Extended the loading process of binary formats to prepare the DWARF support.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@568 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/core')
-rw-r--r--src/core/formats.c198
-rw-r--r--src/core/formats.h15
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 *);