summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-12-28 23:27:12 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-12-28 23:27:12 (GMT)
commitb57e8ef5522dcbe126157fc2c50fcf879aa7d743 (patch)
tree1ecfd9de39073fee3a2c1a4afa9ce5da574b26df
parent276b75e6e9ff99a930bd36045e55b1117bb29579 (diff)
Defined layers to register all kinds of binary portions.
-rw-r--r--ChangeLog24
-rw-r--r--plugins/mobicore/mclf.c17
-rw-r--r--src/analysis/disass/area.c28
-rw-r--r--src/analysis/disass/output.c26
-rw-r--r--src/format/dex/class.c8
-rw-r--r--src/format/dex/class.h2
-rwxr-xr-xsrc/format/dex/dex.c16
-rw-r--r--src/format/dex/method.c6
-rw-r--r--src/format/dex/method.h2
-rw-r--r--src/format/elf/elf.c24
-rw-r--r--src/format/executable-int.h4
-rw-r--r--src/format/executable.c89
-rw-r--r--src/format/executable.h8
-rw-r--r--src/glibext/gbinportion.c904
-rw-r--r--src/glibext/gbinportion.h81
-rw-r--r--src/gtkext/gtkbinarystrip.c39
-rw-r--r--src/gtkext/gtkstatusstack.c8
17 files changed, 825 insertions, 461 deletions
diff --git a/ChangeLog b/ChangeLog
index f1936bb..5d253fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+15-12-29 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/mobicore/mclf.c:
+ * src/analysis/disass/area.c:
+ * src/analysis/disass/output.c:
+ * src/format/dex/class.c:
+ * src/format/dex/class.h:
+ * src/format/dex/dex.c:
+ * src/format/dex/method.c:
+ * src/format/dex/method.h:
+ * src/format/elf/elf.c:
+ * src/format/executable-int.h:
+ * src/format/executable.c:
+ * src/format/executable.h:
+ Update code.
+
+ * src/glibext/gbinportion.c:
+ * src/glibext/gbinportion.h:
+ Clean code. Define layers to register all kinds of binary portions.
+
+ * src/gtkext/gtkbinarystrip.c:
+ * src/gtkext/gtkstatusstack.c:
+ Update code.
+
15-12-28 Cyrille Bagard <nocbos@gmail.com>
* src/arch/vmpa.c:
diff --git a/plugins/mobicore/mclf.c b/plugins/mobicore/mclf.c
index 7b1249c..8e99fc7 100644
--- a/plugins/mobicore/mclf.c
+++ b/plugins/mobicore/mclf.c
@@ -54,7 +54,7 @@ static void g_mclf_format_finalize(GMCLFFormat *);
static const char *g_mclf_format_get_target_machine(const GMCLFFormat *);
/* Etend la définition des portions au sein d'un binaire. */
-static void g_mclf_format_refine_portions(const GMCLFFormat *, GBinPortion *);
+static void g_mclf_format_refine_portions(const GMCLFFormat *, GPortionLayer *);
@@ -261,7 +261,7 @@ static const char *g_mclf_format_get_target_machine(const GMCLFFormat *format)
/******************************************************************************
* *
* Paramètres : format = informations chargées à consulter. *
-* raw = portion de binaire brut à raffiner. *
+* main = couche de portions principale à raffiner. *
* *
* Description : Etend la définition des portions au sein d'un binaire. *
* *
@@ -271,13 +271,18 @@ static const char *g_mclf_format_get_target_machine(const GMCLFFormat *format)
* *
******************************************************************************/
-static void g_mclf_format_refine_portions(const GMCLFFormat *format, GBinPortion *raw)
+static void g_mclf_format_refine_portions(const GMCLFFormat *format, GPortionLayer *main)
{
+ GPortionLayer *layer; /* Couche à mettre en place */
GBinPortion *new; /* Nouvelle portion définie */
char desc[MAX_PORTION_DESC]; /* Description d'une portion */
phys_t length; /* Taille de portion globale */
vmpa2t addr; /* Emplacement dans le binaire */
+ layer = g_portion_layer_new(NO_LENGTH_YET, _("Segment"));
+
+ g_portion_layer_attach_sub(main, layer);
+
/* Segment de code */
new = g_binary_portion_new(BPC_CODE);
@@ -290,7 +295,7 @@ static void g_mclf_format_refine_portions(const GMCLFFormat *format, GBinPortion
g_binary_portion_set_rights(new, PAC_WRITE | PAC_EXEC);
- g_binary_portion_include(raw, new);
+ g_portion_layer_include(layer, new);
/* Segment de données */
@@ -304,7 +309,7 @@ static void g_mclf_format_refine_portions(const GMCLFFormat *format, GBinPortion
g_binary_portion_set_rights(new, PAC_READ | PAC_WRITE);
- g_binary_portion_include(raw, new);
+ g_portion_layer_include(layer, new);
/* Signature finale */
@@ -319,6 +324,6 @@ static void g_mclf_format_refine_portions(const GMCLFFormat *format, GBinPortion
g_binary_portion_set_rights(new, PAC_READ | PAC_WRITE);
- g_binary_portion_include(raw, new);
+ g_portion_layer_include(layer, new);
}
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index d2a03c6..c79b293 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -707,9 +707,11 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
const vmpa2t *border; /* Nouvelle bordure rencontrée */
mem_area_v2 *area; /* Zone avec valeurs à éditer */
vmpa2t tmp; /* Stockage temporaire */
+ GPortionLayer *layer; /* Couche première de portions */
GBinPortion **portions; /* Morceaux d'encadrement */
size_t portions_count; /* Taille de cette liste */
const vmpa2t *portion_start; /* Point de départ de portion */
+ const vmpa2t *portion_next; /* Départ de portion suivante */
size_t j; /* Boucle de parcours #2 */
SymbolType type; /* Nature d'un symbole */
const mrange_t *range; /* Couverture d'un symbole */
@@ -813,7 +815,9 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
/* Seconde étape : on s'assure du découpage autour des portions pour respecter l'alignement */
- portions = g_exe_format_get_portions_at_level(format, -1, &portions_count);
+ layer = g_exe_format_get_main_layer(format);
+
+ portions = g_portion_layer_collect_all_portions(layer, &portions_count);
for (i = 1; i < portions_count; i++)
{
@@ -824,6 +828,20 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
(unsigned int)get_phy_addr(portion_start),
(unsigned int)get_virt_addr(portion_start));
+
+ /**
+ * Si plusieurs portions débutent au même endroit, il ne sert
+ * à rien de découper plusieurs fois.
+ */
+ if ((i + 1) < portions_count)
+ {
+ portion_next = get_mrange_addr(g_binary_portion_get_range(portions[i + 1]));
+
+ if (cmp_vmpa(portion_start, portion_next) == 0)
+ continue;
+
+ }
+
for (j = 0; j < *count; j++)
{
area = &result[j];
@@ -871,7 +889,10 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
}
+ if (portions != NULL)
+ free(portions);
+ g_object_unref(G_OBJECT(layer));
@@ -928,9 +949,6 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
/* Nettoyage final */
- if (portions != NULL)
- free(portions);
-
if (exe_ranges != NULL)
free(exe_ranges);
@@ -2193,7 +2211,7 @@ mem_area *compute_memory_areas(GExeFormat *format, phys_t bin_length, size_t *co
printf("--------------------\n");
- portions = g_exe_format_get_portions_at_level(format, -1, &portions_count);
+ portions = NULL;//g_exe_format_get_portions_at_level(format, -1, &portions_count);
for (i = 1; i < portions_count; i++)
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index 727c34f..67a3ce8 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -56,6 +56,14 @@
void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *format, GArchProcessor *proc, const GArchInstruction *instrs, GBinRoutine * const *routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
{
GLangOutput *output; /* Modèle de sortie adéquat */
+ GPortionLayer *layer; /* Couche première de portions */
+ GBinPortion **portions; /* Morceaux d'encadrement */
+ size_t portions_count; /* Taille de cette liste */
+ size_t portion_index; /* Prochaine portion à traiter */
+ GBinSymbol **symbols; /* Symboles à représenter */
+ size_t sym_count; /* Qté de symboles présents */
+ size_t sym_index; /* Prochain symbole non traité */
+
//GArchProcessor *proc; /* Architecture du binaire */
MemoryDataSize msize; /* Taille du bus d'adresses */
const GBinContent *content; /* Contenu binaire global */
@@ -74,13 +82,6 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
GBufferLine *line;
- GBinPortion **portions; /* Morceaux d'encadrement */
- size_t portions_count; /* Taille de cette liste */
- size_t portion_index; /* Prochaine portion à traiter */
-
- GBinSymbol **symbols; /* Symboles à représenter */
- size_t sym_count; /* Qté de symboles présents */
- size_t sym_index; /* Prochain symbole non traité */
const vmpa2t *paddr; /* Adresse de portion */
@@ -100,12 +101,12 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
output = g_asm_output_new();
+ layer = g_exe_format_get_main_layer(format);
-
- portions = g_exe_format_get_portions_at_level(format, -1, &portions_count);
+ portions = g_portion_layer_collect_all_portions(layer, &portions_count);
portion_index = 0;
- symbols = g_binary_format_get_symbols(format, &sym_count);
+ symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
sym_index = 0;
#if 0
@@ -294,7 +295,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
g_object_unref(G_OBJECT(content));
- /* free portions... */
+ if (portions != NULL)
+ free(portions);
+
+ g_object_unref(G_OBJECT(layer));
g_object_unref(G_OBJECT(output));
diff --git a/src/format/dex/class.c b/src/format/dex/class.c
index 657461f..1dc3a40 100644
--- a/src/format/dex/class.c
+++ b/src/format/dex/class.c
@@ -309,7 +309,7 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
/******************************************************************************
* *
* Paramètres : class = informations chargées à consulter. *
-* raw = portion de binaire brut à raffiner. *
+* layer = couche de portions à raffiner. *
* *
* Description : Intègre la méthode en tant que portion de code. *
* *
@@ -319,15 +319,15 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
* *
******************************************************************************/
-void g_dex_class_include_as_portion(const GDexClass *class, GBinPortion *raw)
+void g_dex_class_include_as_portion(const GDexClass *class, GPortionLayer *layer)
{
size_t i; /* Boucle de parcours */
for (i = 0; i < class->dmethods_count; i++)
- g_dex_method_include_as_portion(class->direct_methods[i], raw);
+ g_dex_method_include_as_portion(class->direct_methods[i], layer);
for (i = 0; i < class->vmethods_count; i++)
- g_dex_method_include_as_portion(class->virtual_methods[i], raw);
+ g_dex_method_include_as_portion(class->virtual_methods[i], layer);
}
diff --git a/src/format/dex/class.h b/src/format/dex/class.h
index 77fa6ba..fb7cada 100644
--- a/src/format/dex/class.h
+++ b/src/format/dex/class.h
@@ -64,7 +64,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 *, GBinPortion *);
+void g_dex_class_include_as_portion(const GDexClass *, GPortionLayer *);
/* 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 afd9db1..ed2565f 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -27,6 +27,9 @@
#include <string.h>
+#include <i18n.h>
+
+
#include "dex-int.h"
#include "pool.h"
@@ -55,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 *, GBinPortion *);
+static void g_dex_format_refine_portions(const GDexFormat *, GPortionLayer *);
/* Fournit l'emplacement d'une section donnée. */
static bool g_dex_format_get_section_range_by_name(const GDexFormat *, const char *, mrange_t *);
@@ -302,7 +305,7 @@ static const char *g_dex_format_get_target_machine(const GDexFormat *format)
/******************************************************************************
* *
* Paramètres : format = informations chargées à consulter. *
-* raw = portion de binaire brut à raffiner. *
+* main = couche de portions principale à raffiner. *
* *
* Description : Etend la définition des portions au sein d'un binaire. *
* *
@@ -312,15 +315,20 @@ static const char *g_dex_format_get_target_machine(const GDexFormat *format)
* *
******************************************************************************/
-static void g_dex_format_refine_portions(const GDexFormat *format, GBinPortion *raw)
+static void g_dex_format_refine_portions(const GDexFormat *format, GPortionLayer *main)
{
+ GPortionLayer *layer; /* Couche à mettre en place */
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);
+
max = g_dex_format_count_classes(format);
for (i = 0; i < max; i++)
- g_dex_class_include_as_portion(format->classes[i], raw);
+ g_dex_class_include_as_portion(format->classes[i], layer);
}
diff --git a/src/format/dex/method.c b/src/format/dex/method.c
index c68e9e1..9c911d1 100644
--- a/src/format/dex/method.c
+++ b/src/format/dex/method.c
@@ -294,7 +294,7 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)
/******************************************************************************
* *
* Paramètres : method = représentation interne du format DEX à consulter. *
-* raw = portion de binaire brut à raffiner. *
+* layer = couche de portions à raffiner. *
* *
* Description : Intègre la méthode en tant que portion de code. *
* *
@@ -304,7 +304,7 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)
* *
******************************************************************************/
-void g_dex_method_include_as_portion(const GDexMethod *method, GBinPortion *raw)
+void g_dex_method_include_as_portion(const GDexMethod *method, GPortionLayer *layer)
{
GBinPortion *new; /* Nouvelle portion définie */
char *desc; /* Description d'une portion */
@@ -327,7 +327,7 @@ void g_dex_method_include_as_portion(const GDexMethod *method, GBinPortion *raw)
g_binary_portion_set_rights(new, PAC_READ | PAC_EXEC);
- g_binary_portion_include(raw, new);
+ g_portion_layer_include(layer, new);
}
diff --git a/src/format/dex/method.h b/src/format/dex/method.h
index dee33cb..4d29bac 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 *, GBinPortion *);
+void g_dex_method_include_as_portion(const GDexMethod *, GPortionLayer *);
/* Indique la position de la méthode au sein du binaire. */
off_t g_dex_method_get_offset(const GDexMethod *);
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 3dc5d64..3491c71 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -67,7 +67,7 @@ static void g_elf_format_finalize(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 *, GBinPortion *);
+static void g_elf_format_refine_portions(const GElfFormat *, GPortionLayer *);
/* Fournit l'emplacement correspondant à une position physique. */
static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *, phys_t, vmpa2t *);
@@ -352,7 +352,7 @@ static const char *g_elf_format_get_target_machine(const GElfFormat *format)
/******************************************************************************
* *
* Paramètres : format = informations chargées à consulter. *
-* raw = portion de binaire brut à raffiner. *
+* main = couche de portions principale à raffiner. *
* *
* Description : Etend la définition des portions au sein d'un binaire. *
* *
@@ -362,8 +362,9 @@ static const char *g_elf_format_get_target_machine(const GElfFormat *format)
* *
******************************************************************************/
-static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *raw)
+static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer *main)
{
+ GPortionLayer *layer; /* Couche à mettre en place */
uint16_t i; /* Boucle de parcours */
off_t offset; /* Début de part de programme */
elf_phdr phdr; /* En-tête de programme ELF */
@@ -381,7 +382,10 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *
/* Côté segments basiques */
-#if 0
+ layer = g_portion_layer_new(NO_LENGTH_YET, _("Segment"));
+
+ g_portion_layer_attach_sub(main, layer);
+
for (i = 0; i < ELF_HDR(format, format->header, e_phnum); i++)
{
offset = ELF_HDR(format, format->header, e_phoff)
@@ -414,10 +418,9 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *
g_binary_portion_set_rights(new, rights);
- g_binary_portion_include(raw, new);
+ g_portion_layer_include(layer, new);
}
-#endif
/* Inclusion des sections, si possible... */
@@ -425,6 +428,10 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *
ELF_HDR(format, format->header, e_shstrndx),
&strings);
+ layer = g_portion_layer_new(NO_LENGTH_YET, _("Section"));
+
+ g_portion_layer_attach_sub(main, layer);
+
for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++)
{
if (!find_elf_section_by_index(format, i, &section))
@@ -432,9 +439,6 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *
sh_flags = ELF_SHDR(format, section, sh_flags);
- printf("[section % 2hu] 0x%08x -> %x -> %d\n", i, sh_flags,
- sh_flags & SHF_ALLOC, (sh_flags & SHF_ALLOC) == 0);
-
if ((sh_flags & SHF_ALLOC) == 0)
continue;
@@ -466,7 +470,7 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *
g_binary_portion_set_rights(new, rights);
- g_binary_portion_include(raw, new);
+ g_portion_layer_include(layer, new);
}
diff --git a/src/format/executable-int.h b/src/format/executable-int.h
index 4b86092..5e57133 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 *, GBinPortion *);
+typedef void (* refine_portions_fc) (const GExeFormat *, GPortionLayer *);
/* Fournit l'emplacement correspondant à une position physique. */
typedef bool (* translate_phys_fc) (const GExeFormat *, phys_t, vmpa2t *);
@@ -57,7 +57,7 @@ struct _GExeFormat
GDbgFormat **debugs; /* Informations de débogage */
size_t debugs_count; /* Nombre de ces informations */
- GBinPortion *portions; /* Morceaux binaires distincts */
+ GPortionLayer *layers; /* Couches de morceaux binaires*/
};
diff --git a/src/format/executable.c b/src/format/executable.c
index 325dc8b..fc34fa0 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -163,11 +163,6 @@ GDbgFormat *g_exe_format_get_debug_info(const GExeFormat *format, size_t index)
}
-
-
-
-
-
/******************************************************************************
* *
* Paramètres : format = informations chargées à consulter. *
@@ -191,89 +186,50 @@ const char *g_exe_format_get_target_machine(const GExeFormat *format)
* *
* Paramètres : format = description de l'exécutable à consulter. *
* *
-* Description : Décrit les différentes portions qui composent le binaire. *
+* Description : Fournit la première couche des portions composent le binaire.*
* *
-* Retour : Défintions de zones. *
+* Retour : Couche brute des différentes portions. *
* *
-* Remarques : - *
+* Remarques : Le compteur de références de l'instance renvoyée doit être *
+* décrémenté après usage. *
* *
******************************************************************************/
-GBinPortion *g_exe_format_get_portions(GExeFormat *format)
+GPortionLayer *g_exe_format_get_main_layer(GExeFormat *format)
{
+ GBinPortion *portion; /* Portion brute globale */
vmpa2t addr; /* Emplacement vide de sens */
phys_t length; /* Taille de portion globale */
+ GPortionLayer *layer; /* Couche à mettre en place */
- if (format->portions == NULL)
+ if (format->layers == NULL)
{
- format->portions = g_binary_portion_new(BPC_RAW);
+ /* 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);
- g_binary_portion_set_values(format->portions, &addr, length);
+ g_binary_portion_set_values(portion, &addr, length);
- G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format, format->portions);
+ /* Création d'une couche de base brute */
- }
+ layer = g_portion_layer_new(length, NULL);
- return format->portions;
+ g_portion_layer_include(layer, portion);
-}
+ /* Remplissage */
+ G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format, layer);
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* level = étage des portions à considérer ou -1 pour tous. *
-* count = nombre de portions trouvées et renvoyées. [OUT] *
-* *
-* Description : Fournit une liste choisie de portions d'un binaire. *
-* *
-* Retour : Liste de définitins de zones à libérer après usage. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBinPortion **g_exe_format_get_portions_at_level(GExeFormat *format, unsigned int level, size_t *count)
-{
- GBinPortion **result; /* Liste à retourner */
-
- typedef struct _portions_list
- {
- unsigned int required;
- GBinPortion **portions;
- size_t length;
-
- } portions_list;
-
- portions_list list; /* Sauvegarde de la liste */
-
- bool visit_for_level(GBinPortion *portion, portions_list *list)
- {
- if (list->required == -1 || g_binary_portion_get_level(portion) == list->required)
- {
- list->portions = (GBinPortion **)realloc(list->portions, ++list->length * sizeof(GBinPortion *));
- list->portions[list->length - 1] = portion;
- }
-
- return true;
+ format->layers = layer;
}
- list.required = level;
- list.portions = NULL;
- list.length = 0;
+ g_object_ref(G_OBJECT(format->layers));
- g_binary_portion_visit(g_exe_format_get_portions(format), (visit_portion_fc)visit_for_level, &list);
-
- result = list.portions;
- *count = list.length;
-
- qsort(result, *count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare);
-
- return result;
+ return format->layers;
}
@@ -303,6 +259,7 @@ mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count)
} x_ranges;
x_ranges tmp; /* Sauvegarde de la liste */
+ GPortionLayer *layer; /* Couche première de portions */
bool visit_for_x(GBinPortion *portion, x_ranges *ranges)
{
@@ -324,7 +281,9 @@ mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count)
tmp.list = NULL;
tmp.length = 0;
- g_binary_portion_visit(g_exe_format_get_portions(format), (visit_portion_fc)visit_for_x, &tmp);
+ 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));
result = tmp.list;
*count = tmp.length;
diff --git a/src/format/executable.h b/src/format/executable.h
index 48a8139..4ca0194 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -62,15 +62,11 @@ size_t g_exe_format_count_debug_info(const GExeFormat *);
/* Fournit un format de débogage attaché à l'exécutable. */
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 *);
-/* Décrit les différentes portions qui composent le binaire. */
-GBinPortion *g_exe_format_get_portions(GExeFormat *);
-
-/* Fournit une liste choisie de portions d'un binaire. */
-GBinPortion **g_exe_format_get_portions_at_level(GExeFormat *, unsigned int, size_t *);
+/* Fournit la première couche des portions composent le binaire. */
+GPortionLayer *g_exe_format_get_main_layer(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/glibext/gbinportion.c b/src/glibext/gbinportion.c
index 920fcfe..790614a 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -24,6 +24,7 @@
#include "gbinportion.h"
+#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
@@ -44,27 +45,16 @@ struct _GBinPortion
{
GObject parent; /* A laisser en premier */
- unsigned int level; /* Profondeur de la portion */
- GBinPortion *container; /* Portion parente ou racine */
+ const unsigned int *level; /* Profondeur de la portion */
char *code; /* Code de la couleur de fond */
char *desc; /* Désignation humaine */
mrange_t range; /* Emplacement dans le code */
- vmpa2t addr; /* Emplacement dans le code */ /* TODO : clean */
- off_t size; /* Taille de la partie */ /* TODO : clean */
PortionAccessRights rights; /* Droits d'accès */
- GBinPortion **sub_portions; /* Portions incluses */
- size_t sub_count; /* Quantité d'inclusions */
-
-#ifdef DEBUG
- unsigned int valid; /* Instructions reconnues */
- unsigned int db; /* Instructions non traduites */
-#endif
-
};
/* Portion de données binaires quelconques (classe) */
@@ -75,10 +65,10 @@ struct _GBinPortionClass
};
-/* Initialise la classe des blocs de données binaires. */
+/* Initialise la classe des portions de données binaires. */
static void g_binary_portion_class_init(GBinPortionClass *);
-/* Initialise une instance de bloc de données binaires. */
+/* Initialise une instance de portion de données binaires. */
static void g_binary_portion_init(GBinPortion *);
/* Supprime toutes les références externes. */
@@ -88,10 +78,57 @@ static void g_binary_portion_dispose(GBinPortion *);
static void g_binary_portion_finalize(GBinPortion *);
/* Définit le niveau de profondeur pour une branche de portions. */
-static void g_binary_portion_set_level(GBinPortion *, unsigned int);
+static void g_binary_portion_set_level(GBinPortion *, const unsigned int *);
/* Détermine l'aire d'une sous-portion. */
-static bool g_binary_portion_compute_sub_area(GBinPortion *, GBinPortion *, const GdkRectangle *, GdkRectangle *);
+static bool g_binary_portion_compute_sub_area(const GBinPortion *, phys_t, const GdkRectangle *, GdkRectangle *);
+
+/* Détermine si une portion contient une adresse donnée. */
+static bool g_portion_layer_contains_addr(const GBinPortion *, const vmpa2t *);
+
+
+
+/* -------------------------- COUCHES DE PORTIONS BINAIRES -------------------------- */
+
+
+/* Couche de portions binaires quelconques (instance) */
+struct _GPortionLayer
+{
+ GObject parent; /* A laisser en premier */
+
+ phys_t length; /* Taille de portion globale */
+ const char *name; /* Désignation de la couche */
+
+ unsigned int level; /* Profondeur de la portion */
+
+ GPortionLayer *sub_layer; /* Eventuelle couche inférieure*/
+
+ GBinPortion **portions; /* Portions incluses */
+ size_t count; /* Quantité d'inclusions */
+
+};
+
+/* Couche de portions binaires quelconques (classe) */
+struct _GPortionLayerClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des couches de portions binaires. */
+static void g_portion_layer_class_init(GPortionLayerClass *);
+
+/* Initialise une instance de couche de portions binaires. */
+static void g_portion_layer_init(GPortionLayer *);
+
+/* Supprime toutes les références externes. */
+static void g_portion_layer_dispose(GPortionLayer *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_portion_layer_finalize(GPortionLayer *);
+
+
@@ -100,7 +137,7 @@ static bool g_binary_portion_compute_sub_area(GBinPortion *, GBinPortion *, cons
/* ---------------------------------------------------------------------------------- */
-/* Indique le type défini par la GLib pour les blocs de données. */
+/* Indique le type défini par la GLib pour les portions de données binaires. */
G_DEFINE_TYPE(GBinPortion, g_binary_portion, G_TYPE_OBJECT);
@@ -108,7 +145,7 @@ G_DEFINE_TYPE(GBinPortion, g_binary_portion, G_TYPE_OBJECT);
* *
* Paramètres : klass = classe à initialiser. *
* *
-* Description : Initialise la classe des blocs de données binaires. *
+* Description : Initialise la classe des portions de données binaires. *
* *
* Retour : - *
* *
@@ -133,7 +170,7 @@ static void g_binary_portion_class_init(GBinPortionClass *klass)
* *
* Paramètres : portion = instance à initialiser. *
* *
-* Description : Initialise une instance de bloc de données binaires. *
+* Description : Initialise une instance de portion de données binaires. *
* *
* Retour : - *
* *
@@ -143,7 +180,7 @@ static void g_binary_portion_class_init(GBinPortionClass *klass)
static void g_binary_portion_init(GBinPortion *portion)
{
- portion->level = 0;
+ portion->level = NULL;
}
@@ -162,11 +199,6 @@ static void g_binary_portion_init(GBinPortion *portion)
static void g_binary_portion_dispose(GBinPortion *portion)
{
- size_t i; /* Boucle de parcours */
-
- for (i = 0; i < portion->sub_count; i++)
- g_object_unref(G_OBJECT(portion->sub_portions[i]));
-
G_OBJECT_CLASS(g_binary_portion_parent_class)->dispose(G_OBJECT(portion));
}
@@ -191,9 +223,6 @@ static void g_binary_portion_finalize(GBinPortion *portion)
if (portion->desc != NULL)
free(portion->desc);
- if (portion->sub_portions != NULL)
- free(portion->sub_portions);
-
G_OBJECT_CLASS(g_binary_portion_parent_class)->finalize(G_OBJECT(portion));
}
@@ -205,7 +234,7 @@ static void g_binary_portion_finalize(GBinPortion *portion)
* *
* Description : Crée une description de partie de code vierge. *
* *
-* Retour : - *
+* Retour : Instance mise en place. *
* *
* Remarques : - *
* *
@@ -226,6 +255,26 @@ GBinPortion *g_binary_portion_new(const char *code)
/******************************************************************************
* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* level = niveau de profondeur à associer. *
+* *
+* Description : Définit le niveau de profondeur pour une branche de portions.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_set_level(GBinPortion *portion, const unsigned int *level)
+{
+ portion->level = level;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : a = premières informations à consulter. *
* b = secondes informations à consulter. *
* *
@@ -240,15 +289,32 @@ GBinPortion *g_binary_portion_new(const char *code)
int g_binary_portion_compare(const GBinPortion **a, const GBinPortion **b)
{
int result; /* Bilan à retourner */
+ const vmpa2t *addr_a; /* Adresse de la portion 'a' */
+ const vmpa2t *addr_b; /* Adresse de la portion 'b' */
+ const unsigned int *level_a; /* Niveau de la portion 'a' */
+ const unsigned int *level_b; /* Niveau de la portion 'b' */
- if ((*a)->level < (*b)->level)
- result = -1;
+ addr_a = get_mrange_addr(&(*a)->range);
+ addr_b = get_mrange_addr(&(*b)->range);
- else if ((*a)->level > (*b)->level)
- result = 1;
+ result = cmp_vmpa(addr_a, addr_b);
- else
- result = cmp_mrange(&(*a)->range, &(*b)->range);
+ if (result == 0)
+ {
+ level_a = (*a)->level;
+ level_b = (*b)->level;
+
+ if (level_a != NULL && level_b != NULL)
+ {
+ if (*level_a < *level_b)
+ result = -1;
+
+ else if (*level_a > *level_b)
+ result = 1;
+
+ }
+
+ }
return result;
@@ -312,9 +378,6 @@ const char *g_binary_portion_get_desc(const GBinPortion *portion)
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);
}
@@ -380,10 +443,81 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion)
/******************************************************************************
* *
-* Paramètres : portion = description de partie à mettre à jour. *
-* sub = portion à inclure dans la définition courante. *
+* Paramètres : portion = portion mère à consulter. *
+* full = taille totale de la couche parente. *
+* area = étendue de représentation de la portion mère. *
+* sub_area = étendue de représentation de la portion fille. *
+* *
+* Description : Détermine l'aire d'une sous-portion. *
* *
-* Description : Procède à l'inclusion d'une portion dans une autre. *
+* Retour : true si la sous-surface a été calculée correctement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_binary_portion_compute_sub_area(const GBinPortion *portion, phys_t full, const GdkRectangle *area, GdkRectangle *sub_area)
+{
+ phys_t length; /* Taille de la portion */
+ phys_t start; /* Position de départ */
+
+ length = get_mrange_length(&portion->range);
+
+ /* On saute les portions comme le segment GNU_STACK... */
+ if (length == 0) return false;
+
+ start = get_phy_addr(get_mrange_addr(&portion->range));
+
+ sub_area->y = area->y;
+ sub_area->height = area->height;
+
+ sub_area->x = area->x + (start * area->width) / full;
+ sub_area->width = (length * area->width) / full;
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = portion mère à consulter. *
+* addr = adresse du point de recherche. *
+* *
+* Description : Détermine si une portion contient une adresse donnée. *
+* *
+* Retour : true ou false selon le résultat. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_portion_layer_contains_addr(const GBinPortion *portion, const vmpa2t *addr)
+{
+ bool result; /* Bilan à retourner */
+
+ result = false;
+
+ /* Portion non allouée en mémoire -> adresse nulle ; on écarte */
+ if (get_virt_addr(get_mrange_addr(&portion->range)) == 0)
+ goto not_found;
+
+ result = mrange_contains_addr(&portion->range, addr);
+
+ not_found:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à consulter. *
+* buffer = espace où placer ledit contenu. *
+* msize = taille idéale des positions et adresses; *
+* *
+* Description : Insère dans un tampon une description de portion. *
* *
* Retour : - *
* *
@@ -391,14 +525,68 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion)
* *
******************************************************************************/
-void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub)
+void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, MemoryDataSize msize)
{
- portion->sub_portions = (GBinPortion **)realloc(portion->sub_portions,
- ++portion->sub_count * sizeof(GBinPortion *));
+ mrange_t range; /* Couverture à fournir */
+ GBufferLine *line; /* Nouvelle ligne à éditer */
+ char rights[64]; /* Traduction en texte */
+
+ /* On ne traite pas les portions anonymes ! */
+ if (portion->desc == NULL) return;
+
+ init_mrange(&range, get_mrange_addr(&portion->range), 0);
+
+ line = g_code_buffer_append_new_line(buffer, &range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
+
+ /* Séparation */
+
+ line = g_code_buffer_append_new_line(buffer, &range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD,
+ "; ======================================================", 56, RTT_COMMENT);
- portion->sub_portions[portion->sub_count - 1] = sub;
+ /* Retour à la ligne */
+
+ line = g_code_buffer_append_new_line(buffer, &range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
+
+ /* Description */
+
+ line = g_code_buffer_append_new_line(buffer, &range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
+
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, portion->desc, strlen(portion->desc), RTT_COMMENT);
- g_binary_portion_set_level(sub, portion->level + 1);
+ snprintf(rights, sizeof(rights), " (%s%s%s%s)",
+ _("rights: "),
+ portion->rights & PAC_READ ? "r" : "-",
+ portion->rights & PAC_WRITE ? "w" : "-",
+ portion->rights & PAC_EXEC ? "x" : "-");
+
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, rights, strlen(rights), RTT_COMMENT);
+
+ /* Retour à la ligne */
+
+ line = g_code_buffer_append_new_line(buffer, &range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
+
+ line = g_code_buffer_append_new_line(buffer, &range);
+ g_buffer_line_fill_mrange(line, msize, msize);
}
@@ -406,9 +594,9 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub)
/******************************************************************************
* *
* Paramètres : portion = description de partie à mettre à jour. *
-* level = niveau de profondeur à associer. *
+* tooltip = astuce à compléter. [OUT] *
* *
-* Description : Définit le niveau de profondeur pour une branche de portions.*
+* Description : Prépare une astuce concernant une portion pour son affichage.*
* *
* Retour : - *
* *
@@ -416,91 +604,231 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub)
* *
******************************************************************************/
-static void g_binary_portion_set_level(GBinPortion *portion, unsigned int level)
+void g_binary_portion_query_tooltip(GBinPortion *portion, GtkTooltip *tooltip)
{
- size_t i; /* Boucle de parcours */
+ char *markup; /* Description à construire */
+ VMPA_BUFFER(value); /* Traduction en texte */
- portion->level = level;
+ /* Nom */
+
+ if (portion->desc != NULL)
+ {
+ markup = strdup("<b>");
+ markup = stradd(markup, portion->desc);
+ markup = stradd(markup, "</b>\n");
+ markup = stradd(markup, "\n");
+
+ }
+ else markup = strdup("");
+
+ markup = stradd(markup, "taille : ");
+ mrange_length_to_string(&portion->range, MDS_UNDEFINED, value, NULL);
+ markup = stradd(markup, value);
+ markup = stradd(markup, "\n");
+
+ /* Localisation */
+
+ markup = stradd(markup, "<b>");
+ markup = stradd(markup, _("Localisation"));
+ markup = stradd(markup, "</b>\n");
+
+ markup = stradd(markup, _("physical: from "));
+
+ mrange_phys_to_string(&portion->range, MDS_UNDEFINED, true, value, NULL);
+ markup = stradd(markup, value);
+ markup = stradd(markup, _(" to "));
+ mrange_phys_to_string(&portion->range, MDS_UNDEFINED, false, value, NULL);
+ markup = stradd(markup, value);
+ markup = stradd(markup, "\n");
+
+ markup = stradd(markup, _("memory: from "));
- for (i = 0; i < portion->sub_count; i++)
- g_binary_portion_set_level(portion->sub_portions[i], level + 1);
+ mrange_virt_to_string(&portion->range, MDS_UNDEFINED, true, value, NULL);
+ markup = stradd(markup, value);
+ markup = stradd(markup, _(" to "));
+ mrange_virt_to_string(&portion->range, MDS_UNDEFINED, false, value, NULL);
+ markup = stradd(markup, value);
+
+ markup = stradd(markup, "\n\n");
+
+ /* Droits d'accès */
+
+ markup = stradd(markup, "<b>");
+ markup = stradd(markup, _("Rights"));
+ markup = stradd(markup, "</b>\n");
+
+ snprintf(value, 2 * VMPA_MAX_SIZE, "%s%s%s",
+ portion->rights & PAC_READ ? "r" : "-",
+ portion->rights & PAC_WRITE ? "w" : "-",
+ portion->rights & PAC_EXEC ? "x" : "-");
+
+ markup = stradd(markup, value);
+
+ /* Impression finale */
+
+ gtk_tooltip_set_markup(tooltip, markup);
+ free(markup);
}
/******************************************************************************
* *
-* Paramètres : portion = description de partie à mettre à jour. *
+* Paramètres : portion = description de partie à consulter. *
+* cr = contexte graphique pour le dessin. *
+* area = étendue mise à disposition. *
* *
-* Description : Indique le niveau de profondeur d'une portion donnée. *
+* Description : Représente la portion sur une bande dédiée. *
* *
-* Retour : Niveau de profondeur positif ou nul. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-unsigned int g_binary_portion_get_level(GBinPortion *portion)
+void g_binary_portion_draw(const GBinPortion *portion, GtkStyleContext *context, cairo_t *cr, const GdkRectangle *area)
{
- return portion->level;
+ //cairo_set_line_width(cr, 1.0);
+
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+
+ gtk_style_context_save(context);
+
+ gtk_style_context_add_class(context, portion->code);
+
+ gtk_render_background(context, cr, area->x, area->y, area->width, area->height);
+
+ gtk_render_frame(context, cr, area->x, area->y, area->width, area->height);
+
+ gtk_style_context_restore(context);
}
+
+/* ---------------------------------------------------------------------------------- */
+/* COUCHES DE PORTIONS BINAIRES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour les couches de portions binaires. */
+G_DEFINE_TYPE(GPortionLayer, g_portion_layer, G_TYPE_OBJECT);
+
+
/******************************************************************************
* *
-* Paramètres : portion = portion mère à consulter. *
-* sub = portion fille à traiter. *
-* area = étendue de représentation de la portion mère. *
-* sub_area = étendue de représentation de la portion fille. *
+* Paramètres : klass = classe à initialiser. *
* *
-* Description : Détermine l'aire d'une sous-portion. *
+* Description : Initialise la classe des couches de portions binaires. *
* *
-* Retour : true si la sous-surface a été calculée correctement. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_binary_portion_compute_sub_area(GBinPortion *portion, GBinPortion *sub, const GdkRectangle *area, GdkRectangle *sub_area)
+static void g_portion_layer_class_init(GPortionLayerClass *klass)
{
- /* On saute les portions comme le segment GNU_STACK... */
- if (sub->size == 0) return false;
+ GObjectClass *object; /* Autre version de la classe */
- sub_area->y = area->y;
- sub_area->height = area->height;
+ object = G_OBJECT_CLASS(klass);
- sub_area->x = area->x + (get_phy_addr(&sub->addr) * area->width) / portion->size;
- sub_area->width = (sub->size * area->width) / portion->size;
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_portion_layer_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_portion_layer_finalize;
- return true;
}
/******************************************************************************
* *
-* 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.*
+* Paramètres : layer = instance à initialiser. *
* *
-* Description : Parcours un ensemble de portions binaires. *
+* Description : Initialise une instance de couche de portions binaires. *
* *
-* Retour : true si la visite a été jusqu'à son terme, false sinon. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void *data)
+static void g_portion_layer_init(GPortionLayer *layer)
+{
+ layer->level = 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : layer = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_portion_layer_dispose(GPortionLayer *layer)
{
- bool result; /* Etat à retourner */
size_t i; /* Boucle de parcours */
- result = visitor(portion, data);
+ if (layer->sub_layer != NULL)
+ g_object_unref(G_OBJECT(layer->sub_layer));
+
+ for (i = 0; i < layer->count; i++)
+ g_object_unref(G_OBJECT(layer->portions[i]));
+
+ G_OBJECT_CLASS(g_portion_layer_parent_class)->dispose(G_OBJECT(layer));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : layer = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_portion_layer_finalize(GPortionLayer *layer)
+{
+ if (layer->portions != NULL)
+ free(layer->portions);
+
+ G_OBJECT_CLASS(g_portion_layer_parent_class)->finalize(G_OBJECT(layer));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : length =
+* name = désignation pouvant servir de suffixe aux portions. *
+* *
+* Description : Crée une nouvelle couche de portions binaires. *
+* *
+* Retour : Instance mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GPortionLayer *g_portion_layer_new(phys_t length, const char *name)
+{
+ GPortionLayer *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_BIN_PORTION, NULL);
- for (i = 0; i < portion->sub_count && result; i++)
- result = g_binary_portion_visit(portion->sub_portions[i], visitor, data);
+ result->length = length;
+ result->name = name;
return result;
@@ -509,10 +837,127 @@ bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void
/******************************************************************************
* *
-* Paramètres : portion = description de partie à mettre à jour. *
-* x = abscisse du point de recherche. *
-* y = ordonnée du point de recherche. *
-* area = étendue de portion mère, puis celle trouvée. [OUT] *
+* Paramètres : layer = couche rassemblant des portions à modifier. *
+* Paramètres : sub = couche inférieure à rattacher à la couche courante. *
+* *
+* Description : Attache une couche à une autre en tant que couche inférieure.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_portion_layer_attach_sub(GPortionLayer *layer, GPortionLayer *sub)
+{
+ void set_layers_length(GPortionLayer *parent, GPortionLayer *child)
+ {
+ if (child->length == NO_LENGTH_YET)
+ {
+ assert(parent->length != NO_LENGTH_YET);
+
+ child->length = parent->length;
+
+ if (child->sub_layer != NULL)
+ set_layers_length(child, child->sub_layer);
+
+ }
+
+ }
+
+ void set_layers_depth(GPortionLayer *parent, GPortionLayer *child)
+ {
+ child->level = parent->level + 1;
+
+ if (child->sub_layer != NULL)
+ set_layers_length(child, child->sub_layer);
+
+ }
+
+ set_layers_length(layer, sub);
+
+ set_layers_depth(layer, sub);
+
+ layer->sub_layer = sub;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : layer = couche rassemblant les portions d'un même niveau. *
+* portion = portion à inclure dans la définition courante. *
+* *
+* Description : Procède à l'inclusion d'une portion dans une couche. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_portion_layer_include(GPortionLayer *layer, GBinPortion *portion)
+{
+ layer->portions = (GBinPortion **)realloc(layer->portions,
+ ++layer->count * sizeof(GBinPortion *));
+
+ layer->portions[layer->count - 1] = portion;
+
+ g_binary_portion_set_level(portion, &layer->level);
+
+ qsort(layer->portions, layer->count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : layer = couche première à parcourir intégralement. *
+* count = nombre de portions trouvées et renvoyées. [OUT] *
+* *
+* Description : Fournit une liste triée de portions d'un binaire. *
+* *
+* Retour : Liste de définitions de zones à libérer après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinPortion **g_portion_layer_collect_all_portions(const GPortionLayer *layer, size_t *count)
+{
+ GBinPortion **result; /* Liste construite à renvoyer */
+
+ GBinPortion **do_collect(const GPortionLayer *l, GBinPortion **lst, size_t *c)
+ {
+ size_t start; /* Indice de départ des ajouts */
+ size_t i; /* Boucle de parcours */
+
+ start = *c;
+ *c += l->count;
+
+ lst = (GBinPortion **)realloc(lst, *c * sizeof(GBinPortion *));
+
+ for (i = 0; i < l->count; i++)
+ lst[start + i] = l->portions[i];
+
+ return lst;
+
+ }
+
+ result = do_collect(layer, NULL, count);
+
+ qsort(result, *count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : layer = couche de portions à parcourir pour les recherches. *
+* x = abscisse du point de recherche. *
+* area = étendue de portion mère, puis celle trouvée. [OUT] *
* *
* Description : Recherche la portion présente à un point donné. *
* *
@@ -522,20 +967,23 @@ bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void
* *
******************************************************************************/
-GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRectangle *area)
+GBinPortion *g_portion_layer_find_portion_at_pos(const GPortionLayer *layer, gint x, GdkRectangle *area)
{
GBinPortion *result; /* Portion à retourner */
size_t i; /* Boucle de parcours */
GBinPortion *sub; /* Portion incluse à traiter */
GdkRectangle sub_area; /* Etendue d'une sous-portion */
- result = NULL;
+ if (layer->sub_layer != NULL)
+ result = g_portion_layer_find_portion_at_pos(layer->sub_layer, x, area);
+ else
+ result = NULL;
- for (i = 0; i < portion->sub_count && !result; i++)
+ for (i = 0; i < layer->count && result == NULL; i++)
{
- sub = portion->sub_portions[i];
+ sub = layer->portions[i];
- if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
+ if (!g_binary_portion_compute_sub_area(sub, layer->length, area, &sub_area))
continue;
if (sub_area.x <= x && x < (sub_area.x + sub_area.width))
@@ -546,9 +994,6 @@ GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRecta
}
- if (result == NULL)
- result = portion;
-
return result;
}
@@ -556,9 +1001,9 @@ GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRecta
/******************************************************************************
* *
-* Paramètres : portion = description de partie à mettre à jour. *
-* addr = adresse du point de recherche. *
-* area = étendue de portion mère, puis celle trouvée. [OUT] *
+* Paramètres : layer = couche de portions à parcourir pour les recherches. *
+* addr = adresse du point de recherche. *
+* area = étendue de portion mère, puis celle trouvée. [OUT] *
* *
* Description : Recherche la portion présente à une adresse donnée. *
* *
@@ -568,47 +1013,33 @@ GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRecta
* *
******************************************************************************/
-GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *addr, GdkRectangle *area)
+GBinPortion *g_portion_layer_find_portion_at_addr(const GPortionLayer *layer, const vmpa2t *addr, GdkRectangle *area)
{
GBinPortion *result; /* Portion à retourner */
size_t i; /* Boucle de parcours #1 */
GBinPortion *sub; /* Portion incluse à traiter */
GdkRectangle sub_area; /* Etendue d'une sous-portion */
- size_t j; /* Boucle de parcours #2 */
- result = NULL;
+ if (layer->sub_layer != NULL)
+ result = g_portion_layer_find_portion_at_addr(layer->sub_layer, addr, area);
+ else
+ result = NULL;
- for (i = 0; i < portion->sub_count && result == NULL; i++)
+ for (i = 0; i < layer->count && result == NULL; i++)
{
- sub = portion->sub_portions[i];
-
- /* FIXME : cmp ? */
+ sub = layer->portions[i];
- /* Portion non allouée en mémoire -> adresse nulle ; on écarte */
- if (get_virt_addr(&sub->addr) == 0)
+ if (!g_portion_layer_contains_addr(sub, addr))
continue;
- if (get_virt_addr(addr) < get_virt_addr(&sub->addr)
- || get_virt_addr(addr) >= (get_virt_addr(&sub->addr) + sub->size))
+ if (!g_binary_portion_compute_sub_area(sub, layer->length, area, &sub_area))
continue;
- if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
- continue;
-
- for (j = 0; j < sub->sub_count && !result; j++)
- result = g_binary_portion_find_at_addr(sub->sub_portions[j], addr, &sub_area);
-
- if (result == NULL)
- {
- result = sub;
- *area = sub_area;
- }
+ result = sub;
+ *area = sub_area;
}
- if (result == NULL)
- result = portion;
-
return result;
}
@@ -616,10 +1047,10 @@ GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *a
/******************************************************************************
* *
-* Paramètres : portion = description de partie à mettre à jour. *
-* x = abscisse du point de recherche. *
-* area = étendue de représentation de la portion mère. *
-* addr = adresse correspondante. [OUT] *
+* Paramètres : layer = couche de portions à parcourir pour les recherches. *
+* x = abscisse du point de recherche. *
+* area = étendue de représentation de la portion mère. *
+* addr = adresse correspondante. [OUT] *
* *
* Description : Fournit la position correspondant à une adresse donnée. *
* *
@@ -629,19 +1060,19 @@ GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *a
* *
******************************************************************************/
-bool g_binary_portion_get_addr_from_pos(GBinPortion *portion, gint x, const GdkRectangle *area, vmpa2t *addr)
+bool g_portion_layer_get_addr_from_pos(GPortionLayer *layer, gint x, const GdkRectangle *area, vmpa2t *addr)
{
GdkRectangle owner_area; /* Aire de contenance */
GBinPortion *owner; /* Conteneur propriétaire */
owner_area = *area;
- owner = g_binary_portion_find_at_pos(portion, x, &owner_area);
+ owner = g_portion_layer_find_portion_at_pos(layer, x, &owner_area);
if (owner == NULL) return false;
- copy_vmpa(addr, &owner->addr);
+ copy_vmpa(addr, get_mrange_addr(&owner->range));
- advance_vmpa(addr, (owner->size * (x - owner_area.x)) / owner_area.width);
+ advance_vmpa(addr, (get_mrange_length(&owner->range) * (x - owner_area.x)) / owner_area.width);
return true;
@@ -650,10 +1081,10 @@ bool g_binary_portion_get_addr_from_pos(GBinPortion *portion, gint x, const GdkR
/******************************************************************************
* *
-* Paramètres : portion = description de partie à mettre à jour. *
-* addr = adresse du point de recherche. *
-* area = étendue de représentation de la portion mère. *
-* x = position correspondante. [OUT] *
+* Paramètres : layer = couche de portions à parcourir pour les recherches. *
+* addr = adresse du point de recherche. *
+* area = étendue de représentation de la portion mère. *
+* x = position correspondante. [OUT] *
* *
* Description : Fournit l'adresse correspondant à une position donnée. *
* *
@@ -663,20 +1094,20 @@ bool g_binary_portion_get_addr_from_pos(GBinPortion *portion, gint x, const GdkR
* *
******************************************************************************/
-bool g_binary_portion_get_pos_from_addr(GBinPortion *portion, const vmpa2t *addr, const GdkRectangle *area, gint *x)
+bool g_portion_layer_get_pos_from_addr(GPortionLayer *layer, const vmpa2t *addr, const GdkRectangle *area, gint *x)
{
GdkRectangle owner_area; /* Aire de contenance */
GBinPortion *owner; /* Conteneur propriétaire */
- off_t diff; /* Décallage à appliquer */
+ phys_t diff; /* Décallage à appliquer */
owner_area = *area;
- owner = g_binary_portion_find_at_addr(portion, addr, &owner_area);
+ owner = g_portion_layer_find_portion_at_addr(layer, addr, &owner_area);
if (owner == NULL) return false;
- diff = compute_vmpa_diff(addr, &owner->addr);
+ diff = compute_vmpa_diff(addr, get_mrange_addr(&owner->range));
- *x = owner_area.x + (diff * owner_area.width) / owner->size;
+ *x = owner_area.x + (diff * owner_area.width) / get_mrange_length(&owner->range);
return true;
@@ -685,87 +1116,39 @@ bool g_binary_portion_get_pos_from_addr(GBinPortion *portion, const vmpa2t *addr
/******************************************************************************
* *
-* Paramètres : portion = description de partie à consulter. *
-* buffer = espace où placer ledit contenu. *
-* msize = taille idéale des positions et adresses; *
+* Paramètres : layer = première couche amorçant la visite. *
+* visitor = fonction à appeler à chaque étape de la descente. *
+* data = adresse pointant vers des données de l'utilisateur.*
* *
-* Description : Insère dans un tampon une description de portion. *
+* Description : Parcours un ensemble de portions binaires. *
* *
-* Retour : - *
+* Retour : true si la visite a été jusqu'à son terme, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, MemoryDataSize msize)
+bool g_portion_layer_visit(const GPortionLayer *layer, visit_portion_fc visitor, void *data)
{
- mrange_t range; /* Couverture à fournir */
- GBufferLine *line; /* Nouvelle ligne à éditer */
- char rights[64]; /* Traduction en texte */
-
- /* On ne traite pas les portions anonymes ! */
- if (portion->desc == NULL) return;
-
- init_mrange(&range, get_mrange_addr(&portion->range), 0);
-
- line = g_code_buffer_append_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER);
-
- /* Séparation */
-
- line = g_code_buffer_append_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD,
- "; ======================================================", 56, RTT_COMMENT);
-
- /* Retour à la ligne */
-
- line = g_code_buffer_append_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
-
- /* Description */
-
- line = g_code_buffer_append_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
-
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-
- g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
-
- g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, portion->desc, strlen(portion->desc), RTT_COMMENT);
-
- snprintf(rights, sizeof(rights), " (%s%s%s%s)",
- _("rights: "),
- portion->rights & PAC_READ ? "r" : "-",
- portion->rights & PAC_WRITE ? "w" : "-",
- portion->rights & PAC_EXEC ? "x" : "-");
-
- g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, rights, strlen(rights), RTT_COMMENT);
-
- /* Retour à la ligne */
+ bool result; /* Etat à retourner */
+ size_t i; /* Boucle de parcours */
- line = g_code_buffer_append_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
+ if (layer->sub_layer != NULL)
+ result = g_portion_layer_visit(layer->sub_layer, visitor, data);
+ else
+ result = true;
- g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
- g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
+ for (i = 0; i < layer->count && result; i++)
+ result = visitor(layer->portions[i], data);
- line = g_code_buffer_append_new_line(buffer, &range);
- g_buffer_line_fill_mrange(line, msize, msize);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : portion = description de partie à mettre à jour. *
+* Paramètres : layer = couche de portions à consulter. *
* x = abscisse du point de recherche. *
* y = ordonnée du point de recherche. *
* area = étendue de représentation de la portion mère. *
@@ -779,81 +1162,14 @@ void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, Mem
* *
******************************************************************************/
-gboolean g_binary_portion_query_tooltip(GBinPortion *portion, gint x, gint y, const GdkRectangle *area, GtkTooltip *tooltip)
+gboolean g_portion_layer_query_tooltip(const GPortionLayer *layer, gint x, gint y, const GdkRectangle *area, GtkTooltip *tooltip)
{
GBinPortion *selected; /* Portion à décrire ici */
- char *markup; /* Description à construire */
- GBinPortion *iter; /* Remontée hiérarchique */
- char value[2 * VMPA_MAX_SIZE]; /* Traduction en texte */
-
- selected = g_binary_portion_find_at_pos(portion, x, (GdkRectangle []) { *area });
-
- /* Nom */
-
- if (selected->desc != NULL)
- {
- markup = strdup("<b>");
- markup = stradd(markup, selected->desc);
- markup = stradd(markup, "</b>\n");
-
- for (iter = selected->container; iter != NULL; iter = iter->container)
- if (iter->desc != NULL)
- {
- markup = stradd(markup, selected->desc);
- markup = stradd(markup, "\n");
- }
-
- markup = stradd(markup, "\n");
-
- }
- else markup = strdup("");
-
- markup = stradd(markup, "taille : ");
- snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->size));
- markup = stradd(markup, value);
- markup = stradd(markup, "\n");
-
- /* Localisation */
-
- markup = stradd(markup, "<b>");
- markup = stradd(markup, _("Localisation"));
- markup = stradd(markup, "</b>\n");
-
- markup = stradd(markup, _("physical: from "));
- snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(get_phy_addr(&selected->addr)));
- markup = stradd(markup, value);
- markup = stradd(markup, _(" to "));
- snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(get_phy_addr(&selected->addr) + selected->size));
- markup = stradd(markup, value);
- markup = stradd(markup, "\n");
-
- markup = stradd(markup, _("memory: from "));
-#if 0
- snprintf(value, 2 * VMPA_MAX_SIZE, VMPA_FMT_LONG, VMPA_CAST(selected->addr));
- markup = stradd(markup, value);
- markup = stradd(markup, _(" to "));
- snprintf(value, 2 * VMPA_MAX_SIZE, VMPA_FMT_LONG, VMPA_CAST(selected->addr + selected->size));
- markup = stradd(markup, value);
-#endif
- markup = stradd(markup, "\n\n");
-
- /* Droits d'accès */
-
- markup = stradd(markup, "<b>");
- markup = stradd(markup, _("Rights"));
- markup = stradd(markup, "</b>\n");
-
- snprintf(value, 2 * VMPA_MAX_SIZE, "%s%s%s",
- selected->rights & PAC_READ ? "r" : "-",
- selected->rights & PAC_WRITE ? "w" : "-",
- selected->rights & PAC_EXEC ? "x" : "-");
- markup = stradd(markup, value);
-
- /* Impression finale */
+ selected = g_portion_layer_find_portion_at_pos(layer, x, (GdkRectangle []) { *area });
+ if (selected == NULL) return FALSE;
- gtk_tooltip_set_markup(tooltip, markup);
- free(markup);
+ g_binary_portion_query_tooltip(selected, tooltip);
return TRUE;
@@ -862,11 +1178,11 @@ gboolean g_binary_portion_query_tooltip(GBinPortion *portion, gint x, gint y, co
/******************************************************************************
* *
-* Paramètres : portion = description de partie à consulter. *
-* cr = contexte graphique pour le dessin. *
-* area = étendue mise à disposition. *
+* Paramètres : layer = couche de portions à consulter. *
+* cr = contexte graphique pour le dessin. *
+* area = étendue mise à disposition. *
* *
-* Description : Représente la portion sur une bande dédiée. *
+* Description : Représente une couche de portions sur une bande dédiée. *
* *
* Retour : - *
* *
@@ -874,42 +1190,24 @@ gboolean g_binary_portion_query_tooltip(GBinPortion *portion, gint x, gint y, co
* *
******************************************************************************/
-void g_binary_portion_draw(GBinPortion *portion, GtkStyleContext *context, cairo_t *cr, const GdkRectangle *area)
+void g_portion_layer_draw(const GPortionLayer *layer, GtkStyleContext *context, cairo_t *cr, const GdkRectangle *area)
{
size_t i; /* Boucle de parcours */
GBinPortion *sub; /* Portion incluse à montrer */
GdkRectangle sub_area; /* Etendue d'une sous-portion */
- /* Dessin de la portion courante */
-
- //cairo_set_line_width(cr, 1.0);
-
- cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
-
- gtk_style_context_save(context);
-
- gtk_style_context_add_class(context, portion->code);
-
- gtk_render_background(context, cr, area->x, area->y, area->width, area->height);
-
- gtk_render_frame(context, cr, area->x, area->y, area->width, area->height);
-
- gtk_style_context_restore(context);
-
- /* Dessin des portions incluses */
-
- sub_area.y = area->y;
- sub_area.height = area->height;
-
- for (i = 0; i < portion->sub_count; i++)
+ for (i = 0; i < layer->count; i++)
{
- sub = portion->sub_portions[i];
+ sub = layer->portions[i];
- if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
+ if (!g_binary_portion_compute_sub_area(sub, layer->length, area, &sub_area))
continue;
g_binary_portion_draw(sub, context, cr, &sub_area);
}
+ if (layer->sub_layer != NULL)
+ g_portion_layer_draw(layer->sub_layer, context, cr, area);
+
}
diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h
index f92b87e..e5c7830 100644
--- a/src/glibext/gbinportion.h
+++ b/src/glibext/gbinportion.h
@@ -36,6 +36,9 @@
+/* ------------------------------- PORTION DE BINAIRE ------------------------------- */
+
+
/**
* Couleurs de représentation.
*/
@@ -73,11 +76,7 @@ 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. */
+/* Indique le type défini par la GLib pour les portions de données binaires. */
GType g_binary_portion_get_type(void);
/* Crée une description de partie de code vierge. */
@@ -104,35 +103,77 @@ void g_binary_portion_set_rights(GBinPortion *, PortionAccessRights);
/* Fournit les droits associés à une partie de code. */
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 *);
+/* Insère dans un tampon une description de portion. */
+void g_binary_portion_print(const GBinPortion *, GCodeBuffer *, MemoryDataSize);
-/* Indique le niveau de profondeur d'une portion donnée. */
-unsigned int g_binary_portion_get_level(GBinPortion *);
+/* Prépare une astuce concernant une portion pour son affichage. */
+void g_binary_portion_query_tooltip(GBinPortion *, GtkTooltip *);
+
+/* Représente la portion sur une bande dédiée. */
+void g_binary_portion_draw(const GBinPortion *, GtkStyleContext *, cairo_t *, const GdkRectangle *);
+
+
+
+/* -------------------------- COUCHES DE PORTIONS BINAIRES -------------------------- */
+
+
+#define G_TYPE_PORTION_LAYER (g_portion_layer_get_type())
+#define G_PORTION_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PORTION_LAYER, GPortionLayer))
+#define G_IS_PORTION_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PORTION_LAYER))
+#define G_PORTION_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PORTION_LAYER, GPortionLayerClass))
+#define G_IS_PORTION_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PORTION_LAYER))
+#define G_PORTION_LAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PORTION_LAYER, GPortionLayerClass))
-/* Parcours un ensemble de portions binaires. */
-bool g_binary_portion_visit(GBinPortion *, visit_portion_fc, void *);
+
+/* Couche de portions binaires quelconques (instance) */
+typedef struct _GPortionLayer GPortionLayer;
+
+/* Couche de portions binaires quelconques (classe) */
+typedef struct _GPortionLayerClass GPortionLayerClass;
+
+
+/* Taille à définir lors d'un rattachement */
+#define NO_LENGTH_YET VMPA_NO_PHYSICAL
+
+
+/* Indique le type défini par la GLib pour les couches de portions binaires. */
+GType g_portion_layer_get_type(void);
+
+/* Crée une nouvelle couche de portions binaires. */
+GPortionLayer *g_portion_layer_new(phys_t, const char *);
+
+/* Attache une couche à une autre en tant que couche inférieure. */
+void g_portion_layer_attach_sub(GPortionLayer *, GPortionLayer *);
+
+/* Procède à l'inclusion d'une portion dans une couche. */
+void g_portion_layer_include(GPortionLayer *, GBinPortion *);
+
+/* Fournit une liste triée de portions d'un binaire. */
+GBinPortion **g_portion_layer_collect_all_portions(const GPortionLayer *, size_t *);
/* Recherche la portion présente à un point donné. */
-GBinPortion *g_binary_portion_find_at_pos(GBinPortion *, gint, GdkRectangle *);
+GBinPortion *g_portion_layer_find_portion_at_pos(const GPortionLayer *, gint, GdkRectangle *);
/* Recherche la portion présente à une adresse donnée. */
-GBinPortion *g_binary_portion_find_at_addr(GBinPortion *, const vmpa2t *, GdkRectangle *);
+GBinPortion *g_portion_layer_find_portion_at_addr(const GPortionLayer *, const vmpa2t *, GdkRectangle *);
/* Fournit la position correspondant à une adresse donnée. */
-bool g_binary_portion_get_addr_from_pos(GBinPortion *, gint, const GdkRectangle *, vmpa2t *);
+bool g_portion_layer_get_addr_from_pos(GPortionLayer *, gint, const GdkRectangle *, vmpa2t *);
/* Fournit l'adresse correspondant à une position donnée. */
-bool g_binary_portion_get_pos_from_addr(GBinPortion *, const vmpa2t *, const GdkRectangle *, gint *);
+bool g_portion_layer_get_pos_from_addr(GPortionLayer *, const vmpa2t *, const GdkRectangle *, gint *);
-/* Insère dans un tampon une description de portion. */
-void g_binary_portion_print(const GBinPortion *, GCodeBuffer *, MemoryDataSize);
+/* Fonction appelée à chaque visite de portion.*/
+typedef bool (* visit_portion_fc) (GBinPortion *, void *);
+
+/* Parcours un ensemble de portions binaires. */
+bool g_portion_layer_visit(const GPortionLayer *, visit_portion_fc, void *);
/* Prépare une astuce concernant une portion pour son affichage. */
-gboolean g_binary_portion_query_tooltip(GBinPortion *, gint, gint, const GdkRectangle *, GtkTooltip *);
+gboolean g_portion_layer_query_tooltip(const GPortionLayer *, gint, gint, const GdkRectangle *, GtkTooltip *);
-/* Représente la portion sur une bande dédiée. */
-void g_binary_portion_draw(GBinPortion *, GtkStyleContext *, cairo_t *, const GdkRectangle *);
+/* Représente une couche de portions sur une bande dédiée. */
+void g_portion_layer_draw(const GPortionLayer *, GtkStyleContext *, cairo_t *, const GdkRectangle *);
diff --git a/src/gtkext/gtkbinarystrip.c b/src/gtkext/gtkbinarystrip.c
index e0016d2..0ad0763 100644
--- a/src/gtkext/gtkbinarystrip.c
+++ b/src/gtkext/gtkbinarystrip.c
@@ -211,7 +211,7 @@ static void gtk_binary_strip_size_allocate(GtkWidget *widget, GtkAllocation *all
{
GtkBinaryStrip *strip; /* Autre version du composant */
GExeFormat *format; /* Format du binaire */
- GBinPortion *portions; /* Portions binaires à dessiner*/
+ GPortionLayer *layer; /* Couche première de portions */
GdkRectangle area; /* Surface du composant */
GTK_WIDGET_CLASS(gtk_binary_strip_parent_class)->size_allocate(widget, allocation);
@@ -222,16 +222,18 @@ static void gtk_binary_strip_size_allocate(GtkWidget *widget, GtkAllocation *all
return;
format = g_loaded_binary_get_format(strip->binary);
- portions = g_exe_format_get_portions(format);
+ layer = g_exe_format_get_main_layer(format);
area.x = 0;
area.y = 0;
area.width = allocation->width;
area.height = allocation->height;
- if (!g_binary_portion_get_pos_from_addr(portions, &strip->cursor_addr, &area, &strip->cursor_pos))
+ if (!g_portion_layer_get_pos_from_addr(layer, &strip->cursor_addr, &area, &strip->cursor_pos))
strip->cursor_pos = 0;
+ g_object_unref(G_OBJECT(layer));
+
}
@@ -254,7 +256,7 @@ static gboolean gtk_binary_strip_button_release(GtkWidget *widget, GdkEventButto
gint height; /* Hauteur du composant */
GtkBinaryStrip *strip; /* Autre version du composant */
GExeFormat *format; /* Format du binaire */
- GBinPortion *portions; /* Portions binaires à dessiner*/
+ GPortionLayer *layer; /* Couche première de portions */
GdkRectangle area; /* Surface du composant */
vmpa2t addr; /* Adresse à sélectionner */
@@ -269,27 +271,26 @@ static gboolean gtk_binary_strip_button_release(GtkWidget *widget, GdkEventButto
strip = GTK_BINARY_STRIP(widget);
format = g_loaded_binary_get_format(strip->binary);
- portions = g_exe_format_get_portions(format);
+ layer = g_exe_format_get_main_layer(format);
area.x = 0;
area.y = 0;
area.width = width;
area.height = height;
- if (g_binary_portion_get_addr_from_pos(portions, event->x, &area, &addr))
+ if (g_portion_layer_get_addr_from_pos(layer, event->x, &area, &addr))
{
copy_vmpa(&strip->cursor_addr, &addr);
strip->cursor_pos = event->x;
gtk_widget_queue_draw(GTK_WIDGET(strip));
- printf("got :: %p\n", &addr);
- printf(" -> 0x%x 0x%x\n", (unsigned int)get_phy_addr(&addr), (unsigned int)get_virt_addr(&addr));
-
g_signal_emit_by_name(strip, "select-address");
}
+ g_object_unref(G_OBJECT(layer));
+
return FALSE;
}
@@ -312,7 +313,7 @@ static gboolean gtk_binary_strip_draw(GtkWidget *widget, cairo_t *cr)
{
GtkBinaryStrip *strip; /* Autre vision du composant */
GExeFormat *format; /* Format du binaire */
- GBinPortion *portions; /* Portions binaires à dessiner*/
+ GPortionLayer *layer; /* Couche première de portions */
GdkRectangle full; /* Taille totale de la surface */
GtkStyleContext *context; /* Contexte du thème actuel */
GdkRGBA *color; /* Couleur du curseur */
@@ -322,11 +323,11 @@ static gboolean gtk_binary_strip_draw(GtkWidget *widget, cairo_t *cr)
if (strip->binary == NULL)
return FALSE;
- format = g_loaded_binary_get_format(strip->binary);
- portions = g_exe_format_get_portions(format);
-
/* Dessin des portions de binaire */
+ format = g_loaded_binary_get_format(strip->binary);
+ layer = g_exe_format_get_main_layer(format);
+
full.x = 0;
full.y = 1;
full.width = gtk_widget_get_allocated_width(widget);
@@ -334,7 +335,9 @@ static gboolean gtk_binary_strip_draw(GtkWidget *widget, cairo_t *cr)
context = gtk_widget_get_style_context(widget);
- g_binary_portion_draw(portions, context, cr, &full);
+ g_portion_layer_draw(layer, context, cr, &full);
+
+ g_object_unref(G_OBJECT(layer));
/* Dessin de la position */
@@ -389,7 +392,7 @@ static gboolean gtk_binary_strip_query_tooltip(GtkWidget *widget, gint x, gint y
gboolean result; /* Bilan à retourner */
GtkBinaryStrip *strip; /* Autre version du composant */
GExeFormat *format; /* Format du binaire */
- GBinPortion *portions; /* Portions binaires à dessiner*/
+ GPortionLayer *layer; /* Couches binaires à consulter*/
GdkRectangle area; /* Surface du composant */
if (keyboard) return FALSE;
@@ -399,14 +402,16 @@ static gboolean gtk_binary_strip_query_tooltip(GtkWidget *widget, gint x, gint y
if (strip->binary != NULL)
{
format = g_loaded_binary_get_format(strip->binary);
- portions = g_exe_format_get_portions(format);
+ layer = g_exe_format_get_main_layer(format);
area.x = 0;
area.y = 0;
area.width = gtk_widget_get_allocated_width(widget);
area.height = gtk_widget_get_allocated_height(widget);
- result = g_binary_portion_query_tooltip(portions, x, y, &area, tooltip);
+ result = g_portion_layer_query_tooltip(layer, x, y, &area, tooltip);
+
+ g_object_unref(G_OBJECT(layer));
}
else result = FALSE;
diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c
index e9a61d8..148dd03 100644
--- a/src/gtkext/gtkstatusstack.c
+++ b/src/gtkext/gtkstatusstack.c
@@ -462,7 +462,7 @@ void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GL
GExeFormat *format; /* Format de binaire à traiter */
const mrange_t *range; /* Emplacement d'instruction */
const vmpa2t *addr; /* Localisation de départ */
- GBinPortion *portions; /* Portions binaires existantes*/
+ GPortionLayer *layer; /* Couche première de portions */
GBinPortion *portion; /* Zone mémoire d'appartenance */
const char *text; /* Texte au contenu à copier */
GBinSymbol *symbol; /* Symbole présent à l'adresse */
@@ -491,9 +491,9 @@ void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GL
/* Zone d'appartenance */
- portions = g_exe_format_get_portions(format);
+ layer = g_exe_format_get_main_layer(format);
- portion = g_binary_portion_find_at_addr(portions, addr, (GdkRectangle []) { });
+ portion = g_portion_layer_find_portion_at_addr(layer, addr, (GdkRectangle []) { });
text = g_binary_portion_get_desc(portion);
@@ -502,6 +502,8 @@ void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GL
else
info->segment = strdup(_("Binary"));
+ g_object_unref(G_OBJECT(layer));
+
/* Adresses de base */
vmpa2_phys_to_string(addr, MDS_UNDEFINED, info->phys, NULL);