summaryrefslogtreecommitdiff
path: root/src/gtkext/graph/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/graph/layout.c')
-rw-r--r--src/gtkext/graph/layout.c398
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, &params);
- build_graph_ranking(&params);
-
- g_instr_block_visit(blocks, (instr_block_visitor_cb)register_graph_nodes, &params);
-
- 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
{