From 674739bedc853681be5a2657a7a4f497d6e82c9b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 4 Mar 2009 01:38:27 +0000
Subject: Added a line type for binary code display.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@51 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog            |  17 +++
 src/analysis/line.c  | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/analysis/line.h  |  42 +++++++-
 src/arch/processor.h |  14 +++
 src/binary.c         |  58 +++++++++-
 src/gtksnippet.c     |  64 ++++++++++-
 src/gtksnippet.h     |   9 --
 7 files changed, 475 insertions(+), 21 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6342c1d..c189e02 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2009-03-04  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/line.c:
+	* src/analysis/line.h:
+	Add a line type for binary code display and some generic
+	functions/properties for all lines.
+
+	* src/arch/processor.h:
+	Move the definition of AdressMode (typo !) here.
+
+	* src/binary.c:
+	Update code and calls.
+
+	* src/gtksnippet.c:
+	* src/gtksnippet.h:
+	Compute requested size and display binary content using the new code lines.
+
 2009-03-03  Cyrille Bagard <nocbos@gmail.com>
 
 	* configure.ac:
diff --git a/src/analysis/line.c b/src/analysis/line.c
index 7431e94..052adea 100644
--- a/src/analysis/line.c
+++ b/src/analysis/line.c
@@ -27,6 +27,7 @@
 #include <malloc.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/param.h>
 
 
 #include "../common/dllist.h"
@@ -38,6 +39,17 @@ extern GtkWidget *mywid;
 
 
 
+
+
+
+/* Méthode de mise à jour du nombre d'octets maximal par instruction. */
+typedef void (* get_bin_len_fc) (rendering_line *, off_t *);
+
+/* Méthode de mise à jour d'une ligne de représentation. */
+typedef void (* refresh_markup_fc) (rendering_line *);
+
+
+
 /* Ligne de représentation générique */
 struct _rendering_line
 {
@@ -47,6 +59,11 @@ struct _rendering_line
 
     PangoLayout *layout;                    /* Moteur de rendu du code/txt */
 
+    get_bin_len_fc get_bin_len;             /* Nbre d'octets représentés   */
+    off_t max_bin_len;                      /* Nombre global maximal       */
+
+    refresh_markup_fc refresh_markup;       /* Reconstruit la représentat° */
+
 };
 
 
@@ -77,11 +94,29 @@ void refresh_prologue_markup(prologue_line *);
 
 
 
+/* ------------------------ LIGNE DE CODE EN LANGAGE MACHINE ------------------------ */
+
 
+/* Ligne de représentation de prologue */
+typedef struct _code_line
+{
+    rendering_line basic;                   /* A laisser en premier        */
+
+    asm_instr *instr;                       /* Instruction représentée     */
+    const disass_options *options;          /* Options de représentation   */
+
+} code_line;
 
 
+/* Taille max d'une traduction */
+#define CODE_BUFFER_LEN 128
 
 
+/* Met à jour la nombre d'octets maximale par instruction. */
+void get_code_binary_len(code_line *, off_t *);
+
+/* Met à jour la ligne de représentation de code. */
+void refresh_code_markup(code_line *);
 
 
 
@@ -106,6 +141,8 @@ void init_rendering_line(rendering_line *line)
 
     line->layout = gtk_widget_create_pango_layout(mywid, NULL);
 
+    line->get_bin_len = NULL;
+    line->refresh_markup = NULL;
 
 
 
