diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/analysis/Makefile.am | 4 | ||||
| -rw-r--r-- | src/analysis/exporter-int.h | 67 | ||||
| -rw-r--r-- | src/analysis/exporter.c | 253 | ||||
| -rw-r--r-- | src/analysis/exporter.h | 92 | ||||
| -rw-r--r-- | src/analysis/line-int.h | 12 | ||||
| -rw-r--r-- | src/analysis/line.c | 26 | ||||
| -rw-r--r-- | src/analysis/line_code.c | 136 | ||||
| -rw-r--r-- | src/analysis/line_comment.c | 130 | ||||
| -rw-r--r-- | src/analysis/line_prologue.c | 39 | ||||
| -rw-r--r-- | src/analysis/roptions.h | 12 | ||||
| -rw-r--r-- | src/arch/Makefile.am | 2 | ||||
| -rw-r--r-- | src/arch/archbase.c | 79 | ||||
| -rw-r--r-- | src/arch/archbase.h | 8 | ||||
| -rw-r--r-- | src/arch/immediate.c | 173 | ||||
| -rw-r--r-- | src/arch/instruction-int.h | 5 | ||||
| -rw-r--r-- | src/arch/instruction.c | 66 | ||||
| -rw-r--r-- | src/arch/operand-int.h | 5 | ||||
| -rw-r--r-- | src/arch/operand.c | 2 | ||||
| -rw-r--r-- | src/arch/x86/operand.c | 220 | ||||
| -rw-r--r-- | src/arch/x86/operand.h | 4 | ||||
| -rw-r--r-- | src/arch/x86/registers.c | 413 | ||||
| -rw-r--r-- | src/arch/x86/registers.h | 35 | ||||
| -rw-r--r-- | src/gtkext/gtkblockview.c | 177 | ||||
| -rw-r--r-- | src/gtkext/gtkextstatusbar.c | 12 | ||||
| -rw-r--r-- | src/main.c | 5 | 
25 files changed, 1359 insertions, 618 deletions
| diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index 2a456ff..d7c694b 100755 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -4,8 +4,10 @@ noinst_LTLIBRARIES  = libanalysis.la  libanalysis_la_SOURCES =				\  	binary.h binary.c					\  	delayed.h delayed.c					\ -	line.h line.c						\ +	exporter-int.h						\ +	exporter.h exporter.c				\  	line-int.h							\ +	line.h line.c						\  	line_code.h line_code.c				\  	line_comment.h line_comment.c		\  	line_prologue.h line_prologue.c		\ diff --git a/src/analysis/exporter-int.h b/src/analysis/exporter-int.h new file mode 100644 index 0000000..0c93980 --- /dev/null +++ b/src/analysis/exporter-int.h @@ -0,0 +1,67 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line-int.h - prototypes pour la traduction humaine des lignes de rendus + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_EXPORTER_INT_H +#define _ANALYSIS_EXPORTER_INT_H + + +#include "exporter.h" + + + +/* Ajoute à un texte GTK le contenu de la ligne de rendu. */ +typedef void (* add_to_gtk_buffer_fc) (GContentExporter *, MainRendering, GtkTextBuffer *, GtkTextIter *, gint [SAR_COUNT]); + +/* Traduit une instruction en version humainement lisible. */ +typedef void (* add_arch_to_gtk_buffer_fc) (const GContentExporter *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); + + + +/* Exportation de contenu (instance) */ +struct _GContentExporter +{ +    GObject parent;                         /* A laisser en premier        */ + +    add_to_gtk_buffer_fc add_to_gtk_buffer; /* Constitution du texte GTK   */ + +    add_arch_to_gtk_buffer_fc add_arch_to_gtk_buffer;   /* Constitution... */ + +}; + + +/* Exportation de contenu (classe) */ +struct _GContentExporterClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +    GtkTextTag *tags[RTT_COUNT];            /* Décorateurs pour les textes */ + +}; + + +/* Ajoute du texte à un texte GTK via l'instance spécifiée. */ +void g_content_exporter_insert_with_gtk_tag(GContentExporter *, GtkTextBuffer *, GtkTextIter *, const char *, size_t, RenderingTagType); + + + +#endif  /* _ANALYSIS_EXPORTER_INT_H */ diff --git a/src/analysis/exporter.c b/src/analysis/exporter.c new file mode 100644 index 0000000..dd0f6c0 --- /dev/null +++ b/src/analysis/exporter.c @@ -0,0 +1,253 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * exporter.c - traduction humaine des lignes de rendus + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "exporter.h" + + +#include "exporter-int.h" + + + +/* Indique le type défini pour une exportation de contenu. */ +G_DEFINE_TYPE(GContentExporter, g_content_exporter, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des lignes de représentation.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_content_exporter_class_init(GContentExporterClass *klass) +{ +    GtkTextTagTable *table;                 /* Seule table globale valable */ +    GtkTextTag *tag; + +    /* Décorateurs GTK */ + +    table = get_gtk_tag_table(); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "green", NULL); + +    klass->tags[RTT_COMMENT] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "gray", NULL); + +    klass->tags[RTT_RAW_CODE] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "red", NULL); + +    klass->tags[RTT_INSTRUCTION] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "purple", NULL); + +    klass->tags[RTT_IMMEDIATE] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "blue", NULL); + +    klass->tags[RTT_REGISTER] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "blue", "background", "black", NULL); + +    klass->tags[RTT_HOOK] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "white", "background", "black", NULL); + +    klass->tags[RTT_SIGNS] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "red", "background", "black", NULL); + +    klass->tags[RTT_LTGT] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "black", NULL); + +    klass->tags[RTT_SEGMENT] = tag; +    gtk_text_tag_table_add(table, tag); + +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "orange", NULL); + +    klass->tags[RTT_STRING] = tag; +    gtk_text_tag_table_add(table, tag); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : exporter = instance à initialiser.                           * +*                                                                             * +*  Description : Initialise une instance de ligne de représentation.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_content_exporter_init(GContentExporter *exporter) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : table = éventuelle instance à enregistrer.                   * +*                                                                             * +*  Description : Définit et/ou renvoie le singleton pour les marques de texte.* +*                                                                             * +*  Retour      : Table courante à utiliser.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GtkTextTagTable *_get_gtk_tag_table(GtkTextTagTable *table) +{ +    static GtkTextTagTable *result = NULL;  /* Table valable à renvoyer    */ + +    if (table != NULL) +    { +        if (result != NULL) /* TODO : free() */; +        result = table; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : exporter = instance sachant exporter son contenu.            * +*                buffer   = zone de texte à venir compléter.                  * +*                iter     = point d'insertion du nouveau texte. [OUT]         * +*                text     = texte à insérer dans l'existant.                  * +*                length   = taille du texte à traiter.                        * +*                tag      = type de décorateur à utiliser.                    * +*                                                                             * +*  Description : Ajoute du texte à un texte GTK via l'instance spécifiée.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_content_exporter_insert_with_gtk_tag(GContentExporter *exporter, GtkTextBuffer *buffer, GtkTextIter *iter, const char *text, size_t length, RenderingTagType tag) +{ +    size_t init;                            /* Point d'insertion initial   */ + +    init = gtk_text_iter_get_offset(iter); + +    if (tag != RTT_NONE) +        gtk_text_buffer_insert_with_tags(buffer, iter, text, length, +                                         G_CONTENT_EXPORTER_GET_CLASS(exporter)->tags[tag], +                                         NULL); + +    else gtk_text_buffer_insert_with_tags(buffer, iter, text, length, NULL); + +    gtk_text_iter_set_offset(iter, init + length); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : exporter  = instance sachant exporter son contenu.           * +*                rendering = support effectif final des lignes de code.       * +*                buffer    = zone de texte à venir compléter.                 * +*                iter      = point d'insertion du nouveau texte.              * +*                                                                             * +*  Description : Ajoute à un texte GTK le contenu de l'instance spécifiée.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_content_exporter_add_to_gtk_buffer(GContentExporter *exporter, MainRendering rendering, GtkTextBuffer *buffer, GtkTextIter *iter) +{ +    if (exporter->add_to_gtk_buffer != NULL) +        exporter->add_to_gtk_buffer(exporter, rendering, buffer, iter, NULL); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : exporter  = instance sachant exporter son contenu.           * +*                format    = format du binaire manipulé.                      * +*                syntax    = type de représentation demandée.                 * +*                buffer    = zone de texte à venir compléter.                 * +*                iter      = point d'insertion du nouveau texte.              * +*                                                                             * +*  Description : Ajoute à un texte GTK le contenu d'une architecture.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_content_exporter_add_arch_to_gtk_buffer(const GContentExporter *exporter, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter) +{ +    if (exporter->add_arch_to_gtk_buffer != NULL) +        exporter->add_arch_to_gtk_buffer(exporter, format, syntax, buffer, iter); + +} diff --git a/src/analysis/exporter.h b/src/analysis/exporter.h new file mode 100644 index 0000000..6d99463 --- /dev/null +++ b/src/analysis/exporter.h @@ -0,0 +1,92 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * exporter.h - prototypes pour la traduction humaine des lignes de rendus + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_EXPORTER_H +#define _ANALYSIS_EXPORTER_H + + +#include <glib-object.h> +#include <gtk/gtktextbuffer.h> + + +#include "roptions.h" + + +/* Types de partie de rendu */ +typedef enum _RenderingTagType +{ +    RTT_COMMENT,                            /* Commentaire                 */ +    RTT_RAW_CODE,                           /* Code binaire brut           */ + +    RTT_INSTRUCTION,                        /* Code binaire brut           */ + +    RTT_IMMEDIATE,                          /* Valeur immédiate            */ + +    RTT_REGISTER,                           /* Registre                    */ + +    RTT_HOOK,                               /* Crochets '[' et ']'         */ +    RTT_SIGNS,                              /* Signes '+', '-' et '*'      */ +    RTT_LTGT,                               /* Caractères '<' et '>'       */ + +    RTT_SEGMENT,                            /* Indication de segment       */ +    RTT_STRING,                             /* Chaîne de caractères avec " */ + +    RTT_COUNT + +} RenderingTagType; + + +#define RTT_NONE RTT_COUNT + + +#define G_TYPE_CONTENT_EXPORTER               g_content_exporter_get_type() +#define G_CONTENT_EXPORTER(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_content_exporter_get_type(), GContentExporter)) +#define G_IS_CONTENT_EXPORTER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_content_exporter_get_type())) +#define G_CONTENT_EXPORTER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CONTENT_EXPORTER, GContentExporterClass)) +#define G_IS_CONTENT_EXPORTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CONTENT_EXPORTER)) +#define G_CONTENT_EXPORTER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CONTENT_EXPORTER, GContentExporterClass)) + + +/* Exportation de contenu (instance) */ +typedef struct _GContentExporter GContentExporter; + +/* Exportation de contenu (classe) */ +typedef struct _GContentExporterClass GContentExporterClass; + + +/* Indique le type défini pour une exportation de contenu. */ +GType g_content_exporter_get_type(void); + +/* Définit et/ou renvoie le singleton pour les marques de texte. */ +GtkTextTagTable *_get_gtk_tag_table(GtkTextTagTable *); + +#define get_gtk_tag_table() _get_gtk_tag_table(NULL) + +/* Ajoute à un texte GTK le contenu de l'instance spécifiée. */ +void g_content_exporter_add_to_gtk_buffer(GContentExporter *, MainRendering, GtkTextBuffer *, GtkTextIter *); + +/* Ajoute à un texte GTK le contenu d'une architecture. */ +void g_content_exporter_add_arch_to_gtk_buffer(const GContentExporter *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); + + +#endif  /* _ANALYSIS_EXPORTER_H */ diff --git a/src/analysis/line-int.h b/src/analysis/line-int.h index 4d181f9..c603837 100644 --- a/src/analysis/line-int.h +++ b/src/analysis/line-int.h @@ -28,6 +28,7 @@  #include "line.h" +#include "exporter-int.h"  #include "../common/dllist.h" @@ -35,18 +36,15 @@  /* Méthode de mise à jour du nombre d'octets maximal par instruction. */  typedef void (* get_bin_len_fc) (GRenderingLine *, off_t *); -/* Méthode de mise à jour d'une ligne de représentation. */ -typedef void (* refresh_markup_fc) (GRenderingLine *, MainRendering); -  /* Ligne de représentation générique (instance) */  struct _GRenderingLine  { -    GObject parent;                         /* A laisser en premier        */ +    GContentExporter parent;                /* A laisser en premier        */      DL_LIST_ITEM(link);                     /* Maillon de liste chaînée    */ -    uint64_t offset;                        /* Position en mémoire/physique*/ +    vmpa_t offset;                          /* Position en mémoire/physique*/      off_t length;                           /* Nombre d'adresses associées */      RenderingLineType type;                 /* Type de représentation      */ @@ -63,8 +61,6 @@ struct _GRenderingLine      get_bin_len_fc get_bin_len;             /* Nbre d'octets représentés   */      off_t max_bin_len[MRD_COUNT];           /* Nombre global maximal       */ -    refresh_markup_fc refresh_markup;       /* Reconstruit la représentat° */ -  }; @@ -77,7 +73,7 @@ struct _GRenderingLine  /* Ligne de représentation générique (classe) */  struct _GRenderingLineClass  { -    GObjectClass parent;                    /* A laisser en premier        */ +    GContentExporterClass parent;           /* A laisser en premier        */      GtkStyle *style;                        /* Style GTK commun aux lignes */ diff --git a/src/analysis/line.c b/src/analysis/line.c index 988de1f..739db2c 100644 --- a/src/analysis/line.c +++ b/src/analysis/line.c @@ -62,7 +62,7 @@ static GdkPixbuf *g_rendering_line_render_icon(const GRenderingLine *, const cha  /* Indique le type définit pour une ligne de représentation. */ -G_DEFINE_TYPE(GRenderingLine, g_rendering_line, G_TYPE_OBJECT); +G_DEFINE_TYPE(GRenderingLine, g_rendering_line, G_TYPE_CONTENT_EXPORTER);  /****************************************************************************** @@ -106,29 +106,8 @@ static void g_rendering_line_class_init(GRenderingLineClass *klass)  static void g_rendering_line_init(GRenderingLine *line)  { -    GdkScreen *screen;                      /* Ecran d'application         */ -    PangoFontDescription *desc;             /* Description de la police    */ -    MainRendering i;                        /* Boucle de parcours          */ - -    static PangoContext *context = NULL;    /* Contexte graphique Pango    */ -      DL_LIST_ITEM_INIT(&line->link); -    if (context == NULL) -    { -        screen = gdk_screen_get_default(); -        desc = pango_font_description_from_string("mono 10"); - -        context = gdk_pango_context_get_for_screen(screen); -        pango_context_set_font_description(context, desc); - -    } - -    for (i = 0; i < MRD_COUNT; i++) -        line->layout[i] = pango_layout_new(context); - -    line->get_bin_len = NULL; -    line->refresh_markup = NULL;  } @@ -429,7 +408,7 @@ static GdkPixbuf *g_rendering_line_render_icon(const GRenderingLine *line, const  void g_rendering_line_draw(GRenderingLine *line, GdkDrawable *drawable, GdkGC *gc, gint x0, gint x1, gint y, gint h, MainRendering rendering)  {      GdkPixbuf *pixbuf;                      /* Données utiles au dessin    */ - +    return ;      gdk_draw_layout(drawable, gc, x1, y, line->layout[rendering]);      if (line->to != NULL) @@ -604,7 +583,6 @@ void g_rendering_line_update_bin_len(GRenderingLine *lines, GRenderingLine *last      lines_list_for_each(iter, lines)      {          iter->max_bin_len[rendering] = (bin_len > 0 ? bin_len * 2 + (bin_len - 1) : 0); -        iter->refresh_markup(iter, rendering);          if (iter == last) break; diff --git a/src/analysis/line_code.c b/src/analysis/line_code.c index 697dd7d..4ceabec 100644 --- a/src/analysis/line_code.c +++ b/src/analysis/line_code.c @@ -61,8 +61,8 @@ static void g_code_line_init(GCodeLine *);  /* Met à jour le nombre d'octets maximal par instruction. */  void g_code_line_get_binary_len(GCodeLine *, off_t *); -/* Met à jour la ligne de représentation de code. */ -void g_code_line_refresh_markup(GCodeLine *, MainRendering); +/* Ajoute à un texte GTK le contenu de la ligne de code. */ +static void g_code_line_add_to_gtk_buffer(GCodeLine *, MainRendering, GtkTextBuffer *, GtkTextIter *, gint [SAR_COUNT]); @@ -103,14 +103,18 @@ static void g_code_line_class_init(GCodeLineClass *klass)  static void g_code_line_init(GCodeLine *line)  { -    GRenderingLine *parent;                 /* Instance parente            */ +    GContentExporter *exporter_parent;      /* Instance parente #1         */ +    GRenderingLine *line_parent;            /* Instance parente #2         */ -    parent = G_RENDERING_LINE(line); +    exporter_parent = G_CONTENT_EXPORTER(line); -    parent->type = RLT_CODE; +    exporter_parent->add_to_gtk_buffer = (add_to_gtk_buffer_fc)g_code_line_add_to_gtk_buffer; -    parent->get_bin_len = (get_bin_len_fc)g_code_line_get_binary_len; -    parent->refresh_markup = (refresh_markup_fc)g_code_line_refresh_markup; +    line_parent = G_RENDERING_LINE(line); + +    line_parent->type = RLT_CODE; + +    line_parent->get_bin_len = (get_bin_len_fc)g_code_line_get_binary_len;  } @@ -143,8 +147,11 @@ void g_code_line_get_binary_len(GCodeLine *line, off_t *blen)  *                                                                             *  *  Paramètres  : line      = ligne de représentation à actualiser.            *  *                rendering = support effectif final des lignes de code.       * +*                buffer    = zone de texte à venir compléter.                 * +*                iter      = point d'insertion du nouveau texte.              * +*                lengths   = taille des différentes composantes de la ligne.  *  *                                                                             * -*  Description : Met à jour la ligne de représentation de code.               * +*  Description : Ajoute à un texte GTK le contenu de la ligne de code.        *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -152,68 +159,35 @@ void g_code_line_get_binary_len(GCodeLine *line, off_t *blen)  *                                                                             *  ******************************************************************************/ -void g_code_line_refresh_markup(GCodeLine *line, MainRendering rendering) +static void g_code_line_add_to_gtk_buffer(GCodeLine *line, MainRendering rendering, GtkTextBuffer *buffer, GtkTextIter *iter, gint lengths[SAR_COUNT])  {      bool show_address;                      /* Affichage de l'adresse ?    */      bool show_code;                         /* Affichage du code brut ?    */ -    size_t len;                             /* Taille du contenu           */ -    char *content;                          /* Contenu réellement imprimé  */ +    MemoryDataSize msize;                   /* Taille du bus d'adresses    */ +    char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */ +    size_t len;                             /* Taille de l'élément inséré  */ +    const bin_t *content;                   /* Contenu binaire global      */      off_t bin_offset;                       /* Début de l'instruction      */      off_t bin_len;                          /* Taille d'instruction        */ -    char buffer[CODE_BUFFER_LEN];           /* Zone tampon à utiliser #1   */ -    char *buffer2;                          /* Zone tampon à utiliser #2   */ -    const uint8_t *exe_content;             /* Contenu binaire global      */ -    const off_t *max_bin_len;               /* Taille de ligne max/globale */      char *bin_code;                         /* Tampon du code binaire      */ -    off_t k;                                /* Boucle de parcours #2       */ -    off_t j;                                /* Boucle de parcours #1       */ +    off_t i;                                /* Boucle de parcours          */      show_address = g_rendering_options_has_to_show_address(line->options, rendering);      show_code = g_rendering_options_has_to_show_code(line->options, rendering); -    len = strlen("<tt>") + 1; -    content = (char *)calloc(len, sizeof(char)); -    strcpy(content, "<tt>"); - -    if (show_code) -        g_arch_instruction_get_location(line->instr, &bin_offset, &bin_len, NULL); - -    /* Eventuelle adresse virtuelle */ +    /* Eventuelle adresse virtuelle ou physique */      if (show_address)      { -        switch (g_arch_processor_get_memory_size(g_rendering_options_get_processor(line->options))) -        { -            case MDS_8_BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%02llx</span>", -                         G_RENDERING_LINE(line)->offset); -                break; - -            case MDS_16_BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%04llx</span>", -                         G_RENDERING_LINE(line)->offset); -                break; - -            case MDS_32_BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%08llx</span>", -                         G_RENDERING_LINE(line)->offset); -                break; - -            default: -            case MDS_64_BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%16llx</span>", -                         G_RENDERING_LINE(line)->offset); -                break; +        msize = g_arch_processor_get_memory_size(g_rendering_options_get_processor(line->options)); -        } +        len = vmpa_to_string(G_RENDERING_LINE(line)->offset, msize, address); -        len += strlen(buffer); -        content = (char *)realloc(content, len * sizeof(char)); -        strcat(content, buffer); +        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                           address, len, RTT_NONE); + +        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                               "\t", 1, RTT_NONE);      } @@ -221,56 +195,34 @@ void g_code_line_refresh_markup(GCodeLine *line, MainRendering rendering)      if (show_code)      { -        exe_content = g_binary_format_get_content(G_BIN_FORMAT(g_rendering_options_get_format(line->options)), NULL); -        max_bin_len = &G_RENDERING_LINE(line)->max_bin_len[rendering]; - -        bin_code = (char *)calloc(*max_bin_len + 1, sizeof(char)); +        content = g_binary_format_get_content(G_BIN_FORMAT(g_rendering_options_get_format(line->options)), NULL); +        g_arch_instruction_get_location(line->instr, &bin_offset, &bin_len, NULL); -        k = 0; +        bin_code = (char *)calloc(bin_len * 3, sizeof(char)); -        for (j = 0; j < bin_len; j++) +        for (i = 0; i < bin_len; i++)          { -            if ((j + 1) < bin_len) -                k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); +            if ((i + 1) < bin_len) +                snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[bin_offset + i]);              else -                k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); +                snprintf(&bin_code[i * (2 + 1)], 3, "%02hhx", content[bin_offset + i]);          } -        for (; k < *max_bin_len; k++) -            snprintf(&bin_code[k], 2, " "); - -        if (show_address) len += strlen("\t"); -        len += strlen(bin_code); -        content = (char *)realloc(content, len * sizeof(char)); -        if (show_address) strcat(content, "\t"); -        strcat(content, bin_code); +        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                               bin_code, bin_len * 3 - 1, RTT_RAW_CODE);          free(bin_code); +        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                               "\t", 1, RTT_NONE); +      }      /* Instruction proprement dite */ -    buffer2 = g_arch_instruction_get_text(line->instr, g_rendering_options_get_format(line->options), ASX_INTEL/*FIXME*/); - -    if (show_address || show_code) len += strlen("\t"); -    len += strlen(buffer2); - -    content = (char *)realloc(content, len * sizeof(char)); -    if (show_address || show_code) strcat(content, "\t"); -    strcat(content, buffer2); - -    free(buffer2); - -    /* Finalisation */ - -    len += strlen("</tt>"); -    content = (char *)realloc(content, len * sizeof(char)); -    strcat(content, "</tt>"); - -    pango_layout_set_markup(G_RENDERING_LINE(line)->layout[rendering], content, len - 1); - -    free(content); +    g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(line->instr), +                                              g_rendering_options_get_format(line->options), +                                              ASX_INTEL/*FIXME*/, buffer, iter);  } diff --git a/src/analysis/line_comment.c b/src/analysis/line_comment.c index a39cb11..2a3030c 100644 --- a/src/analysis/line_comment.c +++ b/src/analysis/line_comment.c @@ -57,8 +57,8 @@ static void g_comment_line_class_init(GCommentLineClass *);  /* Initialise la classe des lignes de commentaires entière. */  static void g_comment_line_init(GCommentLine *); -/* Met à jour la ligne de représentation de commentaires. */ -void g_comment_line_refresh_markup(GCommentLine *, MainRendering); +/* Ajoute à un texte GTK le contenu de la ligne de commentaires. */ +static void g_comment_line_add_to_gtk_buffer(GCommentLine *, MainRendering, GtkTextBuffer *, GtkTextIter *, gint [SAR_COUNT]); @@ -99,13 +99,16 @@ static void g_comment_line_class_init(GCommentLineClass *klass)  static void g_comment_line_init(GCommentLine *line)  { -    GRenderingLine *parent;                 /* Instance parente            */ +    GContentExporter *exporter_parent;      /* Instance parente #1         */ +    GRenderingLine *line_parent;            /* Instance parente #2         */ -    parent = G_RENDERING_LINE(line); +    exporter_parent = G_CONTENT_EXPORTER(line); -    parent->type = RLT_PROTOTYPE/* TODO */; +    exporter_parent->add_to_gtk_buffer = (add_to_gtk_buffer_fc)g_comment_line_add_to_gtk_buffer; -    parent->refresh_markup = (refresh_markup_fc)g_comment_line_refresh_markup; +    line_parent = G_RENDERING_LINE(line); + +    line_parent->type = RLT_PROTOTYPE/* TODO */;  } @@ -114,8 +117,11 @@ static void g_comment_line_init(GCommentLine *line)  *                                                                             *  *  Paramètres  : line      = ligne de représentation à actualiser.            *  *                rendering = support effectif final des lignes de code.       * +*                buffer    = zone de texte à venir compléter.                 * +*                iter      = point d'insertion du nouveau texte.              * +*                lengths   = taille des différentes composantes de la ligne.  *  *                                                                             * -*  Description : Met à jour la ligne de représentation de commentaires.       * +*  Description : Ajoute à un texte GTK le contenu de la ligne de commentaires.*  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -123,116 +129,48 @@ static void g_comment_line_init(GCommentLine *line)  *                                                                             *  ******************************************************************************/ -void g_comment_line_refresh_markup(GCommentLine *line, MainRendering rendering) +static void g_comment_line_add_to_gtk_buffer(GCommentLine *line, MainRendering rendering, GtkTextBuffer *buffer, GtkTextIter *iter, gint lengths[SAR_COUNT])  {      bool show_address;                      /* Affichage de l'adresse ?    */      bool show_code;                         /* Affichage du code brut ?    */ -    size_t len;                             /* Taille du contenu           */ -    char *content;                          /* Contenu réellement imprimé  */ -    char buffer[CODE_BUFFER_LEN];           /* Zone tampon à utiliser      */ -    const off_t *max_bin_len;               /* Taille de ligne max/globale */ -    size_t clen;                            /* Taille du commentaire       */ +    MemoryDataSize msize;                   /* Taille du bus d'adresses    */ +    char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */ +    size_t len;                             /* Taille de l'élément inséré  */      show_address = g_rendering_options_has_to_show_address(line->options, rendering);      show_code = g_rendering_options_has_to_show_code(line->options, rendering); -    len = strlen("<tt>") + 1; -    content = (char *)calloc(len, sizeof(char)); -    strcpy(content, "<tt>"); - -    /* Eventuelle adresse virtuelle */ +    /* Eventuelle adresse virtuelle ou physique */      if (show_address)      { -        switch (g_arch_processor_get_memory_size(g_rendering_options_get_processor(line->options))) -        { -            case MDS_8_BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%02llx</span>", -                         G_RENDERING_LINE(line)->offset); -                break; - -            case MDS_16_BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%04llx</span>", -                         G_RENDERING_LINE(line)->offset); -                break; - -            case MDS_32_BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%08llx</span>", -                         G_RENDERING_LINE(line)->offset); -                break; - -            default: -            case MDS_64_BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%16llx</span>", -                         G_RENDERING_LINE(line)->offset); -                break; - -        } - -        len += strlen(buffer); -        content = (char *)realloc(content, len * sizeof(char)); -        strcat(content, buffer); - -    } - -    /* Eventuel code brut (sauté) */ - -    if (show_code) -    { -        max_bin_len = &G_RENDERING_LINE(line)->max_bin_len[rendering]; - -        clen = (show_address ? strlen("\t") : 0); -        clen += *max_bin_len; - -        content = (char *)realloc(content, (len + clen) * sizeof(char)); +        msize = g_arch_processor_get_memory_size(g_rendering_options_get_processor(line->options)); -        if (show_address) -        { -            strcat(content, "\t"); -            len += strlen("\t"); -        } +        len = vmpa_to_string(G_RENDERING_LINE(line)->offset, msize, address); -        memset(&content[len - 1], -               G_RENDERING_LINE(line)->type == RLT_PROTOTYPE ? '-' : ' ', *max_bin_len); -        len += *max_bin_len; +        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                           address, len, RTT_NONE); -        content[len - 1] = '\0'; +        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                               "\t", 1, RTT_NONE);      } -    /* Commentaire proprement dit */ - -    clen = (show_address || show_code ? strlen("\t") : 0); -    clen += strlen("<b><span foreground='#003300'>"); -    clen += strlen("; ") + strlen(line->comment); -    clen += strlen("</span></b>"); - -    content = (char *)realloc(content, (len + clen) * sizeof(char)); - -    if (show_address || show_code) -    { -        strcat(content, "\t"); -        len += strlen("\t"); -        clen -= strlen("\t"); -    } - -    snprintf(&content[len - 1], clen + 1, "<b><span foreground='#003300'>; %s</span></b>", line->comment); +    /* Eventuel code brut (sauté) */ -    len += clen; +    if (show_code) +        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                               "\t", 1, RTT_NONE); -    /* Finalisation */ +    /* Commentaire proprement dit */ -    len += strlen("</tt>"); -    content = (char *)realloc(content, len * sizeof(char)); -    strcat(content, "</tt>"); +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                           "; ", 2, RTT_COMMENT); -    pango_layout_set_markup(G_RENDERING_LINE(line)->layout[rendering], content, len - 1); +    len = strlen(line->comment); -    free(content); +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                           line->comment, len, RTT_COMMENT);  } diff --git a/src/analysis/line_prologue.c b/src/analysis/line_prologue.c index 4b83b68..13f0c1e 100644 --- a/src/analysis/line_prologue.c +++ b/src/analysis/line_prologue.c @@ -56,8 +56,8 @@ static void g_prologue_line_class_init(GPrologueLineClass *);  /* Initialise la classe des lignes de descriptions initiales. */  static void g_prologue_line_init(GPrologueLine *); -/* Met à jour la ligne de représentation de prologue. */ -void g_prologue_line_refresh_markup(GPrologueLine *, MainRendering); +/* Ajoute à un texte GTK le contenu de la ligne d'ouverture. */ +static void g_prologue_line_add_to_gtk_buffer(GPrologueLine *, MainRendering, GtkTextBuffer *, GtkTextIter *, gint [SAR_COUNT]); @@ -98,15 +98,16 @@ static void g_prologue_line_class_init(GPrologueLineClass *klass)  static void g_prologue_line_init(GPrologueLine *line)  { -    GRenderingLine *parent;                 /* Instance parente            */ +    GContentExporter *exporter_parent;      /* Instance parente #1         */ +    GRenderingLine *line_parent;            /* Instance parente #2         */ -    parent = G_RENDERING_LINE(line); +    exporter_parent = G_CONTENT_EXPORTER(line); -    parent->offset = 0; +    exporter_parent->add_to_gtk_buffer = (add_to_gtk_buffer_fc)g_prologue_line_add_to_gtk_buffer; -    parent->type = RLT_PROLOGUE; +    line_parent = G_RENDERING_LINE(line); -    parent->refresh_markup = (refresh_markup_fc)g_prologue_line_refresh_markup; +    line_parent->type = RLT_PROLOGUE;  } @@ -115,8 +116,11 @@ static void g_prologue_line_init(GPrologueLine *line)  *                                                                             *  *  Paramètres  : line      = ligne de représentation à actualiser.            *  *                rendering = support effectif final des lignes de code.       * +*                buffer    = zone de texte à venir compléter.                 * +*                iter      = point d'insertion du nouveau texte.              * +*                lengths   = taille des différentes composantes de la ligne.  *  *                                                                             * -*  Description : Met à jour la ligne de représentation de prologue.           * +*  Description : Ajoute à un texte GTK le contenu de la ligne d'ouverture.    *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -124,22 +128,17 @@ static void g_prologue_line_init(GPrologueLine *line)  *                                                                             *  ******************************************************************************/ -void g_prologue_line_refresh_markup(GPrologueLine *line, MainRendering rendering) +static void g_prologue_line_add_to_gtk_buffer(GPrologueLine *line, MainRendering rendering, GtkTextBuffer *buffer, GtkTextIter *iter, gint lengths[SAR_COUNT])  { -    size_t len;                             /* Taille du contenu           */ -    char *content;                          /* Contenu réellement imprimé  */ +    size_t len;                             /* Taille de l'élément inséré  */ -    len = strlen("<b><span foreground='#003300'>"); -    len += strlen("; ") + strlen(line->comment); -    len += strlen("</span></b>"); +    len = strlen(line->comment); -    content = (char *)calloc(len + 1, sizeof(char)); +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                           "; ", 2, RTT_COMMENT); -    snprintf(content, len + 1, "<b><span foreground='#003300'>; %s</span></b>", line->comment); - -    pango_layout_set_markup(G_RENDERING_LINE(line)->layout[rendering], content, len); - -    free(content); +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter, +                                           line->comment, len, RTT_COMMENT);  } diff --git a/src/analysis/roptions.h b/src/analysis/roptions.h index 85dc5fb..b2e4973 100644 --- a/src/analysis/roptions.h +++ b/src/analysis/roptions.h @@ -45,6 +45,18 @@ typedef enum _MainRendering  } MainRendering; +/* Zone de rendu */ +typedef enum _ShowingArea +{ +    SAR_ADDRESS,                            /* Adresse d'une ligne         */ +    SAR_CODE,                               /* Code brut d'une ligne       */ +    SAR_INSTRUCTION,                        /* Instruction d'une ligne     */ + +    SAR_COUNT + +} ShowingArea; + +  #define G_TYPE_RENDERING_OPTIONS               g_rendering_options_get_type()  #define G_RENDERING_OPTIONS(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_rendering_options_get_type(), GRenderingOptions))  #define G_IS_RENDERING_OPTIONS(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_rendering_options_get_type())) diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index 6a1d45b..2aa57b7 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -2,7 +2,7 @@  noinst_LTLIBRARIES = libarch.la  libarch_la_SOURCES =					\ -	archbase.h							\ +	archbase.h archbase.c				\  	artificial.h artificial.c			\  	immediate.h immediate.c				\  	instruction-int.h					\ diff --git a/src/arch/archbase.c b/src/arch/archbase.c new file mode 100644 index 0000000..61e2396 --- /dev/null +++ b/src/arch/archbase.c @@ -0,0 +1,79 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * archbase.c - définitions de base pour les architectures + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "archbase.h" + + +#include <stdio.h> + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : addr   = adresse virtuelle ou physique à traiter.            * +*                msize  = taille de cette adresse.                            * +*                buffer = chaîne de caractères à constituer. [OUT]            * +*                                                                             * +*  Description : Transforme une adresse en chaîne de caractères.              * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +size_t vmpa_to_string(vmpa_t addr, MemoryDataSize msize, char buffer[VMPA_MAX_SIZE]) +{ +    size_t result;                          /* Taille en place à renvoyer  */ + +    switch (msize) +    { +        case MDS_8_BITS: +            snprintf(buffer, VMPA_MAX_SIZE,"0x%02llx", addr); +            result = 4; +            break; + +        case MDS_16_BITS: +            snprintf(buffer, VMPA_MAX_SIZE, "0x%04llx", addr); +            result = 6; +            break; + +        case MDS_32_BITS: +            snprintf(buffer, VMPA_MAX_SIZE, "0x%08llx", addr); +            result = 10; +            break; + +        case MDS_64_BITS: +            snprintf(buffer, VMPA_MAX_SIZE, "0x%016llx", addr); +            result = 18; +            break; + +        default: +            result = 0; +            break; + +    } + +    return result; + +} diff --git a/src/arch/archbase.h b/src/arch/archbase.h index 2a0c80e..330e194 100644 --- a/src/arch/archbase.h +++ b/src/arch/archbase.h @@ -26,6 +26,7 @@  #include <stdint.h> +#include <sys/types.h> @@ -36,6 +37,9 @@ typedef uint8_t bin_t;  typedef uint64_t vmpa_t; +#define VMPA_MAX_SIZE 19 + +  /* Taille des données intégrées */  typedef enum _MemoryDataSize  { @@ -72,4 +76,8 @@ typedef enum _AsmSyntax +/* Transforme une adresse en chaîne de caractères. */ +size_t vmpa_to_string(vmpa_t, MemoryDataSize, char [VMPA_MAX_SIZE]); + +  #endif  /* _ARCH_ARCHBASE_H */ diff --git a/src/arch/immediate.c b/src/arch/immediate.c index f8bba35..54d8135 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -27,6 +27,7 @@  #include <malloc.h>  #include <stdarg.h>  #include <stdio.h> +#include <string.h>  #include "operand-int.h" @@ -83,8 +84,8 @@ static void g_imm_operand_class_init(GImmOperandClass *);  /* Initialise la classe des lignes de descriptions initiales. */  static void g_imm_operand_init(GImmOperand *); -/* Traduit un opérande en version humainement lisible. */ -static char *g_imm_operand_get_text(const GImmOperand *, const GExeFormat *, AsmSyntax); +/* Ajoute à un texte GTK le contenu d'un opérande. */ +static void g_imm_operand_add_to_gtk_buffer(const GImmOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *);  /* Indique le type défini pour un opérande de valeur numérique. */ @@ -124,11 +125,11 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)  static void g_imm_operand_init(GImmOperand *operand)  { -    GArchOperand *parent;                   /* Instance parente            */ +    GContentExporter *parent;               /* Instance parente            */ -    parent = G_ARCH_OPERAND(operand); +    parent = G_CONTENT_EXPORTER(operand); -    parent->get_text = (get_operand_text_fc)g_imm_operand_get_text; +    parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_imm_operand_add_to_gtk_buffer;  } @@ -174,21 +175,35 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data                  goto gionfd_error;              break; +        case AOS_64_BITS_UNSIGNED: +            if (!read_u64(&result->unsigned_imm.val64, data, pos, len, endian)) +                goto gionfd_error; +            break; +          case AOS_8_BITS_SIGNED: -            if (!read_u8(&result->signed_imm.val8, data, pos, len, endian)) +            if (!read_s8(&result->signed_imm.val8, data, pos, len, endian))                  goto gionfd_error;              break;          case AOS_16_BITS_SIGNED: -            if (!read_u16(&result->signed_imm.val16, data, pos, len, endian)) +            if (!read_s16(&result->signed_imm.val16, data, pos, len, endian))                  goto gionfd_error;              break;          case AOS_32_BITS_SIGNED: -            if (!read_u32(&result->signed_imm.val32, data, pos, len, endian)) +            if (!read_s32(&result->signed_imm.val32, data, pos, len, endian))                  goto gionfd_error;              break; +        case AOS_64_BITS_SIGNED: +            if (!read_s64(&result->signed_imm.val64, data, pos, len, endian)) +                goto gionfd_error; +            break; + +        case MDS_UNDEFINED: +            goto gionfd_error; +            break; +      }      return G_ARCH_OPERAND(result); @@ -326,74 +341,73 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                format  = format du binaire manipulé.                        * -*                syntax  = type de représentation demandée.                   * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format = format du binaire manipulé.                         * +*                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 *  *                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * +*  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * -*  Retour      : Chaîne de caractères à libérer de la mémoire.                * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static char *g_imm_operand_get_text(const GImmOperand *operand, const GExeFormat *format, AsmSyntax syntax) +static void g_imm_operand_add_to_gtk_buffer(const GImmOperand *operand, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter)  { -    char *result;                           /* Chaîne à retourner          */ +    char value[VMPA_MAX_SIZE];              /* Chaîne à imprimer           */      vmpa_t address;                         /* Décallage final constaté    */      const char *label;                      /* Etiquette de symbole        */      SymbolType symtype;                     /* Type de symbole             */      char *printable;                        /* Version texte présentable   */ -    char buffer[256];                       /* Complément d'information    */      /* Valeur brute */ -    result = (char *)calloc(19, sizeof(char)); -      switch (syntax)      {          case ASX_INTEL:              switch (operand->size)              {                  case MDS_UNDEFINED: -                    snprintf(result, 19, "$0x???"); +                    snprintf(value, VMPA_MAX_SIZE, "0x???");                      break;                  case AOS_8_BITS_UNSIGNED: -                    snprintf(result, 19, "0x%hhx", operand->unsigned_imm.val8); +                    snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8);                      break;                  case AOS_16_BITS_UNSIGNED: -                    snprintf(result, 19, "0x%hx", operand->unsigned_imm.val16); +                    snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16);                      break;                  case AOS_32_BITS_UNSIGNED: -                    snprintf(result, 19, "0x%x", operand->unsigned_imm.val32); +                    snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32);                      break;                  case AOS_64_BITS_UNSIGNED: -                    snprintf(result, 19, "0x%llx", operand->unsigned_imm.val64); +                    snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->unsigned_imm.val64);                      break;                  case AOS_8_BITS_SIGNED:                      if (g_imm_operand_is_negative(operand)) -                        snprintf(result, 19, "0x%hhx", ~operand->signed_imm.val8 + 1); +                        snprintf(value, VMPA_MAX_SIZE, "0x%hhx", ~operand->signed_imm.val8 + 1);                      else -                        snprintf(result, 19, "0x%hhx", operand->signed_imm.val8); +                        snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->signed_imm.val8);                      break;                  case AOS_16_BITS_SIGNED:                      if (g_imm_operand_is_negative(operand)) -                        snprintf(result, 19, "0x%hx", ~operand->signed_imm.val16 + 1); +                        snprintf(value, VMPA_MAX_SIZE, "0x%hx", ~operand->signed_imm.val16 + 1);                      else -                        snprintf(result, 19, "0x%hx", operand->signed_imm.val16); +                        snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->signed_imm.val16);                      break;                  case AOS_32_BITS_SIGNED:                      if (g_imm_operand_is_negative(operand)) -                        snprintf(result, 19, "0x%x", ~operand->signed_imm.val32 + 1); +                        snprintf(value, VMPA_MAX_SIZE, "0x%x", ~operand->signed_imm.val32 + 1);                      else -                        snprintf(result, 19, "0x%x", operand->signed_imm.val32); +                        snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->signed_imm.val32);                      break;                  case AOS_64_BITS_SIGNED:                      if (g_imm_operand_is_negative(operand)) -                        snprintf(result, 19, "0x%llx", ~operand->signed_imm.val64 + 1); +                        snprintf(value, VMPA_MAX_SIZE, "0x%llx", ~operand->signed_imm.val64 + 1);                      else -                        snprintf(result, 19, "0x%llx", operand->signed_imm.val64); +                        snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->signed_imm.val64);                      break;              }              break; @@ -402,63 +416,100 @@ static char *g_imm_operand_get_text(const GImmOperand *operand, const GExeFormat              switch (operand->size)              {                  case MDS_UNDEFINED: -                    snprintf(result, 19, "$0x???"); +                    snprintf(value, VMPA_MAX_SIZE, "$0x???");                      break;                  case AOS_8_BITS_UNSIGNED: -                    snprintf(result, 19, "$0x%hhx", operand->unsigned_imm.val8); +                    snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8);                      break;                  case AOS_16_BITS_UNSIGNED: -                    snprintf(result, 19, "$0x%hx", operand->unsigned_imm.val16); +                    snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16);                      break;                  case AOS_32_BITS_UNSIGNED: -                    snprintf(result, 19, "$0x%x", operand->unsigned_imm.val32); +                    snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32);                      break;                  case AOS_64_BITS_UNSIGNED: -                    snprintf(result, 19, "$0x%llx", operand->unsigned_imm.val64); +                    snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->unsigned_imm.val64);                      break;                  case AOS_8_BITS_SIGNED: -                    snprintf(result, 19, "$0x%hhx", ~operand->signed_imm.val8 + 1); +                    snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1);                      break;                  case AOS_16_BITS_SIGNED: -                    snprintf(result, 19, "$0x%hx", ~operand->signed_imm.val16 + 1); +                    snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1);                      break;                  case AOS_32_BITS_SIGNED: -                    snprintf(result, 19, "$0x%x", ~operand->signed_imm.val32 + 1); +                    snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1);                      break;                  case AOS_64_BITS_SIGNED: -                    snprintf(result, 19, "$0x%llx", ~operand->signed_imm.val64 + 1); +                    snprintf(value, VMPA_MAX_SIZE, "$0x%llx", ~operand->signed_imm.val64 + 1);                      break;              }              break; +        default: +            break; +      } +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                           value, strlen(value), RTT_IMMEDIATE); +      /* Complément d'information */ -    if (operand->size == AOS_32_BITS_SIGNED || operand->size == AOS_32_BITS_UNSIGNED)   /* FIXME */ +    if (operand->size == g_arch_processor_get_memory_size(get_arch_processor_from_format(format)))      { -        address = operand->unsigned_imm.val32; /* FIXME !!! */ - -        if (g_binary_format_resolve_symbol(G_BIN_FORMAT(format), &label, &symtype, &address)) +        if (g_imm_operand_to_vmpa_t(operand, &address))          { -            switch (symtype) +            if (g_binary_format_resolve_symbol(G_BIN_FORMAT(format), &label, &symtype, &address))              { -                case STP_OBJECT: -                case STP_FUNCTION: -                    if (address == 0) snprintf(buffer, 256, " <%s>", label); -                    else snprintf(buffer, 256, " <%s+0x%llx>", label, address); -                    result = stradd(result, buffer); -                    break; +                switch (symtype) +                { +                    case STP_OBJECT: +                    case STP_FUNCTION: +                        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                               " ", 1, RTT_NONE); +                        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                               "<", 1, RTT_LTGT); -                case STP_STRING: -                    printable = strdup(label); -                    printable = escape_crlf(printable); -                    printable = strrpl(printable, "<", "<"); -                    printable = strrpl(printable, ">", ">"); -                    snprintf(buffer, 256, " \"%s\"", printable); -                    result = stradd(result, buffer); -                    free(printable); -                    break; +                        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                               label, strlen(label), RTT_LTGT); + +                        if (address > 0) +                        { +                            g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                                   "+", 1, RTT_LTGT); + +                            snprintf(value, VMPA_MAX_SIZE, "0x%llx", address); + +                            g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                                   value, strlen(value), RTT_LTGT); + +                        } + +                        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                               ">", 1, RTT_LTGT); + +                        break; + +                    case STP_STRING: +                        printable = strdup(label); +                        printable = escape_crlf(printable); +                        /*printable = strrpl(printable, "<", "<"); +                        printable = strrpl(printable, ">", ">");*/ + +                        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                               " ", 1, RTT_NONE); +                        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                               "\"", 1, RTT_STRING); +                        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                               printable, strlen(printable), RTT_STRING); +                        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                               "\"", 1, RTT_STRING); + +                        free(printable); + +                        break; + +                }              } @@ -466,8 +517,6 @@ static char *g_imm_operand_get_text(const GImmOperand *operand, const GExeFormat      } -    return result; -  } diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index ab37d62..4ecb173 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -27,6 +27,7 @@  #include "archbase.h"  #include "instruction.h" +#include "../analysis/exporter-int.h" @@ -43,7 +44,7 @@ typedef bool (* is_instruction_return_fc) (const GArchInstruction *);  /* Définition générique d'une instruction d'architecture (instance) */  struct _GArchInstruction  { -    GObject parent;                         /* A laisser en premier        */ +    GContentExporter parent;                /* A laisser en premier        */      off_t offset;                           /* Position physique de départ */      off_t length;                           /* Taille de l'instruction     */ @@ -63,7 +64,7 @@ struct _GArchInstruction  /* Définition générique d'une instruction d'architecture (classe) */  struct _GArchInstructionClass  { -    GObjectClass parent;                    /* A laisser en premier        */ +    GContentExporterClass parent;           /* A laisser en premier        */  }; diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 338f496..8bc317b 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -38,10 +38,13 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);  /* Initialise une instance d'opérande d'architecture. */  static void g_arch_instruction_init(GArchInstruction *); +/* Ajoute à un texte GTK le contenu d'une instruction. */ +static void g_arch_instruction_add_to_gtk_buffer(const GArchInstruction *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); +  /* Indique le type défini pour une instruction d'architecture. */ -G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT); +G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_CONTENT_EXPORTER);  /****************************************************************************** @@ -76,6 +79,65 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)  static void g_arch_instruction_init(GArchInstruction *instr)  { +    GContentExporter *parent;               /* Instance parente            */ + +    parent = G_CONTENT_EXPORTER(instr); + +    parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_arch_instruction_add_to_gtk_buffer; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = instruction à transcrire.                          * +*                format = format du binaire manipulé.                         * +*                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 * +*                                                                             * +*  Description : Ajoute à un texte GTK le contenu d'une instruction.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_instruction_add_to_gtk_buffer(const GArchInstruction *instr, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter) +{ +    const char *key;                        /* Mot clef principal          */ +    size_t klen;                            /* Taille de ce mot clef       */ +    size_t i;                               /* Boucle de parcours          */ + +    key = instr->get_text(instr, format, syntax); +    klen = strlen(key); + +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(instr), buffer, iter, +                                           key, klen, RTT_INSTRUCTION); + +    if (instr->operands_count > 0) +    { +        g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(instr), buffer, iter, +                                               "\t", 1, RTT_NONE); + +        g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(G_ARCH_INSTRUCTION(instr)->operands[0]), +                                                  format, syntax, buffer, iter); + +        for (i = 1; i < instr->operands_count; i++) +        { +            g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(instr), buffer, iter, +                                                   ",", 1, RTT_NONE/* FIXME */); + +            g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(instr), buffer, iter, +                                                   " ", 1, RTT_NONE); + +            g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(G_ARCH_INSTRUCTION(instr)->operands[i]), +                                                      format, syntax, buffer, iter); + +        } + +    }  } @@ -322,7 +384,7 @@ char *g_arch_instruction_get_text(const GArchInstruction *instr, const GExeForma      char *result;                           /* Chaîne à retourner          */      size_t i;                               /* Boucle de parcours          */      char *opstr;                            /* Chaîne d'opérande           */ - +    return strdup("");      if (instr->operands_count == 0)          result = strdup(instr->get_text(instr, format, syntax)); diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h index 90e3e06..258a60e 100644 --- a/src/arch/operand-int.h +++ b/src/arch/operand-int.h @@ -26,6 +26,7 @@  #include "operand.h" +#include "../analysis/exporter-int.h" @@ -36,7 +37,7 @@ typedef char * (* get_operand_text_fc) (const GArchOperand *, const GExeFormat *  /* Définition générique d'un opérande d'architecture (instance) */  struct _GArchOperand  { -    GObject parent;                         /* A laisser en premier        */ +    GContentExporter parent;                /* A laisser en premier        */      get_operand_text_fc get_text;           /* Texte humain équivalent     */ @@ -46,7 +47,7 @@ struct _GArchOperand  /* Définition générique d'un opérande d'architecture (classe) */  struct _GArchOperandClass  { -    GObjectClass parent;                    /* A laisser en premier        */ +    GContentExporterClass parent;           /* A laisser en premier        */  }; diff --git a/src/arch/operand.c b/src/arch/operand.c index 724f3c0..d4f6b56 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -37,7 +37,7 @@ static void g_arch_operand_init(GArchOperand *);  /* Indique le type défini pour un opérande d'architecture. */ -G_DEFINE_TYPE(GArchOperand, g_arch_operand, G_TYPE_OBJECT); +G_DEFINE_TYPE(GArchOperand, g_arch_operand, G_TYPE_CONTENT_EXPORTER); diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index 69c08dc..31c993f 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -70,7 +70,7 @@ struct _GX86RegisterOperand  {      GX86Operand parent;                     /* Instance parente            */ -    x86_register *reg;                      /* Registre représenté         */ +    GX86Register *reg;                      /* Registre représenté         */  }; @@ -89,8 +89,8 @@ static void g_x86_register_operand_class_init(GX86RegisterOperandClass *);  /* Initialise une instance d'opérande de registre x86. */  static void g_x86_register_operand_init(GX86RegisterOperand *); -/* Traduit un opérande en version humainement lisible. */ -static char *g_x86_register_operand_get_text(const GX86RegisterOperand *, const GExeFormat *, AsmSyntax); +/* Ajoute à un texte GTK le contenu d'un opérande. */ +static void g_x86_register_operand_add_to_gtk_buffer(const GX86RegisterOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -103,8 +103,8 @@ struct _GX86ModRMOperand      GX86Operand parent;                     /* Instance parente            */      uint8_t scale;                          /* Puissance de deux           */ -    x86_register *index;                    /* Registre servant d'indice   */ -    x86_register *base;                     /* Registre de base            */ +    GX86Register *index;                    /* Registre servant d'indice   */ +    GX86Register *base;                     /* Registre de base            */      GImmOperand *displacement;              /* Décallage supplémentaire    */  }; @@ -124,8 +124,8 @@ static void g_x86_mod_rm_operand_class_init(GX86ModRMOperandClass *);  /* Initialise une instance d'opérande x86 de type ModRM. */  static void g_x86_mod_rm_operand_init(GX86ModRMOperand *); -/* Traduit un opérande en version humainement lisible. */ -static char *g_x86_mod_rm_operand_get_text(const GX86ModRMOperand *, const GExeFormat *, AsmSyntax); +/* Ajoute à un texte GTK le contenu d'un opérande. */ +static void g_x86_mod_rm_operand_add_to_gtk_buffer(const GX86ModRMOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -155,8 +155,8 @@ static void g_x86_relative_operand_class_init(GX86RelativeOperandClass *);  /* Initialise une instance d'opérande x86 d'adresse relative. */  static void g_x86_relative_operand_init(GX86RelativeOperand *); -/* Traduit un opérande en version humainement lisible. */ -static char *g_x86_relative_operand_get_text(const GX86RelativeOperand *, const GExeFormat *, AsmSyntax); +/* Ajoute à un texte GTK le contenu d'un opérande. */ +static void g_x86_relative_operand_add_to_gtk_buffer(const GX86RelativeOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -186,8 +186,8 @@ static void g_x86_moffs_operand_class_init(GX86MOffsOperandClass *);  /* Initialise une instance d'opérande d'emplacement mémoire x86. */  static void g_x86_moffs_operand_init(GX86MOffsOperand *); -/* Traduit un opérande en version humainement lisible. */ -static char *g_x86_moffs_operand_get_text(const GX86MOffsOperand *, const GExeFormat *, AsmSyntax); +/* Ajoute à un texte GTK le contenu d'un opérande. */ +static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -278,11 +278,11 @@ static void g_x86_register_operand_class_init(GX86RegisterOperandClass *klass)  static void g_x86_register_operand_init(GX86RegisterOperand *operand)  { -    GArchOperand *parent;                   /* Instance parente            */ +    GContentExporter *parent;               /* Instance parente            */ -    parent = G_ARCH_OPERAND(operand); +    parent = G_CONTENT_EXPORTER(operand); -    parent->get_text = (get_operand_text_fc)g_x86_register_operand_get_text; +    parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_register_operand_add_to_gtk_buffer;  } @@ -306,9 +306,9 @@ static void g_x86_register_operand_init(GX86RegisterOperand *operand)  GArchOperand *g_x86_register_operand_new_from_opcode(const bin_t *data, off_t *pos, off_t len, AsmOperandSize size, bin_t base)  {      GX86RegisterOperand *result;            /* Structure à retourner       */ -    x86_register *reg;                      /* Registre lu                 */ +    GX86Register *reg;                      /* Registre lu                 */ -    reg = get_x86_register(size, data[*pos] - base); +    reg = g_x86_register_new(size, data[*pos] - base);      if (reg != NULL)      { @@ -346,12 +346,12 @@ GArchOperand *g_x86_register_operand_new_from_mod_rm(const bin_t *data, off_t *p  {      GX86RegisterOperand *result;            /* Structure à retourner       */      bin_t index;                            /* Registre lu                 */ -    x86_register *reg;                      /* Registre créé               */ +    GX86Register *reg;                      /* Registre créé               */      if (first) index = data[*pos] & 0x07;      else index = (data[*pos] & 0x38) >> 3; -    reg = get_x86_register(size, index); +    reg = g_x86_register_new(size, index);      if (reg != NULL)      { @@ -385,9 +385,9 @@ GArchOperand *g_x86_register_operand_new_from_mod_rm(const bin_t *data, off_t *p  GArchOperand *g_x86_register_operand_new_from_index(bin_t index, AsmOperandSize size)  {      GX86RegisterOperand *result;            /* Structure à retourner       */ -    x86_register *reg;                      /* Registre lu                 */ +    GX86Register *reg;                      /* Registre lu                 */ -    reg = get_x86_register(size, index); +    reg = g_x86_register_new(size, index);      if (reg != NULL)      { @@ -405,25 +405,23 @@ GArchOperand *g_x86_register_operand_new_from_index(bin_t index, AsmOperandSize  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                format  = format du binaire manipulé.                        * -*                syntax  = type de représentation demandée.                   * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format = format du binaire manipulé.                         * +*                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 *  *                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * +*  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * -*  Retour      : Chaîne de caractères à libérer de la mémoire.                * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static char *g_x86_register_operand_get_text(const GX86RegisterOperand *operand, const GExeFormat *format, AsmSyntax syntax) +static void g_x86_register_operand_add_to_gtk_buffer(const GX86RegisterOperand *operand, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter)  { -    char *result;                           /* Chaîne à retourner          */ - -    result = x86_register_as_text(operand->reg, syntax); - -    return result; +    g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(operand->reg), format, syntax, buffer, iter);  } @@ -470,11 +468,11 @@ static void g_x86_mod_rm_operand_class_init(GX86ModRMOperandClass *klass)  static void g_x86_mod_rm_operand_init(GX86ModRMOperand *operand)  { -    GArchOperand *parent;                   /* Instance parente            */ +    GContentExporter *parent;               /* Instance parente            */ -    parent = G_ARCH_OPERAND(operand); +    parent = G_CONTENT_EXPORTER(operand); -    parent->get_text = (get_operand_text_fc)g_x86_mod_rm_operand_get_text; +    parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_mod_rm_operand_add_to_gtk_buffer;  } @@ -498,43 +496,43 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,  {      GX86ModRMOperand *result;               /* Structure à retourner       */      uint8_t mod;                            /* Modificateur présent        */ -    x86_register *reg;                      /* Registre lu                 */ +    GX86Register *reg;                      /* Registre lu                 */      mod = (data[*pos] & 0xc0);      if (mod == 0xc0)          return g_x86_register_operand_new_from_mod_rm(data, pos, len, size, true); -    reg = get_x86_register(size, data[*pos] & 0x07); +    reg = g_x86_register_new(size, data[*pos] & 0x07);      if (reg == NULL) return NULL;      (*pos)++;      /* Vieille astuce de l'emplacement mémoire fixe ? */ -    if (is_x86_register_base_pointer(reg) && mod == 0x00) +    if (g_x86_register_is_base_pointer(reg) && mod == 0x00)      { -        free_x86_register(reg); +        /* FIXME *///free_x86_register(reg);          return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE);      }      result = g_object_new(G_TYPE_X86_MOD_RM_OPERAND, NULL);      /* A la recherche d'un SIB */ -    if (is_x86_register_stack_pointer(reg)) +    if (g_x86_register_is_stack_pointer(reg))      { -        free_x86_register(reg); +        /* FIXME *///free_x86_register(reg); -        result->base = get_x86_register(size, data[*pos] & 0x07); +        result->base = g_x86_register_new(size, data[*pos] & 0x07);          if (result->base == NULL) goto gxmron_error; -        result->index = get_x86_register(size, (data[*pos] & 0x38) >> 3); +        result->index = g_x86_register_new(size, (data[*pos] & 0x38) >> 3);          if (result->index == NULL) goto gxmron_error;          result->scale = ((data[*pos] & 0xc0) >> 6); -        if (is_x86_register_stack_pointer(result->index)) +        if (g_x86_register_is_stack_pointer(result->index))          { -            free_x86_register(result->index); +            /* FIXME *///free_x86_register(result->index);              result->index = result->base;              result->base = NULL;          } @@ -549,9 +547,9 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,      switch (mod)      {          case 0x00: -            if (result->base != NULL && is_x86_register_base_pointer(result->base)) +            if (result->base != NULL && g_x86_register_is_base_pointer(result->base))              { -                free_x86_register(result->base); +                /* FIXME *///free_x86_register(result->base);                  result->base = NULL;                  result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE); @@ -584,72 +582,79 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                format  = format du binaire manipulé.                        * -*                syntax  = type de représentation demandée.                   * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format = format du binaire manipulé.                         * +*                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 *  *                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * +*  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * -*  Retour      : Chaîne de caractères à libérer de la mémoire.                * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static char *g_x86_mod_rm_operand_get_text(const GX86ModRMOperand *operand, const GExeFormat *format, AsmSyntax syntax) +static void g_x86_mod_rm_operand_add_to_gtk_buffer(const GX86ModRMOperand *operand, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter)  { -    char *result;                           /* Chaîne à retourner          */ -    char *tmp;                              /* Chaîne de registre          */ +    char tmp[2];                            /* Echelle en puissance de 2   */      switch (syntax)      {          case ASX_INTEL: -            result = (char *)calloc(1 + 10 + 2, sizeof(char)); - -            strcpy(result, "["); +            g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                   "[", 1, RTT_HOOK);              if (operand->scale > 0) -                snprintf(&result[1], 12, "%d*", (int)pow(2, operand->scale));  - -            tmp = x86_register_as_text(operand->index, syntax); -            result = stradd(result, tmp); -            free(tmp); - -            if (operand->base != NULL)              { -                result = stradd(result, "+"); +                snprintf(tmp, 2, "%d", (int)pow(2, operand->scale));  + +                g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                       tmp, 1, RTT_IMMEDIATE); -                tmp = x86_register_as_text(operand->base, syntax); -                result = stradd(result, tmp); -                free(tmp); +                g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                       "*", 1, RTT_SIGNS);              } +            g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(operand->index), +                                                      format, syntax, buffer, iter); + +            if (operand->base != NULL) +                g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(operand->base), +                                                          format, syntax, buffer, iter); +              if (operand->displacement != NULL)              { -                if (g_imm_operand_is_negative(operand->displacement)) result = stradd(result, "-"); -                else result = stradd(result, "+"); +                if (g_imm_operand_is_negative(operand->displacement)) +                    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                           "-", 1, RTT_SIGNS); +                else +                    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                           "+", 1, RTT_SIGNS); -                tmp = g_arch_operand_get_text(G_ARCH_OPERAND(operand->displacement), format, syntax); -                result = stradd(result, tmp); -                free(tmp); +                g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(operand->displacement), +                                                          format, syntax, buffer, iter);              } -            result = stradd(result, "]"); +            g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                   "]", 1, RTT_HOOK);              break;          case ASX_ATT: -            result = strdup("[modRM]"); +            /* TODO */ +            g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                                   "[ModRM]", 7, RTT_HOOK); +              break;      } -    return result; -  } @@ -667,7 +672,7 @@ static char *g_x86_mod_rm_operand_get_text(const GX86ModRMOperand *operand, cons  *                                                                             *  ******************************************************************************/ -void g_x86_mod_rm_operand_get_scale_and_index(const GX86ModRMOperand *operand, uint8_t *scale, const x86_register **index) +void g_x86_mod_rm_operand_get_scale_and_index(const GX86ModRMOperand *operand, uint8_t *scale, const GX86Register **index)  {      *scale = operand->scale;      *index = operand->index; @@ -687,7 +692,7 @@ void g_x86_mod_rm_operand_get_scale_and_index(const GX86ModRMOperand *operand, u  *                                                                             *  ******************************************************************************/ -const x86_register *g_x86_mod_rm_operand_get_base(const GX86ModRMOperand *operand) +const GX86Register *g_x86_mod_rm_operand_get_base(const GX86ModRMOperand *operand)  {      return operand->base; @@ -755,11 +760,11 @@ static void g_x86_relative_operand_class_init(GX86RelativeOperandClass *klass)  static void g_x86_relative_operand_init(GX86RelativeOperand *operand)  { -    GArchOperand *parent;                   /* Instance parente            */ +    GContentExporter *parent;               /* Instance parente            */ -    parent = G_ARCH_OPERAND(operand); +    parent = G_CONTENT_EXPORTER(operand); -    parent->get_text = (get_operand_text_fc)g_x86_relative_operand_get_text; +    parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_relative_operand_add_to_gtk_buffer;  } @@ -822,25 +827,24 @@ GArchOperand *g_x86_relative_operand_new(const bin_t *data, off_t *pos, off_t le  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                format  = format du binaire manipulé.                        * -*                syntax  = type de représentation demandée.                   * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format = format du binaire manipulé.                         * +*                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 *  *                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * +*  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * -*  Retour      : Chaîne de caractères à libérer de la mémoire.                * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static char *g_x86_relative_operand_get_text(const GX86RelativeOperand *operand, const GExeFormat *format, AsmSyntax syntax) +static void g_x86_relative_operand_add_to_gtk_buffer(const GX86RelativeOperand *operand, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter)  { -    char *result;                           /* Chaîne à retourner          */ - -    result = g_arch_operand_get_text(operand->immediate, format, syntax); - -    return result; +    g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(operand->immediate), +                                              format, syntax, buffer, iter);  } @@ -906,11 +910,11 @@ static void g_x86_moffs_operand_class_init(GX86MOffsOperandClass *klass)  static void g_x86_moffs_operand_init(GX86MOffsOperand *operand)  { -    GArchOperand *parent;                   /* Instance parente            */ +    GContentExporter *parent;               /* Instance parente            */ -    parent = G_ARCH_OPERAND(operand); +    parent = G_CONTENT_EXPORTER(operand); -    parent->get_text = (get_operand_text_fc)g_x86_moffs_operand_get_text; +    parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_moffs_operand_add_to_gtk_buffer;  } @@ -952,27 +956,27 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len,  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                format  = format du binaire manipulé.                        * -*                syntax  = type de représentation demandée.                   * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format = format du binaire manipulé.                         * +*                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 *  *                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * +*  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * -*  Retour      : Chaîne de caractères à libérer de la mémoire.                * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static char *g_x86_moffs_operand_get_text(const GX86MOffsOperand *operand, const GExeFormat *format, AsmSyntax syntax) +static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *operand, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter)  { -    char *result;                           /* Chaîne à retourner          */ - -    result = g_arch_operand_get_text(operand->offset, format, syntax); - -    result = strprep(result, "ds:"); +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                           "ds:", 3, RTT_SEGMENT); -    return result; +    g_content_exporter_add_arch_to_gtk_buffer(G_CONTENT_EXPORTER(operand->offset), +                                              format, syntax, buffer, iter);  } diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index cbf2ed2..cb04ca8 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -108,10 +108,10 @@ GType g_x86_mod_rm_operand_get_type(void);  GArchOperand *g_x86_mod_rm_operand_new(const bin_t *, off_t *, off_t, AsmOperandSize);  /* Fournit l'indice et l'échelle d'un opérande x86 ModRM. */ -void g_x86_mod_rm_operand_get_scale_and_index(const GX86ModRMOperand *operand, uint8_t *, const x86_register **); +void g_x86_mod_rm_operand_get_scale_and_index(const GX86ModRMOperand *operand, uint8_t *, const GX86Register **);  /* Fournit le registre de base d'un opérande x86 ModRM. */ -const x86_register *g_x86_mod_rm_operand_get_base(const GX86ModRMOperand *); +const GX86Register *g_x86_mod_rm_operand_get_base(const GX86ModRMOperand *);  /* Fournit le décallage supplémentaire d'un opérande x86 ModRM. */  const GImmOperand *g_x86_mod_rm_operand_get_displacement(const GX86ModRMOperand *); diff --git a/src/arch/x86/registers.c b/src/arch/x86/registers.c index 802e2f6..4e186ed 100644 --- a/src/arch/x86/registers.c +++ b/src/arch/x86/registers.c @@ -24,10 +24,12 @@  #include "registers.h" -#include <malloc.h>  #include <stdio.h> +#include "../operand-int.h" + +  /* Liste des registres 8 bits */  typedef enum _X868bRegister @@ -78,9 +80,13 @@ typedef enum _X8632bRegister  } X8632bRegister; -/* Registre x86 */ -struct _x86_register +/* Représentation d'un registre x86 (instance) */ +struct _GX86Register  { +    GArchOperand parent;                    /* Instance parente            */ + +    MemoryDataSize size;                    /* Taille de ce registre       */ +      union      {          X868bRegister reg8;                 /* Registre 8 bits             */ @@ -89,30 +95,85 @@ struct _x86_register      } reg; -    AsmOperandSize size;                    /* Taille de ce registre       */ +}; + + +/* Représentation d'un registre x86 (classe) */ +struct _GX86RegisterClass +{ +    GArchOperandClass parent;               /* Classe parente              */  }; +/* Ajoute à un texte GTK le contenu d'un opérande. */ +static void g_x86_register_add_to_gtk_buffer(const GX86Register *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); + + + +/* Indique le type défini pour une représentation d'un registre x86. */ +G_DEFINE_TYPE(GX86Register, g_x86_register, G_TYPE_CONTENT_EXPORTER); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des lignes de représentation.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_register_class_init(GX86RegisterClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : reg = instance à initialiser.                                * +*                                                                             * +*  Description : Initialise une instance de ligne de représentation.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_register_init(GX86Register *reg) +{ +    GContentExporter *parent;               /* Instance parente            */ + +    parent = G_CONTENT_EXPORTER(reg); + +    parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_register_add_to_gtk_buffer; + +} +  /******************************************************************************  *                                                                             *  *  Paramètres  : size  = indique la taille du registre.                       *  *                value = valeur correspondant au registre.                    *  *                                                                             * -*  Description : Récupère l'indentifiant interne d'un registre.               * +*  Description : Crée une réprésentation de registre x86.                     *  *                                                                             * -*  Retour      : Registre définit ou NULL.                                    * +*  Retour      : Adresse de la structure mise en place.                       *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -x86_register *get_x86_register(AsmOperandSize size, bin_t value) +GX86Register *g_x86_register_new(MemoryDataSize size, bin_t value)  { -    x86_register *result;                   /* Représentation à renvoyer   */ +    GX86Register *result;                   /* Structure à retourner       */ -    result = (x86_register *)calloc(1, sizeof(x86_register)); +    result = g_object_new(G_TYPE_X86_REGISTER, NULL);      result->size = size; @@ -125,7 +186,7 @@ x86_register *get_x86_register(AsmOperandSize size, bin_t value)                      result->reg.reg8 = (X868bRegister)value;                      break;                  default: -                    goto gxr_error; +                    goto gxrn_error;                      break;              }              break; @@ -137,7 +198,7 @@ x86_register *get_x86_register(AsmOperandSize size, bin_t value)                      result->reg.reg16 = (X8616bRegister)value;                      break;                  default: -                    goto gxr_error; +                    goto gxrn_error;                      break;              }              break; @@ -149,22 +210,22 @@ x86_register *get_x86_register(AsmOperandSize size, bin_t value)                      result->reg.reg32 = (X8632bRegister)value;                      break;                  default: -                    goto gxr_error; +                    goto gxrn_error;                      break;              }              break;          default: -            goto gxr_error; +            goto gxrn_error;              break;      }      return result; - gxr_error: + gxrn_error: -    free(result); +    /* FIXME free(result); */      return NULL; @@ -173,133 +234,26 @@ x86_register *get_x86_register(AsmOperandSize size, bin_t value)  /******************************************************************************  *                                                                             * -*  Paramètres  : reg = registre à supprimer.                                  * -*                                                                             * -*  Description : Efface de la mémoire l'indentifiant interne d'un registre.   * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void free_x86_register(x86_register *reg) -{ -    free(reg); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : reg = registre à consulter.                                  * -*                                                                             * -*  Description : Indique si le registre correspond à ebp ou similaire.        * -*                                                                             * -*  Retour      : true si la correspondance est avérée, false sinon.           * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool is_x86_register_base_pointer(const x86_register *reg) -{ -    bool result;                            /* Bilan à remonter            */ - -    switch (reg->size) -    { -        case AOS_8_BITS_UNSIGNED: -        case AOS_8_BITS_SIGNED: -            result = (reg->reg.reg8 == X86_REG8_CH); -            break; -        case AOS_16_BITS_UNSIGNED: -        case AOS_16_BITS_SIGNED: -            result = (reg->reg.reg16 == X86_REG16_BP); -            break; -        case AOS_32_BITS_UNSIGNED: -        case AOS_32_BITS_SIGNED: -            result = (reg->reg.reg32 == X86_REG32_EBP); -            break; -            /* -        case AOS_64_BITS_UNSIGNED: -        case AOS_64_BITS_SIGNED: -            result = (reg->reg.reg8 == X86_REG8_CH); -            break; -            */ -        default: -            result = false; - -    } - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : reg = registre à consulter.                                  * -*                                                                             * -*  Description : Indique si le registre correspond à esp ou similaire.        * -*                                                                             * -*  Retour      : true si la correspondance est avérée, false sinon.           * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool is_x86_register_stack_pointer(const x86_register *reg) -{ -    bool result;                            /* Bilan à remonter            */ - -    switch (reg->size) -    { -        case AOS_8_BITS_UNSIGNED: -        case AOS_8_BITS_SIGNED: -            result = (reg->reg.reg8 == X86_REG8_AH); -            break; -        case AOS_16_BITS_UNSIGNED: -        case AOS_16_BITS_SIGNED: -            result = (reg->reg.reg16 == X86_REG16_SP); -            break; -        case AOS_32_BITS_UNSIGNED: -        case AOS_32_BITS_SIGNED: -            result = (reg->reg.reg32 == X86_REG32_ESP); -            break; -            /* -        case AOS_64_BITS_UNSIGNED: -        case AOS_64_BITS_SIGNED: -            result = (reg->reg.reg8 == X86_REG8_CH); -            break; -            */ -        default: -            result = false; - -    } - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : reg    = registre à imprimer.                                * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format = format du binaire manipulé.                         *  *                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 *  *                                                                             * -*  Description : Traduit un registre x86 en texte.                            * +*  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * -*  Retour      : Traduction en chaîne à libérer de la mémoire.                * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax) +static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter)  { -    char *result;                           /* Chaîne à renvoyer           */ +    char key[5];                            /* Mot clef principal          */ +    size_t klen;                            /* Taille de ce mot clef       */ -    result = (char *)calloc(5, sizeof(char)); +    klen = 0;      switch (syntax)      { @@ -307,31 +261,32 @@ char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax)              switch (reg->size)              {                  case AOS_8_BITS: +                    klen = 2;                      switch (reg->reg.reg8)                      {                          case X86_REG8_AL: -                            snprintf(result, 5, "al"); +                            snprintf(key, 5, "al");                              break;                          case X86_REG8_CL: -                            snprintf(result, 5, "cl"); +                            snprintf(key, 5, "cl");                              break;                          case X86_REG8_DL: -                            snprintf(result, 5, "dl"); +                            snprintf(key, 5, "dl");                              break;                          case X86_REG8_BL: -                            snprintf(result, 5, "bl"); +                            snprintf(key, 5, "bl");                              break;                          case X86_REG8_AH: -                            snprintf(result, 5, "ah"); +                            snprintf(key, 5, "ah");                              break;                          case X86_REG8_CH: -                            snprintf(result, 5, "ch"); +                            snprintf(key, 5, "ch");                              break;                          case X86_REG8_DH: -                            snprintf(result, 5, "dh"); +                            snprintf(key, 5, "dh");                              break;                          case X86_REG8_BH: -                            snprintf(result, 5, "bh"); +                            snprintf(key, 5, "bh");                              break;                          case X86_REG8_NONE:                              /* Ne devrait jamais arriver */ @@ -340,31 +295,32 @@ char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax)                      break;                  case AOS_16_BITS: +                    klen = 2;                      switch (reg->reg.reg16)                      {                          case X86_REG16_AX: -                            snprintf(result, 5, "ax"); +                            snprintf(key, 5, "ax");                              break;                          case X86_REG16_CX: -                            snprintf(result, 5, "cx"); +                            snprintf(key, 5, "cx");                              break;                          case X86_REG16_DX: -                            snprintf(result, 5, "dx"); +                            snprintf(key, 5, "dx");                              break;                          case X86_REG16_BX: -                            snprintf(result, 5, "bx"); +                            snprintf(key, 5, "bx");                              break;                          case X86_REG16_SP: -                            snprintf(result, 5, "sp"); +                            snprintf(key, 5, "sp");                              break;                          case X86_REG16_BP: -                            snprintf(result, 5, "bp"); +                            snprintf(key, 5, "bp");                              break;                          case X86_REG16_SI: -                            snprintf(result, 5, "si"); +                            snprintf(key, 5, "si");                              break;                          case X86_REG16_DI: -                            snprintf(result, 5, "di"); +                            snprintf(key, 5, "di");                              break;                          case X86_REG16_NONE:                              /* Ne devrait jamais arriver */ @@ -373,31 +329,32 @@ char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax)                      break;                  case AOS_32_BITS: +                    klen = 3;                      switch (reg->reg.reg32)                      {                          case X86_REG32_EAX: -                            snprintf(result, 5, "eax"); +                            snprintf(key, 5, "eax");                              break;                          case X86_REG32_ECX: -                            snprintf(result, 5, "ecx"); +                            snprintf(key, 5, "ecx");                              break;                          case X86_REG32_EDX: -                            snprintf(result, 5, "edx"); +                            snprintf(key, 5, "edx");                              break;                          case X86_REG32_EBX: -                            snprintf(result, 5, "ebx"); +                            snprintf(key, 5, "ebx");                              break;                          case X86_REG32_ESP: -                            snprintf(result, 5, "esp"); +                            snprintf(key, 5, "esp");                              break;                          case X86_REG32_EBP: -                            snprintf(result, 5, "ebp"); +                            snprintf(key, 5, "ebp");                              break;                          case X86_REG32_ESI: -                            snprintf(result, 5, "esi"); +                            snprintf(key, 5, "esi");                              break;                          case X86_REG32_EDI: -                            snprintf(result, 5, "edi"); +                            snprintf(key, 5, "edi");                              break;                          case X86_REG32_NONE:                              printf("null reg\n"); @@ -416,31 +373,32 @@ char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax)              switch (reg->size)              {                  case AOS_8_BITS: +                    klen = 3;                      switch (reg->reg.reg8)                      {                          case X86_REG8_AL: -                            snprintf(result, 5, "%%al"); +                            snprintf(key, 5, "%%al");                              break;                          case X86_REG8_CL: -                            snprintf(result, 5, "%%cl"); +                            snprintf(key, 5, "%%cl");                              break;                          case X86_REG8_DL: -                            snprintf(result, 5, "%%dl"); +                            snprintf(key, 5, "%%dl");                              break;                          case X86_REG8_BL: -                            snprintf(result, 5, "%%bl"); +                            snprintf(key, 5, "%%bl");                              break;                          case X86_REG8_AH: -                            snprintf(result, 5, "%%ah"); +                            snprintf(key, 5, "%%ah");                              break;                          case X86_REG8_CH: -                            snprintf(result, 5, "%%ch"); +                            snprintf(key, 5, "%%ch");                              break;                          case X86_REG8_DH: -                            snprintf(result, 5, "%%dh"); +                            snprintf(key, 5, "%%dh");                              break;                          case X86_REG8_BH: -                            snprintf(result, 5, "%%bh"); +                            snprintf(key, 5, "%%bh");                              break;                          case X86_REG8_NONE:                              /* Ne devrait jamais arriver */ @@ -449,31 +407,32 @@ char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax)                      break;                  case AOS_16_BITS: +                    klen = 3;                      switch (reg->reg.reg16)                      {                          case X86_REG16_AX: -                            snprintf(result, 5, "%%ax"); +                            snprintf(key, 5, "%%ax");                              break;                          case X86_REG16_CX: -                            snprintf(result, 5, "%%cx"); +                            snprintf(key, 5, "%%cx");                              break;                          case X86_REG16_DX: -                            snprintf(result, 5, "%%dx"); +                            snprintf(key, 5, "%%dx");                              break;                          case X86_REG16_BX: -                            snprintf(result, 5, "%%bx"); +                            snprintf(key, 5, "%%bx");                              break;                          case X86_REG16_SP: -                            snprintf(result, 5, "%%sp"); +                            snprintf(key, 5, "%%sp");                              break;                          case X86_REG16_BP: -                            snprintf(result, 5, "%%bp"); +                            snprintf(key, 5, "%%bp");                              break;                          case X86_REG16_SI: -                            snprintf(result, 5, "%%si"); +                            snprintf(key, 5, "%%si");                              break;                          case X86_REG16_DI: -                            snprintf(result, 5, "%%di"); +                            snprintf(key, 5, "%%di");                              break;                          case X86_REG16_NONE:                              /* Ne devrait jamais arriver */ @@ -482,31 +441,32 @@ char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax)                      break;                  case AOS_32_BITS: +                    klen = 4;                      switch (reg->reg.reg32)                      {                          case X86_REG32_EAX: -                            snprintf(result, 5, "%%eax"); +                            snprintf(key, 5, "%%eax");                              break;                          case X86_REG32_ECX: -                            snprintf(result, 5, "%%ecx"); +                            snprintf(key, 5, "%%ecx");                              break;                          case X86_REG32_EDX: -                            snprintf(result, 5, "%%edx"); +                            snprintf(key, 5, "%%edx");                              break;                          case X86_REG32_EBX: -                            snprintf(result, 5, "%%ebx"); +                            snprintf(key, 5, "%%ebx");                              break;                          case X86_REG32_ESP: -                            snprintf(result, 5, "%%esp"); +                            snprintf(key, 5, "%%esp");                              break;                          case X86_REG32_EBP: -                            snprintf(result, 5, "%%ebp"); +                            snprintf(key, 5, "%%ebp");                              break;                          case X86_REG32_ESI: -                            snprintf(result, 5, "%%esi"); +                            snprintf(key, 5, "%%esi");                              break;                          case X86_REG32_EDI: -                            snprintf(result, 5, "%%edi"); +                            snprintf(key, 5, "%%edi");                              break;                          case X86_REG32_NONE:                              /* Ne devrait jamais arriver */ @@ -525,6 +485,99 @@ char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax)      } +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(reg), buffer, iter, +                                           key, klen, RTT_REGISTER); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : reg = registre à consulter.                                  * +*                                                                             * +*  Description : Indique si le registre correspond à ebp ou similaire.        * +*                                                                             * +*  Retour      : true si la correspondance est avérée, false sinon.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_x86_register_is_base_pointer(const GX86Register *reg) +{ +    bool result;                            /* Bilan à remonter            */ + +    switch (reg->size) +    { +        case AOS_8_BITS_UNSIGNED: +        case AOS_8_BITS_SIGNED: +            result = (reg->reg.reg8 == X86_REG8_CH); +            break; +        case AOS_16_BITS_UNSIGNED: +        case AOS_16_BITS_SIGNED: +            result = (reg->reg.reg16 == X86_REG16_BP); +            break; +        case AOS_32_BITS_UNSIGNED: +        case AOS_32_BITS_SIGNED: +            result = (reg->reg.reg32 == X86_REG32_EBP); +            break; +            /* +        case AOS_64_BITS_UNSIGNED: +        case AOS_64_BITS_SIGNED: +            result = (reg->reg.reg8 == X86_REG8_CH); +            break; +            */ +        default: +            result = false; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : reg = registre à consulter.                                  * +*                                                                             * +*  Description : Indique si le registre correspond à esp ou similaire.        * +*                                                                             * +*  Retour      : true si la correspondance est avérée, false sinon.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_x86_register_is_stack_pointer(const GX86Register *reg) +{ +    bool result;                            /* Bilan à remonter            */ + +    switch (reg->size) +    { +        case AOS_8_BITS_UNSIGNED: +        case AOS_8_BITS_SIGNED: +            result = (reg->reg.reg8 == X86_REG8_AH); +            break; +        case AOS_16_BITS_UNSIGNED: +        case AOS_16_BITS_SIGNED: +            result = (reg->reg.reg16 == X86_REG16_SP); +            break; +        case AOS_32_BITS_UNSIGNED: +        case AOS_32_BITS_SIGNED: +            result = (reg->reg.reg32 == X86_REG32_ESP); +            break; +            /* +        case AOS_64_BITS_UNSIGNED: +        case AOS_64_BITS_SIGNED: +            result = (reg->reg.reg8 == X86_REG8_CH); +            break; +            */ +        default: +            result = false; + +    } +      return result;  } diff --git a/src/arch/x86/registers.h b/src/arch/x86/registers.h index 491d5bc..18bced7 100644 --- a/src/arch/x86/registers.h +++ b/src/arch/x86/registers.h @@ -25,29 +25,40 @@  #define _ARCH_X86_REGISTERS_H +#include <glib-object.h> +#include <stdbool.h> + +  #include "../archbase.h" -#include "../operand.h" -/* Registre x86 */ -typedef struct _x86_register x86_register; +#define G_TYPE_X86_REGISTER               g_x86_register_get_type() +#define G_X86_REGISTER(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_x86_register_get_type(), GX86Register)) +#define G_IS_X86_REGISTER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_x86_register_get_type())) +#define G_X86_REGISTER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_X86_REGISTER, GX86RegisterClass)) +#define G_IS_X86_REGISTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_X86_REGISTER)) +#define G_X86_REGISTER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_X86_REGISTER, GX86RegisterClass)) + +/* Représentation d'un registre x86 (instance) */ +typedef struct _GX86Register GX86Register; -/* Récupère l'indentifiant interne d'un registre. */ -x86_register *get_x86_register(AsmOperandSize, bin_t); +/* Représentation d'un registre x86 (classe) */ +typedef struct _GX86RegisterClass GX86RegisterClass; -/* Efface de la mémoire l'indentifiant interne d'un registre. */ -void free_x86_register(x86_register *); + +/* Indique le type défini pour une représentation d'un registre x86. */ +GType g_x86_register_get_type(void); + +/* Crée une réprésentation de registre x86. */ +GX86Register *g_x86_register_new(MemoryDataSize, bin_t);  /* Indique si le registre correspond à ebp ou similaire. */ -bool is_x86_register_base_pointer(const x86_register *); +bool g_x86_register_is_base_pointer(const GX86Register *);  /* Indique si le registre correspond à esp ou similaire. */ -bool is_x86_register_stack_pointer(const x86_register *); - -/* Traduit un registre x86 en texte. */ -char *x86_register_as_text(const x86_register *, AsmSyntax); +bool g_x86_register_is_stack_pointer(const GX86Register *); diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c index 2659b0d..99825f0 100644 --- a/src/gtkext/gtkblockview.c +++ b/src/gtkext/gtkblockview.c @@ -27,8 +27,12 @@  #include <malloc.h>  #include <string.h> +#define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API +#include <gtk/gtktextdisplay.h> +  #include "gtkbinview-int.h" +#include "../analysis/exporter.h"  #include "../common/dllist.h" @@ -46,6 +50,9 @@ struct _GtkBlockView      bool show_vaddress;                     /* Affichage des adresses ?    */      bool show_code;                         /* Affichage du code brut ?    */ +    GtkTextBuffer *buffer;                  /* Code sous forme de texte    */ +    GtkTextLayout *_layout;                  /* Disposition du texte        */ +      PangoLayout *layout;                    /* Moteur de rendu du code ASM */      int line_height;                        /* Hauteur maximale des lignes */ @@ -61,6 +68,26 @@ struct _GtkBlockViewClass + +static void +gtk_text_view2_set_attributes_from_style (GtkTextAttributes  *values, +                                         GtkStyle           *style) +{ +    PangoFontDescription *font_desc; + +  values->appearance.bg_color = style->base[GTK_STATE_NORMAL]; +  values->appearance.fg_color = style->text[GTK_STATE_NORMAL]; + +  if (values->font) +    pango_font_description_free (values->font); + +        font_desc = pango_font_description_from_string ("mono 10"); + +  values->font = pango_font_description_copy (/*style->*/font_desc); +        pango_font_description_free (font_desc); +} + +  /* Procède à l'initialisation de l'afficheur d'un bloc binaire. */  static void gtk_block_view_init(GtkBlockView *); @@ -110,7 +137,7 @@ static void gtk_block_view_size_allocate(GtkWidget *widget,  static gboolean gtk_block_view_button_press(GtkWidget *, GdkEventButton *event);  /* Met à jour l'affichage de la vue sous forme de bloc. */ -static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event); +static gboolean gtk_block_view_expose(GtkWidget *, GdkEventExpose *);  static void gtk_block_view_destroy(GtkObject *object); @@ -182,11 +209,100 @@ static void gtk_block_view_init(GtkBlockView *view)  {      GtkBinView *binview;                    /* Instance parente            */ + +    PangoTabArray *tabs; +    gint current_y; +    PangoFontDescription *font_desc; +    GList *child_exposes; +    PangoContext *ltr_context, *rtl_context; +    GtkTextAttributes *style; +    static bool done = false; + +      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; + + +    view->buffer = gtk_text_buffer_new(get_gtk_tag_table()); + + + +    view->_layout = gtk_text_layout_new(); +    gtk_text_layout_set_buffer(view->_layout, view->buffer); + + + +    if (!done || 1) +    { +        done = true; + +        gtk_text_layout_set_cursor_visible(GTK_BLOCK_VIEW(view)->_layout, FALSE); + +        gtk_text_layout_set_overwrite_mode(GTK_BLOCK_VIEW(view)->_layout, FALSE); + + +        ltr_context = gtk_widget_create_pango_context(view); +        pango_context_set_base_dir(ltr_context, PANGO_DIRECTION_LTR); +        rtl_context = gtk_widget_create_pango_context(view); +        pango_context_set_base_dir(rtl_context, PANGO_DIRECTION_RTL); + +        gtk_text_layout_set_contexts(GTK_BLOCK_VIEW(view)->_layout, ltr_context, rtl_context); + + + +        tabs = pango_tab_array_new_with_positions(5, TRUE, +                                                  PANGO_TAB_LEFT, 120, +                                                  PANGO_TAB_LEFT, 290, +                                                  PANGO_TAB_LEFT, 50, +                                                  PANGO_TAB_LEFT, 50, +                                                  PANGO_TAB_LEFT, 50); + + +        style = gtk_text_attributes_new (); + +        gtk_widget_ensure_style(view); + +        font_desc = pango_font_description_from_string ("mono 10"); +        gtk_widget_modify_font (view, font_desc); +        pango_font_description_free (font_desc); + +        gtk_text_view2_set_attributes_from_style(style, GTK_WIDGET(view)->style); +        /* +        style->pixels_above_lines = 5; +        style->pixels_below_lines = 5; +        style->pixels_inside_wrap = 10; +        style->left_margin = 10; +        style->right_margin = 10; +        style->indent = 10;*/ +        style->left_margin = 10; +        style->right_margin = 10; +        style->tabs = tabs; + +        style->wrap_mode = GTK_WRAP_WORD; +        style->justification = GTK_JUSTIFY_LEFT; + +        style->direction = gtk_widget_get_direction(view); + + +        gtk_text_layout_set_default_style(GTK_BLOCK_VIEW(view)->_layout, style); + +        gtk_text_attributes_unref(style); + + +        //gtk_text_layout_get_size (GTK_BLOCK_VIEW(view)->_layout, &width, &height); + +        gtk_text_layout_set_screen_width (GTK_BLOCK_VIEW(view)->_layout, +                                          MAX (1, 1000)); + +    } + + +    gtk_text_buffer_set_text(view->buffer, "\t|\t|\t|\t|\t|\n", -1); + +  } @@ -240,6 +356,7 @@ gtk_block_view_size_allocate(GtkWidget *widget,  static void gtk_block_view_realize(GtkWidget *widget)  {      GtkBinViewClass *parent_class;          /* Version pure du parent      */ +    PangoFontDescription *font_desc;      parent_class = GTK_BIN_VIEW_CLASS(g_type_class_peek_parent(GTK_BLOCK_VIEW_GET_CLASS(widget))); @@ -247,6 +364,10 @@ static void gtk_block_view_realize(GtkWidget *widget)      GTK_BLOCK_VIEW(widget)->layout = gtk_widget_create_pango_layout(widget, NULL); +    font_desc = pango_font_description_from_string("mono 10"); +    gtk_widget_modify_font(widget, font_desc); +    pango_font_description_free(font_desc); +  } @@ -334,8 +455,12 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event)      int y;                                  /* Ordonnée du haut d'une ligne*/      GRenderingLine *iter;                   /* Boucle de parcours          */ -    view = GTK_BIN_VIEW(widget); +    PangoFontDescription *font_desc; +    GList *child_exposes; + +    view = GTK_BIN_VIEW(widget); +#if 0      gdk_window_begin_paint_region(GDK_DRAWABLE(widget->window), event->region);      gdk_gc_set_clip_region(view->gc, event->region); @@ -351,7 +476,7 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event)                         TRUE, 0, 0, width, height);      gdk_gc_set_foreground(view->gc, &values.foreground); - +    /*      y = event->area.y;      iter = g_rendering_line_find_by_y(view->lines, view->last, &y); @@ -367,8 +492,21 @@ static gboolean gtk_block_view_expose(GtkWidget *widget, GdkEventExpose *event)          y += GTK_BLOCK_VIEW(view)->line_height;      } - +    */      gdk_window_end_paint(GDK_DRAWABLE(widget->window)); +#endif + +    gtk_text_layout_set_screen_width (GTK_BLOCK_VIEW(view)->_layout, +                                      MAX (1, 1000)); + +    //gtk_text_buffer_set_text(GTK_BLOCK_VIEW(view)->buffer, "Hello, this some text\n", -1); + +        font_desc = pango_font_description_from_string ("mono 10"); +        gtk_widget_modify_font (view, font_desc); +        pango_font_description_free (font_desc); + +    gtk_text_layout_draw(GTK_BLOCK_VIEW(view)->_layout, widget, GDK_DRAWABLE(widget->window), +                         NULL, 0, 0, 0, 0, 5000, 50000, &child_exposes);      return TRUE; @@ -482,6 +620,7 @@ void gtk_block_view_set_format(GtkBlockView *view, const exe_format *format)  static void gtk_block_view_set_rendering_lines(GtkBlockView *view, GRenderingLine *lines, GRenderingLine *last)  {      GRenderingLine *iter;                   /* Boucle de parcours          */ +    GtkTextIter pos;                        /* Point d'insertion           */      for (iter = GTK_BIN_VIEW(view)->lines;           iter != NULL; @@ -494,6 +633,24 @@ static void gtk_block_view_set_rendering_lines(GtkBlockView *view, GRenderingLin      g_rendering_line_update_bin_len(GTK_BIN_VIEW(view)->lines,                                      GTK_BIN_VIEW(view)->last, view->rendering); +    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)) +    { +        if (iter != GTK_BIN_VIEW(view)->lines) +        { +            gtk_text_buffer_get_end_iter(view->buffer, &pos); +            gtk_text_buffer_insert_with_tags(view->buffer, &pos, "\n", 1, NULL); +        } + +        gtk_text_buffer_get_end_iter(view->buffer, &pos); +        g_content_exporter_add_to_gtk_buffer(G_CONTENT_EXPORTER(iter), view->rendering, +                                             view->buffer, &pos); + +    } + +    gtk_text_layout_validate(GTK_BLOCK_VIEW(view)->_layout, 100000); +      gtk_block_view_recompute_size_request(view);  } @@ -519,6 +676,16 @@ void gtk_block_view_recompute_size_request(GtkBlockView *view)      int width;                              /* Largeur de l'objet actuelle */      int height;                             /* Hauteur de l'objet actuelle */ +    gtk_text_layout_get_size(view->_layout, &width, &height); + +    gtk_widget_set_size_request(GTK_WIDGET(view), +                                width + 2 * MARGIN_SPACE + 20/*view->line_height*/, +                                height); + + +    printf("req size :: (%d ; %d)\n", width, height); + +    /*      g_rendering_line_get_size(GTK_BIN_VIEW(view)->lines,                                GTK_BIN_VIEW(view)->last,                                view->rendering, @@ -527,7 +694,7 @@ void gtk_block_view_recompute_size_request(GtkBlockView *view)      gtk_widget_set_size_request(GTK_WIDGET(view),                                  width + 2 * MARGIN_SPACE + view->line_height,                                  height); - +    */  } diff --git a/src/gtkext/gtkextstatusbar.c b/src/gtkext/gtkextstatusbar.c index cb6851d..79beda2 100644 --- a/src/gtkext/gtkextstatusbar.c +++ b/src/gtkext/gtkextstatusbar.c @@ -124,6 +124,8 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g  {      guint result;                           /* Identifiant à retourner     */ +    gdk_threads_enter(); +      result = gtk_statusbar_push(GTK_STATUSBAR(bar), bar->context, message);      bar->msg_count++; @@ -143,6 +145,10 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g      }      else gtk_widget_hide(GTK_WIDGET(bar->progress)); +    gdk_flush (); + +    gdk_threads_leave(); +      return result;  } @@ -203,6 +209,8 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id)  {      size_t i;                               /* Boucle de parcours          */ +    gdk_threads_enter(); +      gtk_statusbar_remove(GTK_STATUSBAR(bar), bar->context, id);      for (i = 0; i < bar->msg_count; i++) @@ -225,4 +233,8 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id)      else          gtk_widget_hide(GTK_WIDGET(bar->progress)); +    gdk_flush (); + +    gdk_threads_leave(); +  } @@ -32,6 +32,7 @@  #include "params.h"  #include "project.h"  #include "analysis/delayed.h" +#include "analysis/exporter.h"  #include "arch/processor.h"  #include "format/format.h"  #include "format/mangling/demangler.h" @@ -92,6 +93,8 @@ int main(int argc, char **argv)      init_all_demanglers();      init_all_formats(); +    _get_gtk_tag_table(gtk_text_tag_table_new()); +      /* Création de l'interface */      editor = create_editor();      gtk_widget_show(editor); @@ -115,6 +118,8 @@ int main(int argc, char **argv)      gtk_main();      gdk_threads_leave(); +    _get_gtk_tag_table(0xdeadc0de); +      unload_configuration(config);      return EXIT_SUCCESS; | 
