From ae0135d727fdc67a268ede1530042a42a2a1ccd3 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 14 Jun 2009 11:57:14 +0000 Subject: Cleaned and improved the binary views ; implemented some first steps for the graphical view. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@76 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 31 ++++ src/analysis/binary.c | 2 +- src/analysis/line.c | 76 ++++++++-- src/analysis/line.h | 13 +- src/editor.c | 13 +- src/gtkext/gtkbinview-int.h | 14 ++ src/gtkext/gtkbinview.c | 88 ++++++++---- src/gtkext/gtkbinview.h | 11 +- src/gtkext/gtkblockview.c | 338 ++++++++++---------------------------------- src/gtkext/gtkblockview.h | 12 +- src/gtkext/gtkgraphview.c | 117 +++++++++++++++ src/panel/symbols.c | 2 +- src/project.c | 7 +- src/project.h | 3 +- 14 files changed, 396 insertions(+), 331 deletions(-) diff --git a/ChangeLog b/ChangeLog index dc9e705..5b0507a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +09-06-14 Cyrille Bagard + + * src/analysis/binary.c: + Update the call to g_rendering_line_find_by_(offset|address). + + * src/analysis/line.c: + * src/analysis/line.h: + Add a function to get the address of the line. Take care of lines + portions (start -> end). Rename g_rendering_line_find_by_offset into + g_rendering_line_find_by_address. + + * src/editor.c: + Update the code. Register the current GtkBinView widget as needed. + + * src/gtkext/gtkbinview.c: + * src/gtkext/gtkbinview.h: + * src/gtkext/gtkbinview-int.h: + * src/gtkext/gtkblockview.c: + * src/gtkext/gtkblockview.h: + * src/gtkext/gtkgraphview.c: + Clean and improve the binary views. Implement some first steps for the + graphical view. Restore the scrolling to a given address. + + * src/panel/symbols.c: + Update call to gtk_(binview|bin_view)_scroll_to_address(). + + * src/project.c: + * src/project.h: + Update call to gtk_bin_view_set_rendering_lines(). Provide the + GtkBinView widget actually used when requested. + 09-06-13 Cyrille Bagard * src/gtkext/gtkblockview.c: diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 01ccfdd..61d344e 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -667,7 +667,7 @@ void disassemble_openida_binary(openida_binary *binary) - line = g_rendering_line_find_by_offset(binary->lines, get_exe_entry_point(binary->format)); + line = g_rendering_line_find_by_address(binary->lines, NULL, get_exe_entry_point(binary->format)); if (line != NULL) g_rendering_line_add_flag(line, RLF_ENTRY_POINT); diff --git a/src/analysis/line.c b/src/analysis/line.c index 2697f77..08ef3c1 100644 --- a/src/analysis/line.c +++ b/src/analysis/line.c @@ -126,6 +126,25 @@ static void g_rendering_line_init(GRenderingLine *line) * * * Paramètres : line = ligne dont les informations sont à consulter. * * * +* Description : Fournit l'adresse physique ou en mémoire d'une ligne. * +* * +* Retour : Position physique ou en mémoire associée à la ligne. * +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa_t get_rendering_line_address(const GRenderingLine *line) +{ + return line->offset; + +} + + +/****************************************************************************** +* * +* Paramètres : line = ligne dont les informations sont à consulter. * +* * * Description : Fournit le type d'une ligne. * * * * Retour : Type de la ligne fournie. * @@ -395,8 +414,9 @@ void g_rendering_line_insert_into_lines(GRenderingLine **lines, GRenderingLine * /****************************************************************************** * * -* Paramètres : line = liste de lignes de représentation à actualiser. * -* : iter = position actuelle dans la liste. * +* Paramètres : lines = liste de lignes de représentation à actualiser. * +* : iter = position actuelle dans la liste. * +* last = dernière élément imposé du parcours ou NULL. * * * * Description : Fournit l'élement suivant un autre pour un parcours. * * * @@ -406,13 +426,14 @@ void g_rendering_line_insert_into_lines(GRenderingLine **lines, GRenderingLine * * * ******************************************************************************/ -GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *lines, const GRenderingLine *iter) +GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *lines, const GRenderingLine *iter, const GRenderingLine *last) { GRenderingLine *result; /* Elément suivant à renvoyer */ if (iter == NULL) iter = lines; - result = lines_list_next_iter(iter, lines); + if (iter == last) result = NULL; + else result = lines_list_next_iter(iter, lines); return result; @@ -421,7 +442,8 @@ GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *lines, const GRen /****************************************************************************** * * -* Paramètres : line = liste de lignes de représentation à actualiser. * +* Paramètres : lines = liste de lignes de représentation à actualiser. * +* last = dernière élément imposé du parcours ou NULL. * * * * Description : Met à jour le nombre d'octets maximal par instruction. * * * @@ -431,7 +453,7 @@ GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *lines, const GRen * * ******************************************************************************/ -void g_rendering_line_update_bin_len(GRenderingLine *lines) +void g_rendering_line_update_bin_len(GRenderingLine *lines, const GRenderingLine *last) { GRenderingLine *iter; /* Boucle de parcours */ off_t bin_len; /* Taille d'instruction */ @@ -439,13 +461,21 @@ void g_rendering_line_update_bin_len(GRenderingLine *lines) bin_len = 0; lines_list_for_each(iter, lines) + { if (iter->get_bin_len != NULL) iter->get_bin_len(iter, &bin_len); + if (iter == last) break; + + } + lines_list_for_each(iter, lines) { - iter->max_bin_len = bin_len * 2 + (bin_len - 1); + iter->max_bin_len = (bin_len > 0 ? bin_len * 2 + (bin_len - 1) : 0); iter->refresh_markup(iter); + + if (iter == last) break; + } } @@ -454,6 +484,7 @@ void g_rendering_line_update_bin_len(GRenderingLine *lines) /****************************************************************************** * * * Paramètres : lines = liste de lignes de représentation à actualiser. * +* last = dernière élément imposé du parcours ou NULL. * * width = largeur maximale des lignes. [OUT] * * height = hauteur maximale des lignes. [OUT] * * alone = hauteur d'une seule ligne. [OUT] * @@ -466,7 +497,7 @@ void g_rendering_line_update_bin_len(GRenderingLine *lines) * * ******************************************************************************/ -void g_rendering_line_get_size(GRenderingLine *lines, int *width, int *height, int *alone) +void g_rendering_line_get_size(GRenderingLine *lines, const GRenderingLine *last, int *width, int *height, int *alone) { GRenderingLine *iter; /* Boucle de parcours */ int w; /* Largeur de l'objet actuelle */ @@ -486,6 +517,8 @@ void g_rendering_line_get_size(GRenderingLine *lines, int *width, int *height, i if (iter == lines) *alone = h; + if (iter == last) break; + } } @@ -494,6 +527,7 @@ void g_rendering_line_get_size(GRenderingLine *lines, int *width, int *height, i /****************************************************************************** * * * Paramètres : lines = liste de lignes à parcourir. * +* last = dernière élément imposé du parcours ou NULL. * * y = ordonnée à vérifier et à mettre à jour. [OUT] * * * * Description : Recherche une ligne d'après sa position à l'écran. * @@ -504,7 +538,7 @@ void g_rendering_line_get_size(GRenderingLine *lines, int *width, int *height, i * * ******************************************************************************/ -GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *lines, gdouble *y) +GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *lines, const GRenderingLine *last, gdouble *y) { GRenderingLine *result; /* Trouvaille à retourner */ int h; /* Hauteur de l'objet actuel */ @@ -516,6 +550,12 @@ GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *lines, gdouble *y) if (*y < h) break; else *y -= h; + if (result == last) + { + result = NULL; + break; + } + } return result; @@ -525,8 +565,9 @@ GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *lines, gdouble *y) /****************************************************************************** * * -* Paramètres : lines = liste de lignes à parcourir. * -* offset = position en mémoire ou physique à chercher. * +* Paramètres : lines = liste de lignes à parcourir. * +* last = dernière élément imposé du parcours ou NULL. * +* addr = position en mémoire ou physique à chercher. * * * * Description : Recherche une ligne d'après sa position en mémoire/physique. * * * @@ -536,12 +577,21 @@ GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *lines, gdouble *y) * * ******************************************************************************/ -GRenderingLine *g_rendering_line_find_by_offset(GRenderingLine *lines, uint64_t offset) +GRenderingLine *g_rendering_line_find_by_address(GRenderingLine *lines, const GRenderingLine *last, vmpa_t addr) { GRenderingLine *result; /* Trouvaille à retourner */ lines_list_for_each(result, lines) - if (result->offset == offset) break; + { + if (result->offset == addr) break; + + if (result == last) + { + result = NULL; + break; + } + + } return result; diff --git a/src/analysis/line.h b/src/analysis/line.h index ae7698e..69deb57 100644 --- a/src/analysis/line.h +++ b/src/analysis/line.h @@ -83,6 +83,9 @@ typedef struct _GRenderingLineClass GRenderingLineClass; /* Indique le type définit pour une ligne de représentation. */ GType g_rendering_line_get_type(void); +/* Fournit l'adresse physique ou en mémoire d'une ligne. */ +vmpa_t get_rendering_line_address(const GRenderingLine *); + /* Fournit le type d'une ligne. */ RenderingLineType get_rendering_line_type(const GRenderingLine *); @@ -113,19 +116,19 @@ void g_rendering_line_add_to_lines(GRenderingLine **, GRenderingLine *); void g_rendering_line_insert_into_lines(GRenderingLine **, GRenderingLine *, bool); /* Fournit l'élement suivant un autre pour un parcours. */ -GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *, const GRenderingLine *); +GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *, const GRenderingLine *, const GRenderingLine *); /* Met à jour le nombre d'octets maximal par instruction. */ -void g_rendering_line_update_bin_len(GRenderingLine *); +void g_rendering_line_update_bin_len(GRenderingLine *, const GRenderingLine *); /* Fournit les dimensions de lignes de représentation. */ -void g_rendering_line_get_size(GRenderingLine *, int *, int *, int *); +void g_rendering_line_get_size(GRenderingLine *, const GRenderingLine *, int *, int *, int *); /* Recherche une ligne d'après sa position à l'écran. */ -GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *, gdouble *); +GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *, const GRenderingLine *, gdouble *); /* Recherche une ligne d'après sa position en mémoire/physique. */ -GRenderingLine *g_rendering_line_find_by_offset(GRenderingLine *, uint64_t); +GRenderingLine *g_rendering_line_find_by_address(GRenderingLine *, const GRenderingLine *, vmpa_t); diff --git a/src/editor.c b/src/editor.c index 8c28e68..ad0373b 100644 --- a/src/editor.c +++ b/src/editor.c @@ -736,6 +736,7 @@ void mcb_view_change_support(GtkRadioMenuItem *menuitem, GObject *ref) GSList *iter; /* Boucle de parcours */ BinaryView view; /* Nouvelle vue à présenter */ openida_binary *binary; /* Edition courante */ + GtkBinView *binview; /* Afficheur effectif de code */ GtkWidget *panel; /* Nouveau support à utiliser */ GtkDockPanel *dpanel; /* Support de panneaux */ GtkDockItem *ditem; /* Panneau avec ses infos. */ @@ -752,7 +753,9 @@ void mcb_view_change_support(GtkRadioMenuItem *menuitem, GObject *ref) view = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(iter->data), "kind_of_view")); binary = (openida_binary *)g_object_get_data(ref, "current_binary"); - panel = get_view_for_openida_project_binary(get_current_openida_project(), binary, view); + panel = get_view_for_openida_project_binary(get_current_openida_project(), binary, view, &binview); + + g_object_set_data(ref, "binview", binview); dpanel = GTK_DOCK_PANEL(g_object_get_data(ref, "binpanel")); ditem = gtk_dock_panel_item_from_name(dpanel, openida_binary_to_string(binary)); @@ -1002,7 +1005,7 @@ void debugger_stopped_cb(GBinaryDebugger *debugger, uint64_t last, uint64_t cur, if (last != cur) { - line = g_rendering_line_find_by_offset(get_openida_binary_lines(binary), last); + line = g_rendering_line_find_by_address(get_openida_binary_lines(binary), NULL/* FIXME */, last); if (line != NULL) g_rendering_line_remove_flag(line, RLF_RUNNING_BP); @@ -1012,7 +1015,7 @@ void debugger_stopped_cb(GBinaryDebugger *debugger, uint64_t last, uint64_t cur, printf("bp at 0x%016llx\n", cur); - line = g_rendering_line_find_by_offset(get_openida_binary_lines(binary), cur); + line = g_rendering_line_find_by_address(get_openida_binary_lines(binary), NULL/* FIXME */, cur); if (line != NULL) g_rendering_line_add_flag(line, RLF_RUNNING_BP); @@ -1224,6 +1227,7 @@ void open_last_file(GObject *ref) openida_project *project; GtkWidget *view; /* Affichage du code binaire */ + GtkBinView *binview; /* Afficheur effectif de code */ @@ -1240,8 +1244,9 @@ void open_last_file(GObject *ref) attach_binary_to_openida_project(project, binary); - view = get_view_for_openida_project_binary(project, binary, BVW_BLOCK); + view = get_view_for_openida_project_binary(project, binary, BVW_BLOCK, &binview); + g_object_set_data(ref, "binview", binview); diff --git a/src/gtkext/gtkbinview-int.h b/src/gtkext/gtkbinview-int.h index 33ba33c..fffbc9f 100644 --- a/src/gtkext/gtkbinview-int.h +++ b/src/gtkext/gtkbinview-int.h @@ -28,14 +28,28 @@ #include "gtkbinview.h" +#include #include +/* Définit les lignes à associer à la représentation. */ +typedef void (* set_rendering_lines_fc) (GtkBinview *, GRenderingLine *, GRenderingLine *); + +/* Indique la position d'affichage d'une adresse donnée. */ +typedef bool (* get_addr_coordinates_fc) (GtkBinView *, vmpa_t, gint *, gint *); + + struct _GtkBinview { GtkFixed parent; /* A laisser en premier */ + GRenderingLine *lines; /* Contenu à représenter */ + GRenderingLine *last; /* Dernière ligne associée */ + + set_rendering_lines_fc set_lines; /* Association des lignes */ + get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */ + }; struct _GtkBinviewClass diff --git a/src/gtkext/gtkbinview.c b/src/gtkext/gtkbinview.c index 9ffb5f6..3799b25 100644 --- a/src/gtkext/gtkbinview.c +++ b/src/gtkext/gtkbinview.c @@ -106,6 +106,43 @@ 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. * +* * +* Description : Définit les lignes à associer à la représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_bin_view_set_rendering_lines(GtkBinview *view, GRenderingLine *lines, GRenderingLine *last) +{ + view->lines = lines; + view->last = last; + + view->set_lines(view, lines, last); + +} + + + + + + + + + + + + + /****************************************************************************** * * * Paramètres : binview = composant GTK à manipuler. * @@ -134,6 +171,14 @@ void gtk_binview_show_vaddress(GtkBinview *binview, gboolean show) } + + + + + + + + /****************************************************************************** * * * Paramètres : binview = composant GTK à manipuler. * @@ -169,8 +214,8 @@ void gtk_binview_show_code(GtkBinview *binview, gboolean show) /****************************************************************************** * * -* Paramètres : binview = composant GTK à manipuler. * -* address = adresse à présenter à l'écran. * +* Paramètres : view = composant GTK à manipuler. * +* addr = adresse à présenter à l'écran. * * * * Description : S'assure qu'une adresse donnée est visible à l'écran. * * * @@ -180,36 +225,31 @@ void gtk_binview_show_code(GtkBinview *binview, gboolean show) * * ******************************************************************************/ -void gtk_binview_scroll_to_address(GtkBinview *binview, uint64_t address) +void gtk_bin_view_scroll_to_address(GtkBinview *view, vmpa_t addr) { -#if 0 - GList *list; /* Ensemble des enfants */ - GList *iter; /* Boucle de parcours */ - GtkSnippet *snippet; /* Morceau de code présent */ - gint position; /* Position à garantir */ - GtkAdjustment *vadj; /* Défilement à mettre à jour */ + gint x; /* Abscisse à garantir */ + gint y; /* Ordonnée à garantir */ + GtkViewport *support; /* Support avec défilements */ + GtkAdjustment *adj; /* Défilement à mettre à jour */ - list = gtk_container_get_children(GTK_CONTAINER(binview)); - - for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) + if (view->get_coordinates(view, addr, &x, &y)) { - snippet = GTK_SNIPPET(iter->data); + support = GTK_VIEWPORT(gtk_widget_get_parent(GTK_WIDGET(view))); - if (gtk_snippet_get_address_vposition(snippet, address, &position)) - { - vadj = GTK_VIEWPORT(binview)->vadjustment; + adj = gtk_viewport_get_hadjustment(support); - gtk_adjustment_set_value(vadj, position); + if (x > (adj->upper - adj->page_size)) + x = adj->upper - adj->page_size; - break; + gtk_adjustment_set_value(adj, x); - } + adj = gtk_viewport_get_vadjustment(support); - } - - g_list_free(list); -#endif -} + if (y > (adj->upper - adj->page_size)) + y = adj->upper - adj->page_size; + gtk_adjustment_set_value(adj, y); + } +} diff --git a/src/gtkext/gtkbinview.h b/src/gtkext/gtkbinview.h index 722d10d..a80cda3 100644 --- a/src/gtkext/gtkbinview.h +++ b/src/gtkext/gtkbinview.h @@ -28,7 +28,8 @@ #include -#include +#include "../analysis/line.h" +#include "../arch/archbase.h" @@ -56,6 +57,12 @@ GtkWidget* gtk_binview_new(void); +/* Définit les lignes à associer à la représentation. */ +void gtk_bin_view_set_rendering_lines(GtkBinview *, GRenderingLine *, GRenderingLine *); + + + + /* Choisit d'afficher les adresses virtuelles ou non. */ void gtk_binview_show_vaddress(GtkBinview *, gboolean); @@ -65,7 +72,7 @@ void gtk_binview_show_code(GtkBinview *, gboolean); /* S'assure qu'une adresse donnée est visible à l'écran. */ -void gtk_binview_scroll_to_address(GtkBinview *, uint64_t); +void gtk_bin_view_scroll_to_address(GtkBinview *, vmpa_t); diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c index dc889f9..648421d 100644 --- a/src/gtkext/gtkblockview.c +++ b/src/gtkext/gtkblockview.c @@ -33,8 +33,6 @@ -#define CONTENT_BUFFER_LEN 64 - #define MARGIN_SPACE 4 @@ -52,8 +50,6 @@ struct _GtkBlockView const exe_format *format; /* Format du contenu bianire */ - GRenderingLine *lines; /* Contenu à représenter */ - }; struct _GtkBlockViewClass @@ -64,6 +60,13 @@ struct _GtkBlockViewClass +/* Procède à l'initialisation de l'afficheur d'un bloc binaire. */ +static void gtk_block_view_init(GtkBlockView *); + + +/* Définit les lignes du bloc de représentation. */ +static void gtk_block_view_set_rendering_lines(GtkBlockView *, GRenderingLine *, GRenderingLine *); + @@ -82,6 +85,9 @@ void gtk_block_view_recompute_size_request(GtkBlockView *); +/* Indique la position d'affichage d'une adresse donnée. */ +static bool gtk_block_view_get_address_coordinates(GtkBlockView *, vmpa_t, gint *, gint *); + @@ -120,8 +126,8 @@ GtkWidget * gtk_block_view_new(void) } -static void -gtk_block_view_class_init(GtkBlockViewClass *klass) + +static void gtk_block_view_class_init(GtkBlockViewClass *klass) { GtkWidgetClass *widget_class; GtkObjectClass *object_class; @@ -141,13 +147,31 @@ gtk_block_view_class_init(GtkBlockViewClass *klass) } -static void -gtk_block_view_init(GtkBlockView *view) +/****************************************************************************** +* * +* Paramètres : view = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur d'un bloc binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_block_view_init(GtkBlockView *view) { + GtkBinView *binview; /* Instance parente */ + + binview = GTK_BIN_VIEW(view); + + binview->set_lines = (set_rendering_lines_fc)gtk_block_view_set_rendering_lines; + binview->get_coordinates = (get_addr_coordinates_fc)gtk_block_view_get_address_coordinates; } + static void gtk_block_view_size_request(GtkWidget *widget, GtkRequisition *requisition) @@ -221,8 +245,6 @@ gtk_block_view_realize(GtkWidget *widget) GTK_BLOCK_VIEW(widget)->layout = gtk_widget_create_pango_layout(widget, NULL); GTK_BLOCK_VIEW(widget)->gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); - gtk_block_view_build_content(GTK_BLOCK_VIEW(widget)); - } @@ -238,7 +260,7 @@ static gboolean gtk_block_view_button_press(GtkWidget *widget, GdkEventButton *e view = GTK_BLOCK_VIEW(widget); y = event->y; - line = g_rendering_line_find_by_y(view->lines, &y); + line = g_rendering_line_find_by_y(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, &y); if (line != NULL) { @@ -335,14 +357,8 @@ gtk_block_view_paint(GtkBlockView *view) GdkColor white; /* Couleur du fond */ int width; /* Largeur de l'élément */ int height; /* Hauteur de l'élément */ - GdkColor red; /* Couleur des arrêts */ - PangoLayoutIter *iter; /* Boucle de parcours */ - unsigned int index; /* Indice de la ligne visée */ - int y0; /* Ordonnée du haut d'une ligne*/ - int y1; /* Ordonnée du bas d'une ligne */ - - GRenderingLine *liter; - + int y; /* Ordonnée du haut d'une ligne*/ + GRenderingLine *iter; /* Boucle de parcours */ widget = GTK_WIDGET(view); gdk_gc_get_values(view->gc, &values); @@ -355,53 +371,26 @@ gtk_block_view_paint(GtkBlockView *view) gdk_draw_rectangle(GDK_DRAWABLE(widget->window), GTK_BLOCK_VIEW(widget)->gc, TRUE, 0, 0, width, height); - gdk_color_parse("#ff0000", &red); - gdk_color_alloc(gtk_widget_get_colormap(widget), &red); - gdk_gc_set_foreground(view->gc, &red); - - - index = 0; - iter = pango_layout_get_iter(view->layout); - -#if 0 - for (; index < view->info_count; index++, pango_layout_iter_next_line(iter)) - { - if (!view->info[index].bp_set) continue; - - pango_layout_iter_get_line_yrange(iter, &y0, &y1); - - - - gdk_draw_arc(GDK_DRAWABLE(widget->window), GTK_BLOCK_VIEW(widget)->gc, - FALSE, MARGIN_SPACE, y0 / PANGO_SCALE, - view->line_height - 2, view->line_height - 2, - 0, 360 * 64); - - } -#endif - - pango_layout_iter_free(iter); - gdk_gc_set_foreground(view->gc, &values.foreground); gdk_draw_layout(GDK_DRAWABLE(widget->window), view->gc, 2 * MARGIN_SPACE + view->line_height, 0, view->layout); + y = 0; - y0 = 0; - - for (/* l! */liter = view->lines; liter != NULL; liter = g_rendering_line_get_next_iter(view->lines, liter)) + for (iter = GTK_BIN_VIEW(view)->lines; + iter != NULL; + iter = g_rendering_line_get_next_iter(GTK_BIN_VIEW(view)->lines, iter, GTK_BIN_VIEW(view)->last)) { - g_rendering_line_draw(liter, GDK_DRAWABLE(widget->window), view->gc, + g_rendering_line_draw(iter, GDK_DRAWABLE(widget->window), view->gc, MARGIN_SPACE, 2 * MARGIN_SPACE + view->line_height, - y0, view->line_height); + y, view->line_height); - y0 += view->line_height; + y += view->line_height; } - } @@ -445,7 +434,7 @@ void gtk_block_view_show_vaddress(GtkBlockView *view, gboolean show) { view->show_vaddress = show; - gtk_block_view_build_content(view); + //gtk_block_view_build_content(view); } @@ -467,7 +456,7 @@ void gtk_block_view_show_code(GtkBlockView *view, gboolean show) { view->show_code = show; - gtk_block_view_build_content(view); + //gtk_block_view_build_content(view); } @@ -499,6 +488,7 @@ void gtk_block_view_set_format(GtkBlockView *view, const exe_format *format) * * * Paramètres : view = composant GTK à mettre à jour. * * lines = informations à intégrer. * +* last = dernière ligne à intégrer ou NULL pour toutes. * * * * Description : Définit les lignes du bloc de représentation. * * * @@ -508,17 +498,19 @@ void gtk_block_view_set_format(GtkBlockView *view, const exe_format *format) * * ******************************************************************************/ -void gtk_block_view_set_rendering_lines(GtkBlockView *view, GRenderingLine *lines) +static void gtk_block_view_set_rendering_lines(GtkBlockView *view, GRenderingLine *lines, GRenderingLine *last) { GRenderingLine *iter; /* Boucle de parcours */ - view->lines = lines; - - for (iter = lines; iter != NULL; iter = g_rendering_line_get_next_iter(lines, iter)) + for (iter = GTK_BIN_VIEW(view)->lines; + iter != NULL; + iter = g_rendering_line_get_next_iter(GTK_BIN_VIEW(view)->lines, iter, GTK_BIN_VIEW(view)->last)) + { g_signal_connect(iter, "rendering-line-flags-changed", G_CALLBACK(gtk_block_view_update_margin), view); + } - g_rendering_line_update_bin_len(lines); + g_rendering_line_update_bin_len(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last); gtk_block_view_recompute_size_request(view); @@ -545,7 +537,8 @@ void gtk_block_view_recompute_size_request(GtkBlockView *view) int width; /* Largeur de l'objet actuelle */ int height; /* Hauteur de l'objet actuelle */ - g_rendering_line_get_size(view->lines, &width, &height, &view->line_height); + g_rendering_line_get_size(GTK_BIN_VIEW(view)->lines, GTK_BIN_VIEW(view)->last, + &width, &height, &view->line_height); gtk_widget_set_size_request(GTK_WIDGET(view), width + 2 * MARGIN_SPACE + view->line_height, @@ -560,226 +553,39 @@ void gtk_block_view_recompute_size_request(GtkBlockView *view) - - /****************************************************************************** * * -* Paramètres : view = composant GTK à mettre à jour. * +* 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 : Définit le contenu visuel à partir des infos enregistrées. * +* Description : Indique la position d'affichage d'une adresse donnée. * * * -* Retour : - * +* Retour : TRUE si l'adresse fait partie du composant, FALSE sinon. * * * * Remarques : - * * * ******************************************************************************/ -void gtk_block_view_build_content(GtkBlockView *view) +static bool gtk_block_view_get_address_coordinates(GtkBlockView *view, vmpa_t addr, gint *x, gint *y) { -#if 0 - const uint8_t *exe_content; /* Contenu binaire global */ - off_t max_bin_len; /* Taille max du code brut */ - unsigned int i; /* Boucle de traitement */ - off_t bin_len; /* Taille d'instruction */ - char *bin_code; /* Tampon du code binaire */ - char *content; /* Contenu à définir */ - size_t content_len; /* Taille du contenu */ - AdressMode mode; /* Affichage des adresses */ - char buffer[CONTENT_BUFFER_LEN]; /* Zone tampon à utiliser */ - off_t bin_offset; /* Début de l'instruction */ - off_t k; /* Boucle de parcours #2 */ - off_t j; /* Boucle de parcours #1 */ - int width; /* Largeur de l'objet actuelle */ - int height; /* Hauteur de l'objet actuelle */ - PangoLayoutIter *iter; /* Boucle de parcours */ - int y0; /* Ordonnée du haut d'une ligne*/ - int y1; /* Ordonnée du bas d'une ligne */ - - /* Calcul de la largeur maximale brute si besoin est */ - if (view->show_code) - { - exe_content = get_exe_content(view->format, NULL); - - max_bin_len = 1; - - for (i = 0; i < view->info_count; i++) - { - /* Commentaire uniquement */ - if (view->info[i].instr == NULL) continue; - - get_asm_instr_offset_and_length(view->info[i].instr, NULL, &bin_len); - if (bin_len > max_bin_len) max_bin_len = bin_len; - - } - - max_bin_len = max_bin_len * 2 + (max_bin_len - 1); - bin_code = (char *)calloc(max_bin_len + 1, sizeof(char)); - - } - - content_len = strlen("") + 1; - content = (char *)calloc(content_len, sizeof(char)); - strcpy(content, ""); - - mode = ADM_32BITS; /* FIXME */ - - for (i = 0; i < view->info_count; i++) - { - if (i > 0) - { - content = (char *)realloc(content, ++content_len * sizeof(char)); - strcat(content, "\n"); - } - - /* Eventuelle adresse virtuelle */ - - if (view->show_vaddress) - { - switch (mode) - { - case ADM_32BITS: - snprintf(buffer, CONTENT_BUFFER_LEN, - "0x%08llx", - view->info[i].offset); - break; - - case ADM_64BITS: - snprintf(buffer, CONTENT_BUFFER_LEN, - "0x%16llx", - view->info[i].offset); - break; - - } - - content_len += strlen(buffer); - content = (char *)realloc(content, content_len * sizeof(char)); - strcat(content, buffer); - - } - - /* Eventuel code brut */ - - if (view->show_code) - { - k = 0; - - if (view->info[i].instr != NULL) - { - get_asm_instr_offset_and_length(view->info[i].instr, &bin_offset, &bin_len); - - for (j = 0; j < bin_len; j++) - { - if ((j + 1) < bin_len) - k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); - else - k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); - } - - } - - for (; k < max_bin_len; k++) - snprintf(&bin_code[k], 2, " "); - - if (view->show_vaddress) content_len += strlen("\t"); - content_len += strlen(bin_code); - content = (char *)realloc(content, content_len * sizeof(char)); - if (view->show_vaddress) strcat(content, "\t"); - strcat(content, bin_code); - - } - - /* Eventuelle instruction */ - - if (view->info[i].instr != NULL) - { - print_hinstruction(view->proc, view->format, view->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); - - if (view->show_vaddress || view->show_code) content_len += strlen("\t"); - content_len += strlen(buffer); - - content = (char *)realloc(content, content_len * sizeof(char)); - if (view->show_vaddress || view->show_code) strcat(content, "\t"); - strcat(content, buffer); - - } - - /* Eventuel commantaire */ - - if (view->info[i].comment != NULL) - { - if (view->show_vaddress || view->show_code) content_len += strlen("\t"); - content_len += strlen("; ") + strlen(view->info[i].comment) + strlen(""); - - content = (char *)realloc(content, content_len * sizeof(char)); - if (view->show_vaddress || view->show_code) strcat(content, "\t"); - strcat(content, "; "); - strcat(content, view->info[i].comment); - strcat(content, ""); - - } - - } - - content_len += strlen(""); - content = (char *)realloc(content, content_len * sizeof(char)); - strcat(content, ""); - - if (view->show_code) free(bin_code); - - pango_layout_set_markup(view->layout, content, content_len - 1); + bool result; /* Bilan à retourner */ + GRenderingLine *iter; /* Boucle de parcours */ - pango_layout_get_pixel_size(view->layout, &width, &height); + result = false; - view->line_height = 0; - iter = pango_layout_get_iter(view->layout); + *x = 0; + *y = 0; - do + for (iter = GTK_BIN_VIEW(view)->lines; + iter != NULL && !result; + iter = g_rendering_line_get_next_iter(GTK_BIN_VIEW(view)->lines, iter, GTK_BIN_VIEW(view)->last)) { - pango_layout_iter_get_line_yrange(iter, &y0, &y1); - view->line_height = MAX(view->line_height, (y1 - y0) / PANGO_SCALE); + if (get_rendering_line_address(iter) == addr) result = true; + else *y += view->line_height; } - while (pango_layout_iter_next_line(iter)); - - pango_layout_iter_free(iter); - - //gtk_widget_set_size_request(GTK_WIDGET(block_view), width + 2 * MARGIN_SPACE + view->line_height, height); -#endif -} - - - - - - - - -/****************************************************************************** -* * -* Paramètres : view = composant GTK à consulter. * -* address = adresse à présenter à l'écran. * -* position = position verticale au sein du composant. [OUT] * -* * -* Description : Indique la position verticale d'une adresse donnée. * -* * -* Retour : TRUE si l'adresse fait partie du composant, FALSE sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gboolean gtk_block_view_get_address_vposition(GtkBlockView *view, uint64_t address, gint *position) -{ - unsigned int i; /* Boucle de parcours */ - *position = 0; -#if 0 - for (i = 0; i < view->info_count; i++) - { - if (view->info[i].offset == address) break; - else *position += view->line_height; - } -#endif - return false;//(i < view->info_count); + return result; } - diff --git a/src/gtkext/gtkblockview.h b/src/gtkext/gtkblockview.h index 66117fa..d56ed95 100644 --- a/src/gtkext/gtkblockview.h +++ b/src/gtkext/gtkblockview.h @@ -55,7 +55,7 @@ typedef struct _GtkBlockViewClass GtkBlockViewClass; GType gtk_block_view_get_type(void); /* Crée un nouveau composant pour l'affichage en blockique. */ -GtkWidget* gtk_block_view_new(void); +GtkWidget *gtk_block_view_new(void); @@ -80,16 +80,6 @@ void gtk_block_view_show_code(GtkBlockView *, gboolean); /* Définit le format auquel le contenu est lié. */ void gtk_block_view_set_format(GtkBlockView *, const exe_format *); -/* Définit les lignes du bloc de représentation. */ -void gtk_block_view_set_rendering_lines(GtkBlockView *, GRenderingLine *); - -/* Définit le contenu visuel à partir des infos enregistrées. */ -void gtk_block_view_build_content(GtkBlockView *); - - - -/* Indique la position verticale d'une adresse donnée. */ -gboolean gtk_block_view_get_address_vposition(GtkBlockView *, uint64_t, gint *); diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c index d843311..80ca06b 100644 --- a/src/gtkext/gtkgraphview.c +++ b/src/gtkext/gtkgraphview.c @@ -27,12 +27,18 @@ #include "gtkbinview-int.h" +#include + + /* Représentation de code binaire sous forme graphique (instace) */ struct _GtkGraphView { GtkBinView parent; /* A laisser en premier */ + GtkBinView **childs; /* Liste des sous-blocs */ + size_t childs_count; /* Taille de cette liste */ + }; /* Représentation de code binaire sous forme graphique (classe) */ @@ -49,6 +55,12 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *); /* Initialise une instance d'afficheur de code en graphique. */ static void gtk_graph_view_init(GtkGraphView *); +/* Définit les lignes du graphique de représentation. */ +static void gtk_graph_view_set_rendering_lines(GtkGraphView *, GRenderingLine *, GRenderingLine *); + +/* Indique la position d'affichage d'une adresse donnée. */ +static bool gtk_graph_view_get_address_coordinates(GtkGraphView *, vmpa_t, gint *, gint *); + /* Détermine le type du composant d'affichage en graphique. */ @@ -87,6 +99,12 @@ static void gtk_graph_view_class_init(GtkGraphViewClass *class) static void gtk_graph_view_init(GtkGraphView *view) { + GtkBinView *binview; /* Instance parente */ + + binview = GTK_BIN_VIEW(view); + + binview->set_lines = (set_rendering_lines_fc)gtk_graph_view_set_rendering_lines; + binview->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates; } @@ -108,3 +126,102 @@ GtkWidget* gtk_graph_view_new(void) return g_object_new(GTK_TYPE_GRAPH_VIEW, NULL); } + + + + + + + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* lines = informations à intégrer. * +* last = dernière ligne à intégrer ou NULL pour toutes. * +* * +* Description : Définit les lignes du graphique de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_graph_view_set_rendering_lines(GtkGraphView *view, GRenderingLine *lines, GRenderingLine *last) +{ + GRenderingLine *mainl; + + view->childs = (GtkBinView **)calloc(2, sizeof(GtkBinView *)); + view->childs_count = 2; + + view->childs[0] = GTK_BIN_VIEW(gtk_block_view_new()); + + gtk_widget_show(GTK_WIDGET(view->childs[0])); + gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->childs[0]), 50, 50); + + + gtk_bin_view_set_rendering_lines(view->childs[0], lines, lines); + + + + mainl = g_rendering_line_find_by_address(lines, last, 0x08048434); + + printf("mainl : %p\n", mainl); + + + view->childs[1] = GTK_BIN_VIEW(gtk_block_view_new()); + + gtk_widget_show(GTK_WIDGET(view->childs[1])); + gtk_fixed_put(GTK_FIXED(view), GTK_WIDGET(view->childs[1]), 100, 450); + + + gtk_bin_view_set_rendering_lines(view->childs[1], mainl, mainl); + + + +} + + + + + + + + +/****************************************************************************** +* * +* 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(GtkGraphView *view, vmpa_t addr, gint *x, gint *y) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = false; + + *x = 0; + *y = 0; + + for (i = 0; i < view->childs_count && !result; i++) + if (view->childs[i]->get_coordinates(view->childs[i], addr, x, y)) + { + *x += GTK_WIDGET(view->childs[i])->allocation.x; + *y += GTK_WIDGET(view->childs[i])->allocation.y; + result = true; + } + + return result; + +} diff --git a/src/panel/symbols.c b/src/panel/symbols.c index 3937849..38b8089 100644 --- a/src/panel/symbols.c +++ b/src/panel/symbols.c @@ -138,7 +138,7 @@ void change_symbols_selection(GtkTreeSelection *selection, gpointer data) binview = GTK_BIN_VIEW(g_object_get_data(G_OBJECT(data), "binview")); - gtk_binview_scroll_to_address(binview, address); + gtk_bin_view_scroll_to_address(binview, address); } diff --git a/src/project.c b/src/project.c index dc1efd1..bf2c3e0 100644 --- a/src/project.c +++ b/src/project.c @@ -115,8 +115,7 @@ loaded_binary *load_openida_binary(openida_binary *binary) break; } - if (i == 0) - gtk_block_view_set_rendering_lines(GTK_BLOCK_VIEW(view), get_openida_binary_lines(binary)); + gtk_bin_view_set_rendering_lines(GTK_BIN_VIEW(view), get_openida_binary_lines(binary), NULL); gtk_widget_show(view); @@ -429,6 +428,7 @@ void detach_binary_to_openida_project(openida_project *project, openida_binary * * Paramètres : project = projet à consulter. * * binary = binaire chargé, encadré et concerné. * * view = type d'affichage requis. * +* binview = afficheur effectif de code binaire. [OUT] * * * * Description : Fournit un support d'affichage donné pour un binaire chargé. * * * @@ -438,7 +438,7 @@ void detach_binary_to_openida_project(openida_project *project, openida_binary * * * ******************************************************************************/ -GtkWidget *get_view_for_openida_project_binary(const openida_project *project, const openida_binary *binary, BinaryView view) +GtkWidget *get_view_for_openida_project_binary(const openida_project *project, const openida_binary *binary, BinaryView view, GtkBinView **binview) { GtkWidget *result; /* Composant GTK à retourner */ size_t i; /* Boucle de parcours */ @@ -449,6 +449,7 @@ GtkWidget *get_view_for_openida_project_binary(const openida_project *project, c if (project->binaries[i]->binary == binary) { result = get_loaded_binary_view(project->binaries[i], view); + *binview = GTK_BIN_VIEW(gtk_bin_get_child(gtk_bin_get_child(result))); break; } diff --git a/src/project.h b/src/project.h index cf5613d..d05ab5b 100644 --- a/src/project.h +++ b/src/project.h @@ -29,6 +29,7 @@ #include "analysis/binary.h" +#include "gtkext/gtkbinview.h" @@ -82,7 +83,7 @@ void attach_binary_to_openida_project(openida_project *, openida_binary *); void detach_binary_to_openida_project(openida_project *, openida_binary *); /* Fournit un support d'affichage donné pour un binaire chargé. */ -GtkWidget *get_view_for_openida_project_binary(const openida_project *, const openida_binary *, BinaryView); +GtkWidget *get_view_for_openida_project_binary(const openida_project *, const openida_binary *, BinaryView, GtkBinView **); /* Fournit l'ensemble des binaires associés à un projet. */ const openida_binary **get_openida_project_binaries(const openida_project *, size_t *); -- cgit v0.11.2-87-g4458