diff options
Diffstat (limited to 'src/gtkext')
| -rw-r--r-- | src/gtkext/Makefile.am | 13 | ||||
| -rw-r--r-- | src/gtkext/gtkbinview.c | 227 | ||||
| -rw-r--r-- | src/gtkext/gtkbinview.h | 69 | ||||
| -rw-r--r-- | src/gtkext/gtksnippet.c | 896 | ||||
| -rw-r--r-- | src/gtkext/gtksnippet.h | 156 | 
5 files changed, 1360 insertions, 1 deletions
| diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index a42d77c..aa14cf5 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -1,10 +1,15 @@ +BUILT_SOURCES = iodamarshal.h iodamarshal.c +  lib_LIBRARIES = libgtkext.a  libgtkext_a_SOURCES =					\ +	gtkbinview.h gtkbinview.c			\  	gtkdockitem.h gtkdockitem.c			\  	gtkdockpanel.h gtkdockpanel.c		\ -	gtkdropwindow.h gtkdropwindow.c +	gtkdropwindow.h gtkdropwindow.c		\ +	gtksnippet.h gtksnippet.c			\ +	iodamarshal.h iodamarshal.c  libgtkext_a_CFLAGS = $(AM_CFLAGS) @@ -15,3 +20,9 @@ AM_CPPFLAGS =  AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +iodamarshal.h: iodamarshal.list +	glib-genmarshal --header $< > $@ + +iodamarshal.c: iodamarshal.list +	glib-genmarshal --body $< > $@ diff --git a/src/gtkext/gtkbinview.c b/src/gtkext/gtkbinview.c new file mode 100644 index 0000000..5ed6388 --- /dev/null +++ b/src/gtkext/gtkbinview.c @@ -0,0 +1,227 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkbinview.c - affichage d'un ou de plusieurs morceaux de code + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "gtkbinview.h" + + +#include "gtksnippet.h" + + + + + +struct _GtkBinview +{ +    GtkViewport viewport; + +}; + +struct _GtkBinviewClass +{ +    GtkViewportClass parent_class; + +}; + + + + +/* Détermine le type du composant d'affichage des morceaux. */ +G_DEFINE_TYPE(GtkBinview, gtk_binview, GTK_TYPE_VIEWPORT) + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class = classe GTK à initialiser.                            * +*                                                                             * +*  Description : Procède à l'initialisation de l'afficheur de morceaux.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_binview_class_init(GtkBinviewClass *class) +{ +    GtkWidgetClass *widget_class;           /* Classe de haut niveau       */ +    GtkViewportClass *viewport_class;             /* Classe du niveau supérieur  */ + +    widget_class = GTK_WIDGET_CLASS(class); +    viewport_class = GTK_VIEWPORT_CLASS(class); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binview = composant GTK à initialiser.                       * +*                                                                             * +*  Description : Procède à l'initialisation de l'afficheur de morceaux.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_binview_init(GtkBinview *binview) +{ + + + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Crée un nouveau composant pour l'affichage de morceaux.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GtkWidget* gtk_binview_new(void) +{ +    return g_object_new(GTK_TYPE_BIN_VIEW, NULL); + +} + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binview = composant GTK à manipuler.                         * +*                show    = état de l'affichage auquel parvenir.               * +*                                                                             * +*  Description : Choisit d'afficher les adresses virtuelles ou non.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_binview_show_vaddress(GtkBinview *binview, gboolean show) +{ +    GList *list;                            /* Ensemble des enfants        */ +    GList *iter;                            /* Boucle de parcours          */ + +    list = gtk_container_get_children(GTK_CONTAINER(binview)); + +    for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) +        gtk_snippet_show_vaddress(GTK_SNIPPET(iter->data), show); + +    g_list_free(list); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binview = composant GTK à manipuler.                         * +*                show    = état de l'affichage auquel parvenir.               * +*                                                                             * +*  Description : Choisit d'afficher le code brut ou non.                      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_binview_show_code(GtkBinview *binview, gboolean show) +{ +    GList *list;                            /* Ensemble des enfants        */ +    GList *iter;                            /* Boucle de parcours          */ + +    list = gtk_container_get_children(GTK_CONTAINER(binview)); + +    for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) +        gtk_snippet_show_code(GTK_SNIPPET(iter->data), show); + +    g_list_free(list); + +} + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binview = composant GTK à manipuler.                         * +*                address = adresse à présenter à l'écran.                     * +*                                                                             * +*  Description : S'assure qu'une adresse donnée est visible à l'écran.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_binview_scroll_to_address(GtkBinview *binview, uint64_t address) +{ +    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  */ + +    list = gtk_container_get_children(GTK_CONTAINER(binview)); + +    for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) +    { +        snippet = GTK_SNIPPET(iter->data); + +        if (gtk_snippet_get_address_vposition(snippet, address, &position)) +        { +            vadj = GTK_VIEWPORT(binview)->vadjustment; + +            gtk_adjustment_set_value(vadj, position); + +            break; + +        } + +    } + +    g_list_free(list); + +} + + + diff --git a/src/gtkext/gtkbinview.h b/src/gtkext/gtkbinview.h new file mode 100644 index 0000000..4fafad1 --- /dev/null +++ b/src/gtkext/gtkbinview.h @@ -0,0 +1,69 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkbinview.h - prototypes pour l'affichage d'un ou de plusieurs morceaux de code + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTK_BINVIEW_H +#define _GTK_BINVIEW_H + + +#include <gtk/gtkwidget.h> + + +#include <stdint.h> + + + +#define GTK_TYPE_BIN_VIEW                  (gtk_binview_get_type()) +#define GTK_BIN_VIEW(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BIN_VIEW, GtkBinview)) +#define GTK_BIN_VIEW_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BIN_VIEW, GtkBinviewClass)) +#define GTK_IS_BIN_VIEW(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BIN_VIEW)) +#define GTK_IS_BIN_VIEW_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BIN_VIEW)) +#define GTK_BIN_VIEW_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BIN_VIEW, GtkBinviewClass)) + + +typedef struct _GtkBinview        GtkBinview; +typedef struct _GtkBinviewClass   GtkBinviewClass; + + + +/* Détermine le type du composant d'affichage des morceaux. */ +GType gtk_binview_get_type(void); + +/* Crée un nouveau composant pour l'affichage de morceaux. */ +GtkWidget* gtk_binview_new(void); + + + +/* Choisit d'afficher les adresses virtuelles ou non. */ +void gtk_binview_show_vaddress(GtkBinview *, gboolean); + +/* Choisit d'afficher le code brut ou non. */ +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); + + + +#endif  /* _GTK_BINVIEW_H */ diff --git a/src/gtkext/gtksnippet.c b/src/gtkext/gtksnippet.c new file mode 100644 index 0000000..a48baf2 --- /dev/null +++ b/src/gtkext/gtksnippet.c @@ -0,0 +1,896 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtksnippet.c - affichage d'un fragment de code d'assemblage + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "gtksnippet.h" + + +#include <malloc.h> +#include <string.h> + + +#include "../common/dllist.h" + + + +#define CONTENT_BUFFER_LEN 64 + +#define MARGIN_SPACE 4 + + + + +/* Redessine l'affichage suite une mise à jour dans la marge. */ +void gtk_snippet_update_margin(GRenderingLine *, GtkSnippet *); + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : offset  = position de l'instruction à ajouter.               * +*                instr   = instruction à représenter ou NULL.                 * +*                comment = commentaire à imprimer ou NULL.                    * +*                                                                             * +*  Description : Crée une ligne de représentation insérable.                  * +*                                                                             * +*  Retour      : Struture rassemblant les informations mise en place.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +code_line_info *create_code_line_info(uint64_t offset, asm_instr *instr, const char *comment) +{ +    code_line_info *result;                 /* Structure à renvoyer        */ + +    result = (code_line_info *)calloc(1, sizeof(code_line_info)); + +    result->offset = offset; +    result->instr = instr; +    result->comment = (comment != NULL ? strdup(comment) : NULL); + +    result->bp_set = FALSE; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line = informations à effacer de la mémoire.                 * +*                                                                             * +*  Description : Supprime une ligne de représentation.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void delete_code_line_info(code_line_info *line) +{ +    free(line->instr); +    free(line->comment); + +    free(line); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a = premières informations à consulter.                      * +*                b = secondes informations à consulter.                       * +*                                                                             * +*  Description : Etablit la comparaison entre deux lignes de représentation.  * +*                                                                             * +*  Retour      : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b).                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int compare_code_line_info(const code_line_info **a, const code_line_info **b) +{ +    int result;                             /* Bilan à renvoyer            */ + +    if ((*a)->offset < (*b)->offset) result = -1; +    else if((*a)->offset > (*b)->offset) result = 1; +    else result = 0; + +    return result; + +} + + + + + + +/* Réclame une nouvelle taille adaptée au contenu présent. */ +void gtk_snippet_recompute_size_request(GtkSnippet *); + + + + + + + + +static void gtk_snippet_class_init(GtkSnippetClass *klass); +static void gtk_snippet_init(GtkSnippet *cpu); +static void gtk_snippet_size_request(GtkWidget *widget, +    GtkRequisition *requisition); +static void gtk_snippet_size_allocate(GtkWidget *widget, +    GtkAllocation *allocation); +static void gtk_snippet_realize(GtkWidget *widget); + + +static gboolean gtk_snippet_button_press(GtkWidget *, GdkEventButton *event); + +static gboolean gtk_snippet_expose(GtkWidget *widget, +    GdkEventExpose *event); +static void gtk_snippet_paint(GtkSnippet *snippet); +static void gtk_snippet_destroy(GtkObject *object); + + +GtkType +gtk_snippet_get_type(void) +{ +  static GtkType gtk_snippet_type = 0; + + +  if (!gtk_snippet_type) { +      static const GtkTypeInfo gtk_snippet_info = { +          "GtkSnippet", +          sizeof(GtkSnippet), +          sizeof(GtkSnippetClass), +          (GtkClassInitFunc) gtk_snippet_class_init, +          (GtkObjectInitFunc) gtk_snippet_init, +          NULL, +          NULL, +          (GtkClassInitFunc) NULL +      }; +      gtk_snippet_type = gtk_type_unique(GTK_TYPE_WIDGET, >k_snippet_info); +  } + + +  return gtk_snippet_type; +} + + +GtkWidget * gtk_snippet_new(void) +{ +    GtkSnippet *result; + +    result = gtk_type_new(gtk_snippet_get_type()); + +    return GTK_WIDGET(result); + +} + + +static void +gtk_snippet_class_init(GtkSnippetClass *klass) +{ +  GtkWidgetClass *widget_class; +  GtkObjectClass *object_class; + + +  widget_class = (GtkWidgetClass *) klass; +  object_class = (GtkObjectClass *) klass; + + +  widget_class->button_press_event = gtk_snippet_button_press; +  widget_class->realize = gtk_snippet_realize; +  widget_class->size_request = gtk_snippet_size_request; +  widget_class->size_allocate = gtk_snippet_size_allocate; +  widget_class->expose_event = gtk_snippet_expose; + +  object_class->destroy = gtk_snippet_destroy; +} + + +static void +gtk_snippet_init(GtkSnippet *snippet) +{ +   snippet->sel = 0; +} + + +static void +gtk_snippet_size_request(GtkWidget *widget, +    GtkRequisition *requisition) +{ +  g_return_if_fail(widget != NULL); +  g_return_if_fail(GTK_IS_SNIPPET(widget)); +  g_return_if_fail(requisition != NULL); + +  requisition->width = 80; +  requisition->height = 100; +} + + +static void +gtk_snippet_size_allocate(GtkWidget *widget, +    GtkAllocation *allocation) +{ +  g_return_if_fail(widget != NULL); +  g_return_if_fail(GTK_IS_SNIPPET(widget)); +  g_return_if_fail(allocation != NULL); + +  widget->allocation = *allocation; + +  if (GTK_WIDGET_REALIZED(widget)) { +     gdk_window_move_resize( +         widget->window, +         allocation->x, allocation->y, +         allocation->width, allocation->height +     ); +   } +} + + +static void +gtk_snippet_realize(GtkWidget *widget) +{ +    GdkWindowAttr attributes; +    guint attributes_mask; +    GdkColor white;                         /* Couleur de fond normale     */ + +  g_return_if_fail(widget != NULL); +  g_return_if_fail(GTK_IS_SNIPPET(widget)); + +  GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); + +  attributes.window_type = GDK_WINDOW_CHILD; +  attributes.x = widget->allocation.x; +  attributes.y = widget->allocation.y; +  attributes.width = widget->allocation.width; +  attributes.height = widget->allocation.height; + +  attributes.wclass = GDK_INPUT_OUTPUT; +  attributes.event_mask = gtk_widget_get_events(widget) | GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK; + +  attributes_mask = GDK_WA_X | GDK_WA_Y; + +  widget->window = gdk_window_new( +     gtk_widget_get_parent_window (widget), +     & attributes, attributes_mask +  ); + +  gdk_window_set_user_data(widget->window, widget); + +    widget->style = gtk_style_attach(widget->style, widget->window); + + +    gdk_color_white(gtk_widget_get_colormap(widget), &white); +    gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &white); + + +    GTK_SNIPPET(widget)->layout = gtk_widget_create_pango_layout(widget, NULL); +    GTK_SNIPPET(widget)->gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); + +    gtk_snippet_build_content(GTK_SNIPPET(widget)); + +} + + +static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *event) +{ +    gboolean result;                        /* Décision à retourner        */ +    GtkSnippet *snippet;                    /* Composant GTK réel          */ +    gdouble y;                              /* Position à manipuler        */ +    GRenderingLine *line;                   /* Ligne de rendu visée        */ + +    result = FALSE; + +    snippet = GTK_SNIPPET(widget); + +    y = event->y; +    line = g_rendering_line_find_by_y(snippet->lines, &y); + +    if (line != NULL) +    { +        /* Clic dans la marge */ +        if (event->type == GDK_BUTTON_PRESS && event->x < (2 * MARGIN_SPACE + snippet->line_height)) +        { +            result = TRUE; +            g_rendering_line_toggle_flag(line, RLF_BREAK_POINT); +        } + +    } + +    if (result) +    { +        /* TODO: regions */ +        gtk_snippet_paint(snippet); +    } + +    return result; + +} + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line    = ligne dont un drapeau a évolué.                    * +*                snippet = composant GTK à mettre à jour.                     * +*                                                                             * +*  Description : Redessine l'affichage suite une mise à jour dans la marge.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_update_margin(GRenderingLine *line, GtkSnippet *snippet) +{ + + +    gtk_snippet_paint(snippet); + + + + +} + + + + + +static gboolean +gtk_snippet_expose(GtkWidget *widget, +    GdkEventExpose *event) +{ +  g_return_val_if_fail(widget != NULL, FALSE); +  g_return_val_if_fail(GTK_IS_SNIPPET(widget), FALSE); +  g_return_val_if_fail(event != NULL, FALSE); + +  gtk_snippet_paint(GTK_SNIPPET(widget)); + + + +  /* + + +gdk_gc_set_clip_region              (GdkGC *gc, +                                                         const GdkRegion *region); + +gdk_window_invalidate_region        (GdkWindow *window, +                                                         const GdkRegion *region, +                                                         gboolean invalidate_children); +gdk_window_begin_paint_region       (GdkWindow *window, +                                                         const GdkRegion *region); +void                gdk_window_end_paint                (GdkWindow *window); +   */ + + + + + + +    return TRUE; + +} + + +static void +gtk_snippet_paint(GtkSnippet *snippet) +{ +    GtkWidget *widget;                      /* Version GTK du composant    */ +    GdkGCValues values;                     /* Propriétés du contexte      */ +    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; + + +    widget = GTK_WIDGET(snippet); +    gdk_gc_get_values(snippet->gc, &values); + +    gdk_color_white(gtk_widget_get_colormap(widget), &white); +    gdk_gc_set_foreground(snippet->gc, &white); + +    gtk_widget_get_size_request(widget, &width, &height); + +    gdk_draw_rectangle(GDK_DRAWABLE(widget->window), GTK_SNIPPET(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(snippet->gc, &red); + + +    index = 0; +    iter = pango_layout_get_iter(snippet->layout); + +    for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) +    { +        if (!snippet->info[index].bp_set) continue; + +        pango_layout_iter_get_line_yrange(iter, &y0, &y1); + + + +        gdk_draw_arc(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, +                     FALSE, MARGIN_SPACE, y0 / PANGO_SCALE, +                     snippet->line_height - 2, snippet->line_height - 2, +                     0, 360 * 64); + +    } + +    pango_layout_iter_free(iter); + +    gdk_gc_set_foreground(snippet->gc, &values.foreground); + +    gdk_draw_layout(GDK_DRAWABLE(widget->window), snippet->gc, +                    2 * MARGIN_SPACE + snippet->line_height, 0, +                    snippet->layout); + + +    y0 = 0; + +    for (/* l! */liter = snippet->lines; liter != NULL; liter = g_rendering_line_get_next_iter(snippet->lines, liter)) +    { +        g_rendering_line_draw(liter, GDK_DRAWABLE(widget->window), snippet->gc, +                              MARGIN_SPACE, 2 * MARGIN_SPACE + snippet->line_height, +                              y0, snippet->line_height); + +        y0 += snippet->line_height; + +    } + + +} + + +static void +gtk_snippet_destroy(GtkObject *object) +{ +  GtkSnippet *cpu; +  GtkSnippetClass *klass; + +  g_return_if_fail(object != NULL); +  g_return_if_fail(GTK_IS_SNIPPET(object)); + +  cpu = GTK_SNIPPET(object); + +  klass = gtk_type_class(gtk_widget_get_type()); + +  if (GTK_OBJECT_CLASS(klass)->destroy) { +     (* GTK_OBJECT_CLASS(klass)->destroy) (object); +  } +} + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet = composant GTK à mettre à jour.                     * +*                show    = état de l'affichage auquel parvenir.               * +*                                                                             * +*  Description : Choisit d'afficher les adresses virtuelles ou non.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_show_vaddress(GtkSnippet *snippet, gboolean show) +{ +    snippet->show_vaddress = show; + +    gtk_snippet_build_content(snippet); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet = composant GTK à mettre à jour.                     * +*                show    = état de l'affichage auquel parvenir.               * +*                                                                             * +*  Description : Choisit d'afficher le code brut ou non.                      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_show_code(GtkSnippet *snippet, gboolean show) +{ +    snippet->show_code = show; + +    gtk_snippet_build_content(snippet); + +} + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet = composant GTK à mettre à jour.                     * +*                format  = format du binaire affiché.                         * +*                                                                             * +*  Description : Définit le format auquel le contenu est lié.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_set_format(GtkSnippet *snippet, const exe_format *format) +{ +    snippet->format = format; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet = composant GTK à mettre à jour.                     * +*                proc    = architecture à associer au contenu.                * +*                                                                             * +*  Description : Définit l'architecture à laquelle le contenu est lié.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_set_processor(GtkSnippet *snippet, const asm_processor *proc) +{ +    snippet->proc = proc; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet = composant GTK à mettre à jour.                     * +*                lines   = informations à intégrer.                           * +*                                                                             * +*  Description : Définit les lignes du bloc de représentation.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, GRenderingLine *lines) +{ +    GRenderingLine *iter;                   /* Boucle de parcours          */ + +    snippet->lines = lines; + +    for (iter = lines; iter != NULL; iter = g_rendering_line_get_next_iter(lines, iter)) +        g_signal_connect(iter, "rendering-line-flags-changed", +                         G_CALLBACK(gtk_snippet_update_margin), snippet); + +    g_rendering_line_update_bin_len(lines); + +    gtk_snippet_recompute_size_request(snippet); + +} + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet = composant GTK à mettre à jour.                     * +*                                                                             * +*  Description : Réclame une nouvelle taille adaptée au contenu présent.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_recompute_size_request(GtkSnippet *snippet) +{ +    int width;                              /* Largeur de l'objet actuelle */ +    int height;                             /* Hauteur de l'objet actuelle */ + +    g_rendering_line_get_size(snippet->lines, &width, &height, &snippet->line_height); + +    gtk_widget_set_size_request(GTK_WIDGET(snippet), +                                width + 2 * MARGIN_SPACE + snippet->line_height, +                                height); + +} + + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet = composant GTK à mettre à jour.                     * +*                line    = informations à intégrer.                           * +*                                                                             * +*  Description : Ajoute une ligne dans le bloc de représentation.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_add_line(GtkSnippet *snippet, const code_line_info *line) +{ +    snippet->info = (code_line_info *)realloc(snippet->info, ++snippet->info_count * sizeof(code_line_info)); + +    snippet->info[snippet->info_count - 1] = *line; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet = composant GTK à mettre à jour.                     * +*                                                                             * +*  Description : Définit le contenu visuel à partir des infos enregistrées.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void gtk_snippet_build_content(GtkSnippet *snippet) +{ +    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 (snippet->show_code) +    { +        exe_content = get_exe_content(snippet->format, NULL); + +        max_bin_len = 1; + +        for (i = 0; i < snippet->info_count; i++) +        { +            /* Commentaire uniquement */ +            if (snippet->info[i].instr == NULL) continue; + +            get_asm_instr_offset_and_length(snippet->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("<tt>") + 1; +    content = (char *)calloc(content_len, sizeof(char)); +    strcpy(content, "<tt>"); + +    mode = ADM_32BITS;  /* FIXME */ + +    for (i = 0; i < snippet->info_count; i++) +    { +        if (i > 0) +        { +            content = (char *)realloc(content, ++content_len * sizeof(char)); +            strcat(content, "\n"); +        } + +        /* Eventuelle adresse virtuelle */ + +        if (snippet->show_vaddress) +        { +            switch (mode) +            { +                case ADM_32BITS: +                    snprintf(buffer, CONTENT_BUFFER_LEN, +                             "<span foreground='#333333'>0x%08llx</span>",  +                             snippet->info[i].offset); +                    break; + +                case ADM_64BITS: +                    snprintf(buffer, CONTENT_BUFFER_LEN, +                             "<span foreground='#333333'>0x%16llx</span>",  +                             snippet->info[i].offset); +                    break; + +            } + +            content_len += strlen(buffer); +            content = (char *)realloc(content, content_len * sizeof(char)); +            strcat(content, buffer); + +        } + +        /* Eventuel code brut */ + +        if (snippet->show_code) +        { +            k = 0; + +            if (snippet->info[i].instr != NULL) +            { +                get_asm_instr_offset_and_length(snippet->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 (snippet->show_vaddress) content_len += strlen("\t"); +            content_len += strlen(bin_code); +            content = (char *)realloc(content, content_len * sizeof(char)); +            if (snippet->show_vaddress) strcat(content, "\t"); +            strcat(content, bin_code); + +        } + +        /* Eventuelle instruction */ + +        if (snippet->info[i].instr != NULL) +        { +            print_hinstruction(snippet->proc, snippet->format, snippet->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); + +            if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); +            content_len += strlen(buffer); + +            content = (char *)realloc(content, content_len * sizeof(char)); +            if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); +            strcat(content, buffer); + +        } + +        /* Eventuel commantaire */ + +        if (snippet->info[i].comment != NULL) +        { +            if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); +            content_len += strlen("<b><span foreground='#003300'>; ") + strlen(snippet->info[i].comment) + strlen("</span></b>"); + +            content = (char *)realloc(content, content_len * sizeof(char)); +            if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); +            strcat(content, "<b><span foreground='#003300'>; "); +            strcat(content, snippet->info[i].comment); +            strcat(content, "</span></b>"); + +        } + +    } + +    content_len += strlen("</tt>"); +    content = (char *)realloc(content, content_len * sizeof(char)); +    strcat(content, "</tt>"); + +    if (snippet->show_code) free(bin_code); + +    pango_layout_set_markup(snippet->layout, content, content_len - 1); + +    pango_layout_get_pixel_size(snippet->layout, &width, &height); + +    snippet->line_height = 0; +    iter = pango_layout_get_iter(snippet->layout); + +    do +    { +        pango_layout_iter_get_line_yrange(iter, &y0, &y1); +        snippet->line_height = MAX(snippet->line_height, (y1 - y0) / PANGO_SCALE); +    } +    while (pango_layout_iter_next_line(iter)); + +    pango_layout_iter_free(iter); + +    //gtk_widget_set_size_request(GTK_WIDGET(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height); + +} + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : snippet  = 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_snippet_get_address_vposition(GtkSnippet *snippet, uint64_t address, gint *position) +{ +    unsigned int i;                         /* Boucle de parcours          */ + +    *position = 0; + +    for (i = 0; i < snippet->info_count; i++) +    { +        if (snippet->info[i].offset == address) break; +        else *position += snippet->line_height; +    } + +    return (i < snippet->info_count); + +} + diff --git a/src/gtkext/gtksnippet.h b/src/gtkext/gtksnippet.h new file mode 100644 index 0000000..41727bd --- /dev/null +++ b/src/gtkext/gtksnippet.h @@ -0,0 +1,156 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtksnippet.h - prototypes pour l'affichage d'un fragment de code d'assemblage + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTK_SNIPPET_H +#define _GTK_SNIPPET_H + + +#include <stdint.h> +#include <gtk/gtk.h> +#include <cairo.h> + + +#include "../analysis/line.h" +#include "../arch/instruction.h" +#include "../arch/processor.h" +#include "../format/exe_format.h" + + + +typedef struct _code_line_info +{ +    uint64_t offset;                        /* Position de l'instruction   */ +    asm_instr *instr;                       /* Eventuelle instruction      */ +    char *comment;                          /* Eventuel commentaire        */ + +    gboolean bp_set;                        /* Point d'arrêt défini        */ + +} code_line_info; + + + + +/* Crée une ligne de représentation insérable. */ +code_line_info *create_code_line_info(uint64_t, asm_instr *, const char *); + +/* Supprime une ligne de représentation. */ +void delete_code_line_info(code_line_info *); + +/* Etablit la comparaison entre deux lignes de représentation. */ +int compare_code_line_info(const code_line_info **, const code_line_info **); + + + + + +G_BEGIN_DECLS + + +#define GTK_SNIPPET(obj) GTK_CHECK_CAST(obj, gtk_snippet_get_type (), GtkSnippet) +#define GTK_SNIPPET_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_snippet_get_type(), GtkSnippetClass) +#define GTK_IS_SNIPPET(obj) GTK_CHECK_TYPE(obj, gtk_snippet_get_type()) + + +typedef struct _GtkSnippet GtkSnippet; +typedef struct _GtkSnippetClass GtkSnippetClass; + + + + + +struct _GtkSnippet { + +    GtkWidget widget;                       /* Présence obligatoire en 1er */ + +    AdressMode mode;                        /* Mode d'affichage            */ + +    bool show_vaddress;                     /* Affichage des adresses ?    */ +    bool show_code;                         /* Affichage du code brut ?    */ + +    PangoLayout *layout;                    /* Moteur de rendu du code ASM */ +    GdkGC *gc;                              /* Contexte graphique du rendu */ +    int line_height;                        /* Hauteur maximale des lignes */ + +    const exe_format *format;               /* Format du contenu bianire   */ +    const asm_processor *proc;              /* Architecture utilisée       */ +    code_line_info *info;                   /* Contenu à représenter       */ +    unsigned int info_count;                /* Quantité d'informations     */ + +    GRenderingLine *lines;                  /* Contenu à représenter       */ + + +  gint sel; +}; + +struct _GtkSnippetClass { +  GtkWidgetClass parent_class; +}; + + +GtkType gtk_snippet_get_type(void); +void gtk_snippet_set_sel(GtkSnippet *cpu, gint sel); + +GtkWidget * gtk_snippet_new(void); + + + + +/* Choisit d'afficher les adresses virtuelles ou non. */ +void gtk_snippet_show_vaddress(GtkSnippet *, gboolean); + +/* Choisit d'afficher le code brut ou non. */ +void gtk_snippet_show_code(GtkSnippet *, gboolean); + + + + +/* Définit le format auquel le contenu est lié. */ +void gtk_snippet_set_format(GtkSnippet *, const exe_format *); + +/* Définit l'architecture à laquelle le contenu est lié. */ +void gtk_snippet_set_processor(GtkSnippet *, const asm_processor *); + +/* Ajoute une ligne dans le bloc de représentation. */ +void gtk_snippet_add_line(GtkSnippet *, const code_line_info *); + +/* Définit les lignes du bloc de représentation. */ +void gtk_snippet_set_rendering_lines(GtkSnippet *, GRenderingLine *); + +/* Définit le contenu visuel à partir des infos enregistrées. */ +void gtk_snippet_build_content(GtkSnippet *); + + + +/* Indique la position verticale d'une adresse donnée. */ +gboolean gtk_snippet_get_address_vposition(GtkSnippet *, uint64_t, gint *); + + + +G_END_DECLS + + + + + + +#endif  /* _GTK_SNIPPET_H */ | 
