summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-12-29 10:30:28 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-12-29 10:30:28 (GMT)
commit9f9041e11efa71cb043425cd5e89daea0247e76c (patch)
tree84d8704c291a5efef46af1e14a2aa3544dc29455 /src/format
parent403a0519ec85a156a7f306b045d9cab619302473 (diff)
Cut binary data into several areas using all the available CPUs and less memory.
Diffstat (limited to 'src/format')
-rw-r--r--src/format/dex/class.c9
-rw-r--r--src/format/dex/class.h2
-rwxr-xr-xsrc/format/dex/dex.c16
-rw-r--r--src/format/dex/method.c18
-rw-r--r--src/format/dex/method.h2
-rw-r--r--src/format/elf/elf.c155
-rw-r--r--src/format/executable-int.h8
-rw-r--r--src/format/executable.c167
-rw-r--r--src/format/executable.h6
-rw-r--r--src/format/format.c1
-rw-r--r--src/format/symbol.c31
-rw-r--r--src/format/symbol.h3
12 files changed, 197 insertions, 221 deletions
diff --git a/src/format/dex/class.c b/src/format/dex/class.c
index 26907ed..c1ff62a 100644
--- a/src/format/dex/class.c
+++ b/src/format/dex/class.c
@@ -401,9 +401,8 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
/******************************************************************************
* *
-* Paramètres : class = informations chargées à consulter. *
+* Paramètres : class = informations chargées à consulter. *
* format = format permettant d'obtenir une adresse complète. *
-* layer = couche de portions à raffiner. *
* *
* Description : Intègre la méthode en tant que portion de code. *
* *
@@ -413,15 +412,15 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
* *
******************************************************************************/
-void g_dex_class_include_as_portion(const GDexClass *class, const GDexFormat *format, GPortionLayer *layer)
+void g_dex_class_include_as_portion(const GDexClass *class, GExeFormat *format)
{
size_t i; /* Boucle de parcours */
for (i = 0; i < class->dmethods_count; i++)
- g_dex_method_include_as_portion(class->direct_methods[i], format, layer);
+ g_dex_method_include_as_portion(class->direct_methods[i], format);
for (i = 0; i < class->vmethods_count; i++)
- g_dex_method_include_as_portion(class->virtual_methods[i], format, layer);
+ g_dex_method_include_as_portion(class->virtual_methods[i], format);
}
diff --git a/src/format/dex/class.h b/src/format/dex/class.h
index 46529c3..ec2fa24 100644
--- a/src/format/dex/class.h
+++ b/src/format/dex/class.h
@@ -69,7 +69,7 @@ size_t g_dex_class_count_methods(const GDexClass *, bool);
GDexMethod *g_dex_class_get_method(const GDexClass *, bool, size_t);
/* Intègre la méthode en tant que portion de code. */
-void g_dex_class_include_as_portion(const GDexClass *, const GDexFormat *, GPortionLayer *);
+void g_dex_class_include_as_portion(const GDexClass *, GExeFormat *);
/* Retrouve si possible la méthode associée à une adresse. */
GDexMethod *g_dex_class_find_method_by_address(const GDexClass *, vmpa_t);
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index c550375..df920b2 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -58,7 +58,7 @@ static void g_dex_format_finalize(GDexFormat *);
static const char *g_dex_format_get_target_machine(const GDexFormat *);
/* Etend la définition des portions au sein d'un binaire. */
-static void g_dex_format_refine_portions(const GDexFormat *, GPortionLayer *);
+static void g_dex_format_refine_portions(GDexFormat *);
/* Fournit l'emplacement d'une section donnée. */
static bool g_dex_format_get_section_range_by_name(const GDexFormat *, const char *, mrange_t *);
@@ -247,12 +247,14 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus
{
GDexFormat *result; /* Structure à retourner */
GBinFormat *base; /* Version basique du format */
+ GExeFormat *exe_format; /* Autre version du format */
vmpa2t pos; /* Position de tête de lecture */
wgroup_id_t gid; /* Identifiant pour les tâches */
result = g_object_new(G_TYPE_DEX_FORMAT, NULL);
base = G_BIN_FORMAT(result);
+ exe_format = G_EXE_FORMAT(result);
g_binary_format_set_content(base, content);
@@ -277,7 +279,7 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus
if (!load_all_dex_classes(result, gid, status))
goto gdfn_error;
- if (!g_binary_format_complete_loading(base, status))
+ if (!g_executable_format_complete_loading(exe_format, status))
goto gdfn_error;
return base;
@@ -322,20 +324,18 @@ static const char *g_dex_format_get_target_machine(const GDexFormat *format)
* *
******************************************************************************/
-static void g_dex_format_refine_portions(const GDexFormat *format, GPortionLayer *main)
+static void g_dex_format_refine_portions(GDexFormat *format)
{
- GPortionLayer *layer; /* Couche à mettre en place */
+ GExeFormat *exe_format; /* Autre version du format */
size_t max; /* Nombre d'itérations prévues */
size_t i; /* Boucle de parcours */
- layer = g_portion_layer_new(NO_LENGTH_YET, _("Code"));
-
- g_portion_layer_attach_sub(main, layer);
+ exe_format = G_EXE_FORMAT(format);
max = g_dex_format_count_classes(format);
for (i = 0; i < max; i++)
- g_dex_class_include_as_portion(format->classes[i], format, layer);
+ g_dex_class_include_as_portion(format->classes[i], exe_format);
}
diff --git a/src/format/dex/method.c b/src/format/dex/method.c
index 1223eb9..8659a73 100644
--- a/src/format/dex/method.c
+++ b/src/format/dex/method.c
@@ -338,7 +338,6 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)
* *
* Paramètres : method = représentation interne du format DEX à consulter. *
* format = format permettant d'obtenir une adresse complète. *
-* layer = couche de portions à raffiner. *
* *
* Description : Intègre la méthode en tant que portion de code. *
* *
@@ -348,11 +347,10 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)
* *
******************************************************************************/
-void g_dex_method_include_as_portion(const GDexMethod *method, const GDexFormat *format, GPortionLayer *layer)
+void g_dex_method_include_as_portion(const GDexMethod *method, GExeFormat *format)
{
vmpa2t addr; /* Emplacement dans le binaire */
GBinPortion *new; /* Nouvelle portion définie */
- char *desc; /* Description d'une portion */
/* Si la taille est nulle, on ne fait rien */
if (method->info.access_flags & ACC_NATIVE)
@@ -361,22 +359,16 @@ void g_dex_method_include_as_portion(const GDexMethod *method, const GDexFormat
if (!method->has_body)
return;
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), method->offset, &addr))
+ if (!g_exe_format_translate_offset_into_vmpa(format, method->offset, &addr))
return;
- new = g_binary_portion_new(BPC_CODE);
+ new = g_binary_portion_new(BPC_CODE, &addr, method->body.insns_size * sizeof(uint16_t));
- asprintf(&desc, _("Dalvik code"));
-
- g_binary_portion_set_desc(new, desc);
-
- free(desc);
-
- g_binary_portion_set_values(new, &addr, method->body.insns_size * sizeof(uint16_t));
+ g_binary_portion_set_desc(new, _("Dalvik code"));
g_binary_portion_set_rights(new, PAC_READ | PAC_EXEC);
- g_portion_layer_include(layer, new);
+ g_exe_format_include_portion(format, new);
}
diff --git a/src/format/dex/method.h b/src/format/dex/method.h
index 41ddb4c..8836abb 100644
--- a/src/format/dex/method.h
+++ b/src/format/dex/method.h
@@ -82,7 +82,7 @@ const code_item *g_dex_method_get_dex_body(const GDexMethod *);
GBinRoutine *g_dex_method_get_routine(const GDexMethod *);
/* Intègre la méthode en tant que portion de code. */
-void g_dex_method_include_as_portion(const GDexMethod *, const GDexFormat *, GPortionLayer *);
+void g_dex_method_include_as_portion(const GDexMethod *, GExeFormat *);
/* Indique la position de la méthode au sein du binaire. */
bool g_dex_method_get_offset(const GDexMethod *method, phys_t *);
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 2dd41e1..a51fe33 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -69,7 +69,7 @@ static SourceEndian g_elf_format_get_endianness(const GElfFormat *);
static const char *g_elf_format_get_target_machine(const GElfFormat *);
/* Etend la définition des portions au sein d'un binaire. */
-static void g_elf_format_refine_portions(const GElfFormat *, GPortionLayer *);
+static void g_elf_format_refine_portions(GElfFormat *);
/* Fournit l'emplacement correspondant à une position physique. */
static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *, phys_t, vmpa2t *);
@@ -244,10 +244,12 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus
{
GElfFormat *result; /* Structure à retourner */
GBinFormat *base; /* Version basique du format */
+ GExeFormat *exe_format; /* Autre version du format */
result = g_object_new(G_TYPE_ELF_FORMAT, NULL);
base = G_BIN_FORMAT(result);
+ exe_format = G_EXE_FORMAT(result);
g_binary_format_set_content(base, content);
@@ -305,7 +307,7 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus
}
- if (!g_binary_format_complete_loading(base, status))
+ if (!g_executable_format_complete_loading(exe_format, status))
goto gefn_error;
return base;
@@ -383,7 +385,6 @@ static const char *g_elf_format_get_target_machine(const GElfFormat *format)
/******************************************************************************
* *
* Paramètres : format = informations chargées à consulter. *
-* main = couche de portions principale à raffiner. *
* *
* Description : Etend la définition des portions au sein d'un binaire. *
* *
@@ -393,14 +394,13 @@ static const char *g_elf_format_get_target_machine(const GElfFormat *format)
* *
******************************************************************************/
-static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer *main)
+static void g_elf_format_refine_portions(GElfFormat *format)
{
- GPortionLayer *layer; /* Couche à mettre en place */
+ GExeFormat *exe_format; /* Autre version du format */
uint16_t max; /* Décompte d'éléments traités */
- elf_phdr *sorted_phdrs; /* Liste de segments triée */
uint16_t i; /* Boucle de parcours */
off_t offset; /* Début de part de programme */
- elf_phdr *phdr; /* En-tête de programme ELF */
+ elf_phdr phdr; /* En-tête de programme ELF */
uint32_t p_flags; /* Droits associés à une partie*/
const char *background; /* Fond signigicatif */
GBinPortion *new; /* Nouvelle portion définie */
@@ -409,11 +409,12 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer
PortionAccessRights rights; /* Droits d'une portion */
elf_shdr strings; /* Section des descriptions */
bool has_strings; /* Section trouvée ? */
- elf_shdr *sorted_shdrs; /* Liste de sections triée */
- elf_shdr *section; /* En-tête de section ELF */
+ elf_shdr shdr; /* En-tête de section ELF */
uint64_t sh_flags; /* Droits associés à une partie*/
const char *name; /* Nom trouvé ou NULL */
+ exe_format = G_EXE_FORMAT(format);
+
/**
* La copie des différents en-têtes cherche à reproduire l'inclusion native
* du format :
@@ -429,83 +430,35 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer
* Côté segments basiques.
*/
- layer = g_portion_layer_new(NO_LENGTH_YET, _("Segment"));
-
- g_portion_layer_attach_sub(main, layer);
-
- /* Constitution d'une liste de travail */
-
max = ELF_HDR(format, format->header, e_phnum);
- sorted_phdrs = (elf_phdr *)calloc(max, sizeof(elf_phdr));
-
for (i = 0; i < max; i++)
{
offset = ELF_HDR(format, format->header, e_phoff)
+ ELF_HDR(format, format->header, e_phentsize) * i;
- if (!read_elf_program_header(format, offset, &sorted_phdrs[i]))
- {
- if (format->is_32b)
- sorted_phdrs[i].phdr32.p_type = PT_NULL;
- else
- sorted_phdrs[i].phdr64.p_type = PT_NULL;
- }
-
- }
-
- /* Tri de cette liste */
-
- int sort_phdr(elf_phdr *a, elf_phdr *b)
- {
- uint64_t filesz_a; /* Taille de l'en-tête 'a' */
- uint64_t filesz_b; /* Taille de l'en-tête 'b' */
- int status; /* Bilan d'une comparaison */
-
- filesz_a = ELF_PHDR(format, *a, p_filesz);
- filesz_b = ELF_PHDR(format, *b, p_filesz);
-
- if (filesz_a < filesz_b)
- status = 1;
-
- else if (filesz_a > filesz_b)
- status = -1;
-
- else
- status = 0;
-
- return status;
-
- }
-
- qsort(sorted_phdrs, max, sizeof(elf_phdr), (__compar_fn_t)sort_phdr);
-
- /* Inclusion de ces en-têtes */
-
- for (i = 0; i < max; i++)
- {
- phdr = &sorted_phdrs[i];
+ if (!read_elf_program_header(format, offset, &phdr))
+ continue;
- if (ELF_PHDR(format, *phdr, p_type) == PT_NULL)
+ if (ELF_PHDR(format, phdr, p_type) == PT_NULL)
continue;
- p_flags = ELF_PHDR(format, *phdr, p_flags);
+ p_flags = ELF_PHDR(format, phdr, p_flags);
if (p_flags & PF_X) background = BPC_CODE;
else if (p_flags & PF_W) background = BPC_DATA;
else background = BPC_DATA_RO;
- new = g_binary_portion_new(background);
+ init_vmpa(&addr, ELF_PHDR(format, phdr, p_offset), ELF_PHDR(format, phdr, p_vaddr));
+
+ new = g_binary_portion_new(background, &addr, ELF_PHDR(format, phdr, p_filesz));
snprintf(desc, MAX_PORTION_DESC, "%s \"%s\"",
_("Segment"),
- get_elf_program_type_desc(ELF_PHDR(format, *phdr, p_type)));
+ get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type)));
g_binary_portion_set_desc(new, desc);
- init_vmpa(&addr, ELF_PHDR(format, *phdr, p_offset), ELF_PHDR(format, *phdr, p_vaddr));
- g_binary_portion_set_values(new, &addr, ELF_PHDR(format, *phdr, p_filesz));
-
rights = PAC_NONE;
if (p_flags & PF_R) rights |= PAC_READ;
if (p_flags & PF_W) rights |= PAC_WRITE;
@@ -513,12 +466,10 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer
g_binary_portion_set_rights(new, rights);
- g_portion_layer_include(layer, new);
+ g_exe_format_include_portion(exe_format, new);
}
- free(sorted_phdrs);
-
/**
* Inclusion des sections, si possible...
*/
@@ -527,64 +478,17 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer
ELF_HDR(format, format->header, e_shstrndx),
&strings);
- layer = g_portion_layer_new(NO_LENGTH_YET, _("Section"));
-
- g_portion_layer_attach_sub(main, layer);
-
- /* Constitution d'une liste de travail */
-
max = ELF_HDR(format, format->header, e_shnum);
- sorted_shdrs = (elf_shdr *)calloc(max, sizeof(elf_shdr));
-
- for (i = 0; i < max; i++)
- {
- if (!find_elf_section_by_index(format, i, &sorted_shdrs[i]))
- {
- if (format->is_32b)
- sorted_shdrs[i].shdr32.sh_offset = 0;
- else
- sorted_shdrs[i].shdr64.sh_offset = 0;
- }
-
- }
-
- /* Tri de cette liste */
-
- int sort_shdr(elf_shdr *a, elf_shdr *b)
- {
- uint64_t size_a; /* Taille de l'en-tête 'a' */
- uint64_t size_b; /* Taille de l'en-tête 'b' */
- int status; /* Bilan d'une comparaison */
-
- size_a = ELF_SHDR(format, *a, sh_size);
- size_b = ELF_SHDR(format, *b, sh_size);
-
- if (size_a < size_b)
- status = 1;
-
- else if (size_a > size_b)
- status = -1;
-
- else
- status = 0;
-
- return status;
-
- }
-
- qsort(sorted_shdrs, max, sizeof(elf_shdr), (__compar_fn_t)sort_shdr);
-
- /* Inclusion de ces en-têtes */
-
for (i = 0; i < max; i++)
{
- section = &sorted_shdrs[i];
+ if (!find_elf_section_by_index(format, i, &shdr))
+ continue;
- if (ELF_SHDR(format, *section, sh_offset) == 0)
+ if (ELF_SHDR(format, shdr, sh_offset) == 0)
continue;
- sh_flags = ELF_SHDR(format, *section, sh_flags);
+ sh_flags = ELF_SHDR(format, shdr, sh_flags);
if ((sh_flags & SHF_ALLOC) == 0)
continue;
@@ -593,11 +497,13 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer
else if (sh_flags & SHF_WRITE) background = BPC_DATA;
else background = BPC_DATA_RO;
- new = g_binary_portion_new(background);
+ init_vmpa(&addr, ELF_SHDR(format, shdr, sh_offset), ELF_SHDR(format, shdr, sh_addr));
+
+ new = g_binary_portion_new(background, &addr, ELF_SHDR(format, shdr, sh_size));
if (has_strings)
name = extract_name_from_elf_string_section(format, &strings,
- ELF_SHDR(format, *section, sh_name));
+ ELF_SHDR(format, shdr, sh_name));
else name = NULL;
if (name != NULL)
@@ -607,9 +513,6 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer
g_binary_portion_set_desc(new, desc);
- init_vmpa(&addr, ELF_SHDR(format, *section, sh_offset), ELF_SHDR(format, *section, sh_addr));
- g_binary_portion_set_values(new, &addr, ELF_SHDR(format, *section, sh_size));
-
rights = PAC_NONE;
if (sh_flags & SHF_ALLOC) rights |= PAC_READ;
if (sh_flags & SHF_WRITE) rights |= PAC_WRITE;
@@ -617,12 +520,10 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer
g_binary_portion_set_rights(new, rights);
- g_portion_layer_include(layer, new);
+ g_exe_format_include_portion(exe_format, new);
}
- free(sorted_shdrs);
-
}
diff --git a/src/format/executable-int.h b/src/format/executable-int.h
index a4d4b35..88527a5 100644
--- a/src/format/executable-int.h
+++ b/src/format/executable-int.h
@@ -36,7 +36,7 @@
typedef const char * (* get_target_machine_fc) (const GExeFormat *);
/* Etend la définition des portions au sein d'un binaire. */
-typedef void (* refine_portions_fc) (const GExeFormat *, GPortionLayer *);
+typedef void (* refine_portions_fc) (GExeFormat *);
/* Fournit l'emplacement correspondant à une position physique. */
typedef bool (* translate_phys_fc) (const GExeFormat *, phys_t, vmpa2t *);
@@ -57,7 +57,8 @@ struct _GExeFormat
GDbgFormat **debugs; /* Informations de débogage */
size_t debugs_count; /* Nombre de ces informations */
- GPortionLayer *layers; /* Couches de morceaux binaires*/
+ GBinPortion *portions; /* Couches de morceaux binaires*/
+ GMutex mutex; /* Accès à l'arborescence */
};
@@ -77,6 +78,9 @@ struct _GExeFormatClass
};
+/* Effectue les ultimes opérations de chargement d'un binaire. */
+bool g_executable_format_complete_loading(GExeFormat *, GtkStatusStack *);
+
/* Fournit l'emplacement correspondant à une position physique. */
bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExeFormat *, phys_t, vmpa2t *);
diff --git a/src/format/executable.c b/src/format/executable.c
index c1ff940..3e902cf 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -24,6 +24,7 @@
#include "executable.h"
+#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
@@ -39,6 +40,12 @@ static void g_executable_format_class_init(GExeFormatClass *);
/* Initialise une instance de format d'exécutable générique. */
static void g_executable_format_init(GExeFormat *);
+/* Supprime toutes les références externes. */
+static void g_executable_format_dispose(GExeFormat *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_executable_format_finalize(GExeFormat *);
+
/* Indique le type défini pour un format d'exécutable générique. */
@@ -59,6 +66,12 @@ G_DEFINE_TYPE(GExeFormat, g_executable_format, G_TYPE_BIN_FORMAT);
static void g_executable_format_class_init(GExeFormatClass *klass)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_executable_format_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_executable_format_finalize;
}
@@ -77,11 +90,57 @@ static void g_executable_format_class_init(GExeFormatClass *klass)
static void g_executable_format_init(GExeFormat *format)
{
+ g_mutex_init(&format->mutex);
}
+/******************************************************************************
+* *
+* Paramètres : format = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_executable_format_dispose(GExeFormat *format)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < format->debugs_count; i++)
+ g_object_unref(G_OBJECT(format->debugs[i]));
+
+ if (format->portions != NULL)
+ g_object_unref(G_OBJECT(format->portions));
+
+ g_mutex_clear(&format->mutex);
+ G_OBJECT_CLASS(g_executable_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_executable_format_finalize(GExeFormat *format)
+{
+ G_OBJECT_CLASS(g_executable_format_parent_class)->finalize(G_OBJECT(format));
+
+}
/******************************************************************************
@@ -184,109 +243,95 @@ const char *g_exe_format_get_target_machine(const GExeFormat *format)
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à consulter. *
+* Paramètres : format = instance à traiter. *
+* status = barre de statut à tenir informée. *
* *
-* Description : Fournit la première couche des portions composent le binaire.*
+* Description : Effectue les ultimes opérations de chargement d'un binaire. *
* *
-* Retour : Couche brute des différentes portions. *
+* Retour : Bilan de l'opération. *
* *
-* Remarques : Le compteur de références de l'instance renvoyée doit être *
-* décrémenté après usage. *
+* Remarques : - *
* *
******************************************************************************/
-GPortionLayer *g_exe_format_get_main_layer(GExeFormat *format)
+bool g_executable_format_complete_loading(GExeFormat *format, GtkStatusStack *status)
{
- GBinPortion *portion; /* Portion brute globale */
+ bool result; /* Bilan à faire remonter */
+ GBinFormat *base; /* Version basique du format */
vmpa2t addr; /* Emplacement vide de sens */
phys_t length; /* Taille de portion globale */
- GPortionLayer *layer; /* Couche à mettre en place */
-
- if (format->layers == NULL)
- {
- /* Création d'une portion globale */
-
- portion = g_binary_portion_new(BPC_RAW);
- init_vmpa(&addr, 0, VMPA_NO_VIRTUAL);
- length = g_binary_content_compute_size(G_BIN_FORMAT(format)->content);
+ base = G_BIN_FORMAT(format);
- g_binary_portion_set_values(portion, &addr, length);
+ result = g_binary_format_complete_loading(base, status);
- /* Création d'une couche de base brute */
-
- layer = g_portion_layer_new(length, NULL);
-
- g_portion_layer_include(layer, portion);
+ if (result)
+ {
+ result = g_exe_format_translate_offset_into_vmpa(format, 0, &addr);
+ assert(result);
- /* Remplissage */
+ length = g_binary_content_compute_size(base->content);
- G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format, layer);
+ format->portions = g_binary_portion_new(BPC_RAW, &addr, length);
- format->layers = layer;
+ G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format);
}
- g_object_ref(G_OBJECT(format->layers));
-
- return format->layers;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : format = informations chargées à consulter. *
-* count = quantité de zones listées. [OUT] *
+* Paramètres : format = description de l'exécutable à modifier. *
+* portion = portion à inclure dans les définitions du format. *
* *
-* Description : Fournit les espaces mémoires des portions exécutables. *
+* Description : Procède à l'enregistrement d'une portion dans un format. *
* *
-* Retour : Liste de zones binaires exécutables à libérer après usage. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count)
+void g_exe_format_include_portion(GExeFormat *format, GBinPortion *portion)
{
- mrange_t *result; /* Liste à retourner */
-
- typedef struct _x_ranges
- {
- mrange_t *list;
- size_t length;
+ g_mutex_lock(&format->mutex);
- } x_ranges;
+ g_binary_portion_include(format->portions, portion);
- x_ranges tmp; /* Sauvegarde de la liste */
- GPortionLayer *layer; /* Couche première de portions */
+ g_mutex_unlock(&format->mutex);
- bool visit_for_x(GBinPortion *portion, x_ranges *ranges)
- {
- const mrange_t *range;
-
- if (g_binary_portion_get_rights(portion) & PAC_EXEC)
- {
- range = g_binary_portion_get_range(portion);
+}
- ranges->list = (mrange_t *)realloc(ranges->list, ++ranges->length * sizeof(mrange_t));
- copy_mrange(&ranges->list[ranges->length - 1], range);
- }
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* *
+* Description : Fournit la première couche des portions composent le binaire.*
+* *
+* Retour : Arborescence des différentes portions binaires. *
+* *
+* Remarques : Le compteur de références de l'instance renvoyée doit être *
+* décrémenté après usage. *
+* *
+******************************************************************************/
- return true;
+GBinPortion *g_exe_format_get_portions(GExeFormat *format)
+{
+ GBinPortion *result; /* Instance à retourner */
- }
+ g_mutex_lock(&format->mutex);
- tmp.list = NULL;
- tmp.length = 0;
+ result = format->portions;
- layer = g_exe_format_get_main_layer(format);
- g_portion_layer_visit(format->layers, (visit_portion_fc)visit_for_x, &tmp);
- g_object_unref(G_OBJECT(layer));
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
- result = tmp.list;
- *count = tmp.length;
+ g_mutex_unlock(&format->mutex);
return result;
diff --git a/src/format/executable.h b/src/format/executable.h
index ad89948..6384851 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -52,7 +52,6 @@ typedef struct _GExeFormatClass GExeFormatClass;
/* Indique le type défini pour un format d'exécutable générique. */
GType g_executable_format_get_type(void);
-
/* Rajoute des informations de débogage à un exécutable. */
void g_exe_format_add_debug_info(GExeFormat *, GDbgFormat *);
@@ -65,8 +64,11 @@ GDbgFormat *g_exe_format_get_debug_info(const GExeFormat *, size_t);
/* Indique le type d'architecture visée par le format. */
const char *g_exe_format_get_target_machine(const GExeFormat *);
+/* Procède à l'enregistrement d'une portion dans un format. */
+void g_exe_format_include_portion(GExeFormat *, GBinPortion *);
+
/* Fournit la première couche des portions composent le binaire. */
-GPortionLayer *g_exe_format_get_main_layer(GExeFormat *);
+GBinPortion *g_exe_format_get_portions(GExeFormat *);
/* Fournit les espaces mémoires des portions exécutables. */
mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count);
diff --git a/src/format/format.c b/src/format/format.c
index bf4a0e1..516f882 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -137,7 +137,6 @@ bool g_binary_format_complete_loading(GBinFormat *format, GtkStatusStack *status
* *
* Paramètres : format = description de l'exécutable à consulter. *
* content = contenu binaire à parcourir. *
-* length = taille du contenu fourni. *
* *
* Description : Définit le contenu binaire à analyser. *
* *
diff --git a/src/format/symbol.c b/src/format/symbol.c
index 48f3dbb..97ff114 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -226,6 +226,37 @@ int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b)
/******************************************************************************
* *
+* Paramètres : symbol = symbole à analyser. *
+* addr = localisation à venir comparer à celle du symbole. *
+* *
+* Description : Compare un symbole et une localisation. *
+* *
+* Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int g_binary_symbol_cmp_with_vmpa(const GBinSymbol *symbol, const vmpa2t *addr)
+{
+ int result; /* Bilan à retourner */
+ const mrange_t *range; /* Emplacement du symbole */
+
+ range = g_binary_symbol_get_range(symbol);
+
+ if (range == NULL)
+ result = 1;
+
+ else
+ result = cmp_mrange_with_vmpa(range, addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : symbol = symbole à venir consulter. *
* *
* Description : Fournit le type du symbole. *
diff --git a/src/format/symbol.h b/src/format/symbol.h
index 8432d8d..78741cb 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -80,6 +80,9 @@ GBinSymbol *g_binary_symbol_new(SymbolType);
/* Compare deux symboles d'exécutable selon leurs propriétés. */
int g_binary_symbol_cmp(const GBinSymbol **, const GBinSymbol **);
+/* Compare un symbole et une localisation. */
+int g_binary_symbol_cmp_with_vmpa(const GBinSymbol *, const vmpa2t *);
+
/* Fournit le type du symbole. */
SymbolType g_binary_symbol_get_target_type(const GBinSymbol *);