@@ -137,6 +174,78 @@ void add_line_to_rendering_lines(rendering_line **lines, rendering_line *line)
 
 
 
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line = ligne de représentation à actualiser.                 *
+*                blen = longueur maximale à mettre à jour. [OUT]              *
+*                                                                             *
+*  Description : Met à jour le nombre d'octets maximal par instruction.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void get_rendering_line_binary_len(rendering_line *line, off_t *blen)
+{
+    if (line->get_bin_len != NULL)
+        line->get_bin_len(line, blen);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line = ligne de représentation à actualiser.                 *
+*                blen = longueur maximale à prendre en compte.                *
+*                                                                             *
+*  Description : Prend en compte le nombre d'octets maximal par instruction.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void set_rendering_line_max_binary_len(rendering_line *line, off_t blen)
+{
+    line->max_bin_len = blen * 2 + (blen - 1);
+
+    line->refresh_markup(line);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line   = adresse de la structure à représenter.              *
+*                width  = largeur maximale des lignes à compléter.            *
+*                height = hauteur maximale des lignes à compléter.            *
+*                                                                             *
+*  Description : Fournit les dimensions d'une ligne par rapport à d'autres.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void get_rendering_line_size(rendering_line *line, int *width, int *height)
+{
+    int w;                                  /* Largeur de l'objet actuelle */
+    int h;                                  /* Hauteur de l'objet actuelle */
+
+    pango_layout_get_pixel_size(line->layout, &w, &h);
+
+    *width = MAX(*width, w);
+    *height += h;
+
+}
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : line     = adresse de la structure à représenter.            *
@@ -170,9 +279,9 @@ void draw_rendering_line(rendering_line *line, GdkDrawable *drawable, GdkGC *gc,
 *                                                                             *
 *  Paramètres  : comment = texte à afficher au final.                         *
 *                                                                             *
-*  Description : Choisit d'afficher le code brut ou non.                      *
+*  Description : Crée une des lignes de description initiales.                *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Adresse de la structure mise en place.                       *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
@@ -188,9 +297,9 @@ rendering_line *create_prologue_line(const char *comment)
 
     RENDERING_LINE(result)->type = RLT_PROLOGUE;
 
-    result->comment = strdup(comment);
+    RENDERING_LINE(result)->refresh_markup = (refresh_markup_fc)refresh_prologue_markup;
 
-    refresh_prologue_markup(result);
+    result->comment = strdup(comment);
 
     return RENDERING_LINE(result);
 
@@ -229,3 +338,178 @@ void refresh_prologue_markup(prologue_line *line)
 }
 
 
+
+/* ---------------------------------------------------------------------------------- */
+/*                          LIGNE DE CODE EN LANGAGE MACHINE                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction à représenter.                         *
+*                options = paramétrage du rendu.                              *
+*                                                                             *
+*  Description : Crée une ligne de représentation de code binaire.            *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+rendering_line *create_code_line(asm_instr *instr, const disass_options *options)
+{
+    code_line *result;                      /* Structure à retourner       */
+
+    result = (code_line *)calloc(1, sizeof(code_line));
+
+    init_rendering_line(RENDERING_LINE(result));
+
+    RENDERING_LINE(result)->type = RLT_CODE;
+
+    RENDERING_LINE(result)->get_bin_len = (get_bin_len_fc)get_code_binary_len;
+    RENDERING_LINE(result)->refresh_markup = (refresh_markup_fc)refresh_code_markup;
+
+    result->instr = instr;
+    result->options = options;
+
+    return RENDERING_LINE(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line = ligne de représentation à actualiser.                 *
+*                blen = longueur maximale à mettre à jour. [OUT]              *
+*                                                                             *
+*  Description : Met à jour le nombre d'octets maximal par instruction.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void get_code_binary_len(code_line *line, off_t *blen)
+{
+    off_t len;                              /* Taille propre à la ligne    */
+
+    get_asm_instr_offset_and_length(line->instr, NULL, &len);
+
+    *blen = MAX(*blen, len);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : line = ligne de représentation à actualiser.                 *
+*                                                                             *
+*  Description : Met à jour la ligne de représentation de code.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void refresh_code_markup(code_line *line)
+{
+    size_t len;                             /* Taille du contenu           */
+    char *content;                          /* Contenu réellement imprimé  */
+    off_t bin_offset;                       /* Début de l'instruction      */
+    off_t bin_len;                          /* Taille d'instruction        */
+    char buffer[CODE_BUFFER_LEN];           /* Zone tampon à utiliser      */
+    const uint8_t *exe_content;             /* Contenu binaire global      */
+    char *bin_code;                         /* Tampon du code binaire      */
+    off_t k;                                /* Boucle de parcours #2       */
+    off_t j;                                /* Boucle de parcours #1       */
+
+    len = strlen("<tt>") + 1;
+    content = (char *)calloc(len, sizeof(char));
+    strcpy(content, "<tt>");
+
+    if (line->options->show_address || line->options->show_code)
+        get_asm_instr_offset_and_length(line->instr, &bin_offset, &bin_len);
+
+    /* Eventuelle adresse virtuelle */
+
+    if (line->options->show_address)
+    {
+        switch (ADM_32BITS  /* FIXME */)
+        {
+            case ADM_32BITS:
+                snprintf(buffer, CODE_BUFFER_LEN,
+                         "<span foreground='#333333'>0x%08llx</span>",
+                         bin_offset);
+                break;
+
+            case ADM_64BITS:
+                snprintf(buffer, CODE_BUFFER_LEN,
+                         "<span foreground='#333333'>0x%16llx</span>",
+                         bin_offset);
+                break;
+
+        }
+
+        len += strlen(buffer);
+        content = (char *)realloc(content, len * sizeof(char));
+        strcat(content, buffer);
+
+    }
+
+    /* Eventuel code brut */
+
+    if (line->options->show_code)
+    {
+        exe_content = get_exe_content(line->options->format, NULL);
+
+        bin_code = (char *)calloc(RENDERING_LINE(line)->max_bin_len + 1, sizeof(char));
+
+        k = 0;
+
+        for (j = 0; j < bin_len; j++)
+        {
+            if ((j + 1) < bin_len)
+                k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]);
+            else
+                k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]);
+        }
+ 
+        for (; k < RENDERING_LINE(line)->max_bin_len; k++)
+            snprintf(&bin_code[k], 2, " ");
+
+        if (line->options->show_address) len += strlen("\t");
+        len += strlen(bin_code);
+        content = (char *)realloc(content, len * sizeof(char));
+        if (line->options->show_address) strcat(content, "\t");
+        strcat(content, bin_code);
+
+        free(bin_code);
+
+    }
+
+    /* Instruction proprement dite */
+
+    print_hinstruction(line->options->proc, line->options->format,
+                       line->instr, buffer, CODE_BUFFER_LEN, ASX_INTEL/*FIXME*/);
+
+    if (line->options->show_address || line->options->show_code) len += strlen("\t");
+    len += strlen(buffer);
+
+    content = (char *)realloc(content, len * sizeof(char));
+    if (line->options->show_address || line->options->show_code) strcat(content, "\t");
+    strcat(content, buffer);
+
+    /* Finalisation */
+
+    len += strlen("</tt>");
+    content = (char *)realloc(content, len * sizeof(char));
+    strcat(content, "</tt>");
+
+    pango_layout_set_markup(RENDERING_LINE(line)->layout, content, len - 1);
+
+    free(content);
+
+}
diff --git a/src/analysis/line.h b/src/analysis/line.h
index dd0915c..cd2ec71 100644
--- a/src/analysis/line.h
+++ b/src/analysis/line.h
@@ -28,12 +28,16 @@
 #include <gtk/gtk.h>
 
 
