From 2c9fa2bc584305985ae53958ea2fb371adba3834 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 30 Jun 2009 00:00:52 +0000 Subject: Built graphic links from the flow of the code blocks. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@84 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 20 ++++++ src/analysis/binary.c | 4 +- src/analysis/line.c | 22 +++++++ src/analysis/line.h | 3 + src/graph/layout.c | 151 +++++++++++++++++++++++++++++++++++++++----- src/gtkext/gtkbinview-int.h | 2 +- src/gtkext/gtkbinview.c | 61 ++++++++++++++++++ src/gtkext/gtkbinview.h | 10 +++ src/gtkext/gtkblockview.c | 4 +- src/gtkext/gtkgraphview.c | 4 +- 10 files changed, 258 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index e60b797..94c3dd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +09-06-30 Cyrille Bagard + + * src/analysis/binary.c: + Disable the "control flow" link for conditional jumps. + + * src/analysis/line.c: + * src/analysis/line.h: + Retrieve the destination link of a line. + + * src/graph/layout.c: + Build graphic links from the flow of the code blocks. + + * src/gtkext/gtkbinview.c: + * src/gtkext/gtkbinview.h: + * src/gtkext/gtkbinview-int.h: + * src/gtkext/gtkblockview.c: + * src/gtkext/gtkgraphview.c: + Add the 'const' qualifier to some parameters when possible. Add some + functions to deal with lines/addresses of views. + 09-06-29 Cyrille Bagard * src/graph/dot.c: diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 6b5697a..e74680e 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -745,11 +745,11 @@ void establish_links_in_openida_binary(const openida_binary *binary) if (target != NULL) { g_rendering_line_link_with(iter, target, type); - + /* target = g_rendering_line_get_next_iter(binary->lines, iter, NULL); if (target != NULL) g_rendering_line_link_with(iter, target, ILT_JUMP_IF_FALSE); - + */ } break; diff --git a/src/analysis/line.c b/src/analysis/line.c index 8cfad25..958efe3 100644 --- a/src/analysis/line.c +++ b/src/analysis/line.c @@ -335,6 +335,28 @@ bool g_rendering_line_has_destination(const GRenderingLine *line) /****************************************************************************** * * +* Paramètres : line = ligne dont les informations sont à consulter. * +* type = type de lien présent. [OUT] * +* * +* Description : Fournit la ligne de code de destination du lien de la ligne. * +* * +* Retour : Ligne à l'autre extrémité du lien. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GRenderingLine *g_rendering_line_get_destination(const GRenderingLine *line, InstructionLinkType *type) +{ + *type = line->link_type; + + return line->to; + +} + + +/****************************************************************************** +* * * Paramètres : line = ligne dont les informations sont à consulter. * * stock_id = identifiant GTK de l'image à charger. * * size = taille de l'image souhaitée. * diff --git a/src/analysis/line.h b/src/analysis/line.h index aa200f8..e06c53c 100644 --- a/src/analysis/line.h +++ b/src/analysis/line.h @@ -110,6 +110,9 @@ bool g_rendering_line_has_sources(const GRenderingLine *); /* Indique si la ligne a une suite autre que la ligne suivante. */ bool g_rendering_line_has_destination(const GRenderingLine *); +/* Fournit la ligne de code de destination du lien de la ligne. */ +GRenderingLine *g_rendering_line_get_destination(const GRenderingLine *, InstructionLinkType *); + /* Procède à l'initialisation des bases d'une représentation. */ void g_rendering_line_draw(GRenderingLine *, GdkDrawable *, GdkGC *, gint, gint, gint, gint); diff --git a/src/graph/layout.c b/src/graph/layout.c index faf439b..93d6b28 100644 --- a/src/graph/layout.c +++ b/src/graph/layout.c @@ -35,9 +35,18 @@ +/* Taille maximale des descriptions de liens */ +#define LINKS_DESC_LEN 128 + + +/* Etablit tous les liens entre les différents morceaux de code. */ +static char *complete_graph_links(const GtkGraphView *, GtkBinView **, size_t, char *); + + + /****************************************************************************** * * -* Paramètres : view = support à placer les différents éléments. * +* Paramètres : view = support où placer les différents éléments. * * views = morceaux de code à afficher de façon organisée. * * count = quantité de ces morceaux de code. * * * @@ -73,40 +82,150 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count) for (i = 0; i < count; i++) cmds = g_graph_node_register_for_dot(nodes[i], cmds); + cmds = complete_graph_links(view, views, count, cmds); + + cmds = stradd(cmds, "}"); + + printf("first step :: '%s'\n", cmds); + + layout = create_graph_layout(cmds); + /* Affichage du graphique */ + place_nodes_of_graph_layout(layout, GTK_FIXED(view), nodes, count); + links = create_links_from_graph_layout(layout, &links_count); + gtk_graph_view_attach_links(view, links, links_count); + delete_graph_layout(layout); + + /* TODO : free nodes */ + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : view = support contenant les différentes lignes. * +* views = morceaux de code à afficher de façon organisée. * +* count = quantité de ces morceaux de code. * +* desc = description du graphique à compléter. * +* * +* Description : Etablit tous les liens entre les différents morceaux de code.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static char *complete_graph_links(const GtkGraphView *view, GtkBinView **views, size_t count, char *desc) +{ + size_t i; /* Boucle de parcours #1 */ + GRenderingLine *last; /* Dernière ligne d'un bloc */ + GRenderingLine *dest; /* Ligne visée par une autre */ + InstructionLinkType type; /* Type de lien entre lignes */ + bool link_next; /* Lien auto. avec la suivante */ + vmpa_t addr; /* Addresse de destination */ + size_t k; /* Boucle de parcours #2 */ + char buffer[LINKS_DESC_LEN]; /* Tampon pour l'ajout de liens*/ - for (i = 0; (i + 1) < count; i++) + for (i = 0; i < count; i++) { - char buffer[128]; - snprintf(buffer, 128, "_%p -> _%p;\n", views[i], views[i + 1]); - cmds = stradd(cmds, buffer); - } + last = gtk_bin_view_get_last_line(views[i]); + if (g_rendering_line_has_destination(last)) + { + link_next = false; + /* Premier saut : exigé par l'instruction */ + dest = g_rendering_line_get_destination(last, &type); + addr = get_rendering_line_address(dest); - cmds = stradd(cmds, "}"); + for (k = 0; k < count; k++) + if (gtk_bin_view_contain_address(views[k], addr)) + break; - printf("first step :: '%s'\n", cmds); + if (k < count) + switch (type) + { + case ILT_JUMP: + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + break; - layout = create_graph_layout(cmds); + case ILT_JUMP_IF_TRUE: + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + link_next = true; + break; - /* Affichage du graphique */ + case ILT_JUMP_IF_FALSE: + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + link_next = true; + break; - place_nodes_of_graph_layout(layout, GTK_FIXED(view), nodes, count); + default: + break; - links = create_links_from_graph_layout(layout, &links_count); - gtk_graph_view_attach_links(view, links, links_count); + } - delete_graph_layout(layout); + /* Second saut : automatique selon l'instruction */ - /* TODO : free nodes */ + if (link_next) + { + dest = g_rendering_line_get_next_iter(gtk_bin_view_get_lines(GTK_BIN_VIEW(view)), + last, + gtk_bin_view_get_last_line(GTK_BIN_VIEW(view))); - return true; + if (dest == NULL) continue; + + addr = get_rendering_line_address(dest); + + for (k = 0; k < count; k++) + if (gtk_bin_view_contain_address(views[k], addr)) + break; + + if (k < count) + { + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + } + + } + + } + + /* Si la ligne n'est pas la dernière, on suit le flux normal */ + else if (last != gtk_bin_view_get_last_line(view)) + { + dest = g_rendering_line_get_next_iter(gtk_bin_view_get_lines(GTK_BIN_VIEW(view)), + last, + gtk_bin_view_get_last_line(GTK_BIN_VIEW(view))); + + if (dest == NULL) continue; + + addr = get_rendering_line_address(dest); + + for (k = 0; k < count; k++) + if (gtk_bin_view_contain_address(views[k], addr)) + break; + + if (k < count) + { + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + } + + } + + } + + return desc; } diff --git a/src/gtkext/gtkbinview-int.h b/src/gtkext/gtkbinview-int.h index 63334d5..2410915 100644 --- a/src/gtkext/gtkbinview-int.h +++ b/src/gtkext/gtkbinview-int.h @@ -40,7 +40,7 @@ typedef void (* set_rendering_lines_fc) (GtkBinview *, GRenderingLine *, GRender 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 *); +typedef bool (* get_addr_coordinates_fc) (const GtkBinView *, vmpa_t, gint *, gint *); struct _GtkBinview diff --git a/src/gtkext/gtkbinview.c b/src/gtkext/gtkbinview.c index ccb533f..aa231f2 100644 --- a/src/gtkext/gtkbinview.c +++ b/src/gtkext/gtkbinview.c @@ -247,6 +247,44 @@ void gtk_bin_view_set_rendering_lines(GtkBinview *view, openida_binary *binary, } +/****************************************************************************** +* * +* Paramètres : view = composant GTK à consulter. * +* * +* Description : Fournit la liste des lignes associées à la représentation. * +* * +* Retour : Ligne de représentation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GRenderingLine *gtk_bin_view_get_lines(const GtkBinview *view) +{ + return view->lines; + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à consulter. * +* * +* Description : Fournit la dernière ligne associée à la représentation. * +* * +* Retour : Ligne de représentation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GRenderingLine *gtk_bin_view_get_last_line(const GtkBinview *view) +{ + return view->last; /* FIXME last == NULL */ + +} + + @@ -330,6 +368,29 @@ void gtk_binview_show_code(GtkBinview *binview, gboolean show) /****************************************************************************** * * * Paramètres : view = composant GTK à manipuler. * +* addr = adresse à rechercher. * +* * +* Description : Indique si la vue contient une addrese donnée. * +* * +* Retour : true si l'adresse est présente, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_bin_view_contain_address(const GtkBinview *view, vmpa_t addr) +{ + gint dummy_x; /* Abscisse pour l'appel */ + gint dummy_y; /* Ordonnée pour l'appel */ + + return view->get_coordinates(view, addr, &dummy_x, &dummy_y); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à manipuler. * * addr = adresse à présenter à l'écran. * * * * Description : S'assure qu'une adresse donnée est visible à l'écran. * diff --git a/src/gtkext/gtkbinview.h b/src/gtkext/gtkbinview.h index 978c146..241669c 100644 --- a/src/gtkext/gtkbinview.h +++ b/src/gtkext/gtkbinview.h @@ -62,6 +62,13 @@ void gtk_bin_view_show_border(GtkBinview *, bool); /* Définit les lignes à associer à la représentation. */ void gtk_bin_view_set_rendering_lines(GtkBinview *, openida_binary *, GRenderingLine *, GRenderingLine *); +/* Fournit la liste des lignes associées à la représentation. */ +GRenderingLine *gtk_bin_view_get_lines(const GtkBinview *); + +/* Fournit la dernière ligne associée à la représentation. */ +GRenderingLine *gtk_bin_view_get_last_line(const GtkBinview *); + + @@ -73,6 +80,9 @@ void gtk_binview_show_code(GtkBinview *, gboolean); +/* Indique si la vue contient une addrese donnée. */ +bool gtk_bin_view_contain_address(const GtkBinview *, vmpa_t); + /* S'assure qu'une adresse donnée est visible à l'écran. */ void gtk_bin_view_scroll_to_address(GtkBinview *, vmpa_t); diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c index b03bbff..cfd4ee0 100644 --- a/src/gtkext/gtkblockview.c +++ b/src/gtkext/gtkblockview.c @@ -91,7 +91,7 @@ void gtk_block_view_recompute_size_request(GtkBlockView *); /* Indique la position d'affichage d'une adresse donnée. */ -static bool gtk_block_view_get_address_coordinates(GtkBlockView *, vmpa_t, gint *, gint *); +static bool gtk_block_view_get_address_coordinates(const GtkBlockView *, vmpa_t, gint *, gint *); @@ -571,7 +571,7 @@ void gtk_block_view_recompute_size_request(GtkBlockView *view) * * ******************************************************************************/ -static bool gtk_block_view_get_address_coordinates(GtkBlockView *view, vmpa_t addr, gint *x, gint *y) +static bool gtk_block_view_get_address_coordinates(const GtkBlockView *view, vmpa_t addr, gint *x, gint *y) { bool result; /* Bilan à retourner */ GRenderingLine *iter; /* Boucle de parcours */ diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c index dae1d54..d060f69 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphview.c @@ -75,7 +75,7 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *, GRenderingLine *, 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 *); +static bool gtk_graph_view_get_address_coordinates(const 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 *); @@ -349,7 +349,7 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr) * * ******************************************************************************/ -static bool gtk_graph_view_get_address_coordinates(GtkGraphView *view, vmpa_t addr, gint *x, gint *y) +static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, vmpa_t addr, gint *x, gint *y) { bool result; /* Bilan à retourner */ size_t i; /* Boucle de parcours */ -- cgit v0.11.2-87-g4458