summaryrefslogtreecommitdiff
path: root/src/glibext/gbinportion.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glibext/gbinportion.c')
-rw-r--r--src/glibext/gbinportion.c708
1 files changed, 204 insertions, 504 deletions
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index 8fc7805..4137763 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -34,6 +34,7 @@
#include "../common/extstr.h"
+#include "../common/sort.h"
@@ -45,8 +46,6 @@ struct _GBinPortion
{
GObject parent; /* A laisser en premier */
- const unsigned int *level; /* Profondeur de la portion */
-
char *code; /* Code de la couleur de fond */
char *desc; /* Désignation humaine */
@@ -55,6 +54,9 @@ struct _GBinPortion
PortionAccessRights rights; /* Droits d'accès */
+ GBinPortion **subs; /* Portions incluses */
+ size_t count; /* Quantité d'inclusions */
+
};
/* Portion de données binaires quelconques (classe) */
@@ -77,58 +79,16 @@ static void g_binary_portion_dispose(GBinPortion *);
/* Procède à la libération totale de la mémoire. */
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 *, const unsigned int *);
-
/* Détermine l'aire d'une sous-portion. */
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 *);
+/* ------------------------ PARCOURS D'ENSEMBLES DE PORTIONS ------------------------ */
+/* Détermine si une portion contient une adresse donnée. */
+static bool g_portion_layer_contains_addr(const GBinPortion *, const vmpa2t *);
@@ -180,7 +140,6 @@ static void g_binary_portion_class_init(GBinPortionClass *klass)
static void g_binary_portion_init(GBinPortion *portion)
{
- portion->level = NULL;
}
@@ -231,6 +190,8 @@ static void g_binary_portion_finalize(GBinPortion *portion)
/******************************************************************************
* *
* Paramètres : code = désignation humaine de la couleur de fond. *
+* addr = emplacement de la section à conserver. *
+* size = taille de la section à conserver. *
* *
* Description : Crée une description de partie de code vierge. *
* *
@@ -240,7 +201,7 @@ static void g_binary_portion_finalize(GBinPortion *portion)
* *
******************************************************************************/
-GBinPortion *g_binary_portion_new(const char *code)
+GBinPortion *g_binary_portion_new(const char *code, const vmpa2t *addr, phys_t size)
{
GBinPortion *result; /* Structure à retourner */
@@ -248,27 +209,9 @@ GBinPortion *g_binary_portion_new(const char *code)
result->code = strdup(code);
- return result;
-
-}
+ init_mrange(&result->range, addr, size);
-
-/******************************************************************************
-* *
-* 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;
+ return result;
}
@@ -291,31 +234,12 @@ 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' */
addr_a = get_mrange_addr(&(*a)->range);
addr_b = get_mrange_addr(&(*b)->range);
result = cmp_vmpa(addr_a, addr_b);
- 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;
}
@@ -365,27 +289,6 @@ const char *g_binary_portion_get_desc(const GBinPortion *portion)
/******************************************************************************
* *
* Paramètres : portion = description de partie à mettre à jour. *
-* addr = emplacement de la section à conserver. *
-* size = taille de la section à conserver. *
-* *
-* Description : Définit les valeurs utiles d'une partie de code binaire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_binary_portion_set_values(GBinPortion *portion, const vmpa2t *addr, phys_t 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. *
* *
@@ -443,76 +346,6 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion)
/******************************************************************************
* *
-* 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. *
-* *
-* 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; *
@@ -686,52 +519,50 @@ void g_binary_portion_query_tooltip(GBinPortion *portion, GtkTooltip *tooltip)
/******************************************************************************
* *
-* Paramètres : portion = description de partie à consulter. *
-* cr = contexte graphique pour le dessin. *
-* area = étendue mise à disposition. *
+* 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 : Représente la portion sur une bande dédiée. *
+* Description : Détermine l'aire d'une sous-portion. *
* *
-* Retour : - *
+* Retour : true si la sous-surface a été calculée correctement. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_binary_portion_draw(const GBinPortion *portion, GtkStyleContext *context, cairo_t *cr, const GdkRectangle *area)
+static bool g_binary_portion_compute_sub_area(const GBinPortion *portion, phys_t full, const GdkRectangle *area, GdkRectangle *sub_area)
{
- //cairo_set_line_width(cr, 1.0);
+ phys_t length; /* Taille de la portion */
+ phys_t start; /* Position de départ */
- cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+ length = get_mrange_length(&portion->range);
- gtk_style_context_save(context);
+ /* On saute les portions comme le segment GNU_STACK... */
+ if (length == 0) return false;
- gtk_style_context_add_class(context, portion->code);
+ start = get_phy_addr(get_mrange_addr(&portion->range));
- gtk_render_background(context, cr, area->x, area->y, area->width, area->height);
+ sub_area->y = area->y;
+ sub_area->height = area->height;
- gtk_render_frame(context, cr, area->x, area->y, area->width, area->height);
+ sub_area->x = area->x + (start * area->width) / full;
+ sub_area->width = (length * area->width) / full;
- gtk_style_context_restore(context);
+ return true;
}
-
-/* ---------------------------------------------------------------------------------- */
-/* 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 : klass = classe à initialiser. *
+* Paramètres : portion = description de partie à consulter. *
+* context = contexte graphique associé à la procédure. *
+* cr = contexte graphique pour le dessin. *
+* area = étendue mise à disposition. *
* *
-* Description : Initialise la classe des couches de portions binaires. *
+* Description : Représente la portion sur une bande dédiée. *
* *
* Retour : - *
* *
@@ -739,70 +570,51 @@ G_DEFINE_TYPE(GPortionLayer, g_portion_layer, G_TYPE_OBJECT);
* *
******************************************************************************/
-static void g_portion_layer_class_init(GPortionLayerClass *klass)
+void g_binary_portion_draw(const GBinPortion *portion, GtkStyleContext *context, cairo_t *cr, const GdkRectangle *area)
{
- GObjectClass *object; /* Autre version de la classe */
-
- object = G_OBJECT_CLASS(klass);
+ phys_t full; /* Espace total représenté */
+ size_t i; /* Boucle de parcours */
+ GBinPortion *sub; /* Portion incluse à montrer */
+ GdkRectangle sub_area; /* Etendue d'une sous-portion */
- object->dispose = (GObjectFinalizeFunc/* ! */)g_portion_layer_dispose;
- object->finalize = (GObjectFinalizeFunc)g_portion_layer_finalize;
+ /* Dessin de la portion courante */
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
-}
+ gtk_style_context_save(context);
+ gtk_style_context_add_class(context, portion->code);
-/******************************************************************************
-* *
-* Paramètres : layer = instance à initialiser. *
-* *
-* Description : Initialise une instance de couche de portions binaires. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ gtk_render_background(context, cr, area->x, area->y, area->width, area->height);
-static void g_portion_layer_init(GPortionLayer *layer)
-{
- layer->level = 0;
+ gtk_render_frame(context, cr, area->x, area->y, area->width, area->height);
-}
+ gtk_style_context_restore(context);
+ /* Dessin des portions contenues */
-/******************************************************************************
-* *
-* Paramètres : layer = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ full = get_mrange_length(&portion->range);
-static void g_portion_layer_dispose(GPortionLayer *layer)
-{
- size_t i; /* Boucle de parcours */
+ for (i = 0; i < portion->count; i++)
+ {
+ sub = portion->subs[i];
- if (layer->sub_layer != NULL)
- g_object_unref(G_OBJECT(layer->sub_layer));
+ if (!g_binary_portion_compute_sub_area(sub, full, area, &sub_area))
+ continue;
- for (i = 0; i < layer->count; i++)
- g_object_unref(G_OBJECT(layer->portions[i]));
+ g_binary_portion_draw(sub, context, cr, &sub_area);
- G_OBJECT_CLASS(g_portion_layer_parent_class)->dispose(G_OBJECT(layer));
+ }
}
/******************************************************************************
* *
-* Paramètres : layer = instance d'objet GLib à traiter. *
+* Paramètres : portion = portion principale à compléter. *
+* sub = portion à inclure dans la définition courante. *
* *
-* Description : Procède à la libération totale de la mémoire. *
+* Description : Procède à l'inclusion d'une portion dans une autre. *
* *
* Retour : - *
* *
@@ -810,204 +622,161 @@ static void g_portion_layer_dispose(GPortionLayer *layer)
* *
******************************************************************************/
-static void g_portion_layer_finalize(GPortionLayer *layer)
+void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub)
{
- 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);
-
- result->length = length;
- result->name = name;
-
- return result;
-
-}
+ bool found; /* Zone d'accueil trouvée ? */
+ size_t best; /* Meilleur point d'insertion */
+ const mrange_t *prange; /* Emplacement de portion #1 */
+ const mrange_t *srange; /* Emplacement de portion #2 */
+ GBinPortion tmp; /* Sauvegarde temporaire */
+ found = bsearch_index(sub, portion->subs, portion->count, sizeof(GBinPortion *),
+ (__compar_fn_t)g_binary_portion_compare, &best);
-/******************************************************************************
-* *
-* 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 : - *
-* *
-******************************************************************************/
+ if (!found)
+ portion->subs = qinsert(portion->subs, &portion->count, sizeof(GBinPortion *),
+ (__compar_fn_t)g_binary_portion_compare, &sub);
-void g_portion_layer_attach_sub(GPortionLayer *layer, GPortionLayer *sub)
-{
- void set_layers_length(GPortionLayer *parent, GPortionLayer *child)
+ else
{
- if (child->length == NO_LENGTH_YET)
+ /**
+ * On prend ici en compte le genre de situations suivantes :
+ *
+ * [21] .bss NOBITS 00088240 07823c 0018c8 00 WA 0 0 8
+ * [22] __libc_freeres_ptrs NOBITS 00089b08 07823c 000018 00 WA 0 0 4
+ * [23] .comment PROGBITS 00000000 07823c 000022 01 MS 0 0 1
+ *
+ * Pendant le désassemblage, la procédure n'aime pas trop les intersections
+ * de zones mémoire.
+ */
+
+ prange = g_binary_portion_get_range(portion->subs[best]);
+ srange = g_binary_portion_get_range(sub);
+
+ if (mrange_contains_mrange(prange, srange))
+ g_binary_portion_include(portion->subs[best], sub);
+
+ else
{
- assert(parent->length != NO_LENGTH_YET);
+ assert(mrange_contains_mrange(srange, prange));
- child->length = parent->length;
+ memcpy(&tmp, portion->subs[best], sizeof(GBinPortion));
+ memcpy(portion->subs[best], sub, sizeof(GBinPortion));
+ memcpy(sub, &tmp, sizeof(GBinPortion));
- if (child->sub_layer != NULL)
- set_layers_length(child, child->sub_layer);
+ g_binary_portion_include(portion->subs[best], sub);
}
}
- 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. *
+* Paramètres : portion = 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 : Procède à l'inclusion d'une portion dans une couche. *
+* Description : Parcourt un ensemble de portions binaires. *
* *
-* Retour : - *
+* Retour : true si la visite a été jusqu'à son terme, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_portion_layer_include(GPortionLayer *layer, GBinPortion *portion)
+bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void *data)
{
- GPortionLayer *sub; /* Sous couche indispensable */
- bool conflict; /* Conflit dû aux débordements */
- const mrange_t *range; /* Emplacement de la portion */
- size_t i; /* Boucle de parcours */
- const mrange_t *other; /* Emplacements déjà occupés */
-
- /**
- * On prend ici en compte le genre de situations suivantes :
- *
- * [21] .bss NOBITS 00088240 07823c 0018c8 00 WA 0 0 8
- * [22] __libc_freeres_ptrs NOBITS 00089b08 07823c 000018 00 WA 0 0 4
- * [23] .comment PROGBITS 00000000 07823c 000022 01 MS 0 0 1
- *
- * Pendant le désassemblage, la procédure n'aime pas trop les intersections
- * de zones mémoire.
- */
+ bool result; /* Etat à retourner */
- conflict = false;
+ bool visit_portion(GBinPortion *p, GBinPortion *pp)
+ {
+ bool ret; /* Etat à retourner */
+ size_t i; /* Boucle de parcours */
- range = g_binary_portion_get_range(portion);
+ if (p->count == 0)
+ ret = visitor(p, pp, BPV_SHOW, data);
- for (i = 0; i < layer->count && !conflict; i++)
- {
- other = g_binary_portion_get_range(layer->portions[i]);
+ else
+ {
+ ret = visitor(p, pp, BPV_ENTER, data);
- conflict = mrange_intersects_mrange(range, other);
+ for (i = 0; i < p->count && ret; i++)
+ ret = visit_portion(p->subs[i], p);
- }
+ if (ret)
+ ret = visitor(p, pp, BPV_EXIT, data);
- /* La portion recouvre-t-elle une portion déjà existante ? */
- if (conflict)
- {
- if (layer->sub_layer == NULL)
- {
- sub = g_portion_layer_new(layer->length, layer->name);
- g_portion_layer_attach_sub(layer, sub);
}
- g_portion_layer_include(layer->sub_layer, portion);
+ return ret;
}
- /* Sinon on l'intègre dans la couche courante */
- else
- {
- layer->portions = (GBinPortion **)realloc(layer->portions,
- ++layer->count * sizeof(GBinPortion *));
+ result = visit_portion(portion, NULL);
- layer->portions[layer->count - 1] = portion;
+ return result;
- g_binary_portion_set_level(portion, &layer->level);
+}
- qsort(layer->portions, layer->count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare);
- }
-}
+/* ---------------------------------------------------------------------------------- */
+/* PARCOURS D'ENSEMBLES DE PORTIONS */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : layer = couche première à parcourir intégralement. *
-* count = nombre de portions trouvées et renvoyées. [OUT] *
+* Paramètres : portion = 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 : Fournit une liste triée de portions d'un binaire. *
+* Description : Recherche la portion présente à un point donné. *
* *
-* Retour : Liste de définitions de zones à libérer après usage. *
+* Retour : Portion trouvée à l'endroit indiqué. *
* *
* Remarques : - *
* *
******************************************************************************/
-GBinPortion **g_portion_layer_collect_all_portions(const GPortionLayer *layer, size_t *count)
+GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRectangle *area)
{
- GBinPortion **result; /* Liste construite à renvoyer */
+ GBinPortion *result; /* Portion à retourner */
+ phys_t full; /* Espace total représenté */
+ size_t i; /* Boucle de parcours */
+ GBinPortion *sub; /* Portion incluse à traiter */
+ GdkRectangle sub_area; /* Etendue d'une sous-portion */
- 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 */
+ result = NULL;
- start = *c;
- *c += l->count;
+ full = get_mrange_length(&portion->range);
- lst = (GBinPortion **)realloc(lst, *c * sizeof(GBinPortion *));
+ for (i = 0; i < portion->count && result == NULL; i++)
+ {
+ sub = portion->subs[i];
- for (i = 0; i < l->count; i++)
- lst[start + i] = l->portions[i];
+ if (!g_binary_portion_compute_sub_area(sub, full, area, &sub_area))
+ continue;
- return lst;
+ if (sub_area.x <= x && x < (sub_area.x + sub_area.width))
+ {
+ result = g_binary_portion_find_at_pos(sub, x, &sub_area);
- }
+ if (result != NULL)
+ *area = sub_area;
- *count = 0;
+ }
- result = do_collect(layer, NULL, count);
+ }
- qsort(result, *count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare);
+ if (result == NULL)
+ {
+ result = portion;
+ g_object_ref(G_OBJECT(result));
+ }
return result;
@@ -1016,44 +785,30 @@ GBinPortion **g_portion_layer_collect_all_portions(const GPortionLayer *layer, s
/******************************************************************************
* *
-* 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] *
+* Paramètres : portion = portion mère à consulter. *
+* addr = adresse du point de recherche. *
* *
-* Description : Recherche la portion présente à un point donné. *
+* Description : Détermine si une portion contient une adresse donnée. *
* *
-* Retour : Portion trouvée à l'endroit indiqué. *
+* Retour : true ou false selon le résultat. *
* *
* Remarques : - *
* *
******************************************************************************/
-GBinPortion *g_portion_layer_find_portion_at_pos(const GPortionLayer *layer, gint x, GdkRectangle *area)
+static bool g_portion_layer_contains_addr(const GBinPortion *portion, const vmpa2t *addr)
{
- GBinPortion *result; /* Portion à retourner */
- size_t i; /* Boucle de parcours */
- GBinPortion *sub; /* Portion incluse à traiter */
- GdkRectangle sub_area; /* Etendue d'une sous-portion */
-
- if (layer->sub_layer != NULL)
- result = g_portion_layer_find_portion_at_pos(layer->sub_layer, x, area);
- else
- result = NULL;
+ bool result; /* Bilan à retourner */
- for (i = 0; i < layer->count && result == NULL; i++)
- {
- sub = layer->portions[i];
+ result = false;
- if (!g_binary_portion_compute_sub_area(sub, layer->length, area, &sub_area))
- continue;
+ /* Portion non allouée en mémoire -> adresse nulle ; on écarte */
+ if (get_virt_addr(get_mrange_addr(&portion->range)) == 0)
+ goto not_found;
- if (sub_area.x <= x && x < (sub_area.x + sub_area.width))
- {
- result = sub;
- *area = sub_area;
- }
+ result = mrange_contains_addr(&portion->range, addr);
- }
+ not_found:
return result;
@@ -1062,9 +817,9 @@ GBinPortion *g_portion_layer_find_portion_at_pos(const GPortionLayer *layer, gin
/******************************************************************************
* *
-* 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] *
+* Paramètres : portion = 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. *
* *
@@ -1074,31 +829,39 @@ GBinPortion *g_portion_layer_find_portion_at_pos(const GPortionLayer *layer, gin
* *
******************************************************************************/
-GBinPortion *g_portion_layer_find_portion_at_addr(const GPortionLayer *layer, const vmpa2t *addr, GdkRectangle *area)
+GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *addr, GdkRectangle *area)
{
GBinPortion *result; /* Portion à retourner */
+ phys_t full; /* Espace total représenté */
size_t i; /* Boucle de parcours #1 */
GBinPortion *sub; /* Portion incluse à traiter */
GdkRectangle sub_area; /* Etendue d'une sous-portion */
- if (layer->sub_layer != NULL)
- result = g_portion_layer_find_portion_at_addr(layer->sub_layer, addr, area);
- else
- result = NULL;
+ result = NULL;
+
+ full = get_mrange_length(&portion->range);
- for (i = 0; i < layer->count && result == NULL; i++)
+ for (i = 0; i < portion->count && result == NULL; i++)
{
- sub = layer->portions[i];
+ sub = portion->subs[i];
if (!g_portion_layer_contains_addr(sub, addr))
continue;
- if (!g_binary_portion_compute_sub_area(sub, layer->length, area, &sub_area))
+ if (!g_binary_portion_compute_sub_area(sub, full, area, &sub_area))
continue;
- result = sub;
- *area = sub_area;
+ result = g_binary_portion_find_at_addr(sub, addr, &sub_area);
+
+ if (result != NULL)
+ *area = sub_area;
+
+ }
+ if (result == NULL)
+ {
+ result = portion;
+ g_object_ref(G_OBJECT(result));
}
return result;
@@ -1108,10 +871,10 @@ GBinPortion *g_portion_layer_find_portion_at_addr(const GPortionLayer *layer, co
/******************************************************************************
* *
-* 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] *
+* Paramètres : root = 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. *
* *
@@ -1121,20 +884,22 @@ GBinPortion *g_portion_layer_find_portion_at_addr(const GPortionLayer *layer, co
* *
******************************************************************************/
-bool g_portion_layer_get_addr_from_pos(GPortionLayer *layer, gint x, const GdkRectangle *area, vmpa2t *addr)
+bool get_binary_portion_addr_from_pos(GBinPortion *root, gint x, const GdkRectangle *area, vmpa2t *addr)
{
GdkRectangle owner_area; /* Aire de contenance */
GBinPortion *owner; /* Conteneur propriétaire */
owner_area = *area;
- owner = g_portion_layer_find_portion_at_pos(layer, x, &owner_area);
+ owner = g_binary_portion_find_at_pos(root, x, &owner_area);
if (owner == NULL) return false;
copy_vmpa(addr, get_mrange_addr(&owner->range));
advance_vmpa(addr, (get_mrange_length(&owner->range) * (x - owner_area.x)) / owner_area.width);
+ g_object_unref(G_OBJECT(owner));
+
return true;
}
@@ -1142,10 +907,10 @@ bool g_portion_layer_get_addr_from_pos(GPortionLayer *layer, gint x, const GdkRe
/******************************************************************************
* *
-* 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] *
+* Paramètres : root = 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. *
* *
@@ -1155,7 +920,7 @@ bool g_portion_layer_get_addr_from_pos(GPortionLayer *layer, gint x, const GdkRe
* *
******************************************************************************/
-bool g_portion_layer_get_pos_from_addr(GPortionLayer *layer, const vmpa2t *addr, const GdkRectangle *area, gint *x)
+bool get_binary_portion_pos_from_addr(GBinPortion *root, const vmpa2t *addr, const GdkRectangle *area, gint *x)
{
GdkRectangle owner_area; /* Aire de contenance */
GBinPortion *owner; /* Conteneur propriétaire */
@@ -1163,46 +928,16 @@ bool g_portion_layer_get_pos_from_addr(GPortionLayer *layer, const vmpa2t *addr,
owner_area = *area;
- owner = g_portion_layer_find_portion_at_addr(layer, addr, &owner_area);
+ owner = g_binary_portion_find_at_addr(root, addr, &owner_area);
if (owner == NULL) return false;
diff = compute_vmpa_diff(addr, get_mrange_addr(&owner->range));
*x = owner_area.x + (diff * owner_area.width) / get_mrange_length(&owner->range);
- return true;
-
-}
-
+ g_object_unref(G_OBJECT(owner));
-/******************************************************************************
-* *
-* 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 : Parcours un ensemble de portions binaires. *
-* *
-* Retour : true si la visite a été jusqu'à son terme, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_portion_layer_visit(const GPortionLayer *layer, visit_portion_fc visitor, void *data)
-{
- bool result; /* Etat à retourner */
- size_t i; /* Boucle de parcours */
-
- if (layer->sub_layer != NULL)
- result = g_portion_layer_visit(layer->sub_layer, visitor, data);
- else
- result = true;
-
- for (i = 0; i < layer->count && result; i++)
- result = visitor(layer->portions[i], data);
-
- return result;
+ return true;
}
@@ -1223,52 +958,17 @@ bool g_portion_layer_visit(const GPortionLayer *layer, visit_portion_fc visitor,
* *
******************************************************************************/
-gboolean g_portion_layer_query_tooltip(const GPortionLayer *layer, gint x, gint y, const GdkRectangle *area, GtkTooltip *tooltip)
+gboolean query_tooltip_for_binary_portion(GBinPortion *root, gint x, gint y, const GdkRectangle *area, GtkTooltip *tooltip)
{
GBinPortion *selected; /* Portion à décrire ici */
- selected = g_portion_layer_find_portion_at_pos(layer, x, (GdkRectangle []) { *area });
+ selected = g_binary_portion_find_at_pos(root, x, (GdkRectangle []) { *area });
if (selected == NULL) return FALSE;
g_binary_portion_query_tooltip(selected, tooltip);
- return TRUE;
-
-}
-
+ g_object_unref(G_OBJECT(selected));
-/******************************************************************************
-* *
-* Paramètres : layer = couche de portions à consulter. *
-* cr = contexte graphique pour le dessin. *
-* area = étendue mise à disposition. *
-* *
-* Description : Représente une couche de portions sur une bande dédiée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-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 */
-
- for (i = 0; i < layer->count; i++)
- {
- sub = layer->portions[i];
-
- 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);
+ return TRUE;
}