From 866993263387f96ebe2e482d63c9c4225e2c6085 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 13 Nov 2012 20:31:09 +0000
Subject: Improved the flow graph a little more.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@283 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                     | 17 ++++++++++++++++
 src/arch/dalvik/instruction.c | 12 ++++++++++++
 src/gtkext/graph/dot.c        | 26 ++++++++++++-------------
 src/gtkext/graph/layout.c     |  5 ++++-
 src/gtkext/graph/node.c       |  2 ++
 src/gtkext/gtkgraphview.c     | 45 ++++++++++++++++++++++++++++---------------
 6 files changed, 78 insertions(+), 29 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9580c23..0d4df40 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+12-11-13  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/arch/dalvik/instruction.c:
+	Add links for 'goto' instructions too.
+
+	* src/gtkext/graph/dot.c:
+	Typos.
+
+	* src/gtkext/graph/layout.c:
+	Mark 'return' instructions as pitfalls.
+
+	* src/gtkext/graph/node.c:
+	Avoid a graphical bug with wrong edges.
+
+	* src/gtkext/gtkgraphview.c:
+	Typos. Add more space around the right and bottom sides.
+
 12-11-11  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/gtkext/gtkdockstation.c:
diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c
index a1f29bc..065c67a 100644
--- a/src/arch/dalvik/instruction.c
+++ b/src/arch/dalvik/instruction.c
@@ -508,6 +508,18 @@ static InstructionLinkType dalvik_get_instruction_link(const GDalvikInstruction
 
     switch (instr->type)
     {
+        case DOP_GOTO:
+        case DOP_GOTO_16:
+        case DOP_GOTO_32:
+
+            operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 0);
+            imm = g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand));
+
+            if (g_imm_operand_to_vmpa_t(imm, addr)) result = ILT_JUMP;
+            else result = ILT_NONE;
+
+            break;
+
         case DOP_IF_EQ:
         case DOP_IF_NE:
         case DOP_IF_LT:
diff --git a/src/gtkext/graph/dot.c b/src/gtkext/graph/dot.c
index 396aa93..4c35089 100644
--- a/src/gtkext/graph/dot.c
+++ b/src/gtkext/graph/dot.c
@@ -188,12 +188,12 @@ GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, siz
     GdkPoint *points;                       /* Points de ligne relus       */
     size_t points_count;                    /* Nombre de ces points        */
     splines *lines;                         /* Lignes déjà tracées         */
+    Agsym_t *attrib;                        /* Couleur d'un lien           */
+    LinkColor color;                        /* Couleur d'impression        */
     GGraphNode *node;                       /* Noeud rattaché              */
     int i;                                  /* Boucle de parcours #3       */
     int k;                                  /* Boucle de parcours #4       */
     bezier *bez;                            /* Courbe à reproduire         */
-    Agsym_t *attrib;                        /* Couleur d'un lien           */
-    LinkColor color;                        /* Couleur d'impression        */
 
     result = NULL;
     *count = 0;
@@ -208,6 +208,17 @@ GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, siz
 
             lines = ED_spl(eiter);
 
+            /* Détermination de la couleur */
+
+            attrib = agfindedgeattr(agraphof(agtail(eiter)), "color");
+
+            if (eiter->attr[attrib->index][0] == 'g')   /* "green" */
+                color = LKC_GREEN;
+            else if (eiter->attr[attrib->index][0] == 'r')   /* "red" */
+                color = LKC_RED;
+            else
+                color = LKC_DEFAULT;
+
             /* Raccordement au point de départ */
 
             node = find_graph_node_by_name(nodes, ncount, agtail(eiter)->name);
@@ -244,19 +255,8 @@ GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, siz
                                  height - bez->list[k - 1].y,
                                  &points, &points_count);
 
-            /* Détermination de la couleur */
-
-            attrib = agfindedgeattr(agraphof(agtail(eiter)), "color");
-
             result = (GtkLinkRenderer **)realloc(result, ++(*count) * sizeof(GtkLinkRenderer *));
 
-            if (eiter->attr[attrib->index][0] == 'g')   /* "green" */
-                color = LKC_GREEN;
-            else if (eiter->attr[attrib->index][0] == 'r')   /* "red" */
-                color = LKC_RED;
-            else
-                color = LKC_DEFAULT;
-
             result[*count - 1] = GTK_LINK_RENDERER(gtk_link_renderer_new(color,
                                                                          points, points_count));
 
diff --git a/src/gtkext/graph/layout.c b/src/gtkext/graph/layout.c
index 69e32cc..64a8236 100644
--- a/src/gtkext/graph/layout.c
+++ b/src/gtkext/graph/layout.c
@@ -78,7 +78,7 @@ bool build_graph_view(GtkGraphView *view, GtkViewPanel **views, size_t count)
  
     /* Définition du graphique */
 
-    cmds = strdup("digraph G {\noverlap=false;\n  splines=ortho;\n  compound=true;\n");
+    cmds = strdup("digraph G {\n  overlap=false;\n  splines=ortho;\n  compound=true;\n");
 
     for (i = 0; i < count; i++)
         cmds = g_graph_node_register_for_dot(nodes[i], cmds);
