summaryrefslogtreecommitdiff
path: root/src/gtkext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-06-25 00:34:22 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-06-25 00:34:22 (GMT)
commitf2696c85e502e36a529a1d8ee3d209498ac2c0e9 (patch)
tree3d8ffe28a730d32c98e8d048b99f67b7856acec9 /src/gtkext
parent23c7cd436e2ec980a68e6d12a6d8a750e357763c (diff)
Used Graphviz library for building graphs (first attempt).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@80 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gtkext')
-rw-r--r--src/gtkext/Makefile.am2
-rw-r--r--src/gtkext/gtkbinview-int.h6
-rw-r--r--src/gtkext/gtkbinview.c14
-rw-r--r--src/gtkext/gtkbinview.h5
-rw-r--r--src/gtkext/gtkgraphview.c183
5 files changed, 200 insertions, 10 deletions
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 421a1c4..a7023c5 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -18,7 +18,7 @@ libgtkext_la_SOURCES = \
libgtkext_la_LDFLAGS =
-INCLUDES = $(LIBGTK_CFLAGS)
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
AM_CPPFLAGS =
diff --git a/src/gtkext/gtkbinview-int.h b/src/gtkext/gtkbinview-int.h
index fffbc9f..0c17554 100644
--- a/src/gtkext/gtkbinview-int.h
+++ b/src/gtkext/gtkbinview-int.h
@@ -36,6 +36,9 @@
/* Définit les lignes à associer à la représentation. */
typedef void (* set_rendering_lines_fc) (GtkBinview *, GRenderingLine *, GRenderingLine *);
+/* Réagit à la sélection externe d'une adresse. */
+typedef void (* define_main_address_fc) (GtkBinView *, vmpa_t);
+
/* Indique la position d'affichage d'une adresse donnée. */
typedef bool (* get_addr_coordinates_fc) (GtkBinView *, vmpa_t, gint *, gint *);
@@ -44,10 +47,13 @@ struct _GtkBinview
{
GtkFixed parent; /* A laisser en premier */
+ openida_binary *binary; /* Contenu binaire affiché */
+
GRenderingLine *lines; /* Contenu à représenter */
GRenderingLine *last; /* Dernière ligne associée */
set_rendering_lines_fc set_lines; /* Association des lignes */
+ define_main_address_fc define_address; /* Sélection externe d'adresse */
get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */
};
diff --git a/src/gtkext/gtkbinview.c b/src/gtkext/gtkbinview.c
index 3799b25..2cb046f 100644
--- a/src/gtkext/gtkbinview.c
+++ b/src/gtkext/gtkbinview.c
@@ -110,9 +110,10 @@ GtkWidget* gtk_binview_new(void)
/******************************************************************************
* *
-* Paramètres : view = composant GTK à mettre à jour. *
-* lines = informations à intégrer. *
-* last = dernière ligne à intégrer ou NULL pour toutes. *
+* Paramètres : view = composant GTK à mettre à jour. *
+* binary = contenu binaire dont les lignes sont issues. *
+* lines = informations à intégrer. *
+* last = dernière ligne à intégrer ou NULL pour toutes. *
* *
* Description : Définit les lignes à associer à la représentation. *
* *
@@ -122,8 +123,10 @@ GtkWidget* gtk_binview_new(void)
* *
******************************************************************************/
-void gtk_bin_view_set_rendering_lines(GtkBinview *view, GRenderingLine *lines, GRenderingLine *last)
+void gtk_bin_view_set_rendering_lines(GtkBinview *view, openida_binary *binary, GRenderingLine *lines, GRenderingLine *last)
{
+ view->binary = binary;
+
view->lines = lines;
view->last = last;
@@ -232,6 +235,9 @@ void gtk_bin_view_scroll_to_address(GtkBinview *view, vmpa_t addr)
GtkViewport *support; /* Support avec défilements */
GtkAdjustment *adj; /* Défilement à mettre à jour */
+ if (view->define_address != NULL)
+ view->define_address(view, addr);
+
if (view->get_coordinates(view, addr, &x, &y))
{
support = GTK_VIEWPORT(gtk_widget_get_parent(GTK_WIDGET(view)));
diff --git a/src/gtkext/gtkbinview.h b/src/gtkext/gtkbinview.h
index a80cda3..10f1c2f 100644
--- a/src/gtkext/gtkbinview.h
+++ b/src/gtkext/gtkbinview.h
@@ -28,8 +28,7 @@
#include <gtk/gtkwidget.h>
-#include "../analysis/line.h"
-#include "../arch/archbase.h"
+#include "../analysis/binary.h"
@@ -58,7 +57,7 @@ GtkWidget* gtk_binview_new(void);
/* Définit les lignes à associer à la représentation. */
-void gtk_bin_view_set_rendering_lines(GtkBinview *, GRenderingLine *, GRenderingLine *);
+void gtk_bin_view_set_rendering_lines(GtkBinview *, openida_binary *, GRenderingLine *, GRenderingLine *);
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 80ca06b..8389148 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -25,6 +25,7 @@
#include "gtkbinview-int.h"
+#include "../graph/layout.h"
#include <malloc.h>
@@ -36,6 +37,9 @@ struct _GtkGraphView
{
GtkBinView parent; /* A laisser en premier */
+ vmpa_t start; /* Début de la portion vue */
+ vmpa_t end; /* Fin de la portion affichée */
+
GtkBinView **childs; /* Liste des sous-blocs */
size_t childs_count; /* Taille de cette liste */
@@ -55,12 +59,20 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *);
/* Initialise une instance d'afficheur de code en graphique. */
static void gtk_graph_view_init(GtkGraphView *);
+/* Supprime tout contenu de l'afficheur de code en graphique. */
+static void gtk_graph_view_reset(GtkGraphView *);
+
/* Définit les lignes du graphique de représentation. */
static void gtk_graph_view_set_rendering_lines(GtkGraphView *, GRenderingLine *, GRenderingLine *);
+/* Réagit à la sélection externe d'une adresse. */
+static void gtk_graph_view_define_main_address(GtkGraphView *, vmpa_t);
+
/* Indique la position d'affichage d'une adresse donnée. */
static bool gtk_graph_view_get_address_coordinates(GtkGraphView *, vmpa_t, gint *, gint *);
+/* Définit la liste complète des éléments du futur graphique. */
+static GtkBinView **gtk_graph_view_load_nodes(openida_binary *, GRenderingLine *, GRenderingLine *, size_t *);
/* Détermine le type du composant d'affichage en graphique. */
@@ -104,6 +116,7 @@ static void gtk_graph_view_init(GtkGraphView *view)
binview = GTK_BIN_VIEW(view);
binview->set_lines = (set_rendering_lines_fc)gtk_graph_view_set_rendering_lines;
+ binview->define_address = (define_main_address_fc)gtk_graph_view_define_main_address;
binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
}
@@ -128,6 +141,36 @@ GtkWidget* gtk_graph_view_new(void)
}
+/******************************************************************************
+* *
+* Paramètres : view = instance GTK à réinitialiser. *
+* *
+* Description : Supprime tout contenu de l'afficheur de code en graphique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_view_reset(GtkGraphView *view)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < view->childs_count; i++)
+ gtk_widget_destroy(view->childs[i]);
+
+ if (view->childs_count > 0)
+ {
+ free(view->childs);
+ view->childs = NULL;
+
+ view->childs_count = 0;
+
+ }
+
+}
+
@@ -161,7 +204,7 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->childs[0]), 50, 50);
- gtk_bin_view_set_rendering_lines(view->childs[0], lines, lines);
+ gtk_bin_view_set_rendering_lines(view->childs[0], GTK_BIN_VIEW(view)->binary, lines, lines);
@@ -176,7 +219,7 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->childs[1]), 100, 450);
- gtk_bin_view_set_rendering_lines(view->childs[1], mainl, mainl);
+ gtk_bin_view_set_rendering_lines(view->childs[1], GTK_BIN_VIEW(view)->binary, mainl, mainl);
@@ -191,6 +234,65 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
/******************************************************************************
* *
+* Paramètres : view = composant GTK à mettre à jour. *
+* addr = adresse sélectionnée de manière externe. *
+* *
+* Description : Réagit à la sélection externe d'une adresse. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr)
+{
+ exe_format *format; /* Type de fichier chargé */
+ GBinRoutine **routines; /* Liste des routines trouvées */
+ size_t routines_count; /* Nombre de ces routines */
+ size_t i; /* Boucle de parcours */
+ vmpa_t start; /* Début d'une routine */
+ vmpa_t end; /* Fin d'une routine */
+ GRenderingLine *first; /* Première ligne à traiter */
+ GRenderingLine *last; /* Dernière ligne à traiter */
+
+ if (!(view->start <= addr && addr < view->end))
+ {
+ gtk_graph_view_reset(view);
+
+ format = get_openida_binary_format(GTK_BIN_VIEW(view)->binary);
+ routines = get_all_exe_routines(format, &routines_count);
+
+ for (i = 0; i < routines_count; i++)
+ {
+ start = g_binary_routine_get_address(routines[i]);
+ end = start + g_binary_routine_get_size(routines[i]);
+
+ if (start <= addr && addr < end)
+ {
+ view->start = start;
+ view->end = end;
+
+ first = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, start);
+ last = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, end);
+
+ view->childs = gtk_graph_view_load_nodes(GTK_BIN_VIEW(view)->binary, first, last, &view->childs_count);
+
+ build_graph_view(GTK_FIXED(view), view->childs, view->childs_count);
+
+ break;
+
+ }
+
+ }
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = composant GTK à consulter. *
* addr = adresse à présenter à l'écran. *
* x = position horizontale au sein du composant. [OUT] *
@@ -225,3 +327,80 @@ static bool gtk_graph_view_get_address_coordinates(GtkGraphView *view, vmpa_t ad
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = contenu binaire à l'origine des lignes. *
+* first = première ligne à analyser. *
+* last = dernière ligne à analyser. *
+* count = nombre d'éléments créés. [OUT] *
+* *
+* Description : Définit la liste complète des éléments du futur graphique. *
+* *
+* Retour : Liste d'éléments du graphique à placer. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkBinView **gtk_graph_view_load_nodes(openida_binary *binary, GRenderingLine *first, GRenderingLine *last, size_t *count)
+{
+ GtkBinView **result; /* Liste à retourner */
+ GRenderingLine *begin; /* Début d'un groupe de lignes */
+ GRenderingLine *end; /* Fin d'un groupe de lignes */
+ GRenderingLine *iter; /* Boucle de parcours */
+
+ result = NULL;
+ *count = 0;
+
+ begin = NULL;
+
+ for (iter = first; iter != NULL; iter = g_rendering_line_get_next_iter(first, iter, last))
+ {
+ if (begin != NULL && g_rendering_line_has_sources(iter))
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ begin = NULL;
+
+ }
+
+ if (begin == NULL) begin = iter;
+ end = iter;
+
+ if (g_rendering_line_has_destination(iter))
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ begin = NULL;
+
+ }
+
+ }
+
+ if (begin != NULL)
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ }
+
+ return result;
+
+
+}