+#include "../arch/processor.h"
+#include "../format/exe_format.h"
+
+
+
 /* Définitions des types de ligne */
 typedef enum _RenderingLineType
 {
-    RLT_PROLOGUE                            /* Description de l'analyse    */
-
-
+    RLT_PROLOGUE,                           /* Description de l'analyse    */
+    RLT_CODE                                /* Code en langage machine     */
 
 } RenderingLineType;
 
@@ -50,6 +54,15 @@ void add_line_to_rendering_lines(rendering_line **, rendering_line *);
 
 
 
+/* Met à jour la nombre d'octets maximale par instruction. */
+void get_rendering_line_binary_len(rendering_line *, off_t *);
+
+/* Prend en compte le nombre d'octets maximal par instruction. */
+void set_rendering_line_max_binary_len(rendering_line *, off_t);
+
+/* Fournit les dimensions d'une ligne par rapport à d'autres. */
+void get_rendering_line_size(rendering_line *, int *, int *);
+
 /* Procède à l'initialisation des bases d'une représentation. */
 void draw_rendering_line(rendering_line *, GdkDrawable *, GdkGC *, gint, gint);
 
@@ -58,11 +71,32 @@ void draw_rendering_line(rendering_line *, GdkDrawable *, GdkGC *, gint, gint);
 /* ------------------------- LIGNE EN TETE DE DESASSEMBLAGE ------------------------- */
 
 
-/* Choisit d'afficher le code brut ou non. */
+/* Crée une des lignes de description initiales. */
 rendering_line *create_prologue_line(const char *);
 
 
 
+/* ------------------------ LIGNE DE CODE EN LANGAGE MACHINE ------------------------ */
+
+
+/* Passage de paramètres compact */
+typedef struct _disass_options
+{
+    bool show_address;                      /* Affichage de l'adresse ?    */
+    bool show_code;                         /* Affichage du code brut ?    */
+
+    exe_format *format;                     /* Format du contenu bianire   */
+    asm_processor *proc;                    /* Architecture utilisée       */
+
+} disass_options;
+
+
+/* Crée une ligne de représentation de code binaire. */
+rendering_line *create_code_line(asm_instr *, const disass_options *);
+
+
+
+
 
 
 #endif  /* _ANALYSIS_LINE_H */
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 7fc1023..343a98c 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -34,6 +34,20 @@
 
 
 
+/* FIXME : lieu de définition temporaire */
+
+/* Mode d'adressage à utiliser */
+typedef enum _AdressMode
+{
+    ADM_32BITS,                             /* Adresses sur 32 bits        */
+    ADM_64BITS                              /* Adresses sur 64 bits        */
+
+} AdressMode;
+
+
+
+
+
 /* Définition générique d'une architecture */
 typedef struct _asm_processor asm_processor;
 
diff --git a/src/binary.c b/src/binary.c
index 16be5ef..d55eb4a 100644
--- a/src/binary.c
+++ b/src/binary.c
@@ -444,6 +444,7 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2)
     size_t comments_count;
     code_line_info **comments_list;
 