@@ -203,6 +203,9 @@ static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views
         /* Sinon on suit le flux normal */
         else
         {
+            if (g_arch_instruction_is_return(last))
+                continue;
+
             next = g_arch_instruction_get_next_iter(instrs, last, VMPA_MAX);
             if (next == NULL) continue;
 
diff --git a/src/gtkext/graph/node.c b/src/gtkext/graph/node.c
index e2af8f7..0d746e2 100644
--- a/src/gtkext/graph/node.c
+++ b/src/gtkext/graph/node.c
@@ -314,6 +314,8 @@ void g_graph_node_connect(const GGraphNode *node, gint x, gint y, GdkPoint **poi
         (*points)[*count - 1].y = alloc->y + alloc->height;
     }
 
+    else (*count)--;
+
 }
 
 
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index e1a943b..f205ee2 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -43,9 +43,9 @@ struct _GtkGraphView
     vmpa_t start;                           /* Début de la portion vue     */
     vmpa_t end;                             /* Fin de la portion affichée  */
 
-    GtkViewPanel **childs;                  /* Liste des sous-blocs        */
+    GtkViewPanel **children;                /* Liste des sous-blocs        */
     GtkAllocation *allocs;                  /* Emplacements prévisibles    */
-    size_t childs_count;                    /* Taille de cette liste       */
+    size_t children_count;                  /* Taille de cette liste       */
 
     GtkLinkRenderer **links;                /* Liste des liens graphiques  */
     size_t links_count;                     /* Nombre de ces liens         */
@@ -190,6 +190,9 @@ static void gtk_graph_view_size_request(GtkWidget *widget, GtkRequisition *requi
 {
     gpointer fixed_class;                   /* Classe parente              */
     GtkGraphView *view;                     /* Autre vision du composant   */
+    gint left_corner;                       /* Abscisse minimale           */
+    gint top_corner;                        /* Ordonnée minimale           */
+    size_t i;                               /* Boucle de parcours          */
 
     fixed_class = g_type_class_peek_parent(GTK_GRAPH_VIEW_GET_CLASS(widget));
     fixed_class = g_type_class_peek_parent(fixed_class);
@@ -198,6 +201,18 @@ static void gtk_graph_view_size_request(GtkWidget *widget, GtkRequisition *requi
 
     view = GTK_GRAPH_VIEW(widget);
 
+    left_corner = G_MAXINT;
+    top_corner = G_MAXINT;
+
+    for (i = 0; i < view->children_count; i++)
+    {
+        left_corner = MIN(left_corner, view->allocs[i].x);
+        top_corner = MIN(top_corner, view->allocs[i].y);
+    }
+
+    if (left_corner != G_MAXINT) requisition->width += left_corner;
+    if (top_corner != G_MAXINT) requisition->height += top_corner;
+
     if (view->requisition.width == 0 && view->requisition.height == 0)
         view->requisition = *requisition;
 
@@ -338,13 +353,13 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr)
                 view->start = start;
                 view->end = end;
 
-                view->childs = gtk_graph_view_load_nodes(view, GTK_VIEW_PANEL(view)->binary,
+                view->children = gtk_graph_view_load_nodes(view, GTK_VIEW_PANEL(view)->binary,
                                                          start, end);
 
-                view->allocs = (GtkAllocation *)calloc(view->childs_count,
+                view->allocs = (GtkAllocation *)calloc(view->children_count,
                                                        sizeof(GtkAllocation));
 
-                build_graph_view(view, view->childs, view->childs_count);
+                build_graph_view(view, view->children, view->children_count);
 
                 break;
 
@@ -426,7 +441,7 @@ static void gtk_graph_view_cache_glance(GtkGraphView *view, cairo_t *cairo)
     cairo_set_line_width(cairo, 2);
     cairo_set_source_rgb(cairo, 0, 0, 0);
 
-    for (i = 0; i < view->childs_count; i++)
+    for (i = 0; i < view->children_count; i++)
     {
         alloc = &view->allocs[i];
 
@@ -482,8 +497,8 @@ void gtk_graph_view_put(GtkGraphView *view, GtkWidget *widget, const GtkAllocati
 {
     size_t i;                               /* Boucle de parcours          */
 
-    for (i = 0; i < view->childs_count; i++)
-        if (GTK_WIDGET(view->childs[i]) == widget)
+    for (i = 0; i < view->children_count; i++)
+        if (GTK_WIDGET(view->children[i]) == widget)
         {
             view->allocs[i] = *alloc;
             break;
@@ -550,17 +565,17 @@ static void gtk_graph_view_reset(GtkGraphView *view)
 
     }
 
-    for (i = 0; i < view->childs_count; i++)
-        gtk_widget_destroy(GTK_WIDGET(view->childs[i]));
+    for (i = 0; i < view->children_count; i++)
+        gtk_widget_destroy(GTK_WIDGET(view->children[i]));
 
-    if (view->childs_count > 0)
+    if (view->children_count > 0)
     {
-        free(view->childs);
-        view->childs = NULL;
+        free(view->children);
+        view->children = NULL;
         free(view->allocs);
         view->allocs = NULL;
 
-        view->childs_count = 0;
+        view->children_count = 0;
 
     }
 
@@ -597,7 +612,7 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinar
 
     result = NULL;
 
-    count = &view->childs_count;
+    count = &view->children_count;
     *count = 0;
 
     list = g_loaded_binary_get_instructions(binary);
-- 
cgit v0.11.2-87-g4458