summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/disass/fetch.c547
-rw-r--r--src/arch/instruction.c20
-rw-r--r--src/arch/instruction.h3
-rw-r--r--src/format/elf/symbols.c2
-rw-r--r--src/format/executable.c59
-rw-r--r--src/format/executable.h5
-rw-r--r--src/glibext/gbinportion.c55
-rw-r--r--src/glibext/gbinportion.h12
8 files changed, 441 insertions, 262 deletions
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index eee2eb6..f10178a 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -24,18 +24,33 @@
#include "fetch.h"
-#include "../../arch/artificial.h"
+#include <assert.h>
+#include "../../arch/raw.h"
+#include "../../arch/instruction.h"
-#include "../../arch/raw.h"
-#include "../../arch/instruction-int.h"
+/* Zone mémoire bien bornée */
+typedef struct _mem_area
+{
+ mrange_t range; /* Couverture de la zone */
+ bool has_sym; /* Représentation via symbole ?*/
+
+ union
+ {
+ bool exec; /* Zone exécutable ? */
+ GBinSymbol *symbol; /* Symbole associé à la zone */
+ };
+} mem_area;
+/* Détermine une liste de zones contigües à traiter. */
+static mem_area *compute_memory_areas(const GExeFormat *, phys_t, size_t *);
+
/* Procède au désassemblage basique d'un contenu binaire. */
static GArchInstruction *load_raw_binary(const GLoadedBinary *, const vmpa2t *, off_t, GtkExtStatusBar *, bstatus_id_t);
@@ -44,6 +59,241 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *, const vmpa2t *,
+/******************************************************************************
+* *
+* Paramètres : format = format d'un exécutable à consulter. *
+* bin_length = quantité d'octets à traiter au total. *
+* count = nombre de zones mises en place. [OUT] *
+* *
+* Description : Détermine une liste de zones contigües à traiter. *
+* *
+* Retour : Liste de zones mémoire à libérer après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static mem_area *compute_memory_areas(const GExeFormat *format, phys_t bin_length, size_t *count)
+{
+ mem_area *result; /* Liste à renvoyer */
+ mrange_t *exe_ranges; /* Liste de zones exécutables */
+ size_t exe_count; /* Nombre de ces zones */
+ GBinSymbol **symbols; /* Symboles à représenter */
+ size_t sym_count; /* Qté de symboles présents */
+ vmpa2t *last; /* Dernière bordure rencontrée */
+ size_t i; /* Boucle de parcours #1 */
+ vmpa2t *border; /* Nouvelle bordure rencontrée */
+ mem_area *area; /* Zone avec valeurs à éditer */
+ vmpa2t tmp; /* Stockage temporaire */
+ size_t j; /* Boucle de parcours #2 */
+ const mrange_t *range; /* Couverture d'un symbole */
+ const vmpa2t *start; /* Point de départ du symbole */
+ phys_t length; /* Taille de ce même symbole */
+ bool included; /* Inclusion dans une zone ? */
+ mem_area orig; /* Copie de la zone réduite */
+ phys_t old_length; /* Taille de zone originelle */
+ phys_t new_length; /* Nouvelle taille déterminée */
+ size_t next; /* Indice de zone suivante */
+
+ result = NULL;
+ *count = 0;
+
+ /**
+ * Le parcours n'est valide que si les listes, symboles et zones exécutables,
+ * sont triées !
+ */
+
+ exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
+
+ symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
+
+ /* Première étape : on comble les trous ! */
+
+ last = make_vmpa(0, VMPA_NO_VIRTUAL);
+
+ for (i = 0; i < exe_count; i++)
+ {
+ border = get_mrange_addr(&exe_ranges[i]);
+
+ /* Zone tampon à constituer */
+
+ if (cmp_vmpa_by_phy(last, border) < 0)
+ {
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
+
+ area = &result[*count - 1];
+
+ init_mrange(&area->range, last, compute_vmpa_diff(last, border));
+ area->has_sym = false;
+ area->exec = false;
+
+ }
+
+ /* Insertion d'une zone exécutable déjà définie */
+
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
+
+ area = &result[*count - 1];
+
+ copy_mrange(&area->range, &exe_ranges[i]);
+ area->has_sym = false;
+ area->exec = true;
+
+ /* Avancée du curseur */
+
+ copy_vmpa(last, border);
+
+ advance_vmpa(last, get_mrange_length(&exe_ranges[i]));
+
+ }
+
+ delete_vmpa(last);
+
+ /* Extension finale complémentaire ? */
+
+ area = &result[*count - 1];
+
+ copy_vmpa(&tmp, get_mrange_addr(&area->range));
+ advance_vmpa(&tmp, get_mrange_length(&area->range));
+
+ if (get_phy_addr(&tmp) < bin_length)
+ {
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
+
+ area = &result[*count - 1];
+
+ init_mrange(&area->range, &tmp, bin_length - get_phy_addr(&tmp));
+ area->has_sym = false;
+ area->exec = false;
+
+ }
+
+ /* Seconde étape : on insère les symboles existants */
+
+ j = 0;
+
+#define SKIP_EMPTY_SYMBOLS \
+ for (; j < sym_count; j++) \
+ { \
+ range = g_binary_symbol_get_range(symbols[j]); \
+ \
+ length = get_mrange_length(range); \
+ if (length > 0) break; \
+ \
+ } \
+
+ SKIP_EMPTY_SYMBOLS
+
+ for (i = 0; i < *count && j < sym_count; i++)
+ {
+ range = g_binary_symbol_get_range(symbols[j]);
+
+ start = get_mrange_addr(range);
+ length = get_mrange_length(range);
+
+ /* Si un découpage s'impose... */
+
+ if (mrange_contains_addr(&result[i].range, start))
+ {
+ copy_vmpa(&tmp, start);
+ advance_vmpa(&tmp, length);
+
+ included = mrange_contains_addr(&result[i].range, &tmp);
+
+ memcpy(&orig, &result[i], sizeof(mem_area));
+
+ /* Réduction de la zone de départ */
+
+ copy_vmpa(&tmp, get_mrange_addr(&result[i].range));
+ old_length = get_mrange_length(&result[i].range);
+
+ new_length = compute_vmpa_diff(get_mrange_addr(&result[i].range), start);
+
+ if (new_length == 0)
+ {
+ memmove(&result[i], &result[i + 1], (*count - i - 1) * sizeof(mem_area));
+
+ (*count)--;
+ next = i;
+
+ }
+ else
+ {
+ init_mrange(&result[i].range, &tmp, new_length);
+ next = i + 1;
+ }
+
+ /* Insertion de la zone du symbole */
+
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
+
+ memmove(&result[next + 1], &result[next], (*count - next - 1) * sizeof(mem_area));
+
+ area = &result[next];
+
+ copy_mrange(&area->range, range);
+
+ area->has_sym = true;
+ area->symbol = symbols[j];
+
+ /* Jointure finale... */
+
+ if (included)
+ {
+ /* Simple extension pour rattraper la fin originelle */
+
+ if ((old_length - new_length - length) > 0)
+ {
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
+
+ memmove(&result[next + 2], &result[next + 1], (*count - next - 2) * sizeof(mem_area));
+
+ area = &result[next + 1];
+
+ copy_vmpa(&tmp, start);
+ advance_vmpa(&tmp, length);
+
+ memcpy(area, &orig, sizeof(mem_area));
+
+ init_mrange(&area->range, &tmp, old_length - new_length - length);
+
+ }
+
+ i = next;
+
+ }
+ else
+ {
+ /* Suppression des éventuelles zones totalement recouvertes */
+
+
+
+ /* Réduction de la zone d'arrivée */
+
+
+ }
+
+
+
+
+
+ j++;
+
+ SKIP_EMPTY_SYMBOLS
+
+ }
+
+ }
+
+
+
+ //free
+
+ //exit(0);
+
+ return result;
+
+}
/******************************************************************************
@@ -159,7 +409,7 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp
{
instr = g_arch_processor_disassemble(proc, NULL, bin_data, &pos, end);
- if (!G_IS_RAW_INSTRUCTION(instr)) printf("GOT %p\n", instr);
+ //if (!G_IS_RAW_INSTRUCTION(instr)) printf("GOT %p\n", instr);
if (instr == NULL)
instr = g_raw_instruction_new_array(bin_data, MDS_32_BITS, 1, &pos, end,
@@ -187,12 +437,6 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp
}
-
-
-
-
-
-
/******************************************************************************
* *
* Paramètres : binary = représentation de binaire chargé. *
@@ -209,277 +453,66 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp
GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExtStatusBar *statusbar, bstatus_id_t id)
{
-
GArchInstruction *result; /* Instruction désassemblées */
-
-
- GBinFormat *format; /* Format du fichier binaire */
-
-
-
- vmpa2t *last; /* Dernière bordure rencontrée */
-
-
-
- GBinSymbol **symbols; /* Symboles à représenter */
- size_t sym_count; /* Qté de symboles présents */
-
-
+ GExeFormat *format; /* Format du fichier binaire */
+ off_t length; /* Taille des données à lire */
+ mem_area *areas; /* Zone de productions */
+ size_t count; /* Nombre de ces zones */
size_t i; /* Boucle de parcours */
-
-
- const mrange_t *range; /* Couverture d'un symbole */
- const vmpa2t *border; /* Nouvelle bordure rencontrée */
- off_t length; /* Taille d'une partie traitée */
-
-
- GArchInstruction *instr; /* Instruction à insérer */
-
-
-
- GArchInstruction *joint; /* Jointure entre deux lots */
-
-
-
- off_t max_length; /* Taille des données à lire */
-
-
-
-
- result = NULL;
-
-
-
- format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
-
- last = make_vmpa(0, VMPA_NO_VIRTUAL);
-
- symbols = g_binary_format_get_symbols(format, &sym_count);
-
-
- //sym_count = 0;
-
-
- for (i = 0; i < sym_count; i++)
- {
-
-
-
-
- range = g_binary_symbol_get_range(symbols[i]);
-
- border = get_mrange_addr(range);
- length = get_mrange_length(range);
-
-
-
-
- switch (g_binary_symbol_get_target_type(symbols[i]))
- {
- case STP_DATA:
- instr = g_binary_symbol_get_instruction(symbols[i]);
- g_object_ref(G_OBJECT(instr));
- break;
-
- case STP_ROUTINE:
- instr = load_code_binary(binary, border,
- get_phy_addr(border) + length,
- statusbar, id);
- break;
-
- default:
- printf("BADDD !\n");
- exit(0);
- break;
-
- }
-
- /* Traiter la diff */
-
- if (0 && cmp_vmpa_by_phy(last, border) < 0)
- {
- joint = load_raw_binary(binary, last,
- get_phy_addr(last) + compute_vmpa_diff(border, last),
- statusbar, id);
-
- ainstr_list_merge(&result, &joint);
-
- }
-
- /* Ajout des instructions déjà établies */
-
- ainstr_list_merge(&result, &instr);
-
- /* Marquage de la nouvelle dernière bordure */
-
- copy_vmpa(last, border);
-
- advance_vmpa(last, length);
-
- }
-
- /* Raccord final ? */
-
- g_loaded_binary_get_data(binary, &max_length);
-
- if (get_phy_addr(last) < max_length)
- {
- joint = load_raw_binary(binary, last, max_length, statusbar, id);
- ainstr_list_merge(&result, &joint);
- }
-
-
-
-
- printf("COUNT :: %zu\n", sym_count);
-
- //exit(0);
-
-
- return result;
-
-
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#ifdef DEBUG
-# include "../../arch/artificial.h"
-#endif
-
-
-
-/******************************************************************************
-* *
-* Paramètres : binary = représentation de binaire chargé. *
-* parts = parties binaires à désassembler. *
-* count = nombre de parties à traiter. *
-* statusbar = barre de statut avec progression à mettre à jour.*
-* id = identifiant du message affiché à l'utilisateur. *
-* *
-* Description : Procède au désassemblage basique d'un contenu binaire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchInstruction *disassemble_binary_parts(const GLoadedBinary *binary, GBinPart **parts, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
-{
- GArchInstruction *result; /* Liste d'instr. à renvoyer */
- GBinFormat *format; /* Format du fichier binaire */
- GArchProcessor *proc; /* Architecture du binaire */
- off_t bin_length; /* Taille des données à lire */
- bin_t *bin_data; /* Données binaires à lire */
- size_t i; /* Boucle de parcours #1 */
- off_t sum; /* Somme de toutes les tailles */
- off_t done; /* Quantité déjà traitée */
-#ifdef DEBUG
- unsigned int valid; /* Instructions traduites */
- unsigned int db; /* Instructions non décodées */
-#endif
- off_t pos; /* Début d'une zone binaire */
- off_t len; /* Taille de cette même zone */
- vmpa_t base; /* Adresse de la zone binaire */
- off_t start; /* Conservation du pt de départ*/
- GProcContext *context; /* Contexte pour le décodage */
- vmpa_t addr; /* Adresse d'une instruction */
- GArchInstruction *instr; /* Instruction décodée */
+ mem_area *iter; /* Zone parcourue */
+ GArchInstruction *instr; /* Instruction(s) à insérer */
+ const vmpa2t *start; /* Début d'une zone traitée */
+ phys_t end; /* Fin d'une zone traitée */
result = NULL;
- format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
- proc = get_arch_processor_from_format(G_EXE_FORMAT(format));
- bin_data = g_loaded_binary_get_data(binary, &bin_length);
-
- /* Préparation du suivi de la progression */
+ format = g_loaded_binary_get_format(binary);
+ g_loaded_binary_get_data(binary, &length);
- sum = 0;
+ areas = compute_memory_areas(format, length, &count);
for (i = 0; i < count; i++)
{
- g_binary_part_get_values(parts[i], NULL, &len, NULL);
- if (len > bin_length) continue;
- sum += len;
- }
-
- done = 0;
+ iter = &areas[i];
- for (i = 0; i < count; i++)
- {
- g_binary_part_get_values(parts[i], &pos, &len, &base);
+ start = get_mrange_addr(&iter->range);
+ end = get_phy_addr(start) + get_mrange_length(&iter->range);
- if (len > bin_length) continue;
+ assert(get_mrange_length(&iter->range) > 0);
- context = g_arch_processor_get_context(proc);
+ if (iter->has_sym)
+ switch (g_binary_symbol_get_target_type(iter->symbol))
+ {
+ case STP_DATA:
+ instr = g_binary_symbol_get_instruction(iter->symbol);
+ g_object_ref(G_OBJECT(instr));
+ break;
- /* Décodage des instructions */
+ case STP_ROUTINE:
+ instr = load_code_binary(binary, start, end, statusbar, id);
+ break;
-#ifdef DEBUG
- valid = 0;
- db = 0;
-#endif
+ default:
+ assert(false);
+ break;
- start = pos;
- len += start;
+ }
- while (pos < len)
+ else
{
- addr = base + (pos - start);
-
- instr = g_arch_processor_decode_instruction(proc, context, bin_data,
- &pos, len, addr, format);
- g_arch_instruction_add_to_list(&result, instr);
-
-#ifdef DEBUG
- if (G_IS_DB_INSTRUCTION(instr) && !g_db_instruction_is_skipped(G_DB_INSTRUCTION(instr)))
- db++;
+ if (iter->exec)
+ instr = load_code_binary(binary, start, end, statusbar, id);
else
- valid++;
-#endif
-
- if (pos < len)
- gtk_extended_status_bar_update_activity(statusbar, id, (done + pos - start) * 1.0 / sum);
+ instr = load_raw_binary(binary, start, end, statusbar, id);
}
- if (context != NULL)
- g_object_unref(context);
-
-#ifdef DEBUG
- g_binary_part_set_checkup(parts[i], valid, db);
-#endif
-
- done += (len - start);
- gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / sum);
+ g_arch_instruction_merge_lists(&result, &instr);
}
+ free(areas);
+
return result;
}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 402b0f5..8312bf6 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -829,6 +829,26 @@ void g_arch_instruction_add_to_list(GArchInstruction **list, GArchInstruction *i
/******************************************************************************
* *
+* Paramètres : list1 = première liste à traiter. *
+* list2 = seconde liste à traiter. *
+* *
+* Description : Fusionne deux listes d'instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_instruction_merge_lists(GArchInstruction **list1, GArchInstruction **list2)
+{
+ ainstr_list_merge(list1, list2);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : list = liste d'instructions à consulter. *
* : iter = position actuelle dans la liste. *
* *
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 4fe0569..eadac8b 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -168,6 +168,9 @@ GArchInstruction *g_arch_instruction_find_last(const GArchInstruction *);
/* Ajoute une instruction à un ensemble existant. */
void g_arch_instruction_add_to_list(GArchInstruction **, GArchInstruction *);
+/* Fusionne deux listes d'instructions. */
+void g_arch_instruction_merge_lists(GArchInstruction **, GArchInstruction **);
+
/* Fournit l'élement suivant un autre pour un parcours. */
GArchInstruction *g_arch_instruction_get_prev_iter(const GArchInstruction *, const GArchInstruction *);
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index 84bf9b7..15c3a6b 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -1321,7 +1321,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL);
- init_mrange(&range, &addr, 4/*ELF_SYM(format, sym, st_size) FIXME !!! */);
+ init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
/* Première ébauche de nom */
diff --git a/src/format/executable.c b/src/format/executable.c
index 6b39ac8..ea1b398 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -28,6 +28,9 @@
#include "format.h"
+#include <malloc.h>
+
+
/* Initialise la classe des formats d'exécutables génériques. */
static void g_executable_format_class_init(GExeFormatClass *);
@@ -162,6 +165,62 @@ GBinPortion *g_exe_format_get_portions(GExeFormat *format)
* Paramètres : format = informations chargées à consulter. *
* count = quantité de zones listées. [OUT] *
* *
+* Description : Fournit les espaces mémoires des portions exécutables. *
+* *
+* Retour : Liste de zones binaires exécutables à libérer après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count)
+{
+ mrange_t *result; /* Liste à retourner */
+
+ typedef struct _x_ranges
+ {
+ mrange_t *list;
+ size_t length;
+
+ } x_ranges;
+
+ x_ranges tmp; /* Sauvegarde de la liste */
+
+ 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);
+
+ }
+
+ return true;
+
+ }
+
+ tmp.list = NULL;
+ tmp.length = 0;
+
+ g_binary_portion_visit(g_exe_format_get_portions(format), (visit_portion_fc)visit_for_x, &tmp);
+
+ result = tmp.list;
+ *count = tmp.length;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* count = quantité de zones listées. [OUT] *
+* *
* Description : Fournit les références aux zones binaires à analyser. *
* *
* Retour : Zones binaires à analyser. *
diff --git a/src/format/executable.h b/src/format/executable.h
index b43a9f5..10bff42 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -78,8 +78,11 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *);
/* Décrit les différentes portions qui composent le binaire. */
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);
+
/* Fournit les références aux zones binaires à analyser. */
-GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *);
+GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *) __attribute__ ((deprecated));
/* Fournit la position correspondant à une adresse virtuelle. */
bool g_exe_format_translate_address_into_offset(const GExeFormat *, vmpa_t, off_t *);
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index 76926ca..94a04cc 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -50,6 +50,7 @@ struct _GBinPortion
char *desc; /* Désignation humaine */
+ mrange_t range; /* Emplacement dans le code */
vmpa2t addr; /* Emplacement dans le code */
off_t size; /* Taille de la partie */
@@ -265,7 +266,7 @@ const char *g_binary_portion_get_desc(const GBinPortion *portion)
* addr = emplacement de la section à conserver. *
* size = taille de la section à conserver. *
* *
-* Description : Définit les valeurs utiles d'une partie de code. *
+* Description : Définit les valeurs utiles d'une partie de code binaire. *
* *
* Retour : - *
* *
@@ -273,11 +274,32 @@ const char *g_binary_portion_get_desc(const GBinPortion *portion)
* *
******************************************************************************/
-void g_binary_portion_set_values(GBinPortion *portion, const vmpa2t *addr, off_t size)
+void g_binary_portion_set_values(GBinPortion *portion, const vmpa2t *addr, phys_t size)
{
copy_vmpa(&portion->addr, addr);
portion->size = size;
+ init_mrange(&portion->range, addr, size);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* *
+* Description : Fournit l'emplacement d'une partie de code binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const mrange_t *g_binary_portion_get_range(const GBinPortion *portion)
+{
+ return &portion->range;
+
}
@@ -376,6 +398,35 @@ static bool g_binary_portion_compute_sub_area(GBinPortion *portion, GBinPortion
/******************************************************************************
* *
+* Paramètres : portion = première portion amorçant la visite. *
+* visitor = fonction à appeler à chaque étape de la descente. *
+* data = adresse pointant vers des données de l'utilisateur.*
+* *
+* Description : Parcours un ensemble de portions binaires. *
+* *
+* Retour : true si la visite a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void *data)
+{
+ bool result; /* Etat à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = visitor(portion, data);
+
+ for (i = 0; i < portion->sub_count && result; i++)
+ result = g_binary_portion_visit(portion->sub_portions[i], visitor, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : portion = description de partie à mettre à jour. *
* x = abscisse du point de recherche. *
* y = ordonnée du point de recherche. *
diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h
index fb32496..ac6b4fd 100644
--- a/src/glibext/gbinportion.h
+++ b/src/glibext/gbinportion.h
@@ -72,6 +72,10 @@ typedef enum _PortionAccessRights
} PortionAccessRights;
+/* Fonction appelée à chaque visite de portion.*/
+typedef bool (* visit_portion_fc) (GBinPortion *, void *);
+
+
/* Indique le type défini par la GLib pour les blocs de données. */
GType g_binary_portion_get_type(void);
@@ -85,7 +89,10 @@ void g_binary_portion_set_desc(GBinPortion *, const char *);
const char *g_binary_portion_get_desc(const GBinPortion *);
/* Définit les valeurs utiles d'une partie de code. */
-void g_binary_portion_set_values(GBinPortion *, const vmpa2t *, off_t);
+void g_binary_portion_set_values(GBinPortion *, const vmpa2t *, phys_t);
+
+/* Fournit l'emplacement d'une partie de code binaire. */
+const mrange_t *g_binary_portion_get_range(const GBinPortion *);
/* Définit les droits associés à une partie de code. */
void g_binary_portion_set_rights(GBinPortion *, PortionAccessRights);
@@ -96,6 +103,9 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *);
/* Procède à l'inclusion d'une portion dans une autre. */
void g_binary_portion_include(GBinPortion *, GBinPortion *);
+/* Parcours un ensemble de portions binaires. */
+bool g_binary_portion_visit(GBinPortion *, visit_portion_fc, void *);
+
/* Recherche la portion présente à un point donné. */
GBinPortion *g_binary_portion_find_at_pos(GBinPortion *, gint, GdkRectangle *);