diff options
Diffstat (limited to 'src/gtkext/gtkgraphview.c')
-rw-r--r-- | src/gtkext/gtkgraphview.c | 183 |
1 files changed, 181 insertions, 2 deletions
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; + + +} |