summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2012-06-24 15:04:46 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2012-06-24 15:04:46 (GMT)
commita4b70be160203f0c0c50e9ba4d8ab07db08bdeb6 (patch)
tree88eff9a8ccb6bcab73ef5a823fef632c38d0a24b /src
parent923776410a0b4d847f09428d93101a8b63c9ae60 (diff)
Updated code to prepare the return of graph views.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@245 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r--src/glibext/gcodebuffer.c140
-rw-r--r--src/glibext/gcodebuffer.h9
-rw-r--r--src/graph/dot.c9
-rw-r--r--src/graph/layout.c78
-rw-r--r--src/graph/layout.h6
-rw-r--r--src/graph/node.c20
-rw-r--r--src/graph/node.h7
-rw-r--r--src/gtkext/gtkblockview.c4
-rw-r--r--src/gtkext/gtkbufferview.c25
-rw-r--r--src/gtkext/gtkbufferview.h5
-rw-r--r--src/gtkext/gtkgraphview.c268
-rw-r--r--src/gtkext/gtkviewpanel.c43
-rw-r--r--src/gtkext/gtkviewpanel.h6
13 files changed, 493 insertions, 127 deletions
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index 3dfb10e..de92b71 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -118,6 +118,9 @@ static void g_code_buffer_class_init(GCodeBufferClass *);
/* Procède à l'initialisation d'un tampon pour code désassemblé. */
static void g_code_buffer_init(GCodeBuffer *);
+/* Convertit une adresse en indice de ligne. */
+static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t);
+
/* ---------------------- VUE PARTICULIERE D'UN TAMPON DE CODE ---------------------- */
@@ -129,8 +132,8 @@ struct _GBufferView
GObject parent; /* A laisser en premier */
GCodeBuffer *buffer; /* Tampon de code visualisé */
- size_t first; /* Première ligne intégrée */
- size_t last; /* Dernière ligne intégrée */
+ vmpa_t start; /* Première ligne intégrée */
+ vmpa_t end; /* Dernière ligne intégrée */
gint line_height; /* Hauteur maximale des lignes */
gint max_widths[BLC_COUNT]; /* Taille cachée des colonnes */
@@ -273,8 +276,10 @@ static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar)
guint id; /* Identifiant de statut */
size_t i; /* Boucle de parcours */
- first = 0;
- last = (scan->buffer->used > 0 ? scan->buffer->used - 1 : 0);
+ /* TODO : lock scan->buffer->lines */
+
+ first = g_code_buffer_get_index_from_address(scan->buffer, scan->start);
+ last = g_code_buffer_get_index_from_address(scan->buffer, scan->end);
lines = scan->buffer->lines;
@@ -290,6 +295,8 @@ static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar)
}
+ /* TODO : unlock scan->buffer->lines */
+
gtk_extended_status_bar_remove(statusbar, id);
/* Avertit le commanditaire... */
@@ -366,6 +373,32 @@ GCodeBuffer *g_code_buffer_new(void)
}
+/******************************************************************************
+* *
+* Paramètres : buffer = composant GTK à mettre à jour. *
+* addr = adresse où va se situer la ligne. *
+* *
+* Description : Convertit une adresse en indice de ligne. *
+* *
+* Retour : Indice de l'adresse trouvée, ou buffer->used en cas d'échec, *
+* pour assurer la prise en compte de VMPA_MAX. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t addr)
+{
+ size_t result; /* Indice à retourner */
+
+ for (result = 0; result < buffer->used; result++)
+ if (g_buffer_line_get_address(buffer->lines[result]) == addr)
+ break;
+
+ return result;
+
+}
+
/******************************************************************************
* *
@@ -477,7 +510,7 @@ static void g_buffer_view_init(GBufferView *buffer)
/******************************************************************************
* *
-* Paramètres : buffer = tamon à représenter à l'écran. *
+* Paramètres : buffer = tampon à représenter à l'écran. *
* *
* Description : Crée une nouvelle vue d'un tampon pour code désassemblé. *
* *
@@ -493,9 +526,11 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer)
result = g_object_new(G_TYPE_BUFFER_VIEW, NULL);
+ g_object_ref(G_OBJECT(buffer));
+
result->buffer = buffer;
- result->first = 0;
- result->last = buffer->used;
+ result->start = 0;
+ result->end = VMPA_MAX;
g_buffer_view_reset_required_widths(result);
@@ -506,6 +541,69 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer)
/******************************************************************************
* *
+* Paramètres : view = visualisateur à mettre à jour. *
+* first = première ligne à imprimer. *
+* last = première ligne hors cadre. *
+* *
+* Description : Restreint le champ d'application de l'affichage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_view_restrict(GBufferView *view, vmpa_t start, vmpa_t end)
+{
+ view->start = start;
+ view->end = end;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = visualisateur à mettre à jour. *
+* first = première ligne à imprimer ou NULL. [OUT] *
+* last = première ligne hors cadre ou NULL. [OUT] *
+* *
+* Description : Indique le champ d'application de l'affichage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_view_get_restrictions(GBufferView *view, vmpa_t *start, vmpa_t *end)
+{
+ if (start != NULL) *start = view->start;
+ if (end != NULL) *end = view->end;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = visualisateur à consulter. *
+* *
+* Description : Fournit le tampon de code lié à un visualisateur donné. *
+* *
+* Retour : Tampon de code associé au gestionnaire d'affichage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *view)
+{
+ return view->buffer;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = visualisation à consulter. *
* *
* Description : Réinitialise le cache des largeurs de colonne calculées. *
@@ -541,18 +639,25 @@ static void g_buffer_view_reset_required_widths(GBufferView *view)
static void g_buffer_view_compute_required_widths(GBufferView *view)
{
GBufferLine **lines; /* Liste des lignes à traiter */
+ size_t first; /* Première ligne intégrée */
+ size_t last; /* Dernière ligne intégrée */
size_t i; /* Boucle de parcours #1 */
unsigned int j; /* Boucle de parcours #2 */
gint width; /* Largeur d'une colonne */
lines = view->buffer->lines;
+ first = g_code_buffer_get_index_from_address(view->buffer, view->start);
+ last = g_code_buffer_get_index_from_address(view->buffer, view->end);
+
+ last = MIN(last, view->buffer->used > 0 ? view->buffer->used - 1 : 0);
+
view->line_height = 17;
view->left_margin = 2 * view->line_height;
view->left_text = 2.5 * view->line_height;
- for (i = view->first; i < view->last; i++)
+ for (i = first; i <= last; i++)
for (j = 0; j < BLC_COUNT; j++)
{
width = g_buffer_line_get_width(lines[i], j);
@@ -603,6 +708,8 @@ gint g_buffer_view_get_line_height(GBufferView *view)
void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool addr, bool code)
{
unsigned int i; /* Boucle de parcours */
+ size_t first; /* Première ligne intégrée */
+ size_t last; /* Dernière ligne intégrée */
*width = 0;
*height = view->line_height;
@@ -619,7 +726,10 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
}
- *height *= (view->last - view->first);
+ first = g_code_buffer_get_index_from_address(view->buffer, view->start);
+ last = g_code_buffer_get_index_from_address(view->buffer, view->end);
+
+ *height *= (last - first);
}
@@ -760,15 +870,21 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y)
bool g_buffer_view_get_address_coordinates(GBufferView *view, vmpa_t addr, gint *x, gint *y)
{
gint lheight; /* Hauteur d'une ligne */
- size_t i; /* Boucle de parcours */
vmpa_t current; /* Adresse parcourue */
+ size_t first; /* Première ligne intégrée */
+ size_t last; /* Dernière ligne intégrée */
+ size_t i; /* Boucle de parcours */
*x = 0;
*y = 0;
lheight = g_buffer_view_get_line_height(view);
+ current = VMPA_MAX;
+
+ first = g_code_buffer_get_index_from_address(view->buffer, view->start);
+ last = g_code_buffer_get_index_from_address(view->buffer, view->end);
- for (i = 0; i < view->buffer->used; i++)
+ for (i = first; i < last; i++)
{
current = g_buffer_line_get_address(view->buffer->lines[i]);
@@ -782,6 +898,6 @@ bool g_buffer_view_get_address_coordinates(GBufferView *view, vmpa_t addr, gint
}
- return true;
+ return (current == addr);
}
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
index 74e376c..3fc6155 100644
--- a/src/glibext/gcodebuffer.h
+++ b/src/glibext/gcodebuffer.h
@@ -94,6 +94,15 @@ GType g_buffer_view_get_type(void);
/* Crée une nouvelle vue d'un tampon pour code désassemblé. */
GBufferView *g_buffer_view_new(GCodeBuffer *);
+/* Restreint le champ d'application de l'affichage. */
+void g_buffer_view_restrict(GBufferView *, vmpa_t, vmpa_t);
+
+/* Indique le champ d'application de l'affichage. */
+void g_buffer_view_get_restrictions(GBufferView *, vmpa_t *, vmpa_t *);
+
+/* Fournit le tampon de code lié à un visualisateur donné. */
+GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *);
+
/* Fournit la hauteur d'impression d'une ligne visualisée. */
gint g_buffer_view_get_line_height(GBufferView *);
diff --git a/src/graph/dot.c b/src/graph/dot.c
index 27e60bc..5a80f59 100644
--- a/src/graph/dot.c
+++ b/src/graph/dot.c
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* dot.c - interactions avec le système dot
*
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -148,15 +148,12 @@ void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view,
{
int height; /* Hauteur du graphique */
node_t *iter; /* Boucle de parcours */
- GGraphNode *node; /* Intermédiaire concerné */
+ const GGraphNode *node; /* Intermédiaire concerné */
height = GD_bb(layout->graph).UR.y;
for (iter = agfstnode(layout->graph); iter != NULL; iter = agnxtnode(layout->graph, iter))
{
-
- printf(" pos :: (%d ; %d)\n", iter->u.coord.x, height - iter->u.coord.y);
-
node = find_graph_node_by_name(nodes, count, iter->name);
g_graph_node_place(node, view, iter->u.coord.x, height - iter->u.coord.y);
}
@@ -227,7 +224,7 @@ GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, siz
}
result = (GtkLinkRenderer **)realloc(result, ++(*count) * sizeof(GtkLinkRenderer *));
- result[*count - 1] = gtk_link_renderer_new(points, points_count);
+ result[*count - 1] = GTK_LINK_RENDERER(gtk_link_renderer_new(points, points_count));
}
diff --git a/src/graph/layout.c b/src/graph/layout.c
index 667074b..21f7454 100644
--- a/src/graph/layout.c
+++ b/src/graph/layout.c
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* layout.c - mise en place de graphique
*
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -31,7 +31,9 @@
#include "dot.h"
#include "node.h"
+#include "../analysis/binary.h"
#include "../common/extstr.h"
+#include "../gtkext/gtkbufferview.h"
@@ -40,7 +42,7 @@
/* Etablit tous les liens entre les différents morceaux de code. */
-static char *complete_graph_links(const GtkGraphView *, GtkBinView **, size_t, char *);
+static char *complete_graph_links(const GtkGraphView *, GtkViewPanel **, size_t, char *);
@@ -58,7 +60,7 @@ static char *complete_graph_links(const GtkGraphView *, GtkBinView **, size_t, c
* *
******************************************************************************/
-bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
+bool build_graph_view(GtkGraphView *view, GtkViewPanel **views, size_t count)
{
GGraphNode **nodes; /* Intermédiaires en place */
size_t i; /* Boucle de parcours */
@@ -72,12 +74,11 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
nodes = (GGraphNode **)calloc(count, sizeof(GGraphNode *));
for (i = 0; i < count; i++)
- nodes[i] = g_graph_node_new(views[i]);
+ nodes[i] = g_graph_node_new(GTK_WIDGET(views[i]));
/* Définition du graphique */
cmds = strdup("digraph G {\noverlap=false;\n splines=true;\n");
- //cmds = strdup("digraph G {\n");
for (i = 0; i < count; i++)
cmds = g_graph_node_register_for_dot(nodes[i], cmds);
@@ -86,8 +87,6 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
cmds = stradd(cmds, "}");
- printf("first step :: '%s'\n", cmds);
-
layout = create_graph_layout(cmds);
/* Affichage du graphique */
@@ -113,7 +112,7 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
* 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. *
+* desc = description du graphique à compléter. [OUT] *
* *
* Description : Etablit tous les liens entre les différents morceaux de code.*
* *
@@ -123,51 +122,65 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count)
* *
******************************************************************************/
-static char *complete_graph_links(const GtkGraphView *view, GtkBinView **views, size_t count, char *desc)
+static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views, size_t count, char *desc)
{
+ GOpenidaBinary *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 */
- GRenderingLine *last; /* Dernière ligne d'un bloc */
- GRenderingLine **dests; /* Ligne visée par une autre */
+ 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 */
- vmpa_t addr; /* Addresse de destination */
size_t k; /* Boucle de parcours #3 */
- char buffer[LINKS_DESC_LEN]; /* Tampon pour l'ajout de liens*/
- GRenderingLine *next; /* Ligne suivante dans le flux */
+ char cmd[LINKS_DESC_LEN]; /* Tampon pour l'ajout de liens*/
+ GArchInstruction *next; /* Instruction suivante */
+
+ if (count == 0)
+ return desc;
+
+ binary = gtk_view_panel_get_binary(views[0]);
+ instrs = g_openida_binary_get_instructions(binary);
for (i = 0; i < count; i++)
{
- last = gtk_bin_view_get_last_line(views[i]);
+ buffer = gtk_buffer_view_get_buffer(GTK_BUFFER_VIEW(views[i]));
+ g_buffer_view_get_restrictions(buffer, NULL, &end);
- if (g_rendering_line_has_destinations(last))
+ 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_rendering_line_get_destinations(last, &dests, &types);
+ dcount = g_arch_instruction_get_destinations(last, &dests, &types);
for (j = 0; j < dcount; j++)
{
- addr = get_rendering_line_address(dests[j]);
+ g_arch_instruction_get_location(dests[j], NULL, NULL, &addr);
for (k = 0; k < count; k++)
- if (gtk_bin_view_contain_address(views[k], addr))
+ if (gtk_view_panel_contain_address(views[k], addr))
break;
if (k < count)
switch (types[j])
{
case ILT_JUMP:
- snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
- desc = stradd(desc, buffer);
+ snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+ desc = stradd(desc, cmd);
break;
case ILT_JUMP_IF_TRUE:
- snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
- desc = stradd(desc, buffer);
+ snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+ desc = stradd(desc, cmd);
break;
case ILT_JUMP_IF_FALSE:
- snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
- desc = stradd(desc, buffer);
+ snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+ desc = stradd(desc, cmd);
break;
default:
@@ -180,24 +193,21 @@ static char *complete_graph_links(const GtkGraphView *view, GtkBinView **views,
}
/* Si la ligne n'est pas la dernière, on suit le flux normal */
- else if (last != gtk_bin_view_get_last_line(view))
+ else if (addr != end)
{
- next = g_rendering_line_get_next_iter(gtk_bin_view_get_lines(GTK_BIN_VIEW(view)),
- last,
- gtk_bin_view_get_last_line(GTK_BIN_VIEW(view)));
-
+ next = g_arch_instruction_get_next_iter(instrs, last, end);
if (next == NULL) continue;
- addr = get_rendering_line_address(next);
+ g_arch_instruction_get_location(next, NULL, NULL, &addr);
for (k = 0; k < count; k++)
- if (gtk_bin_view_contain_address(views[k], addr))
+ if (gtk_view_panel_contain_address(views[k], addr))
break;
if (k < count)
{
- snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
- desc = stradd(desc, buffer);
+ snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+ desc = stradd(desc, cmd);
}
}
diff --git a/src/graph/layout.h b/src/graph/layout.h
index 5212168..006fa9b 100644
--- a/src/graph/layout.h
+++ b/src/graph/layout.h
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* layout.h - prototypes pour la mise en place de graphique
*
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -28,13 +28,13 @@
#include <stdbool.h>
-#include "../gtkext/gtkbinview.h"
#include "../gtkext/gtkgraphview.h"
+#include "../gtkext/gtkviewpanel.h"
/* Dispose une série de morceaux d'affichage en graphique. */
-bool build_graph_view(GtkGraphView *, GtkBinView **, size_t);
+bool build_graph_view(GtkGraphView *, GtkViewPanel **, size_t);
diff --git a/src/graph/node.c b/src/graph/node.c
index 09cfe30..3e6cc14 100644
--- a/src/graph/node.c
+++ b/src/graph/node.c
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* node.c - éléments de graphiques chez dot
*
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -24,7 +24,9 @@
#include "node.h"
+#include <malloc.h>
#include <stdio.h>
+#include <string.h>
#include "../common/extstr.h"
@@ -39,7 +41,7 @@ struct _GGraphNode
{
GObject parent; /* A laisser en premier */
- GtkBinView *view; /* Morceau de code représenté */
+ GtkWidget *view; /* Morceau de code représenté */
char *name; /* Adresse sous forme humaine */
};
@@ -159,7 +161,7 @@ static void g_graph_node_init(GGraphNode *node)
* *
******************************************************************************/
-GGraphNode *g_graph_node_new(GtkBinView *view)
+GGraphNode *g_graph_node_new(GtkWidget *view)
{
GGraphNode *result; /* Structure à retourner */
size_t len; /* Taille du nom */
@@ -168,7 +170,7 @@ GGraphNode *g_graph_node_new(GtkBinView *view)
result->view = view;
- len = 3 + sizeof(GtkBinView *) * 2 + 1;
+ len = 3 + sizeof(GtkWidget *) * 2 + 1;
result->name = (char *)calloc(len, sizeof(char));
snprintf(result->name, len, "_%p", result->view);
@@ -196,7 +198,7 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds)
GtkRequisition requisition; /* Taille à l'écran requise */
char buffer[128];
- gtk_widget_size_request(GTK_WIDGET(node->view), &requisition);
+ gtk_widget_size_request(node->view, &requisition);
cmds = stradd(cmds, node->name);
cmds = stradd(cmds, " [shape=box, fixedsize ");
@@ -240,12 +242,12 @@ void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint
{
GtkRequisition requisition; /* Taille à l'écran actuelle */
- gtk_widget_size_request(GTK_WIDGET(node->view), &requisition);
+ gtk_widget_size_request(node->view, &requisition);
x -= requisition.width / 2;
y -= requisition.height / 2;
- gtk_graph_view_put(view, GTK_WIDGET(node->view), x, y);
+ gtk_graph_view_put(view, node->view, x, y);
}
@@ -270,9 +272,9 @@ void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint
* *
******************************************************************************/
-GGraphNode *find_graph_node_by_name(const GGraphNode **nodes, size_t count, const char *target)
+const GGraphNode *find_graph_node_by_name(GGraphNode **nodes, size_t count, const char *target)
{
- GGraphNode *result; /* Trouvaille à remonter */
+ const GGraphNode *result; /* Trouvaille à remonter */
size_t i; /* Boucle de parcours */
result = NULL;
diff --git a/src/graph/node.h b/src/graph/node.h
index 4998553..f8d0078 100644
--- a/src/graph/node.h
+++ b/src/graph/node.h
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* node.h - prototypes pour les éléments de graphiques chez dot
*
- * Copyright (C) 2009 Cyrille Bagard
+ * Copyright (C) 2009-2012 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -25,7 +25,6 @@
#define _GRAPH_NODE_H
-#include "../gtkext/gtkbinview.h"
#include "../gtkext/gtkgraphview.h"
@@ -51,7 +50,7 @@ typedef struct _GGraphNodeClass GGraphNodeClass;
GType g_graph_node_get_type(void);
/* Constitue un intermédiaire entre un noeud dot et du code. */
-GGraphNode *g_graph_node_new(GtkBinView *);
+GGraphNode *g_graph_node_new(GtkWidget *);
/* Déclare l'intermédiaire en tant que noeud pour dot. */
char *g_graph_node_register_for_dot(const GGraphNode *, char *);
@@ -65,7 +64,7 @@ void g_graph_node_place(const GGraphNode *, GtkGraphView *, gint , gint);
/* Recherche un noeud donné dans une série de noeuds. */
-GGraphNode *find_graph_node_by_name(const GGraphNode **, size_t, const char *);
+const GGraphNode *find_graph_node_by_name(GGraphNode **, size_t, const char *);
diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c
index a420194..cd2d99d 100644
--- a/src/gtkext/gtkblockview.c
+++ b/src/gtkext/gtkblockview.c
@@ -123,7 +123,7 @@ GtkWidget *gtk_block_view_new(void)
{
GtkBlockView *result; /* Composant à retourner */
- result = gtk_type_new(GTK_TYPE_BLOCK_VIEW);
+ result = g_object_new(GTK_TYPE_BLOCK_VIEW, NULL);
return GTK_WIDGET(result);
@@ -151,6 +151,6 @@ static void gtk_block_view_attach_binary(GtkBlockView *view, GOpenidaBinary *bin
buffer = g_openida_binary_get_disassembled_buffer(binary);
- gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), buffer, addr, code);
+ gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), g_buffer_view_new(buffer), addr, code);
}
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index c3457e9..99b67ab 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -397,7 +397,7 @@ static void gtk_buffer_view_scroll(GtkBufferView *view)
* *
******************************************************************************/
-void gtk_buffer_view_attach_buffer(GtkBufferView *view, GCodeBuffer *buffer, bool *addr, bool *code)
+void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer, bool *addr, bool *code)
{
gint width; /* Largeur de l'objet actuelle */
gint height; /* Hauteur de l'objet actuelle */
@@ -408,10 +408,10 @@ void gtk_buffer_view_attach_buffer(GtkBufferView *view, GCodeBuffer *buffer, boo
g_object_unref(G_OBJECT(view->buffer_view));
}
- view->buffer = buffer;
+ view->buffer = g_buffer_view_get_buffer(buffer);
g_object_ref(G_OBJECT(view->buffer));
- view->buffer_view = g_buffer_view_new(view->buffer);
+ view->buffer_view = buffer;
//gdk_threads_enter();
@@ -436,3 +436,22 @@ void gtk_buffer_view_attach_buffer(GtkBufferView *view, GCodeBuffer *buffer, boo
//gdk_threads_leave();
}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant GTK à consulter. *
+* *
+* Description : Fournit la vue associée au tampon de lignes courant. *
+* *
+* Retour : Vue mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *view)
+{
+ return view->buffer_view;
+
+}
diff --git a/src/gtkext/gtkbufferview.h b/src/gtkext/gtkbufferview.h
index da04533..df34b72 100644
--- a/src/gtkext/gtkbufferview.h
+++ b/src/gtkext/gtkbufferview.h
@@ -52,7 +52,10 @@ typedef struct _GtkBufferViewClass GtkBufferViewClass;
GType gtk_buffer_view_get_type(void);
/* Prend acte de l'association d'un tampon de lignes. */
-void gtk_buffer_view_attach_buffer(GtkBufferView *, GCodeBuffer *, bool *, bool *);
+void gtk_buffer_view_attach_buffer(GtkBufferView *, GBufferView *, bool *, bool *);
+
+/* Fournit la vue associée au tampon de lignes courant. */
+GBufferView *gtk_buffer_view_get_buffer(const GtkBufferView *);
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index ff020d4..263ab7d 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -25,6 +25,7 @@
#include "gtkblockview.h"
+#include "gtkbufferview.h"
#include "gtkviewpanel-int.h"
@@ -37,6 +38,9 @@ struct _GtkGraphView
GtkRequisition requisition; /* Espace requis d'affichage */ /* A garder ?? */
+ vmpa_t start; /* Début de la portion vue */
+ vmpa_t end; /* Fin de la portion affichée */
+
GtkBlockView **childs; /* Liste des sous-blocs */
size_t childs_count; /* Taille de cette liste */
@@ -69,9 +73,15 @@ static void gtk_graph_view_size_allocate(GtkWidget *, GtkAllocation *);
/* Met à jour l'affichage de la vue sous forme graphique. */
static gboolean gtk_graph_view_expose(GtkWidget *, GdkEventExpose *, GtkGraphView *);
+/* Indique la position d'affichage d'une adresse donnée. */
+static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, vmpa_t, gint *, gint *);
+
/* Réagit à un défilement quelconque. */
static void gtk_graph_view_scroll(GtkGraphView *);
+/* Supprime tout contenu de l'afficheur de code en graphique. */
+static void gtk_graph_view_reset(GtkGraphView *);
+
/* Détermine le type du composant d'affichage en graphique. */
@@ -122,6 +132,7 @@ static void gtk_graph_view_init(GtkGraphView *view)
viewpanel = GTK_VIEW_PANEL(view);
+ viewpanel->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
viewpanel->scroll = (scroll_fc)gtk_graph_view_scroll;
//binview = GTK_BIN_VIEW(view);
@@ -131,7 +142,7 @@ static void gtk_graph_view_init(GtkGraphView *view)
//binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
view->support = GTK_FIXED(gtk_fixed_new());
- gtk_fixed_set_has_window(view->support, TRUE);
+ gtk_widget_set_has_window(GTK_WIDGET(view->support), TRUE);
g_signal_connect(G_OBJECT(view->support), "expose-event",
G_CALLBACK(gtk_graph_view_expose), view);
@@ -276,6 +287,31 @@ static gboolean gtk_graph_view_expose(GtkWidget *widget, GdkEventExpose *event,
/******************************************************************************
* *
+* Paramètres : view = composant GTK à consulter. *
+* addr = adresse à présenter à l'écran. *
+* x = position horizontale au sein du composant. [OUT] *
+* y = position verticale au sein du composant. [OUT] *
+* *
+* Description : Indique la position d'affichage d'une adresse donnée. *
+* *
+* Retour : true si l'adresse fait partie du composant, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *view, vmpa_t addr, gint *x, gint *y)
+{
+
+
+
+ return false;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = composant GTK à mettre à jour. *
* *
* Description : Réagit à un défilement quelconque. *
@@ -365,6 +401,184 @@ void gtk_graph_view_attach_links(GtkGraphView *view, GtkLinkRenderer **links, si
}
+/******************************************************************************
+* *
+* 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 */
+
+ view->requisition.width = 0;
+ view->requisition.height = 0;
+
+ view->start = VMPA_MAX;
+ view->end = VMPA_MAX;
+
+ for (i = 0; i < view->links_count; i++)
+ gtk_object_destroy(GTK_OBJECT(view->links[i]));
+
+ if (view->links_count > 0)
+ {
+ free(view->links);
+ view->links = NULL;
+
+ view->links_count = 0;
+
+ }
+
+ for (i = 0; i < view->childs_count; i++)
+ gtk_widget_destroy(GTK_WIDGET(view->childs[i]));
+
+ if (view->childs_count > 0)
+ {
+ free(view->childs);
+ view->childs = NULL;
+
+ view->childs_count = 0;
+
+ }
+
+}
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : view = composant d'affichage GTK à mettre à jour. *
+* binary = contenu binaire à l'origine des lignes. *
+* start = première adresse à traiter. *
+* end = première adresse hors cadre de l'opération. *
+* *
+* Description : Définit la liste complète des éléments du futur graphique. *
+* *
+* Retour : Liste d'éléments du graphique à placer. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GOpenidaBinary *binary, vmpa_t start, vmpa_t end)
+{
+ GtkViewPanel **result; /* Liste à retourner */
+ size_t *count; /* Nombre d'éléments créés. */
+ GArchInstruction *list; /* Liste des instructions */
+ GCodeBuffer *buffer; /* Tampon brut à découper */
+ bool *addr; /* Affichage des adresses ? */
+ bool *code; /* Affichage du binaire ? */
+ vmpa_t first; /* Début d'un groupe de lignes */
+ GArchInstruction *iter; /* Boucle de parcours */
+ vmpa_t last; /* Fin d'un groupe de lignes */
+ GBufferView *subview; /* Partie affichée du tampon */
+
+ result = NULL;
+
+ count = &view->childs_count;
+ *count = 0;
+
+ list = g_openida_binary_get_instructions(binary);
+ buffer = g_openida_binary_get_disassembled_buffer(binary);
+
+ addr = g_openida_binary_display_addresses_in_text(binary);
+ code = g_openida_binary_display_code_in_text(binary);
+
+ first = start;
+
+ for (iter = g_arch_instruction_find_by_address(list, start, true);
+ iter != NULL;
+ iter = g_arch_instruction_get_next_iter(list, iter, end))
+ {
+ if (g_arch_instruction_has_sources(iter))
+ {
+ result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
+
+ result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+
+ gtk_view_panel_show_border(result[*count - 1], true);
+
+ subview = g_buffer_view_new(buffer);
+ //g_buffer_view_restrict(subview, size_t first, size_t last);
+ gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
+ subview, addr, code);
+
+ first = VMPA_MAX;
+
+ }
+
+ g_arch_instruction_get_location(iter, NULL, NULL, &last);
+ if (first == VMPA_MAX) first = last;
+
+ if (g_arch_instruction_has_destinations(iter))
+ {
+ result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
+
+ result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+
+ gtk_view_panel_show_border(result[*count - 1], true);
+
+ subview = g_buffer_view_new(buffer);
+ //g_buffer_view_restrict(subview, size_t first, size_t last);
+ gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
+ subview, addr, code);
+
+ first = VMPA_MAX;
+
+ }
+
+ }
+
+ if (first != VMPA_MAX)
+ {
+ result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
+
+ result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+
+ gtk_view_panel_show_border(result[*count - 1], true);
+
+ subview = g_buffer_view_new(buffer);
+ //g_buffer_view_restrict(subview, size_t first, size_t last);
+ gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
+ subview, addr, code);
+
+ }
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -424,9 +638,6 @@ 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 *);
@@ -524,55 +735,6 @@ static void gtk_graph_view_init(GtkGraphView *view)
-/******************************************************************************
-* *
-* 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 */
-
- view->requisition.width = 0;
- view->requisition.height = 0;
-
- view->start = 0;
- view->end = 0;
-
- for (i = 0; i < view->links_count; i++)
- gtk_object_destroy(view->links[i]);
-
- if (view->links_count > 0)
- {
- free(view->links);
- view->links = NULL;
-
- view->links_count = 0;
-
- }
-
- 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;
-
- }
-
-}
-
-
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 35cfa5c..2dac981 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -323,6 +323,26 @@ static gboolean gtk_view_panel_expose(GtkWidget *widget, GdkEventExpose *event)
/******************************************************************************
* *
+* Paramètres : panel = composant GTK à mettre à jour. *
+* show = état de l'affichage auquel parvenir. *
+* *
+* Description : Définit si une bordure est à afficher. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_view_panel_show_border(GtkViewPanel *panel, bool show)
+{
+ panel->show_border = show;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : panel = composant GTK à mettre à jour. *
* binary = binaire associé à intégrer. *
* addr = indique si les positions doivent être affichées. *
@@ -457,6 +477,29 @@ GOpenidaBinary *gtk_view_panel_get_binary(const GtkViewPanel *panel)
/******************************************************************************
* *
+* Paramètres : view = composant GTK à manipuler. *
+* addr = adresse à rechercher. *
+* *
+* Description : Indique si la vue contient une addrese donnée. *
+* *
+* Retour : true si l'adresse est présente, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool gtk_view_panel_contain_address(const GtkViewPanel *panel, vmpa_t addr)
+{
+ gint dummy_x; /* Abscisse pour l'appel */
+ gint dummy_y; /* Ordonnée pour l'appel */
+
+ return panel->get_coordinates(panel, addr, &dummy_x, &dummy_y);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : panel = composant GTK à manipuler. *
* addr = adresse à présenter à l'écran. *
* *
diff --git a/src/gtkext/gtkviewpanel.h b/src/gtkext/gtkviewpanel.h
index ccac08b..12b0e44 100644
--- a/src/gtkext/gtkviewpanel.h
+++ b/src/gtkext/gtkviewpanel.h
@@ -50,6 +50,9 @@ typedef struct _GtkViewPanelClass GtkViewPanelClass;
/* Détermine le type du composant d'affichage générique. */
GType gtk_view_panel_get_type(void);
+/* Définit si une bordure est à afficher. */
+void gtk_view_panel_show_border(GtkViewPanel *, bool);
+
/* Associe à un panneau d'affichage un binaire chargé. */
void gtk_view_panel_attach_binary(GtkViewPanel *, GOpenidaBinary *, bool *, bool *);
@@ -68,6 +71,9 @@ void gtk_view_panel_set_code_display(const GtkViewPanel *, bool);
/* Fournit le binaire associé à la représentation. */
GOpenidaBinary *gtk_view_panel_get_binary(const GtkViewPanel *);
+/* Indique si la vue contient une addrese donnée. */
+bool gtk_view_panel_contain_address(const GtkViewPanel *, vmpa_t);
+
/* S'assure qu'une adresse donnée est visible à l'écran. */
void gtk_view_panel_scroll_to_address(const GtkViewPanel *, vmpa_t);