diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-04-06 10:15:41 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-04-06 10:15:41 (GMT) |
commit | e108e192582aa1dbe020dfbc09bee5e6ab2cc534 (patch) | |
tree | ff037f19f3ab5ee2aabb8f1cd62d6c7f634179ad /src/gtkext/graph/layout.c | |
parent | 40d624af29e752bb4255099ab3f1de64e3c96dd3 (diff) |
Said goodbye to Graphviz.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@505 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gtkext/graph/layout.c')
-rw-r--r-- | src/gtkext/graph/layout.c | 398 |
1 files changed, 1 insertions, 397 deletions
diff --git a/src/gtkext/graph/layout.c b/src/gtkext/graph/layout.c index 2e3759a..de83a22 100644 --- a/src/gtkext/graph/layout.c +++ b/src/gtkext/graph/layout.c @@ -25,411 +25,15 @@ #include <malloc.h> -#include <string.h> -#include <gtk/gtkfixed.h> -#include "dot.h" #include "node.h" -#include "nodes/flow.h" -#include "../gtkbufferview.h" -#include "../../analysis/binary.h" -#include "../../analysis/blocks/flow.h" -#include "../../common/extstr.h" - - - -/* Taille maximale des noms de classement */ -#define RANK_DESC_LEN 128 - -/* Taille maximale des introductions aux clusters */ -#define CLUSTER_DESC_LEN 128 - -/* Taille maximale des descriptions de liens */ -#define LINKS_DESC_LEN 128 - - -/* Paramètres de construction des commandes */ -typedef struct _visitor_dot_params -{ - GGraphNode **nodes; /* Intermédiaires en place */ - size_t count; /* Quantité de noeuds en place */ - - char **ranks; /* Profondeurs des blocs */ - - unsigned int level; /* Profondeur de la visite */ - char *cmds; /* Description à envoyer à dot */ - -} visitor_dot_params; - - -/* Construit les rangs pour dot en parcourant les noeuds. */ -static bool rank_graph_nodes(GInstrBlock *, BlockVisitOrder, visitor_dot_params *); - -/* Etablit le classement de tous les prochains noeuds pour dot. */ -static void build_graph_ranking(visitor_dot_params *); - -/* Construit les commandes pour dot en parcourant les noeuds. */ -static bool register_graph_nodes(GInstrBlock *, BlockVisitOrder, visitor_dot_params *); - -/* Etablit tous les liens entre les différents morceaux de code. */ -static char *complete_graph_links(const GtkGraphView *, GtkViewPanel **, size_t, char *); - - - -/****************************************************************************** -* * -* 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. * -* * -* Description : Dispose une série de morceaux d'affichage en graphique. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool build_graph_view(GtkGraphView *view, GInstrBlock *blocks, GtkViewPanel **views, size_t count) -{ - visitor_dot_params params; /* Paramètres de construction */ - size_t i; /* Boucle de parcours */ - graph_layout *layout; /* Graphique construit */ - GtkLinkRenderer **links; /* Liens graphiques construits */ - size_t links_count; /* Quantité de ces liens */ - - /* Création de la glue */ - - params.nodes = (GGraphNode **)calloc(count, sizeof(GGraphNode *)); - params.count = count; - - for (i = 0; i < count; i++) - params.nodes[i] = g_graph_node_new(GTK_WIDGET(views[i])); - - /* Définition du graphique */ - - params.level = 1; - params.cmds = strdup("digraph G {\n overlap=false;\n splines=ortho;\n compound=true;\n"); - - params.ranks = (char **)calloc(count, sizeof(char *)); - - g_instr_block_visit(blocks, (instr_block_visitor_cb)rank_graph_nodes, ¶ms); - build_graph_ranking(¶ms); - - g_instr_block_visit(blocks, (instr_block_visitor_cb)register_graph_nodes, ¶ms); - - params.cmds = complete_graph_links(view, views, count, params.cmds); - - params.cmds = stradd(params.cmds, "}"); - - layout = create_graph_layout(params.cmds); - - /* Affichage du graphique */ - - place_nodes_of_graph_layout(layout, view, params.nodes, count); - - links = create_links_from_graph_layout(layout, &links_count, params.nodes, count); - gtk_graph_view_attach_links(view, links, links_count); - - gtk_widget_queue_draw(GTK_WIDGET(view)); - - delete_graph_layout(layout); - - for (i = 0; i < count; i++) - g_object_unref(params.nodes[i]); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions concerné par la visite. * -* order = position dans la visite. * -* params = informations à mettre à jour pour dot. * -* * -* Description : Construit les rangs pour dot en parcourant les noeuds. * -* * -* Retour : true si le parcours a été jusqu'à son terme, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool rank_graph_nodes(GInstrBlock *block, BlockVisitOrder order, visitor_dot_params *params) -{ - vmpa2t start; /* Adresse de départ d'un bloc */ - GGraphNode *node; /* Noeud rattaché */ - unsigned int rank; /* Classement du bloc lié */ - - if (G_IS_FLOW_BLOCK(block)) - { - g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(block), &start, NULL); - node = find_graph_node_by_start_address(params->nodes, params->count, &start); - - rank = g_flow_block_get_rank(G_FLOW_BLOCK(block)); - /* BUG_ON(count >= params->count) */ - - params->ranks[rank] = g_graph_node_append_name_to_rank(node, params->ranks[rank]); - - } - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : params = informations à mettre à jour pour dot. * -* * -* Description : Etablit le classement de tous les prochains noeuds pour dot. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void build_graph_ranking(visitor_dot_params *params) -{ - unsigned int id; /* Identifiant unique */ - size_t i; /* Boucle de parcours #1 */ - char buffer[RANK_DESC_LEN]; /* Tampon pour les commandes */ - unsigned int j; /* Boucle de parcours #2 */ - - id = 0; - - for (i = 0; i < params->count; i++) - { - if (params->ranks[i] == NULL) - continue; - - snprintf(buffer, CLUSTER_DESC_LEN, DOT_IDENT "{ rank = same; rk%u;", id++); - params->cmds = stradd(params->cmds, buffer); - - params->cmds = stradd(params->cmds, params->ranks[i]); - - params->cmds = stradd(params->cmds, " }\n"); - - } - - params->cmds = stradd(params->cmds, DOT_IDENT); - - for (j = 0; j < id; j++) - { - if (j == 0) - snprintf(buffer, CLUSTER_DESC_LEN, "rk%u", j); - else - snprintf(buffer, CLUSTER_DESC_LEN, " -> rk%u", j); - - params->cmds = stradd(params->cmds, buffer); - - } - - params->cmds = stradd(params->cmds, "\n"); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions concerné par la visite. * -* order = position dans la visite. * -* params = informations à mettre à jour pour dot. * -* * -* Description : Construit les commandes pour dot en parcourant les noeuds. * -* * -* Retour : true si le parcours a été jusqu'à son terme, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool register_graph_nodes(GInstrBlock *block, BlockVisitOrder order, visitor_dot_params *params) -{ - char *cmds; /* Raccourci d'usage pratique */ - vmpa2t start; /* Adresse de départ d'un bloc */ - GGraphNode *node; /* Noeud rattaché */ - unsigned int i; /* Boucle de parcours */ - char buffer[CLUSTER_DESC_LEN]; /* Tampon pour les commandes */ - - cmds = params->cmds; - - if (G_IS_FLOW_BLOCK(block)) - { - g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(block), &start, NULL); - node = find_graph_node_by_start_address(params->nodes, params->count, &start); - - cmds = g_graph_node_register_for_dot(node, cmds, params->level); - - } - else - { - if (order == BVO_IN) - { - for (i = 0; i < params->level; i++) - cmds = stradd(cmds, DOT_IDENT); - - snprintf(buffer, CLUSTER_DESC_LEN, "subgraph cluster_v%p {\n", block); - cmds = stradd(cmds, buffer); - - params->level++; - - for (i = 0; i < params->level; i++) - cmds = stradd(cmds, DOT_IDENT); - - cmds = stradd(cmds, "style=invisible;\n"); - - } - else if (order == BVO_OUT) - { - params->level--; - - for (i = 0; i < params->level; i++) - cmds = stradd(cmds, DOT_IDENT); - - cmds = stradd(cmds, "}\n"); - - } - - } - - params->cmds = cmds; - - 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. [OUT] * -* * -* Description : Etablit tous les liens entre les différents morceaux de code.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views, size_t count, char *desc) -{ - GLoadedBinary *binary; /* Binaire rattaché aux vues */ - GArchInstruction *instrs; /* Instructions pour assembleur*/ - GBufferView *buffer; /* Tampon d'une partie de code */ - vmpa_t end; /* Adresse finale du tampon */ - size_t i; /* Boucle de parcours #1 */ - GArchInstruction *last; /* Dernière instruc. d'un bloc */ - vmpa_t addr; /* Addresse d'instruction */ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ - size_t dcount; /* Nombre de liens de dest. */ - size_t j; /* Boucle de parcours #2 */ - size_t k; /* Boucle de parcours #3 */ - char cmd[LINKS_DESC_LEN]; /* Tampon pour l'ajout de liens*/ - - if (count == 0) - return desc; - - binary = gtk_view_panel_get_binary(views[0]); - instrs = g_loaded_binary_get_instructions(binary); - - for (i = 0; i < count; i++) - { - buffer = gtk_buffer_view_get_buffer(GTK_BUFFER_VIEW(views[i])); - g_buffer_view_get_restrictions(buffer, NULL, &end); - - last = g_arch_instruction_find_by_address(instrs, end, true); - g_arch_instruction_get_location(last, NULL, NULL, &addr); - - if (g_arch_instruction_has_destinations(last)) - { - dcount = g_arch_instruction_get_destinations(last, &dests, &types, NULL); - - for (j = 0; j < dcount; j++) - { - g_arch_instruction_get_location(dests[j], NULL, NULL, &addr); - - for (k = 0; k < count; k++) - if (gtk_view_panel_contain_address(views[k], addr)) - break; - - if (k < count) - switch (types[j]) - { - case ILT_EXEC_FLOW: - case ILT_JUMP: - case ILT_CASE_JUMP: - snprintf(cmd, LINKS_DESC_LEN, - "_%p:s -> _%p:n [ltail=cluster_%p, lhead=cluster_%p];\n", - views[i], views[k], views[i], views[k]); - desc = stradd(desc, cmd); - break; - - case ILT_JUMP_IF_TRUE: - snprintf(cmd, LINKS_DESC_LEN, - "_%p:s -> _%p:n [ltail=cluster_%p, lhead=cluster_%p, " \ - "color=green];\n", - views[i], views[k], views[i], views[k]); - desc = stradd(desc, cmd); - break; - - case ILT_JUMP_IF_FALSE: - snprintf(cmd, LINKS_DESC_LEN, - "_%p:s -> _%p:n [ltail=cluster_%p, lhead=cluster_%p, " \ - "color=red];\n", - views[i], views[k], views[i], views[k]); - desc = stradd(desc, cmd); - break; - - case ILT_LOOP: - snprintf(cmd, LINKS_DESC_LEN, - "_%p:s -> _%p:n [ltail=cluster_%p, lhead=cluster_%p, " \ - "color=blue];\n", - views[i], views[k], views[i], views[k]); - desc = stradd(desc, cmd); - break; - - case ILT_CATCH_EXCEPTION: - snprintf(cmd, LINKS_DESC_LEN, - "_%p:s -> _%p:n [ltail=cluster_%p, lhead=cluster_%p, " \ - "color=gray];\n", - views[i], views[k], views[i], views[k]); - desc = stradd(desc, cmd); - break; - - default: - break; - - } - - } - - } - - } - - return desc; - -} - - - - - #include "ranks.h" +#include "nodes/flow.h" #include "nodes/virtual.h" - /* Mise en disposition de blocs en graphique (instance) */ struct _GGraphLayout { |