summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2012-11-02 15:50:07 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2012-11-02 15:50:07 (GMT)
commitf5df6496fa50927d3d274c939a888afde652b7ad (patch)
tree281dbfdfdcb8765fea7036af274c63fb5acde8ff
parentc3aba0893c29cc098c029306fd7a4c8c1fa2eee2 (diff)
Improved the computing and the rendering of the graphic view.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@277 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog56
-rw-r--r--configure.ac2
-rw-r--r--src/Makefile.am3
-rw-r--r--src/analysis/binary-int.h2
-rw-r--r--src/analysis/binary.c16
-rw-r--r--src/analysis/binary.h14
-rw-r--r--src/arch/dalvik/instruction.c45
-rw-r--r--src/glibext/gbufferline.c4
-rw-r--r--src/glibext/gbufferline.h4
-rw-r--r--src/glibext/gcodebuffer.c11
-rw-r--r--src/gtkext/Makefile.am5
-rwxr-xr-xsrc/gtkext/graph/Makefile.am (renamed from src/graph/Makefile.am)6
-rw-r--r--src/gtkext/graph/dot.c (renamed from src/graph/dot.c)82
-rw-r--r--src/gtkext/graph/dot.h (renamed from src/graph/dot.h)4
-rw-r--r--src/gtkext/graph/layout.c (renamed from src/graph/layout.c)34
-rw-r--r--src/gtkext/graph/layout.h (renamed from src/graph/layout.h)4
-rw-r--r--src/gtkext/graph/node.c (renamed from src/graph/node.c)78
-rw-r--r--src/gtkext/graph/node.h (renamed from src/graph/node.h)9
-rw-r--r--src/gtkext/gtkgraphview.c8
-rw-r--r--src/gtkext/gtklinkrenderer.c100
-rw-r--r--src/gtkext/gtklinkrenderer.h14
-rw-r--r--src/gtkext/gtkviewpanel.c7
-rw-r--r--src/project.c4
23 files changed, 427 insertions, 85 deletions
diff --git a/ChangeLog b/ChangeLog
index af9d3e2..46b8ce7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,59 @@
+12-11-02 Cyrille Bagard <nocbos@gmail.com>
+
+ * configure.ac:
+ Move the Makefile of the graph directory.
+
+ * src/analysis/binary.c:
+ * src/analysis/binary.h:
+ * src/analysis/binary-int.h:
+ Define display options for each kind of view.
+
+ * src/arch/dalvik/instruction.c:
+ Provide links from Dalvik instructions.
+
+ * src/glibext/gbufferline.c:
+ * src/glibext/gbufferline.h:
+ Define COL_MARGIN in the header file.
+
+ * src/glibext/gcodebuffer.c:
+ Compute size of buffers more accurately. Fix a bug when looking for
+ a line using an address.
+
+ * src/graph/dot.c:
+ * src/graph/dot.h:
+ * src/graph/layout.c:
+ * src/graph/layout.h:
+ * src/graph/Makefile.am:
+ * src/graph/node.c:
+ * src/graph/node.h:
+ Moved entries.
+
+ * src/gtkext/graph/dot.c:
+ * src/gtkext/graph/dot.h:
+ * src/gtkext/graph/layout.c:
+ * src/gtkext/graph/layout.h:
+ * src/gtkext/graph/Makefile.am:
+ * src/gtkext/graph/node.c:
+ * src/gtkext/graph/node.h:
+ Improve the computing and the rendering of the graphic view.
+
+ * src/gtkext/gtkgraphview.c:
+ * src/gtkext/gtklinkrenderer.c:
+ * src/gtkext/gtklinkrenderer.h:
+ Improve the computing and the rendering of the graphic view.
+
+ * src/gtkext/gtkviewpanel.c:
+ Fix a bug: use the real requested size of a panel.
+
+ * src/gtkext/Makefile.am:
+ Add graph/libgtkextgraph.la to libgtkext_la_LIBADD.
+
+ * src/Makefile.am:
+ Remove all references to the graph directory.
+
+ * src/project.c:
+ Update code.
+
12-10-28 Cyrille Bagard <nocbos@gmail.com>
* src/arch/archbase.c:
diff --git a/configure.ac b/configure.ac
index 0a79182..5ccb4af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -288,8 +288,8 @@ AC_CONFIG_FILES([Makefile
src/format/mangling/Makefile
src/format/pe/Makefile
src/glibext/Makefile
- src/graph/Makefile
src/gtkext/Makefile
+ src/gtkext/graph/Makefile
src/gui/Makefile
src/gui/menus/Makefile
src/gui/panels/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 2d6fd46..8eff972 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,7 +43,6 @@ libchrysagtkext_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBGRAPH_LIBS) \
-L.libs -lchrysadisass
libchrysagtkext_la_LIBADD = \
- graph/libgraph.la \
gtkext/libgtkext.la
@@ -107,6 +106,6 @@ chrysalide_LDADD = $(LIBINTL) \
# gtkext doit être traité en premier, à cause des marshals GLib
-SUBDIRS = glibext gtkext analysis arch format common debug decomp dialogs graph gui plugins
+SUBDIRS = glibext gtkext analysis arch format common debug decomp dialogs gui plugins
# TODO: rm -rf panels
diff --git a/src/analysis/binary-int.h b/src/analysis/binary-int.h
index c9be0bf..f813aa8 100644
--- a/src/analysis/binary-int.h
+++ b/src/analysis/binary-int.h
@@ -63,7 +63,7 @@ struct _GLoadedBinary
size_t decbuf_count; /* Taille des tableaux */
size_t defsrc; /* Fichier source principal */
- bool text_display[2]; /* Position et code binaire #1 */
+ bool text_display[BDT_COUNT][2]; /* Position et code binaire #1 */
bool lines_display; /* Affichage des lignes */
};
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index d5bf029..b9292aa 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -122,8 +122,10 @@ static void g_loaded_binary_class_init(GLoadedBinaryClass *klass)
static void g_loaded_binary_init(GLoadedBinary *binary)
{
- binary->text_display[0] = true;
- binary->text_display[1] = true;
+ binary->text_display[BDT_ASM][0] = true;
+ binary->text_display[BDT_ASM][1] = true;
+ binary->text_display[BDT_GRAPH][0] = true;
+ binary->text_display[BDT_GRAPH][1] = false;
binary->lines_display = true;
@@ -681,6 +683,7 @@ GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
+* type = type de représentation visée. *
* *
* Description : Indique si les adresses doivent apparaître dans le rendu. *
* *
@@ -690,9 +693,9 @@ GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *binary
* *
******************************************************************************/
-bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *binary)
+bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *binary, BinaryDisplayType type)
{
- return &binary->text_display[0];
+ return &binary->text_display[type][0];
}
@@ -700,6 +703,7 @@ bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *binary)
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
+* type = type de représentation visée. *
* *
* Description : Indique si le code doit apparaître dans le rendu. *
* *
@@ -709,9 +713,9 @@ bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *binary)
* *
******************************************************************************/
-bool *g_loaded_binary_display_code_in_text(GLoadedBinary *binary)
+bool *g_loaded_binary_display_code_in_text(GLoadedBinary *binary, BinaryDisplayType type)
{
- return &binary->text_display[1];
+ return &binary->text_display[type][1];
}
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 7ff9080..eb042c6 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -62,6 +62,16 @@ typedef enum _BinaryPartModel
} BinaryPartModel;
+/* Types de représentation */
+typedef enum _BinaryDisplayType
+{
+ BDT_ASM, /* Rendu du code brut */
+ BDT_GRAPH, /* Rendu avec graphiques */
+
+ BDT_COUNT
+
+} BinaryDisplayType;
+
/* Indique le type défini pour une description de fichier binaire. */
GType g_loaded_binary_get_type(void);
@@ -97,10 +107,10 @@ GArchInstruction *g_loaded_binary_get_instructions(const GLoadedBinary *);
GCodeBuffer *g_loaded_binary_get_disassembled_buffer(const GLoadedBinary *);
/* Indique si les adresses doivent apparaître dans le rendu. */
-bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *);
+bool *g_loaded_binary_display_addresses_in_text(GLoadedBinary *, BinaryDisplayType);
/* Indique si le code doit apparaître dans le rendu. */
-bool *g_loaded_binary_display_code_in_text(GLoadedBinary *);
+bool *g_loaded_binary_display_code_in_text(GLoadedBinary *, BinaryDisplayType);
/* Fournit le tampon associé au contenu d'un fichier source. */
GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *, size_t);
diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c
index 49b5573..d494fb4 100644
--- a/src/arch/dalvik/instruction.c
+++ b/src/arch/dalvik/instruction.c
@@ -26,6 +26,7 @@
#include "instruction-int.h"
#include "decomp/translate.h"
+#include "operands/target.h"
#include "../instruction-int.h"
@@ -452,7 +453,49 @@ static const char *dalvik_get_instruction_text(const GDalvikInstruction *instr,
static InstructionLinkType dalvik_get_instruction_link(const GDalvikInstruction *instr, vmpa_t *addr)
{
- return ILT_NONE/*instr->get_link(instr, addr)*/;
+ InstructionLinkType result; /* Type de lien à retourner */
+ GArchOperand *operand; /* Opérande à manipuler */
+ const GImmOperand *imm; /* Valeur immédiate */
+
+ switch (instr->type)
+ {
+ case DOP_IF_EQ:
+ case DOP_IF_NE:
+ case DOP_IF_LT:
+ case DOP_IF_GE:
+ case DOP_IF_GT:
+ case DOP_IF_LE:
+
+ operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 2);
+ imm = g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand));
+
+ if (g_imm_operand_to_vmpa_t(imm, addr)) result = ILT_JUMP_IF_TRUE;
+ else result = ILT_NONE;
+
+ break;
+
+ case DOP_IF_EQZ:
+ case DOP_IF_NEZ:
+ case DOP_IF_LTZ:
+ case DOP_IF_GEZ:
+ case DOP_IF_GTZ:
+ case DOP_IF_LEZ:
+
+ operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 1);
+ imm = g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand));
+
+ if (g_imm_operand_to_vmpa_t(imm, addr)) result = ILT_JUMP_IF_TRUE;
+ else result = ILT_NONE;
+
+ break;
+
+ default:
+ result = ILT_NONE;
+ break;
+
+ }
+
+ return result;
}
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 4360f8c..ce3e19f 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -35,10 +35,6 @@
-/* Espace entre les colonnes */
-#define COL_MARGIN 23
-
-
/* ---------------------------- REGROUPEMENT PAR COLONNE ---------------------------- */
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index ce75895..3cc992b 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -100,9 +100,13 @@ typedef enum _RenderingTagType
#define RTT_NONE RTT_RAW /* TODO : remme */
+
/* Confort pour l'insertion de texte */
#define SL(str) str, strlen(str)
+/* Espace entre les colonnes */
+#define COL_MARGIN 23
+
/* Accompagnement du dessin pour compléments */
typedef void (* buffer_line_draw_fc) (GBufferLine *, GdkDrawable *, GdkGC *, gint, gint, void *);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index 573d07d..aec3303 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -803,12 +803,12 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
size_t first; /* Première ligne intégrée */
size_t last; /* Dernière ligne intégrée */
- *width = 0;
- *height = view->line_height;
-
if (!WIDTHS_CACHED(view))
g_buffer_view_compute_required_widths(view);
+ *width = view->left_text;
+ *height = view->line_height;
+
for (i = 0; i < BLC_COUNT; i++)
{
if (i == BLC_ADDRESS && !addr) continue;
@@ -816,6 +816,9 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
*width += view->max_widths[i];
+ if ((i + 1) < BLC_COUNT)
+ *width += COL_MARGIN;
+
}
first = g_code_buffer_get_index_from_address(view->buffer, view->start);
@@ -1083,7 +1086,7 @@ bool g_buffer_view_get_address_coordinates(GBufferView *view, vmpa_t addr, gint
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 = first; i < last; i++)
+ for (i = first; i <= last; i++)
{
current = g_buffer_line_get_address(view->buffer->lines[i]);
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index f590693..863c7a8 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -18,6 +18,9 @@ libgtkext_la_SOURCES = \
iodamarshal.h iodamarshal.c \
support.h support.c
+libgtkext_la_LIBADD = \
+ graph/libgtkextgraph.la
+
libgtkext_la_LDFLAGS =
@@ -27,6 +30,8 @@ AM_CPPFLAGS =
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+SUBDIRS = graph
+
iodamarshal.h: iodamarshal.list
glib-genmarshal --header $< > $@
diff --git a/src/graph/Makefile.am b/src/gtkext/graph/Makefile.am
index e374709..a631a90 100755
--- a/src/graph/Makefile.am
+++ b/src/gtkext/graph/Makefile.am
@@ -1,12 +1,12 @@
-noinst_LTLIBRARIES = libgraph.la
+noinst_LTLIBRARIES = libgtkextgraph.la
-libgraph_la_SOURCES = \
+libgtkextgraph_la_SOURCES = \
dot.h dot.c \
layout.h layout.c \
node.h node.c
-libgraph_la_LDFLAGS =
+libgtkextgraph_la_LDFLAGS =
INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBGRAPH_CFLAGS)
diff --git a/src/graph/dot.c b/src/gtkext/graph/dot.c
index 5a80f59..396aa93 100644
--- a/src/graph/dot.c
+++ b/src/gtkext/graph/dot.c
@@ -66,10 +66,13 @@ graph_layout *create_graph_layout(char *cmds)
+ //printf("CMDS =======\n%s\n\n=================\n", cmds);
+
ret = gvLayout(result->context, result->graph, "dot");
+ if (ret != 0) goto cdl_error;
- printf("ret = %d\n", ret);
+ //printf("ret = %d\n", ret);
/*
ret = gvLayoutJobs(result->context, result->graph);
@@ -78,14 +81,14 @@ graph_layout *create_graph_layout(char *cmds)
printf("ret = %d\n", ret);
*/
-
ret = gvRender(result->context, result->graph, "dot", NULL);
+ if (ret != 0) goto cdl_error;
- ret = gvRender(result->context, result->graph, "plain", NULL);
+ //ret = gvRender(result->context, result->graph, "plain", NULL);
- printf("ret = %d\n", ret);
+ //printf("ret = %d\n", ret);
@@ -148,7 +151,7 @@ void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view,
{
int height; /* Hauteur du graphique */
node_t *iter; /* Boucle de parcours */
- const GGraphNode *node; /* Intermédiaire concerné */
+ GGraphNode *node; /* Intermédiaire concerné */
height = GD_bb(layout->graph).UR.y;
@@ -165,6 +168,8 @@ void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view,
* *
* Paramètres : layout = graphique à supprimer de la mémoire. *
* count = nombre d'éléments mis en place. *
+* nodes = liste de noeuds à consulter. *
+* ncount = taille de la liste des noeuds. *
* *
* Description : Charge la définition de tous les liens graphiques. *
* *
@@ -174,17 +179,21 @@ void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view,
* *
******************************************************************************/
-GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, size_t *count)
+GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, size_t *count, GGraphNode **nodes, size_t ncount)
{
GtkLinkRenderer **result; /* Liste à retourner */
int height; /* Hauteur du graphique */
node_t *niter; /* Boucle de parcours #1 */
edge_t *eiter; /* Boucle de parcours #2 */
+ GdkPoint *points; /* Points de ligne relus */
+ size_t points_count; /* Nombre de ces points */
splines *lines; /* Lignes déjà tracées */
+ GGraphNode *node; /* Noeud rattaché */
int i; /* Boucle de parcours #3 */
int k; /* Boucle de parcours #4 */
- GdkPoint *points; /* Points de ligne relus */
- size_t points_count; /* Nombre de ces points */
+ bezier *bez; /* Courbe à reproduire */
+ Agsym_t *attrib; /* Couleur d'un lien */
+ LinkColor color; /* Couleur d'impression */
result = NULL;
*count = 0;
@@ -194,37 +203,62 @@ GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, siz
for (niter = agfstnode(layout->graph); niter != NULL; niter = agnxtnode(layout->graph, niter))
for (eiter = agfstout(layout->graph, niter); eiter != NULL; eiter = agnxtout(layout->graph, eiter))
{
+ points = NULL;
+ points_count = 0;
+
lines = ED_spl(eiter);
- //printf("edge == %p\n", eiter);
+ /* Raccordement au point de départ */
- points = NULL;
- points_count = 0;
+ node = find_graph_node_by_name(nodes, ncount, agtail(eiter)->name);
+
+ g_graph_node_connect(node,
+ lines->list[0].list[0].x,
+ height - lines->list[0].list[0].y,
+ &points, &points_count);
+
+ /* Tracé du lien... */
for (i = 0; i < lines->size; i++)
{
- points = (GdkPoint *)realloc(points, (points_count + lines->list[i].size) * sizeof(GdkPoint));
+ bez = &lines->list[i];
- for (k = 0; k < lines->list[i].size; k++)
+ points = (GdkPoint *)realloc(points, (points_count + bez->size) * sizeof(GdkPoint));
+
+ for (k = 0; k < bez->size; k++)
{
- points[points_count + k].x = lines->list[i].list[k].x;
- points[points_count + k].y = height - lines->list[i].list[k].y;
+ points[points_count + k].x = bez->list[k].x;
+ points[points_count + k].y = height - bez->list[k].y;
+ }
- /*
- printf(" ... ( %d ; %d)\n",
- lines->list[i].list[k].x, height - lines->list[i].list[k].y);
- */
+ points_count += bez->size;
- }
+ }
- points_count += lines->list[i].size;
+ /* Raccordement au point d'arrivée */
- //printf(" ...\n");
+ node = find_graph_node_by_name(nodes, ncount, aghead(eiter)->name);
- }
+ g_graph_node_connect(node,
+ bez->list[k - 1].x,
+ 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 *));
- result[*count - 1] = GTK_LINK_RENDERER(gtk_link_renderer_new(points, points_count));
+
+ 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/graph/dot.h b/src/gtkext/graph/dot.h
index 47550a8..d610e1b 100644
--- a/src/graph/dot.h
+++ b/src/gtkext/graph/dot.h
@@ -26,7 +26,7 @@
#include "node.h"
-#include "../gtkext/gtklinkrenderer.h"
+#include "../gtklinkrenderer.h"
@@ -44,7 +44,7 @@ void delete_graph_layout(graph_layout *);
void place_nodes_of_graph_layout(const graph_layout *, GtkGraphView *, GGraphNode **, size_t);
/* Charge la définition de tous les liens graphiques. */
-GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *, size_t *);
+GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *, size_t *, GGraphNode **, size_t);
diff --git a/src/graph/layout.c b/src/gtkext/graph/layout.c
index f8afad6..69e32cc 100644
--- a/src/graph/layout.c
+++ b/src/gtkext/graph/layout.c
@@ -31,9 +31,9 @@
#include "dot.h"
#include "node.h"
-#include "../analysis/binary.h"
-#include "../common/extstr.h"
-#include "../gtkext/gtkbufferview.h"
+#include "../gtkbufferview.h"
+#include "../../analysis/binary.h"
+#include "../../common/extstr.h"
@@ -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=true;\n");
+ cmds = strdup("digraph G {\noverlap=false;\n splines=ortho;\n compound=true;\n");
for (i = 0; i < count; i++)
cmds = g_graph_node_register_for_dot(nodes[i], cmds);
@@ -93,7 +93,7 @@ bool build_graph_view(GtkGraphView *view, GtkViewPanel **views, size_t count)
place_nodes_of_graph_layout(layout, view, nodes, count);
- links = create_links_from_graph_layout(layout, &links_count);
+ links = create_links_from_graph_layout(layout, &links_count, nodes, count);
gtk_graph_view_attach_links(view, links, links_count);
gtk_widget_queue_draw(GTK_WIDGET(view));
@@ -169,17 +169,25 @@ static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views
switch (types[j])
{
case ILT_JUMP:
- snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+ 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 -> _%p;\n", views[i], views[k]);
+ 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 -> _%p;\n", views[i], views[k]);
+ 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;
@@ -192,10 +200,10 @@ static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views
}
- /* Si la ligne n'est pas la dernière, on suit le flux normal */
- else if (addr != end)
+ /* Sinon on suit le flux normal */
+ else
{
- next = g_arch_instruction_get_next_iter(instrs, last, end);
+ next = g_arch_instruction_get_next_iter(instrs, last, VMPA_MAX);
if (next == NULL) continue;
g_arch_instruction_get_location(next, NULL, NULL, &addr);
@@ -206,7 +214,9 @@ static char *complete_graph_links(const GtkGraphView *view, GtkViewPanel **views
if (k < count)
{
- snprintf(cmd, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]);
+ 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);
}
diff --git a/src/graph/layout.h b/src/gtkext/graph/layout.h
index 006fa9b..ffb227f 100644
--- a/src/graph/layout.h
+++ b/src/gtkext/graph/layout.h
@@ -28,8 +28,8 @@
#include <stdbool.h>
-#include "../gtkext/gtkgraphview.h"
-#include "../gtkext/gtkviewpanel.h"
+#include "../gtkgraphview.h"
+#include "../gtkviewpanel.h"
diff --git a/src/graph/node.c b/src/gtkext/graph/node.c
index 0d278f3..f3e6352 100644
--- a/src/graph/node.c
+++ b/src/gtkext/graph/node.c
@@ -29,7 +29,7 @@
#include <string.h>
-#include "../common/extstr.h"
+#include "../../common/extstr.h"
@@ -44,6 +44,8 @@ struct _GGraphNode
GtkWidget *view; /* Morceau de code représenté */
char *name; /* Adresse sous forme humaine */
+ GtkAllocation alloc; /* Emplacement du bloc rattaché*/
+
};
@@ -200,6 +202,12 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds)
gtk_widget_size_request(node->view, &requisition);
+ snprintf(buffer, 128, " subgraph cluster%s {\n", node->name);
+ cmds = stradd(cmds, buffer);
+
+ cmds = stradd(cmds, " style=invisible;\n");
+
+ cmds = stradd(cmds, " ");
cmds = stradd(cmds, node->name);
cmds = stradd(cmds, " [shape=box, fixedsize ");
@@ -213,6 +221,8 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds)
cmds = stradd(cmds, "];\n");
+ cmds = stradd(cmds, " }\n");
+
return cmds;
}
@@ -233,7 +243,7 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds)
* *
******************************************************************************/
-void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint y)
+void g_graph_node_place(GGraphNode *node, GtkGraphView *view, gint x, gint y)
{
GtkRequisition requisition; /* Taille à l'écran actuelle */
@@ -244,6 +254,66 @@ void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint
gtk_graph_view_put(view, node->view, x, y);
+ node->alloc.x = x;
+ node->alloc.y = y;
+ node->alloc.width = requisition.width;
+ node->alloc.height = requisition.height;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : node = intermédiaire à consulter. *
+* x = abscisse du point à relier. *
+* y = ordonnée du point à relier. *
+* points = liste de points à mettre à jour. [OUT] *
+* count = taille de cette même liste. [OUT] *
+* *
+* Description : Etablit une jonction ferme avec un noeud. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_graph_node_connect(const GGraphNode *node, gint x, gint y, GdkPoint **points, size_t *count)
+{
+ const GtkAllocation *alloc; /* Emplacement du bloc rattaché*/
+
+ alloc = &node->alloc;
+
+ *points = (GdkPoint *)realloc(*points, ++(*count) * sizeof(GdkPoint));
+
+ /* Si le point est sur la gauche... */
+ if (alloc->y <= y && y < (alloc->y + alloc->height) && x < alloc->x)
+ {
+ (*points)[*count - 1].x = alloc->x;
+ (*points)[*count - 1].y = y;
+ }
+
+ /* Si le point est sur la droite... */
+ else if (alloc->y <= y && y < (alloc->y + alloc->height) && x > (alloc->x + alloc->width))
+ {
+ (*points)[*count - 1].x = alloc->x + alloc->width;
+ (*points)[*count - 1].y = y;
+ }
+
+ /* Si le point est au dessus... */
+ else if (alloc->x <= x && x < (alloc->x + alloc->width) && y < alloc->y)
+ {
+ (*points)[*count - 1].x = x;
+ (*points)[*count - 1].y = alloc->y;
+ }
+
+ /* Si le point est en dessous... */
+ else if (alloc->x <= x && x < (alloc->x + alloc->width) && y > (alloc->y + alloc->height))
+ {
+ (*points)[*count - 1].x = x;
+ (*points)[*count - 1].y = alloc->y + alloc->height;
+ }
+
}
@@ -267,9 +337,9 @@ void g_graph_node_place(const GGraphNode *node, GtkGraphView *view, gint x, gint
* *
******************************************************************************/
-const GGraphNode *find_graph_node_by_name(GGraphNode **nodes, size_t count, const char *target)
+GGraphNode *find_graph_node_by_name(GGraphNode **nodes, size_t count, const char *target)
{
- const GGraphNode *result; /* Trouvaille à remonter */
+ GGraphNode *result; /* Trouvaille à remonter */
size_t i; /* Boucle de parcours */
result = NULL;
diff --git a/src/graph/node.h b/src/gtkext/graph/node.h
index f8d0078..515c92b 100644
--- a/src/graph/node.h
+++ b/src/gtkext/graph/node.h
@@ -25,7 +25,7 @@
#define _GRAPH_NODE_H
-#include "../gtkext/gtkgraphview.h"
+#include "../gtkgraphview.h"
@@ -56,7 +56,10 @@ GGraphNode *g_graph_node_new(GtkWidget *);
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 *, GtkGraphView *, gint , gint);
+void g_graph_node_place(GGraphNode *, GtkGraphView *, gint , gint);
+
+/* Etablit une jonction ferme avec un noeud. */
+void g_graph_node_connect(const GGraphNode *, gint, gint, GdkPoint **, size_t *);
@@ -64,7 +67,7 @@ void g_graph_node_place(const GGraphNode *, GtkGraphView *, gint , gint);
/* Recherche un noeud donné dans une série de noeuds. */
-const GGraphNode *find_graph_node_by_name(GGraphNode **, size_t, const char *);
+GGraphNode *find_graph_node_by_name(GGraphNode **, size_t, const char *);
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 9fa9135..c0ea347 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -27,7 +27,7 @@
#include "gtkblockview.h"
#include "gtkbufferview.h"
#include "gtkviewpanel-int.h"
-#include "../graph/layout.h"
+#include "graph/layout.h"
@@ -554,8 +554,8 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinar
list = g_loaded_binary_get_instructions(binary);
buffer = g_loaded_binary_get_disassembled_buffer(binary);
- addr = g_loaded_binary_display_addresses_in_text(binary);
- code = g_loaded_binary_display_code_in_text(binary);
+ addr = g_loaded_binary_display_addresses_in_text(binary, BDT_GRAPH);
+ code = g_loaded_binary_display_code_in_text(binary, BDT_GRAPH);
first = start;
last = first;
@@ -564,7 +564,7 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBinar
iter != NULL;
iter = g_arch_instruction_get_next_iter(list, iter, end))
{
- if (g_arch_instruction_has_sources(iter))
+ if (first != VMPA_MAX && g_arch_instruction_has_sources(iter))
{
result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
diff --git a/src/gtkext/gtklinkrenderer.c b/src/gtkext/gtklinkrenderer.c
index 9332860..2913c19 100644
--- a/src/gtkext/gtklinkrenderer.c
+++ b/src/gtkext/gtklinkrenderer.c
@@ -24,12 +24,16 @@
#include "gtklinkrenderer.h"
+#include <math.h>
+
+
/* Lien entre morceaux de code (instance) */
struct _GtkLinkRenderer
{
GtkObject parent; /* A laisser en premier */
+ LinkColor color; /* Couleur d'impression */
GdkPoint *points; /* Points de la ligne dessinée */
size_t count; /* Quantité de ces points */
@@ -44,12 +48,18 @@ struct _GtkLinkRendererClass
};
+#define ARROW_LENGHT 10
+#define ARROW_DEGREES 10
+
+
/* Initialise la classe générique des liens graphiques. */
static void gtk_link_renderer_class_init(GtkLinkRendererClass *);
/* Initialise une instance de lien graphique entre codes. */
static void gtk_link_renderer_init(GtkLinkRenderer *);
+/* Dessine une flèche au bout du lien représenté. */
+static void draw_link_arrow(cairo_t *, gint, gint, gint, gint);
@@ -95,7 +105,8 @@ static void gtk_link_renderer_init(GtkLinkRenderer *view)
/******************************************************************************
* *
-* Paramètres : points = points consituant la ligne à représenter. *
+* Paramètres : color = couleur d'impression. *
+ù points = points consituant la ligne à représenter. *
* count = nombre de ces points. *
* *
* Description : Crée un nouveau moteur de rendu pour les liens graphiques. *
@@ -106,12 +117,13 @@ static void gtk_link_renderer_init(GtkLinkRenderer *view)
* *
******************************************************************************/
-GtkObject *gtk_link_renderer_new(GdkPoint *points, size_t count)
+GtkObject *gtk_link_renderer_new(LinkColor color, GdkPoint *points, size_t count)
{
GtkLinkRenderer *result; /* Moteur de rendu à retourner */
result = g_object_new(GTK_TYPE_LINK_RENDERER, NULL);
+ result->color = color;
result->points = points;
result->count = count;
@@ -136,6 +148,88 @@ GtkObject *gtk_link_renderer_new(GdkPoint *points, size_t count)
void gtk_link_renderer_draw(const GtkLinkRenderer *renderer, GdkDrawable *drawable, GdkGC *gc)
{
- gdk_draw_lines(drawable, gc, renderer->points, renderer->count);
+ cairo_t *cairo; /* Gestionnaire de rendu */
+ size_t i; /* Boucle de parcours */
+
+ cairo = gdk_cairo_create(drawable);
+
+ switch (renderer->color)
+ {
+ default:
+ case LKC_DEFAULT:
+ cairo_set_source_rgb(cairo, 0, 0, 0);
+ break;
+ case LKC_GREEN:
+ cairo_set_source_rgb(cairo, 0, 0.6, 0);
+ break;
+ case LKC_RED:
+ cairo_set_source_rgb(cairo, 0.8, 0, 0);
+ break;
+ }
+
+ cairo_set_line_width(cairo, 1);
+
+ cairo_move_to(cairo, renderer->points[0].x, renderer->points[0].y);
+
+ for (i = 1; i < renderer->count; i++)
+ cairo_line_to(cairo, renderer->points[i].x, renderer->points[i].y);
+
+ cairo_stroke(cairo);
+
+ draw_link_arrow(cairo,
+ renderer->points[renderer->count - 2].x,
+ renderer->points[renderer->count - 2].y,
+ renderer->points[renderer->count - 1].x,
+ renderer->points[renderer->count - 1].y);
+
+ cairo_destroy(cairo);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cairo = gestionnaire de rendu graphique. *
+* start_x = abscisse du début du segment final. *
+* start_y = ordonnée du début du segment final. *
+* end_x = abscisse de fin de segment et pointe de flèche. *
+* end_y = ordonnée de fin de segment et pointe de flèche. *
+* *
+* Description : Dessine une flèche au bout du lien représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void draw_link_arrow(cairo_t *cairo, gint start_x, gint start_y, gint end_x, gint end_y)
+{
+ double angle; /* Angle du triangle à remplir */
+ double factor_x; /* Direction de la flèche #1 */
+ double factor_y; /* Direction de la flèche #2 */
+ double x1; /* Abscisse du point n°1 */
+ double y1; /* Ordonnée du point n°1 */
+ double x2; /* Abscisse du point n°2 */
+ double y2; /* Ordonnée du point n°2 */
+
+ angle = atan2(end_y - start_y, end_x - start_x) + M_PI;
+
+ factor_x = -1;
+ factor_y = -1;
+
+ x1 = end_x + factor_x * ARROW_LENGHT * cos(angle - ARROW_DEGREES);
+ y1 = end_y + factor_y * ARROW_LENGHT * sin(angle - ARROW_DEGREES);
+ x2 = end_x + factor_x * ARROW_LENGHT * cos(angle + ARROW_DEGREES);
+ y2 = end_y + factor_y * ARROW_LENGHT * sin(angle + ARROW_DEGREES);
+
+ cairo_move_to(cairo, end_x, end_y);
+
+ cairo_line_to(cairo, x1, y1);
+ cairo_line_to(cairo, x2, y2);
+
+ cairo_move_to(cairo, end_x, end_y);
+
+ cairo_fill(cairo);
}
diff --git a/src/gtkext/gtklinkrenderer.h b/src/gtkext/gtklinkrenderer.h
index d662454..95cdea6 100644
--- a/src/gtkext/gtklinkrenderer.h
+++ b/src/gtkext/gtklinkrenderer.h
@@ -45,11 +45,23 @@ typedef struct _GtkLinkRenderer GtkLinkRenderer;
typedef struct _GtkLinkRendererClass GtkLinkRendererClass;
+/* Couleur de représentation */
+typedef enum _LinkColor
+{
+ LKC_DEFAULT, /* Noir, par défaut */
+ LKC_GREEN, /* Condition vérifiée */
+ LKC_RED, /* Condition non vérifiée */
+
+ LKC_COUNT
+
+} LinkColor;
+
+
/* Détermine le type du moteur de rendu pour les liens graphiques. */
GType gtk_link_renderer_get_type(void);
/* Crée un nouveau moteur de rendu pour les liens graphiques. */
-GtkObject *gtk_link_renderer_new(GdkPoint *, size_t);
+GtkObject *gtk_link_renderer_new(LinkColor, GdkPoint *, size_t);
/* Dessine les liens graphiques enregistrés dans le moteur. */
void gtk_link_renderer_draw(const GtkLinkRenderer *, GdkDrawable *, GdkGC *);
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 3ccc0ff..0ab4f72 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -293,8 +293,7 @@ static gboolean gtk_view_panel_expose(GtkWidget *widget, GdkEventExpose *event)
GtkViewPanel *panel;
GdkGCValues values; /* Propriétés du contexte */
GtkStyle *style; /* Style associé au composant */
- int width; /* Largeur de l'élément */
- int height; /* Hauteur de l'élément */
+ GtkRequisition req; /* Taille allouée à l'élément */
GtkStateType state; /* Etat du composant */
panel = GTK_VIEW_PANEL(widget);
@@ -304,13 +303,13 @@ static gboolean gtk_view_panel_expose(GtkWidget *widget, GdkEventExpose *event)
gdk_gc_get_values(panel->gc, &values);
style = gtk_widget_get_style(widget);
- gtk_widget_get_size_request(widget, &width, &height);
+ gtk_widget_size_request(widget, &req);
state = gtk_widget_get_state(widget);
gdk_gc_set_foreground(panel->gc, &style->dark[state]);
gdk_draw_rectangle(GDK_DRAWABLE(widget->window), panel->gc,
- FALSE, 0, 0, width - 1, height - 1);
+ FALSE, 0, 0, req.width - 1, req.height - 1);
gdk_gc_set_foreground(panel->gc, &values.foreground);
diff --git a/src/project.c b/src/project.c
index b6526c7..106bf3a 100644
--- a/src/project.c
+++ b/src/project.c
@@ -390,8 +390,8 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina
loaded->views[i] = GTK_VIEW_PANEL(view);
gtk_view_panel_attach_binary(loaded->views[i], binary,
- g_loaded_binary_display_addresses_in_text(binary),
- g_loaded_binary_display_code_in_text(binary));
+ g_loaded_binary_display_addresses_in_text(binary, BDT_ASM),
+ g_loaded_binary_display_code_in_text(binary, BDT_ASM));
/* Intégration finale dans un support défilant */