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  { | 
