summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-06-25 00:34:22 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-06-25 00:34:22 (GMT)
commitf2696c85e502e36a529a1d8ee3d209498ac2c0e9 (patch)
tree3d8ffe28a730d32c98e8d048b99f67b7856acec9 /src
parent23c7cd436e2ec980a68e6d12a6d8a750e357763c (diff)
Used Graphviz library for building graphs (first attempt).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@80 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am5
-rw-r--r--src/analysis/line-int.h1
-rw-r--r--src/analysis/line.c46
-rw-r--r--src/analysis/line.h6
-rw-r--r--src/analysis/line_code.c1
-rwxr-xr-xsrc/graph/Makefile.am18
-rw-r--r--src/graph/dot.c148
-rw-r--r--src/graph/dot.h47
-rw-r--r--src/graph/layout.c93
-rw-r--r--src/graph/layout.h41
-rw-r--r--src/graph/node.c225
-rw-r--r--src/graph/node.h74
-rw-r--r--src/gtkext/Makefile.am2
-rw-r--r--src/gtkext/gtkbinview-int.h6
-rw-r--r--src/gtkext/gtkbinview.c14
-rw-r--r--src/gtkext/gtkbinview.h5
-rw-r--r--src/gtkext/gtkgraphview.c183
-rw-r--r--src/project.c2
18 files changed, 903 insertions, 14 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c47f5e7..347980b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,10 +26,11 @@ liboidadisass_la_LIBADD = \
liboidagtkext_la_SOURCES =
-liboidagtkext_la_LDFLAGS = $(LIBGTK_LIBS) \
+liboidagtkext_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBGRAPH_LIBS) \
-L.libs -loidadisass
liboidagtkext_la_LIBADD = \
+ graph/libgraph.la \
gtkext/libgtkext.la
@@ -96,4 +97,4 @@ openida_LDADD = $(LIBINTL) \
# gtkext doit être traité en premier, à cause des marshals GLib
-SUBDIRS = gtkext analysis arch format common debug panel plugins
+SUBDIRS = gtkext analysis arch format common debug graph panel plugins
diff --git a/src/analysis/line-int.h b/src/analysis/line-int.h
index 97aa93c..59ef5f8 100644
--- a/src/analysis/line-int.h
+++ b/src/analysis/line-int.h
@@ -47,6 +47,7 @@ struct _GRenderingLine
DL_LIST_ITEM(link); /* Maillon de liste chaînée */
uint64_t offset; /* Position en mémoire/physique*/
+ off_t length; /* Nombre d'adresses associées */
RenderingLineType type; /* Type de représentation */
RenderingLineFlag flags; /* Extension d'informations */
diff --git a/src/analysis/line.c b/src/analysis/line.c
index 31a8a36..8cfad25 100644
--- a/src/analysis/line.c
+++ b/src/analysis/line.c
@@ -55,6 +55,7 @@ static void g_rendering_line_add_link_reference(GRenderingLine *, GRenderingLine
static GdkPixbuf *g_rendering_line_render_icon(const GRenderingLine *, const char *, GtkIconSize);
+
/* Indique le type définit pour une ligne de représentation. */
G_DEFINE_TYPE(GRenderingLine, g_rendering_line, G_TYPE_OBJECT);
@@ -296,6 +297,44 @@ void g_rendering_line_link_with(GRenderingLine *line, GRenderingLine *dest, Inst
/******************************************************************************
* *
+* Paramètres : line = ligne dont les informations sont à consulter. *
+* *
+* Description : Indique si la ligne a une ou plusieurs origines. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_rendering_line_has_sources(const GRenderingLine *line)
+{
+ return (line->from_count > 0);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont les informations sont à consulter. *
+* *
+* Description : Indique si la ligne a une suite autre que la ligne suivante. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_rendering_line_has_destination(const GRenderingLine *line)
+{
+ return (line->to != NULL && line->link_type != ILT_CALL);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne dont les informations sont à consulter. *
* stock_id = identifiant GTK de l'image à charger. *
* size = taille de l'image souhaitée. *
@@ -355,6 +394,11 @@ void g_rendering_line_draw(GRenderingLine *line, GdkDrawable *drawable, GdkGC *g
gdk_draw_layout(drawable, gc, x1, y, line->layout);
+ if (line->to != NULL)
+ pixbuf = g_rendering_line_render_icon(line, "gtk-bold", GTK_ICON_SIZE_MENU);
+ else
+
+
if (line->flags & RLF_BREAK_POINT)
pixbuf = g_rendering_line_render_icon(line, "gtk-yes", GTK_ICON_SIZE_MENU);
@@ -632,7 +676,7 @@ GRenderingLine *g_rendering_line_find_by_address(GRenderingLine *lines, const GR
lines_list_for_each(result, lines)
{
- if (result->offset == addr) break;
+ if (result->offset <= addr && addr < (result->offset + result->length)) break;
if (result == last)
{
diff --git a/src/analysis/line.h b/src/analysis/line.h
index b27bd9b..aa200f8 100644
--- a/src/analysis/line.h
+++ b/src/analysis/line.h
@@ -104,6 +104,12 @@ RenderingLineFlag g_rendering_line_get_flags(const GRenderingLine *);
/* Etablit un lien entre deux lignes de représentation. */
void g_rendering_line_link_with(GRenderingLine *, GRenderingLine *, InstructionLinkType);
+/* Indique si la ligne a une ou plusieurs origines. */
+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 *);
+
/* 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/analysis/line_code.c b/src/analysis/line_code.c
index dcb8c5e..5ca3623 100644
--- a/src/analysis/line_code.c
+++ b/src/analysis/line_code.c
@@ -287,6 +287,7 @@ GRenderingLine *g_code_line_new(uint64_t offset, GArchInstruction *instr, const
result = g_object_new(G_TYPE_CODE_LINE, NULL);
G_RENDERING_LINE(result)->offset = offset;
+ g_arch_instruction_get_location(instr, NULL, &G_RENDERING_LINE(result)->length, NULL);
result->instr = instr;
result->options = options;
diff --git a/src/graph/Makefile.am b/src/graph/Makefile.am
new file mode 100755
index 0000000..e374709
--- /dev/null
+++ b/src/graph/Makefile.am
@@ -0,0 +1,18 @@
+
+noinst_LTLIBRARIES = libgraph.la
+
+libgraph_la_SOURCES = \
+ dot.h dot.c \
+ layout.h layout.c \
+ node.h node.c
+
+libgraph_la_LDFLAGS =
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBGRAPH_CFLAGS)
+
+AM_CPPFLAGS =
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS =
diff --git a/src/graph/dot.c b/src/graph/dot.c
new file mode 100644
index 0000000..dc1c9a9
--- /dev/null
+++ b/src/graph/dot.c
@@ -0,0 +1,148 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * dot.c - interactions avec le système dot
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "dot.h"
+
+
+#include <malloc.h>
+#include <graphviz/gvc.h>
+#include <graphviz/types.h>
+
+
+
+/* Graphique selon Graphviz */
+struct _graph_layout
+{
+ GVC_t *context; /* Contexte pour Graphviz */
+ graph_t *graph; /* Graphique construit */
+
+};
+
+
+
+/******************************************************************************
+* *
+* Paramètres : cmds = description textuelle du graphique à représenter. *
+* *
+* Description : Charge un graphique à partir de sa description. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+graph_layout *create_graph_layout(char *cmds)
+{
+ graph_layout *result; /* Composants à retourner */
+ int ret; /* Bilan d'un appel */
+
+ result = (graph_layout *)calloc(1, sizeof(graph_layout));
+
+ result->context = gvContext();
+ result->graph = agmemread(cmds);
+
+ if (result->graph == NULL) goto cdl_error;
+
+
+
+ ret = gvLayout(result->context, result->graph, "dot");
+
+
+ printf("ret = %d\n", ret);
+
+
+
+
+ ret = gvRender(result->context, result->graph, "dot", NULL);
+
+ printf("ret = %d\n", ret);
+
+
+
+
+ return result;
+
+ cdl_error:
+
+ delete_graph_layout(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : layout = graphique à supprimer de la mémoire. *
+* *
+* Description : Décharge un graphique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void delete_graph_layout(graph_layout *layout)
+{
+ if (layout->graph != NULL)
+ {
+ gvFreeLayout(layout->context, layout->graph);
+ agclose(layout->graph);
+ }
+
+ gvFreeContext(layout->context);
+
+ free(layout);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : layout = graphique à supprimer de la mémoire. *
+* fixed = support de destination. *
+* nodes = liste de noeuds à traiter. *
+* count = taille de la liste. *
+* *
+* Description : Place tous les éléments du graphique à l'écran. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void place_nodes_of_graph_layout(const graph_layout *layout, GtkFixed *fixed, GGraphNode **nodes, size_t count)
+{
+ node_t *iter; /* Boucle de parcours */
+ GGraphNode *node; /* Intermédiaire concerné */
+
+ for (iter = agfstnode(layout->graph); iter != NULL; iter = agnxtnode(layout->graph, iter))
+ {
+ node = find_graph_node_by_name(nodes, count, iter->name);
+ g_graph_node_place(node, fixed, (double)iter->u.coord.x, (double)iter->u.coord.y);
+ }
+
+}
diff --git a/src/graph/dot.h b/src/graph/dot.h
new file mode 100644
index 0000000..8538e52
--- /dev/null
+++ b/src/graph/dot.h
@@ -0,0 +1,47 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * dot.h - prototypes pour les interactions avec le système dot
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GRAPH_DOT_H
+#define _GRAPH_DOT_H
+
+
+#include "node.h"
+
+
+
+/* Graphique selon Graphviz */
+typedef struct _graph_layout graph_layout;
+
+
+/* Charge un graphique à partir de sa description. */
+graph_layout *create_graph_layout(char *);
+
+/* Décharge un graphique. */
+void delete_graph_layout(graph_layout *);
+
+/* Place tous les éléments du graphique à l'écran. */
+void place_nodes_of_graph_layout(const graph_layout *, GtkFixed *, GGraphNode **, size_t);
+
+
+
+#endif /* _GRAPH_DOT_H */
diff --git a/src/graph/layout.c b/src/graph/layout.c
new file mode 100644
index 0000000..c76df49
--- /dev/null
+++ b/src/graph/layout.c
@@ -0,0 +1,93 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * layout.c - mise en place de graphique
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "layout.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "dot.h"
+#include "node.h"
+#include "../common/extstr.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : fixed = support à 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(GtkFixed *fixed, GtkBinView **views, size_t count)
+{
+ GGraphNode **nodes; /* Intermédiaires en place */
+ size_t i; /* Boucle de parcours */
+ char *cmds; /* Description à envoyer à dot */
+ graph_layout *layout; /* Graphique construit */
+
+ /* Création de la glue */
+
+ nodes = (GGraphNode **)calloc(count, sizeof(GGraphNode *));
+
+ for (i = 0; i < count; i++)
+ nodes[i] = g_graph_node_new(views[i]);
+
+ /* Définition du graphique */
+
+ cmds = strdup("digraph G {\n");
+
+ for (i = 0; i < count; i++)
+ cmds = g_graph_node_register_for_dot(nodes[i], cmds);
+
+
+
+
+ cmds = stradd(cmds, "}");
+
+ printf("first step :: '%s'\n", cmds);
+
+ layout = create_graph_layout(cmds);
+
+ /* Affichage du graphique */
+
+ place_nodes_of_graph_layout(layout, fixed, nodes, count);
+
+
+
+ delete_graph_layout(layout);
+
+ /* TODO : free nodes */
+
+ return true;
+
+}
diff --git a/src/graph/layout.h b/src/graph/layout.h
new file mode 100644
index 0000000..cbb8e6c
--- /dev/null
+++ b/src/graph/layout.h
@@ -0,0 +1,41 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * layout.h - prototypes pour la mise en place de graphique
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GRAPH_LAYOUT_H
+#define _GRAPH_LAYOUT_H
+
+
+#include <stdbool.h>
+#include <gtk/gtkfixed.h>
+
+
+#include "../gtkext/gtkbinview.h"
+
+
+
+/* Dispose une série de morceaux d'affichage en graphique. */
+bool build_graph_view(GtkFixed *, GtkBinView **, size_t);
+
+
+
+#endif /* _GRAPH_LAYOUT_H */
diff --git a/src/graph/node.c b/src/graph/node.c
new file mode 100644
index 0000000..b220c4f
--- /dev/null
+++ b/src/graph/node.c
@@ -0,0 +1,225 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * node.c - éléments de graphiques chez dot
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "node.h"
+
+
+#include <stdio.h>
+
+
+#include "../common/extstr.h"
+
+
+
+/* -------------------------- GESTION DES NOEUDS A L'UNITE -------------------------- */
+
+
+/* Intermédiaire entre le noeud dot et la bribe de code (instance) */
+struct _GGraphNode
+{
+ GObject parent; /* A laisser en premier */
+
+ GtkBinView *view; /* Morceau de code représenté */
+ char *name; /* Adresse sous forme humaine */
+
+};
+
+
+/* Intermédiaire entre le noeud dot et la bribe de code (classe) */
+struct _GGraphNodeClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des intermédiaires avec les noeuds dot. */
+static void g_graph_node_class_init(GGraphNodeClass *);
+
+/* Initialise la classe des intermédiaires avec les noeuds dot. */
+static void g_graph_node_init(GGraphNode *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GESTION DES NOEUDS A L'UNITE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type définit par la GLib pour le noeud. */
+G_DEFINE_TYPE(GGraphNode, g_graph_node, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des intermédiaires avec les noeuds dot. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_graph_node_class_init(GGraphNodeClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : node = instance à initialiser. *
+* *
+* Description : Initialise la classe des intermédiaires avec les noeuds dot. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_graph_node_init(GGraphNode *node)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = morceau d'affichage à représenter. *
+* *
+* Description : Constitue un intermédiaire entre un noeud dot et du code. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GGraphNode *g_graph_node_new(GtkBinView *view)
+{
+ GGraphNode *result; /* Structure à retourner */
+ size_t len; /* Taille du nom */
+
+ result = g_object_new(G_TYPE_GRAPH_NODE, NULL);
+
+ result->view = view;
+
+ len = 3 + sizeof(GtkBinView *) * 2 + 1;
+
+ result->name = (char *)calloc(len, sizeof(char));
+ snprintf(result->name, len, "_%p", result->view);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : node = intermédiaire à consulter. *
+* cmds = description pour dot à compléter. *
+* *
+* Description : Déclare l'intermédiaire en tant que noeud pour dot. *
+* *
+* Retour : Description dûment complétée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds)
+{
+ GtkRequisition requisition; /* Taille à l'écran requise */
+
+ cmds = stradd(cmds, node->name);
+
+
+ gtk_widget_size_request(GTK_WIDGET(node->view), &requisition);
+
+
+ cmds = stradd(cmds, " [shape=box];\n");
+
+ return cmds;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : node = intermédiaire à consulter. *
+* fixed = support de destination. *
+* x = abscisse du point d'intégration. *
+* y = ordonnée du point d'intégration. *
+* *
+* Description : Place le morceau de code de l'intermédiaire à l'écran. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_graph_node_place(const GGraphNode *node, GtkFixed *fixed, gint x, gint y)
+{
+ gtk_fixed_put(fixed, GTK_WIDGET(node->view), x, y);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MANIPULATION D'ENSEMBLES DE NOEUDS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : nodes = liste de noeuds à parcourir. *
+* count = taille de la liste. *
+* target = nom du noeud recherché. *
+* *
+* Description : Recherche un noeud donné dans une série de noeuds. *
+* *
+* Retour : Noeud trouvé ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GGraphNode *find_graph_node_by_name(const GGraphNode **nodes, size_t count, const char *target)
+{
+ GGraphNode *result; /* Trouvaille à remonter */
+ size_t i; /* Boucle de parcours */
+
+ result = NULL;
+
+ for (i = 0; i < count && result == NULL; i++)
+ if (strcmp(nodes[i]->name, target) == 0)
+ result = nodes[i];
+
+ return result;
+
+}
diff --git a/src/graph/node.h b/src/graph/node.h
new file mode 100644
index 0000000..456e236
--- /dev/null
+++ b/src/graph/node.h
@@ -0,0 +1,74 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * node.h - prototypes pour les éléments de graphiques chez dot
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GRAPH_NODE_H
+#define _GRAPH_NODE_H
+
+
+#include <gtk/gtkfixed.h>
+
+
+#include "../gtkext/gtkbinview.h"
+
+
+
+/* -------------------------- GESTION DES NOEUDS A L'UNITE -------------------------- */
+
+
+#define G_TYPE_GRAPH_NODE g_graph_node_get_type()
+#define G_GRAPH_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_graph_node_get_type(), GGraphNode))
+#define G_IS_GRAPH_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_graph_node_get_type()))
+#define G_GRAPH_NODE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_graph_node_get_type(), GGraphNodeIface))
+#define G_GRAPH_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GRAPH_NODE, GGraphNodeClass))
+
+
+/* Intermédiaire entre le noeud dot et la bribe de code (instance) */
+typedef struct _GGraphNode GGraphNode;
+
+/* Intermédiaire entre le noeud dot et la bribe de code (classe) */
+typedef struct _GGraphNodeClass GGraphNodeClass;
+
+
+/* Indique le type définit par la GLib pour le noeud. */
+GType g_graph_node_get_type(void);
+
+/* Constitue un intermédiaire entre un noeud dot et du code. */
+GGraphNode *g_graph_node_new(GtkBinView *);
+
+/* Déclare l'intermédiaire en tant que noeud pour dot. */
+char *g_graph_node_register_for_dot(const GGraphNode *, char *);
+
+/* Place le morceau de code de l'intermédiaire à l'écran. */
+void g_graph_node_place(const GGraphNode *, GtkFixed *, gint , gint);
+
+
+
+/* ----------------------- MANIPULATION D'ENSEMBLES DE NOEUDS ----------------------- */
+
+
+/* Recherche un noeud donné dans une série de noeuds. */
+GGraphNode *find_graph_node_by_name(const GGraphNode **, size_t, const char *);
+
+
+
+#endif /* _GRAPH_NODE_H */
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 421a1c4..a7023c5 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -18,7 +18,7 @@ libgtkext_la_SOURCES = \
libgtkext_la_LDFLAGS =
-INCLUDES = $(LIBGTK_CFLAGS)
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
AM_CPPFLAGS =
diff --git a/src/gtkext/gtkbinview-int.h b/src/gtkext/gtkbinview-int.h
index fffbc9f..0c17554 100644
--- a/src/gtkext/gtkbinview-int.h
+++ b/src/gtkext/gtkbinview-int.h
@@ -36,6 +36,9 @@
/* Définit les lignes à associer à la représentation. */
typedef void (* set_rendering_lines_fc) (GtkBinview *, GRenderingLine *, GRenderingLine *);
+/* Réagit à la sélection externe d'une adresse. */
+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 *);
@@ -44,10 +47,13 @@ struct _GtkBinview
{
GtkFixed parent; /* A laisser en premier */
+ openida_binary *binary; /* Contenu binaire affiché */
+
GRenderingLine *lines; /* Contenu à représenter */
GRenderingLine *last; /* Dernière ligne associée */
set_rendering_lines_fc set_lines; /* Association des lignes */
+ define_main_address_fc define_address; /* Sélection externe d'adresse */
get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */
};
diff --git a/src/gtkext/gtkbinview.c b/src/gtkext/gtkbinview.c
index 3799b25..2cb046f 100644
--- a/src/gtkext/gtkbinview.c
+++ b/src/gtkext/gtkbinview.c
@@ -110,9 +110,10 @@ GtkWidget* gtk_binview_new(void)
/******************************************************************************
* *
-* Paramètres : view = composant GTK à mettre à jour. *
-* lines = informations à intégrer. *
-* last = dernière ligne à intégrer ou NULL pour toutes. *
+* Paramètres : view = composant GTK à mettre à jour. *
+* binary = contenu binaire dont les lignes sont issues. *
+* lines = informations à intégrer. *
+* last = dernière ligne à intégrer ou NULL pour toutes. *
* *
* Description : Définit les lignes à associer à la représentation. *
* *
@@ -122,8 +123,10 @@ GtkWidget* gtk_binview_new(void)
* *
******************************************************************************/
-void gtk_bin_view_set_rendering_lines(GtkBinview *view, GRenderingLine *lines, GRenderingLine *last)
+void gtk_bin_view_set_rendering_lines(GtkBinview *view, openida_binary *binary, GRenderingLine *lines, GRenderingLine *last)
{
+ view->binary = binary;
+
view->lines = lines;
view->last = last;
@@ -232,6 +235,9 @@ void gtk_bin_view_scroll_to_address(GtkBinview *view, vmpa_t addr)
GtkViewport *support; /* Support avec défilements */
GtkAdjustment *adj; /* Défilement à mettre à jour */
+ if (view->define_address != NULL)
+ view->define_address(view, addr);
+
if (view->get_coordinates(view, addr, &x, &y))
{
support = GTK_VIEWPORT(gtk_widget_get_parent(GTK_WIDGET(view)));
diff --git a/src/gtkext/gtkbinview.h b/src/gtkext/gtkbinview.h
index a80cda3..10f1c2f 100644
--- a/src/gtkext/gtkbinview.h
+++ b/src/gtkext/gtkbinview.h
@@ -28,8 +28,7 @@
#include <gtk/gtkwidget.h>
-#include "../analysis/line.h"
-#include "../arch/archbase.h"
+#include "../analysis/binary.h"
@@ -58,7 +57,7 @@ GtkWidget* gtk_binview_new(void);
/* Définit les lignes à associer à la représentation. */
-void gtk_bin_view_set_rendering_lines(GtkBinview *, GRenderingLine *, GRenderingLine *);
+void gtk_bin_view_set_rendering_lines(GtkBinview *, openida_binary *, GRenderingLine *, GRenderingLine *);
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 80ca06b..8389148 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -25,6 +25,7 @@
#include "gtkbinview-int.h"
+#include "../graph/layout.h"
#include <malloc.h>
@@ -36,6 +37,9 @@ struct _GtkGraphView
{
GtkBinView parent; /* A laisser en premier */
+ vmpa_t start; /* Début de la portion vue */
+ vmpa_t end; /* Fin de la portion affichée */
+
GtkBinView **childs; /* Liste des sous-blocs */
size_t childs_count; /* Taille de cette liste */
@@ -55,12 +59,20 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *);
/* Initialise une instance d'afficheur de code en graphique. */
static void gtk_graph_view_init(GtkGraphView *);
+/* Supprime tout contenu de l'afficheur de code en graphique. */
+static void gtk_graph_view_reset(GtkGraphView *);
+
/* Définit les lignes du graphique de représentation. */
static void gtk_graph_view_set_rendering_lines(GtkGraphView *, GRenderingLine *, GRenderingLine *);
+/* Réagit à la sélection externe d'une adresse. */
+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 *);
+/* 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 *);
/* Détermine le type du composant d'affichage en graphique. */
@@ -104,6 +116,7 @@ static void gtk_graph_view_init(GtkGraphView *view)
binview = GTK_BIN_VIEW(view);
binview->set_lines = (set_rendering_lines_fc)gtk_graph_view_set_rendering_lines;
+ binview->define_address = (define_main_address_fc)gtk_graph_view_define_main_address;
binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
}
@@ -128,6 +141,36 @@ GtkWidget* gtk_graph_view_new(void)
}
+/******************************************************************************
+* *
+* Paramètres : view = instance GTK à réinitialiser. *
+* *
+* Description : Supprime tout contenu de l'afficheur de code en graphique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_view_reset(GtkGraphView *view)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < view->childs_count; i++)
+ gtk_widget_destroy(view->childs[i]);
+
+ if (view->childs_count > 0)
+ {
+ free(view->childs);
+ view->childs = NULL;
+
+ view->childs_count = 0;
+
+ }
+
+}
+
@@ -161,7 +204,7 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->childs[0]), 50, 50);
- gtk_bin_view_set_rendering_lines(view->childs[0], lines, lines);
+ gtk_bin_view_set_rendering_lines(view->childs[0], GTK_BIN_VIEW(view)->binary, lines, lines);
@@ -176,7 +219,7 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->childs[1]), 100, 450);
- gtk_bin_view_set_rendering_lines(view->childs[1], mainl, mainl);
+ gtk_bin_view_set_rendering_lines(view->childs[1], GTK_BIN_VIEW(view)->binary, mainl, mainl);
@@ -191,6 +234,65 @@ static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLin
/******************************************************************************
* *
+* Paramètres : view = composant GTK à mettre à jour. *
+* addr = adresse sélectionnée de manière externe. *
+* *
+* Description : Réagit à la sélection externe d'une adresse. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr)
+{
+ exe_format *format; /* Type de fichier chargé */
+ GBinRoutine **routines; /* Liste des routines trouvées */
+ size_t routines_count; /* Nombre de ces routines */
+ size_t i; /* Boucle de parcours */
+ vmpa_t start; /* Début d'une routine */
+ vmpa_t end; /* Fin d'une routine */
+ GRenderingLine *first; /* Première ligne à traiter */
+ GRenderingLine *last; /* Dernière ligne à traiter */
+
+ if (!(view->start <= addr && addr < view->end))
+ {
+ gtk_graph_view_reset(view);
+
+ format = get_openida_binary_format(GTK_BIN_VIEW(view)->binary);
+ routines = get_all_exe_routines(format, &routines_count);
+
+ for (i = 0; i < routines_count; i++)
+ {
+ start = g_binary_routine_get_address(routines[i]);
+ end = start + g_binary_routine_get_size(routines[i]);
+
+ if (start <= addr && addr < end)
+ {
+ view->start = start;
+ view->end = end;
+
+ first = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, start);
+ last = g_rendering_line_find_by_address(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, end);
+
+ view->childs = gtk_graph_view_load_nodes(GTK_BIN_VIEW(view)->binary, first, last, &view->childs_count);
+
+ build_graph_view(GTK_FIXED(view), view->childs, view->childs_count);
+
+ break;
+
+ }
+
+ }
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = composant GTK à consulter. *
* addr = adresse à présenter à l'écran. *
* x = position horizontale au sein du composant. [OUT] *
@@ -225,3 +327,80 @@ static bool gtk_graph_view_get_address_coordinates(GtkGraphView *view, vmpa_t ad
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = contenu binaire à l'origine des lignes. *
+* first = première ligne à analyser. *
+* last = dernière ligne à analyser. *
+* count = nombre d'éléments créés. [OUT] *
+* *
+* Description : Définit la liste complète des éléments du futur graphique. *
+* *
+* Retour : Liste d'éléments du graphique à placer. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkBinView **gtk_graph_view_load_nodes(openida_binary *binary, GRenderingLine *first, GRenderingLine *last, size_t *count)
+{
+ GtkBinView **result; /* Liste à retourner */
+ GRenderingLine *begin; /* Début d'un groupe de lignes */
+ GRenderingLine *end; /* Fin d'un groupe de lignes */
+ GRenderingLine *iter; /* Boucle de parcours */
+
+ result = NULL;
+ *count = 0;
+
+ begin = NULL;
+
+ for (iter = first; iter != NULL; iter = g_rendering_line_get_next_iter(first, iter, last))
+ {
+ if (begin != NULL && g_rendering_line_has_sources(iter))
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ begin = NULL;
+
+ }
+
+ if (begin == NULL) begin = iter;
+ end = iter;
+
+ if (g_rendering_line_has_destination(iter))
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ begin = NULL;
+
+ }
+
+ }
+
+ if (begin != NULL)
+ {
+ result = (GtkBinView **)realloc(result, ++(*count) * sizeof(GtkBinView *));
+
+ result[*count - 1] = GTK_BIN_VIEW(gtk_block_view_new());
+ gtk_widget_show(GTK_WIDGET(result[*count - 1]));
+
+ gtk_bin_view_set_rendering_lines(result[*count - 1], binary, begin, end);
+
+ }
+
+ return result;
+
+
+}
diff --git a/src/project.c b/src/project.c
index bf2c3e0..0e6f0a7 100644
--- a/src/project.c
+++ b/src/project.c
@@ -115,7 +115,7 @@ loaded_binary *load_openida_binary(openida_binary *binary)
break;
}
- gtk_bin_view_set_rendering_lines(GTK_BIN_VIEW(view), get_openida_binary_lines(binary), NULL);
+ gtk_bin_view_set_rendering_lines(GTK_BIN_VIEW(view), binary, get_openida_binary_lines(binary), NULL);
gtk_widget_show(view);