+    rendering_line *lines;
     rendering_line *line;
 
     code_line_info **list;
@@ -463,6 +464,8 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2)
 
     size_t k;
 
+    disass_options options;
+
     proc = create_x86_processor();
 
     pos = 0;
@@ -490,10 +493,61 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2)
     //exit(0);
 
 
-    line = build_binary_prologue("/tmp/hello", bin_data, length);
+    lines = build_binary_prologue("/tmp/hello", bin_data, length);
+
+
+
+    options.show_address = true;
+    options.show_code = true;
+
+    options.format = format;
+    options.proc = proc;
+
+
+    parts = get_elf_default_code_parts(format, &parts_count);
+
+
+    for (i = 0; i < parts_count; i++)
+    {
+        get_bin_part_values(parts[i], &pos, &len, &base);
+
+
+
+        start = pos;
+        pos = 0;
+
+        while (pos < len)
+        {
+            offset = base + pos;
+
+
+            instr = decode_instruction(proc, &bin_data[start], &pos, len, start, offset);
+
+
+            line = create_code_line(instr, &options);
+            add_line_to_rendering_lines(&lines, line);
+
+        }
+
+
+        /****
+             ret = munmap(bin_data, length);
+        ****/
+
+        /*
+          gtk_snippet_build_content(snippet);
+        */
+
+    }
+
+
+
+
+
+
 
 
-    gtk_snippet_set_rendering_lines(snippet, line);
+    gtk_snippet_set_rendering_lines(snippet, lines);
 
 
     return;
diff --git a/src/gtksnippet.c b/src/gtksnippet.c
index 791338e..989e22b 100644
--- a/src/gtksnippet.c
+++ b/src/gtksnippet.c
@@ -124,7 +124,8 @@ int compare_code_line_info(const code_line_info **a, const code_line_info **b)
 
 
 
-
+/* Réclame une nouvelle taille adaptée au contenu présent. */
+void gtk_snippet_recompute_size_request(GtkSnippet *);
 
 
 
@@ -569,11 +570,70 @@ void gtk_snippet_set_processor(GtkSnippet *snippet, const asm_processor *proc)
 
 void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, rendering_line *lines)
 {
+    rendering_line *iter;                   /* Boucle de parcours          */
+    off_t bin_len;                          /* Taille d'instruction        */
+
     snippet->lines = lines;
 
+    bin_len = 0;
+
+    dl_list_for_each(iter, lines, rendering_line *)
+        get_rendering_line_binary_len(iter, &bin_len);
+
+    dl_list_for_each(iter, lines, rendering_line *)
+        set_rendering_line_max_binary_len(iter, bin_len);
+
+    gtk_snippet_recompute_size_request(snippet);
+
 }
 
 
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : snippet = composant GTK à mettre à jour.                     *
+*                                                                             *
+*  Description : Réclame une nouvelle taille adaptée au contenu présent.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_snippet_recompute_size_request(GtkSnippet *snippet)
+{
+    int width;                              /* Largeur de l'objet actuelle */
+    int height;                             /* Hauteur de l'objet actuelle */
+    rendering_line *iter;                   /* Boucle de parcours          */
+
+    width = 0;
+    height = 0;
+
+    dl_list_for_each(iter, snippet->lines, rendering_line *)
+    {
+        get_rendering_line_size(iter, &width, &height);
+
+        if (iter == snippet->lines)
+            snippet->line_height = height;
+
+    }
+
+    gtk_widget_set_size_request(GTK_WIDGET(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height);
+
+}
+
+
+
+
+
+
+
+
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : snippet = composant GTK à mettre à jour.                     *
@@ -775,7 +835,7 @@ void gtk_snippet_build_content(GtkSnippet *snippet)
 
     pango_layout_iter_free(iter);
 
-    gtk_widget_set_size_request(GTK_WIDGET(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height);
+    //gtk_widget_set_size_request(GTK_WIDGET(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height);
 
 }
 
diff --git a/src/gtksnippet.h b/src/gtksnippet.h
index f3b541d..7488122 100644
--- a/src/gtksnippet.h
+++ b/src/gtksnippet.h
@@ -75,15 +75,6 @@ typedef struct _GtkSnippet GtkSnippet;
 typedef struct _GtkSnippetClass GtkSnippetClass;
 
 
-/* Mode d'adressage à utiliser */
-typedef enum _AdressMode
-{
-    ADM_32BITS,                             /* Adresses sur 32 bits        */
-    ADM_64BITS                              /* Adresses sur 64 bits        */
-
-} AdressMode;
-
-
 
 
 
-- 
cgit v0.11.2-87-g4458