From ed4bb73e5d68c1f81b8e0c3210aa221ec6f2675b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 31 Aug 2013 15:56:10 +0000
Subject: Loaded a binary strip into the editor.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@358 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                        |  54 +++
 src/arch/archbase.h              |   5 +
 src/common/xml.h                 |   2 +-
 src/editor.c                     |   4 +
 src/format/elf/elf.c             | 135 +++++-
 src/format/elf/elf_def.h         |  25 +-
 src/format/elf/program.c         |  51 ++-
 src/format/elf/program.h         |   5 +-
 src/format/elf/symbols.c         |   6 +-
 src/format/executable-int.h      |   6 +
 src/format/executable.c          |  29 ++
 src/format/executable.h          |   4 +
 src/glibext/Makefile.am          |   1 +
 src/glibext/gbinportion.c        | 938 +++++++++++++++++++++++++++++++++++++++
 src/glibext/gbinportion.h        | 148 ++++++
 src/gtkext/Makefile.am           |   1 +
 src/gtkext/graph/nodes/flow.c    |   4 +
 src/gtkext/graph/nodes/virtual.c |  16 +-
 src/gtkext/gtkbinarystrip.c      | 462 +++++++++++++++++++
 src/gtkext/gtkbinarystrip.h      |  62 +++
 src/gui/editem-int.h             |   4 +
 src/gui/editem.c                 |  24 +
 src/gui/editem.h                 |   3 +
 src/gui/tb/Makefile.am           |   1 +
 src/gui/tb/portions.c            | 162 +++++++
 src/gui/tb/portions.h            |  38 ++
 src/main.c                       |   3 +
 27 files changed, 2177 insertions(+), 16 deletions(-)
 create mode 100644 src/glibext/gbinportion.c
 create mode 100644 src/glibext/gbinportion.h
 create mode 100644 src/gtkext/gtkbinarystrip.c
 create mode 100644 src/gtkext/gtkbinarystrip.h
 create mode 100644 src/gui/tb/portions.c
 create mode 100644 src/gui/tb/portions.h

diff --git a/ChangeLog b/ChangeLog
index 4c9409e..ade8874 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,57 @@
+13-08-31  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/arch/archbase.h:
+	Define some stuff for file offsets.
+
+	* src/common/xml.h:
+	Update the GLib headers.
+
+	* src/editor.c:
+	Load a binary strip into the editor.
+
+	* src/format/elf/elf.c:
+	* src/format/elf/elf_def.h:
+	* src/format/elf/program.c:
+	* src/format/elf/program.h:
+	* src/format/elf/symbols.c:
+	* src/format/executable.c:
+	* src/format/executable.h:
+	* src/format/executable-int.h:
+	Cut binary programs into portions.
+
+	* src/glibext/gbinportion.c:
+	* src/glibext/gbinportion.h:
+	New entries: introduce data portions.
+
+	* src/glibext/Makefile.am:
+	Add the 'gbinportion.[ch]' files to libglibext_la_SOURCES.
+
+	* src/gtkext/graph/nodes/flow.c:
+	* src/gtkext/graph/nodes/virtual.c:
+	Work on the code.
+
+	* src/gtkext/gtkbinarystrip.c:
+	* src/gtkext/gtkbinarystrip.h:
+	New entries: create binary strips for the GUI.
+
+	* src/gtkext/Makefile.am:
+	Add the 'gtkbinarystrip.[ch]' files to libgtkext_la_SOURCES.
+
+	* src/gui/editem.c:
+	* src/gui/editem.h:
+	* src/gui/editem-int.h:
+	Handle a global position in the current binary.
+
+	* src/gui/tb/Makefile.am:
+	Add the 'portions.[ch]' files to libguitb_la_SOURCES.
+
+	* src/gui/tb/portions.c:
+	* src/gui/tb/portions.h:
+	Create a place for a global binary strip.
+
+	* src/main.c:
+	Load the binary strip colors.
+
 13-08-21  Cyrille Bagard <nocbos@gmail.com>
 
 	* plugins/androhelpers/try_n_catch.c:
diff --git a/src/arch/archbase.h b/src/arch/archbase.h
index 1169c16..5ef412c 100644
--- a/src/arch/archbase.h
+++ b/src/arch/archbase.h
@@ -30,6 +30,10 @@
 
 
 
+#define OFF_FMT     "%ld"
+#define OFF_CAST(v) ((long)v)
+
+
 /* Octet de données binaires */
 typedef uint8_t bin_t;
 
@@ -42,6 +46,7 @@ typedef uint64_t vmpa_t;
 
 #define VMPA_FMT        "0x%llx"
 #define VMPA_FMT_LONG   "0x%08llx"
+#define VMPA_CAST(v)    ((unsigned long long)v)
 #define VMPA_MAX_SIZE   19
 
 
diff --git a/src/common/xml.h b/src/common/xml.h
index f96f65a..c637235 100644
--- a/src/common/xml.h
+++ b/src/common/xml.h
@@ -26,8 +26,8 @@
 #define _XML_H
 
 
+#include <glib.h>
 #include <stdbool.h>
-#include <glib/gtypes.h>
 #include <libxml/tree.h>
 #include <libxml/xmlwriter.h>
 #include <libxml/xpath.h>
diff --git a/src/editor.c b/src/editor.c
index 6386858..5df04ed 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -35,6 +35,7 @@
 #include "gui/status.h"
 #include "gui/menus/menubar.h"
 #include "gui/panels/panel.h"
+#include "gui/tb/portions.h"
 #include "gui/tb/source.h"
 
 
@@ -421,6 +422,9 @@ static GtkWidget *build_editor_toolbar(GObject *ref)
     item = create_source_tb_item(ref);
     register_editor_item(item);
 
+    item = create_portions_tb_item(ref);
+    register_editor_item(item);
+
 
     return result;
 
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 158a6b6..6807e36 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -26,9 +26,13 @@
 
 #include <malloc.h>
 #include <stddef.h>
+#include <stdio.h>
 #include <string.h>
 
 
+#include <i18n.h>
+
+
 #include "elf-int.h"
 #include "program.h"
 #include "section.h"
@@ -39,11 +43,11 @@
 
 
 
-#ifndef _
-#   define _(str) (str)
-#endif
 
 
+/* Taille maximale d'une description */
+#define MAX_PORTION_DESC 256
+
 
 
 /* Initialise la classe des formats d'exécutables ELF. */
@@ -58,6 +62,9 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *);
 /* Fournit l'adresse mémoire du point d'entrée du programme. */
 static vmpa_t g_elf_format_get_entry_point(const GElfFormat *);
 
+/* Etend la définition des portions au sein d'un binaire. */
+static void g_elf_format_refine_portions(const GElfFormat *, GBinPortion *);
+
 /* Fournit les références aux zones binaires à analyser. */
 static GBinPart **g_elf_format_get_parts(const GElfFormat *, size_t *);
 
@@ -139,6 +146,7 @@ static void g_elf_format_init(GElfFormat *format)
 
     exe_format->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine;
     exe_format->get_entry_point = (get_entry_point_fc)g_elf_format_get_entry_point;
+    exe_format->refine_portions = (refine_portions_fc)g_elf_format_refine_portions;
     exe_format->get_parts = (get_parts_fc)g_elf_format_get_parts;
 
     exe_format->translate_addr = (translate_addr_fc)g_elf_format_translate_address_into_offset;
@@ -291,6 +299,127 @@ static vmpa_t g_elf_format_get_entry_point(const GElfFormat *format)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format = informations chargées à consulter.                  *
+*                raw    = portion de binaire brut à raffiner.                 *
+*                                                                             *
+*  Description : Etend la définition des portions au sein d'un binaire.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *raw)
+{
+    uint16_t i;                             /* Boucle de parcours          */
+    off_t offset;                           /* Début de part de programme  */
+    elf_phdr phdr;                          /* En-tête de programme ELF    */
+    uint32_t p_flags;                       /* Droits associés à une partie*/
+    const char *background;                 /* Fond signigicatif           */
+    GBinPortion *new;                       /* Nouvelle portion définie    */
+    char desc[MAX_PORTION_DESC];            /* Description d'une portion   */
+    PortionAccessRights rights;             /* Droits d'une portion        */
+    elf_shdr strings;                       /* Section des descriptions    */
+    bool has_strings;                       /* Section trouvée ?           */
+    elf_shdr section;                       /* En-tête de section ELF      */
+    uint64_t sh_flags;                      /* Droits associés à une partie*/
+    const char *name;                       /* Nom trouvé ou NULL          */
+
+    /* Côté segments basiques */
+
+#if 0
+    for (i = 0; i < ELF_HDR(format, format->header, e_phnum); i++)
+    {
+        offset = ELF_HDR(format, format->header, e_phoff)
+            + ELF_HDR(format, format->header, e_phentsize) * i;
+
+        if (!read_elf_program_header(format, &offset, &phdr))
+            continue;
+
+        p_flags = ELF_PHDR(format, phdr, p_flags);
+
+        if (p_flags & PF_X) background = BPC_CODE;
+        else if (p_flags & PF_W) background = BPC_DATA;
+        else background = BPC_DATA_RO;
+
+        new = g_binary_portion_new(background);
+
+        sprintf(desc, "%s %s",
+                _("Segment"),
+                get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type)));
+
+        g_binary_portion_set_desc(new, desc);
+
+        g_binary_portion_set_values(new,
+                                    ELF_PHDR(format, phdr, p_offset),
+                                    ELF_PHDR(format, phdr, p_filesz),
+                                    ELF_PHDR(format, phdr, p_vaddr));
+
+        rights = PAC_NONE;
+        if (p_flags & PF_R) rights |= PAC_READ;
+        if (p_flags & PF_W) rights |= PAC_WRITE;
+        if (p_flags & PF_X) rights |= PAC_EXEC;
+
+        g_binary_portion_set_rights(new, rights);
+
+        g_binary_portion_include(raw, new);
+
+    }
+#endif
+
+    /* Inclusion des sections, si possible... */
+
+    has_strings = find_elf_section_by_index(format,
+                                            ELF_HDR(format, format->header, e_shstrndx),
+                                            &strings);
+
+    for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++)
+    {
+        if (!find_elf_section_by_index(format, i, &section))
+            continue;
+
+        sh_flags = ELF_SHDR(format, section, sh_flags);
+
+        if (sh_flags & SHF_EXECINSTR) background = BPC_CODE;
+        else if (sh_flags & SHF_WRITE) background = BPC_DATA;
+        else background = BPC_DATA_RO;
+
+        new = g_binary_portion_new(background);
+
+        if (has_strings)
+            name = extract_name_from_elf_string_section(format, &strings,
+                                                        ELF_SHDR(format, section, sh_name));
+        else name = NULL;
+
+        if (name != NULL)
+            sprintf(desc, "%s %s", _("Section"), name);
+        else
+            sprintf(desc, "%s ???", _("Section"));
+
+        g_binary_portion_set_desc(new, desc);
+
+        rights = PAC_NONE;
+        if (sh_flags & SHF_ALLOC) rights |= PAC_READ;
+        if (sh_flags & SHF_WRITE) rights |= PAC_WRITE;
+        if (sh_flags & SHF_EXECINSTR) rights |= PAC_EXEC;
+
+        g_binary_portion_set_rights(new, rights);
+
+        g_binary_portion_set_values(new,
+                                    ELF_SHDR(format, section, sh_offset),
+                                    ELF_SHDR(format, section, sh_size),
+                                    ELF_SHDR(format, section, sh_addr));
+
+        g_binary_portion_include(raw, new);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = informations chargées à consulter.                  *
 *                count  = quantité de zones listées. [OUT]                    *
 *                                                                             *
 *  Description : Fournit les références aux zones binaires à analyser.        *
diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h
index dda1b1c..831e4ff 100644
--- a/src/format/elf/elf_def.h
+++ b/src/format/elf/elf_def.h
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * elf_def.h - liste des structures et constantes utilisées par le format ELF
  *
- * Copyright (C) 2009-2010 Cyrille Bagard
+ * Copyright (C) 2009-2013 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -178,6 +178,28 @@ typedef union _elf_phdr
 
 #define ELF_SIZEOF_PHDR(fmt) (fmt->is_32b ? sizeof(elf32_phdr) : sizeof(elf64_phdr))
 
+/* Valeurs possibles pour p_type */
+
+#define PT_NULL         0                   /* Program header table entry unused */
+#define PT_LOAD         1                   /* Loadable program segment */
+#define PT_DYNAMIC      2                   /* Dynamic linking information */
+#define PT_INTERP       3                   /* Program interpreter */
+#define PT_NOTE         4                   /* Auxiliary information */
+#define PT_SHLIB        5                   /* Reserved */
+#define PT_PHDR         6                   /* Entry for header table itself */
+#define PT_TLS          7                   /* Thread-local storage segment */
+#define PT_NUM          8                   /* Number of defined types */
+#define PT_LOOS         0x60000000          /* Start of OS-specific */
+#define PT_GNU_EH_FRAME 0x6474e550          /* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK    0x6474e551          /* Indicates stack executability */
+#define PT_GNU_RELRO    0x6474e552          /* Read-only after relocation */
+#define PT_LOSUNW       0x6ffffffa
+#define PT_SUNWBSS      0x6ffffffa          /* Sun Specific segment */
+#define PT_SUNWSTACK    0x6ffffffb          /* Stack segment */
+#define PT_HISUNW       0x6fffffff
+#define PT_HIOS         0x6fffffff          /* End of OS-specific */
+#define PT_LOPROC       0x70000000          /* Start of processor-specific */
+#define PT_HIPROC       0x7fffffff          /* End of processor-specific */
 
 /* Valeurs possibles pour p_flags */
 
@@ -246,6 +268,7 @@ typedef union _elf_shdr
 
 /* Valeurs possibles pour sh_flags */
 
+#define SHF_WRITE       (1 << 0)            /* Accessible en écriture      */
 #define SHF_ALLOC       (1 << 1)            /* Copie en mémoire pdt l'exec.*/
 #define SHF_EXECINSTR   (1 << 2)            /* Section exécutable          */
 #define SHF_STRINGS     (1 << 5)            /* Contient des chaînes ('\0') */
diff --git a/src/format/elf/program.c b/src/format/elf/program.c
index f55b7c7..48d6d19 100644
--- a/src/format/elf/program.c
+++ b/src/format/elf/program.c
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * program.c - gestion des en-têtes de programme d'un ELF
  *
- * Copyright (C) 2010 Cyrille Bagard
+ * Copyright (C) 2010-2013 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -30,6 +30,55 @@
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : p_type = type associé à un en-tête de programme.             *
+*                                                                             *
+*  Description : Fournit la description humaine d'un type de segment ELF.     *
+*                                                                             *
+*  Retour      : Désignation prête à emploi.                                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *get_elf_program_type_desc(uint32_t p_type)
+{
+    const char *result;                     /* Description à renvoyer      */
+
+#define MAKE_STRING_FROM_PT(pt) case pt: result = #pt; break;
+
+    switch(p_type)
+    {
+        MAKE_STRING_FROM_PT(PT_NULL);
+        MAKE_STRING_FROM_PT(PT_LOAD);
+        MAKE_STRING_FROM_PT(PT_DYNAMIC);
+        MAKE_STRING_FROM_PT(PT_INTERP);
+        MAKE_STRING_FROM_PT(PT_NOTE);
+        MAKE_STRING_FROM_PT(PT_SHLIB);
+        MAKE_STRING_FROM_PT(PT_PHDR);
+        MAKE_STRING_FROM_PT(PT_TLS);
+        MAKE_STRING_FROM_PT(PT_NUM);
+        MAKE_STRING_FROM_PT(PT_LOOS);
+        MAKE_STRING_FROM_PT(PT_GNU_EH_FRAME);
+        MAKE_STRING_FROM_PT(PT_GNU_STACK);
+        MAKE_STRING_FROM_PT(PT_GNU_RELRO);
+        MAKE_STRING_FROM_PT(PT_LOSUNW);
+        MAKE_STRING_FROM_PT(PT_SUNWSTACK);
+        MAKE_STRING_FROM_PT(PT_HIOS);
+        MAKE_STRING_FROM_PT(PT_LOPROC);
+        MAKE_STRING_FROM_PT(PT_HIPROC);
+
+        default:
+            result = "PT_???";
+            break;
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : format  = description de l'exécutable à consulter.           *
 *                index   = indice de la section recherchée.                   *
 *                program = ensemble d'informations à faire remonter. [OUT]    *
diff --git a/src/format/elf/program.h b/src/format/elf/program.h
index 1718ca7..276e720 100644
--- a/src/format/elf/program.h
+++ b/src/format/elf/program.h
@@ -2,7 +2,7 @@
 /* OpenIDA - Outil d'analyse de fichiers binaires
  * program.h - prototypes pour la gestion des en-têtes de programme d'un ELF
  *
- * Copyright (C) 2010 Cyrille Bagard
+ * Copyright (C) 2010-2013 Cyrille Bagard
  *
  *  This file is part of OpenIDA.
  *
@@ -30,6 +30,9 @@
 
 
 
+/* Fournit la description humaine d'un type de segment ELF. */
+const char *get_elf_program_type_desc(uint32_t);
+
 /* Recherche un programme donné au sein de binaire par indice. */
 bool find_elf_program_by_index(const GElfFormat *, uint16_t, elf_phdr *);
 
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index df1b613..50750ae 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -28,6 +28,9 @@
 #include <string.h>
 
 
+#include <i18n.h>
+
+
 #include "elf-int.h"
 #include "helper_x86.h"
 #include "section.h"
@@ -38,9 +41,6 @@
 
 
 
-#define _(str) str
-
-
 
 
 /* Récupère la désignation d'un symbole donné. */
diff --git a/src/format/executable-int.h b/src/format/executable-int.h
index 49b5275..6b843a5 100644
--- a/src/format/executable-int.h
+++ b/src/format/executable-int.h
@@ -38,6 +38,9 @@ typedef FormatTargetMachine (* get_target_machine_fc) (const GExeFormat *);
 /* Fournit l'adresse mémoire du point d'entrée du programme. */
 typedef vmpa_t (* get_entry_point_fc) (const GExeFormat *);
 
+/* Etend la définition des portions au sein d'un binaire. */
+typedef void (* refine_portions_fc) (const GExeFormat *, GBinPortion *);
+
 /* Fournit les références aux zones de code à analyser. */
 typedef GBinPart ** (* get_parts_fc) (const GExeFormat *, size_t *);
 
@@ -57,11 +60,14 @@ struct _GExeFormat
 
     get_target_machine_fc get_machine;      /* Architecture ciblée         */
     get_entry_point_fc get_entry_point;     /* Obtention du point d'entrée */
+    refine_portions_fc refine_portions;     /* Décrit les portions binaires*/
     get_parts_fc get_parts;                 /* Liste des parties binaires  */
 
     translate_addr_fc translate_addr;       /* Correspondance addr -> pos  */
     translate_off_fc translate_off;         /* Correspondance pos -> addr  */
 
+    GBinPortion *portions;                  /* Morceaux binaires distincts */
+
 };
 
 /* Format d'exécutable générique (classe) */
diff --git a/src/format/executable.c b/src/format/executable.c
index 2d7c185..13482c0 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -126,6 +126,35 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *format)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : format = description de l'exécutable à consulter.            *
+*                                                                             *
+*  Description : Décrit les différentes portions qui composent le binaire.    *
+*                                                                             *
+*  Retour      : Défintions de zones.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinPortion *g_exe_format_get_portions(GExeFormat *format)
+{
+    if (format->portions == NULL)
+    {
+        format->portions = g_binary_portion_new(BPC_RAW);
+        g_binary_portion_set_values(format->portions, 0, G_BIN_FORMAT(format)->length, 0);
+
+        if (format->refine_portions != NULL)
+            format->refine_portions(format, format->portions);
+
+    }
+
+    return format->portions;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : format = informations chargées à consulter.                  *
 *                count  = quantité de zones listées. [OUT]                    *
 *                                                                             *
diff --git a/src/format/executable.h b/src/format/executable.h
index d4f2645..2831696 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -29,6 +29,7 @@
 
 
 #include "part.h"
+#include "../glibext/gbinportion.h"
 
 
 
@@ -74,6 +75,9 @@ FormatTargetMachine g_exe_format_get_target_machine(const GExeFormat *);
 /* Fournit l'adresse mémoire du point d'entrée du programme. */
 vmpa_t g_exe_format_get_entry_point(const GExeFormat *);
 
+/* Décrit les différentes portions qui composent le binaire. */
+GBinPortion *g_exe_format_get_portions(GExeFormat *);
+
 /* Fournit les références aux zones binaires à analyser. */
 GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *);
 
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index b6f100b..e5c1a46 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -7,6 +7,7 @@ libglibext_la_SOURCES =					\
 	chrysamarshal.h chrysamarshal.c		\
 	delayed-int.h						\
 	delayed.h delayed.c					\
+	gbinportion.h gbinportion.c			\
 	gbufferline.h gbufferline.c			\
 	gbuffersegment.h gbuffersegment.c	\
 	gcodebuffer.h gcodebuffer.c			\
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
new file mode 100644
index 0000000..8272e55
--- /dev/null
+++ b/src/glibext/gbinportion.c
@@ -0,0 +1,938 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * binportion.c - représentation graphique de portions de binaire
+ *
+ * Copyright (C) 2013 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 "gbinportion.h"
+
+
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include <i18n.h>
+
+
+#include "../common/extstr.h"
+
+
+
+/* --------------------------- COULEURS DE REPRESENTATION --------------------------- */
+
+
+/* Information sur une colorisation de portion */
+typedef struct _portion_color
+{
+    bp_color_t code;                        /* Identifiant pour les usages */
+    char *name;                             /* Désignation humaine         */
+
+    double red;                             /* Taux de rouge               */
+    double green;                           /* Taux de vert                */
+    double blue;                            /* Taux de bleu                */
+    double alpha;                           /* Transparence                */
+
+} portion_color;
+
+
+/* Mémoire centrale... */
+static portion_color *_portion_colors = NULL;
+static size_t _portion_colors_count = 0;
+
+
+/* Compare deux enregistrements de couleur pour portions. */
+static int compare_portion_colors(const portion_color *, const portion_color *);
+
+/* Tente de retrouver une couleur de portion donnée. */
+static portion_color *find_binary_portion_color(bp_color_t);
+
+
+
+/* ------------------------------- PORTION DE BINAIRE ------------------------------- */
+
+
+/* Portion de données binaires quelconques (instance) */
+struct _GBinPortion
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GBinPortion *container;                 /* Portion parente ou racine   */
+
+    bp_color_t code;                        /* Code de la couleur de fond  */
+
+    char *desc;                             /* Désignation humaine         */
+
+    off_t offset;                           /* Position physique           */
+    off_t size;                             /* Taille de la partie         */
+    vmpa_t addr;                            /* Adresse associée            */
+
+    PortionAccessRights rights;             /* Droits d'accès              */
+
+    GBinPortion **sub_portions;             /* Portions incluses           */
+    size_t sub_count;                       /* Quantité d'inclusions       */
+
+#ifdef DEBUG
+    unsigned int valid;                     /* Instructions reconnues      */
+    unsigned int db;                        /* Instructions non traduites  */
+#endif
+
+};
+
+/* Portion de données binaires quelconques (classe) */
+struct _GBinPortionClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des blocs de données binaires. */
+static void g_binary_portion_class_init(GBinPortionClass *);
+
+/* Initialise une instance de bloc de données binaires. */
+static void g_binary_portion_init(GBinPortion *);
+
+/* Supprime toutes les références externes. */
+static void g_binary_portion_dispose(GBinPortion *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_binary_portion_finalize(GBinPortion *);
+
+/* Détermine l'aire d'une sous-portion. */
+static bool g_binary_portion_compute_sub_area(GBinPortion *, GBinPortion *, const GdkRectangle *, GdkRectangle *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                             COULEURS DE REPRESENTATION                             */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = échantillon n°1 à comparer.                              *
+*                b = échantillon n°2 à comparer.                              *
+*                                                                             *
+*  Description : Compare deux enregistrements de couleur pour portions.       *
+*                                                                             *
+*  Retour      : Bilan de la comparaison.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int compare_portion_colors(const portion_color *a, const portion_color *b)
+{
+    int result;                             /* Bilan à renvoyer            */
+
+    if (a->code < b->code)
+        result = -1;
+
+    else if (a->code > b->code)
+        result = 1;
+
+    else
+        result = 0;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : name  = désignation humaine de la couleur.                   *
+*                red   = taux de rouge dans la couleur.                       *
+*                gren  = taux de vert dans la couleur.                        *
+*                blue  = taux de bleu dans la couleur.                        *
+*                alpha = transparence de la couleur.                          *
+*                                                                             *
+*  Description : Enregistre une couleur pour le dessin de portions.           *
+*                                                                             *
+*  Retour      : true si l'enregistrement a pu être effectué, false sinon.    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_binary_portion_color(const char *name, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
+{
+    bp_color_t code;                        /* Accès rapide à la couleur   */
+    portion_color *new;                     /* Nouvel élément à constituer */
+
+    /* Vérification de l'unicité des noms */
+
+    code = fnv_64a_hash(name);
+
+    new = find_binary_portion_color(code);
+    if (new != NULL) return false;
+
+    /* Création du nouvel élément */
+
+    _portion_colors = (portion_color *)realloc(_portion_colors,
+                                               ++_portion_colors_count * sizeof(portion_color));
+
+    new = &_portion_colors[_portion_colors_count - 1];
+
+    /* Définition du nouvel élément */
+
+    new->name = strdup(name);
+    new->code = code;
+
+    new->red = red / 255.0;
+    new->green = green / 255.0;
+    new->blue = blue / 255.0;
+    new->alpha = alpha / 255.0;
+
+    /* Actualisation finale par tri */
+
+    qsort(_portion_colors, _portion_colors_count, sizeof(portion_color),
+          (__compar_fn_t)compare_portion_colors);
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : name = désignation humaine de la couleur.                    *
+*                                                                             *
+*  Description : Supprime une couleur pour le dessin de portions.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void unregister_binary_portion_color(const char *name)
+{
+    bp_color_t code;                        /* Accès rapide à la couleur   */
+    portion_color *item;                    /* Elément à retirer           */
+    size_t left;                            /* Quantité à déplacer         */
+
+    code = fnv_64a_hash(name);
+
+    item = find_binary_portion_color(code);
+    if (item == NULL) return;
+
+    free(item->name);
+
+    left = (size_t)(_portion_colors + _portion_colors_count) - (size_t)(item + 1);
+
+    if (left > 0)
+        memmove(item, item + 1, left);
+
+    _portion_colors = (portion_color *)realloc(_portion_colors,
+                                               --_portion_colors_count * sizeof(portion_color));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : code = identifiant de la couleur à retrouver.                *
+*                                                                             *
+*  Description : Tente de retrouver une couleur de portion donnée.            *
+*                                                                             *
+*  Retour      : Caractéristiques de la couleur visée, ou NULL.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static portion_color *find_binary_portion_color(bp_color_t code)
+{
+    portion_color *result;                  /* Elément trouvé à retourner  */
+
+    result = (portion_color *)bsearch(&code, _portion_colors,
+                                      _portion_colors_count, sizeof(portion_color),
+                                      (__compar_fn_t)compare_portion_colors);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Enregistre les couleurs de base pour le dessin des portions. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void init_binary_portion_colors(void)
+{
+    register_binary_portion_color(BPC_RAW, 0, 0, 0, 255);
+    register_binary_portion_color(BPC_CODE, 0, 0, 255, 255);
+    register_binary_portion_color(BPC_DATA, 255, 255, 0, 255);
+    register_binary_portion_color(BPC_DATA_RO, 0, 255, 0, 255);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Supprime les couleurs de base pour le dessin des portions.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void exit_binary_portion_colors(void)
+{
+    while (_portion_colors_count > 0)
+        unregister_binary_portion_color(_portion_colors[0].name);
+
+    if (_portion_colors != NULL)
+    {
+        free(_portion_colors);
+        _portion_colors = NULL;
+    }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                                 PORTION DE BINAIRE                                 */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour les blocs de données. */
+G_DEFINE_TYPE(GBinPortion, g_binary_portion, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des blocs de données binaires.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_portion_class_init(GBinPortionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_portion_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_binary_portion_finalize;
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de bloc de données binaires.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_portion_init(GBinPortion *portion)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_portion_dispose(GBinPortion *portion)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < portion->sub_count; i++)
+        g_object_unref(G_OBJECT(portion->sub_portions[i]));
+
+    G_OBJECT_CLASS(g_binary_portion_parent_class)->dispose(G_OBJECT(portion));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_portion_finalize(GBinPortion *portion)
+{
+    if (portion->desc != NULL)
+        free(portion->desc);
+
+    if (portion->sub_portions != NULL)
+        free(portion->sub_portions);
+
+    G_OBJECT_CLASS(g_binary_portion_parent_class)->finalize(G_OBJECT(portion));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : code = désignation humaine de la couleur de fond.            *
+*                                                                             *
+*  Description : Crée une description de partie de code vierge.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinPortion *g_binary_portion_new(const char *code)
+{
+    GBinPortion *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_BIN_PORTION, NULL);
+
+    result->code = fnv_64a_hash(code);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                desc    = nom à donner à la partie.                          *
+*                                                                             *
+*  Description : Attribue une description humaine à une partie de code.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_portion_set_desc(GBinPortion *portion, const char *desc)
+{
+    if (portion->desc != NULL) free(portion->desc);
+
+    portion->desc = strdup(desc);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à consulter.                 *
+*                                                                             *
+*  Description : Fournit la description attribuée à une partie de code.       *
+*                                                                             *
+*  Retour      : Nom donné à la partie.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_binary_portion_get_desc(const GBinPortion *portion)
+{
+    return portion->desc;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                offset  = position de la section à conserver.                *
+*                size    = taille de la section à conserver.                  *
+*                addr    = adresse de la section à conserver.                 *
+*                                                                             *
+*  Description : Définit les valeurs utiles d'une partie de code.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_portion_set_values(GBinPortion *portion, off_t offset, off_t size, vmpa_t addr)
+{
+    portion->offset = offset;
+    portion->size = size;
+    portion->addr = addr;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                rights  = droits d'accès de la partie.                       *
+*                                                                             *
+*  Description : Définit les droits associés à une partie de code.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_portion_set_rights(GBinPortion *portion, PortionAccessRights rights)
+{
+    portion->rights = rights;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à consulter.                 *
+*                                                                             *
+*  Description : Fournit les droits associés à une partie de code.            *
+*                                                                             *
+*  Retour      : Droits d'accès de la partie.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion)
+{
+    return portion->rights;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                sub     = portion à inclure dans la définition courante.     *
+*                                                                             *
+*  Description : Procède à l'inclusion d'une portion dans une autre.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub)
+{
+    portion->sub_portions = (GBinPortion **)realloc(portion->sub_portions,
+                                                    ++portion->sub_count * sizeof(GBinPortion *));
+
+    portion->sub_portions[portion->sub_count - 1] = sub;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion  = portion mère à consulter.                         *
+*                sub      = portion fille à traiter.                          *
+*                area     = étendue de représentation de la portion mère.     *
+*                sub_area = étendue de représentation de la portion fille.    *
+*                                                                             *
+*  Description : Détermine l'aire d'une sous-portion.                         *
+*                                                                             *
+*  Retour      : true si la sous-surface a été calculée correctement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_portion_compute_sub_area(GBinPortion *portion, GBinPortion *sub, const GdkRectangle *area, GdkRectangle *sub_area)
+{
+    /* On saute les portions comme le segment GNU_STACK... */
+    if (sub->size == 0) return false;
+
+    sub_area->y = area->y;
+    sub_area->height = area->height;
+
+    sub_area->x = area->x + (sub->offset * area->width) / portion->size;
+    sub_area->width = (sub->size * area->width) / portion->size;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                x       = abscisse du point de recherche.                    *
+*                y       = ordonnée du point de recherche.                    *
+*                area    = étendue de portion mère, puis celle trouvée. [OUT] *
+*                                                                             *
+*  Description : Recherche la portion présente à un point donné.              *
+*                                                                             *
+*  Retour      : Portion trouvée à l'endroit indiqué.                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRectangle *area)
+{
+    GBinPortion *result;                    /* Portion à retourner         */
+    size_t i;                               /* Boucle de parcours          */
+    GBinPortion *sub;                       /* Portion incluse à traiter   */
+    GdkRectangle sub_area;                  /* Etendue d'une sous-portion  */
+
+    result = NULL;
+
+    for (i = 0; i < portion->sub_count && !result; i++)
+    {
+        sub = portion->sub_portions[i];
+
+        if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
+            continue;
+
+        if (sub_area.x <= x && x < (sub_area.x + sub_area.width))
+        {
+            result = sub;
+            *area = sub_area;
+        }
+
+    }
+
+    if (result == NULL)
+        result = portion;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                addr    = adresse du point de recherche.                     *
+*                area    = étendue de portion mère, puis celle trouvée. [OUT] *
+*                                                                             *
+*  Description : Recherche la portion présente à une adresse donnée.          *
+*                                                                             *
+*  Retour      : Portion trouvée à l'endroit indiqué.                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, vmpa_t addr, GdkRectangle *area)
+{
+    GBinPortion *result;                    /* Portion à retourner         */
+    size_t i;                               /* Boucle de parcours #1       */
+    GBinPortion *sub;                       /* Portion incluse à traiter   */
+    GdkRectangle sub_area;                  /* Etendue d'une sous-portion  */
+    size_t j;                               /* Boucle de parcours #2       */
+
+    result = NULL;
+
+    for (i = 0; i < portion->sub_count && !result; i++)
+    {
+        sub = portion->sub_portions[i];
+
+        /* Portion non allouée en mémoire -> adresse nulle ; on écarte */
+        if (sub->addr == 0)
+            continue;
+
+        if (addr < sub->addr || addr >= (sub->addr + sub->size))
+            continue;
+
+        if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
+            continue;
+
+        for (j = 0; j < sub->sub_count && !result; j++)
+            result = g_binary_portion_find_at_addr(sub->sub_portions[j], addr, &sub_area);
+
+        if (result == NULL)
+        {
+            result = sub;
+            *area = sub_area;
+        }
+
+    }
+
+    if (result == NULL)
+        result = portion;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                x       = abscisse du point de recherche.                    *
+*                area    = étendue de représentation de la portion mère.      *
+*                addr    = adresse correspondante. [OUT]                      *
+*                                                                             *
+*  Description : Fournit la position correspondant à une adresse donnée.      *
+*                                                                             *
+*  Retour      : Succès de la traduction.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_portion_get_addr_from_pos(GBinPortion *portion, gint x, const GdkRectangle *area, vmpa_t *addr)
+{
+    GdkRectangle owner_area;                /* Aire de contenance          */
+    GBinPortion *owner;                     /* Conteneur propriétaire      */
+
+    owner_area = *area;
+
+    owner = g_binary_portion_find_at_pos(portion, x, &owner_area);
+    if (owner == NULL) return false;
+
+    *addr = owner->addr + (owner->size * (x - owner_area.x)) / owner_area.width;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                addr    = adresse du point de recherche.                     *
+*                area    = étendue de représentation de la portion mère.      *
+*                x       = position correspondante. [OUT]                     *
+*                                                                             *
+*  Description : Fournit l'adresse correspondant à une position donnée.       *
+*                                                                             *
+*  Retour      : Succès de la traduction.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_portion_get_pos_from_addr(GBinPortion *portion, vmpa_t addr, const GdkRectangle *area, gint *x)
+{
+    GdkRectangle owner_area;                /* Aire de contenance          */
+    GBinPortion *owner;                     /* Conteneur propriétaire      */
+    vmpa_t diff;                            /* Décallage à appliquer       */
+
+    owner_area = *area;
+
+    owner = g_binary_portion_find_at_addr(portion, addr, &owner_area);
+    if (owner == NULL) return false;
+
+    diff = addr - owner->addr;
+
+    *x = owner_area.x + (diff * owner_area.width) / owner->size;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à mettre à jour.             *
+*                x       = abscisse du point de recherche.                    *
+*                y       = ordonnée du point de recherche.                    *
+*                area    = étendue de représentation de la portion mère.      *
+*                tooltip = astuce à compléter. [OUT]                          *
+*                                                                             *
+*  Description : Prépare une astuce concernant une portion pour son affichage.*
+*                                                                             *
+*  Retour      : TRUE pour valider l'affichage.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+gboolean g_binary_portion_query_tooltip(GBinPortion *portion, gint x, gint y, const GdkRectangle *area, GtkTooltip *tooltip)
+{
+    GBinPortion *selected;                  /* Portion à décrire ici       */
+    char *markup;                           /* Description à construire    */
+    GBinPortion *iter;                      /* Remontée hiérarchique       */
+    char value[2 * VMPA_MAX_SIZE];          /* Traduction en texte         */
+
+    selected = g_binary_portion_find_at_pos(portion, x, (GdkRectangle []) { *area });
+
+    /* Nom */
+
+    if (selected->desc != NULL)
+    {
+        markup = strdup("<b>");
+        markup = stradd(markup, selected->desc);
+        markup = stradd(markup, "</b>\n");
+
+        for (iter = selected->container; iter != NULL; iter = iter->container)
+            if (iter->desc != NULL)
+            {
+                markup = stradd(markup, selected->desc);
+                markup = stradd(markup, "\n");
+            }
+
+        markup = stradd(markup, "\n");
+
+    }
+    else markup = strdup("");
+
+    markup = stradd(markup, "taille : ");
+    snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->size));
+    markup = stradd(markup, value);
+    markup = stradd(markup, "\n");
+
+    /* Localisation */
+
+    markup = stradd(markup, "<b>");
+    markup = stradd(markup, _("Localisation"));
+    markup = stradd(markup, "</b>\n");
+
+    markup = stradd(markup, _("physical: from "));
+    snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->offset));
+    markup = stradd(markup, value);
+    markup = stradd(markup, _(" to "));
+    snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->offset + selected->size));
+    markup = stradd(markup, value);
+    markup = stradd(markup, "\n");
+
+    markup = stradd(markup, _("memory: from "));
+    snprintf(value, 2 * VMPA_MAX_SIZE, VMPA_FMT_LONG, VMPA_CAST(selected->addr));
+    markup = stradd(markup, value);
+    markup = stradd(markup, _(" to "));
+    snprintf(value, 2 * VMPA_MAX_SIZE, VMPA_FMT_LONG, VMPA_CAST(selected->addr + selected->size));
+    markup = stradd(markup, value);
+    markup = stradd(markup, "\n\n");
+
+    /* Droits d'accès */
+
+    markup = stradd(markup, "<b>");
+    markup = stradd(markup, _("Rights"));
+    markup = stradd(markup, "</b>\n");
+
+    snprintf(value, 2 * VMPA_MAX_SIZE, "%s%s%s",
+             selected->rights & PAC_READ ? "r" : "-",
+             selected->rights & PAC_WRITE ? "w" : "-",
+             selected->rights & PAC_EXEC ? "x" : "-");
+
+    markup = stradd(markup, value);
+
+    /* Impression finale */
+
+    gtk_tooltip_set_markup(tooltip, markup);
+    free(markup);
+
+    return TRUE;
+
+}
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : portion = description de partie à consulter.                 *
+*                cr      = contexte graphique pour le dessin.                 *
+*                area    = étendue mise à disposition.                        *
+*                                                                             *
+*  Description : Représente la portion sur une bande dédiée.                  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_portion_draw(GBinPortion *portion, cairo_t *cr, const GdkRectangle *area)
+{
+    portion_color *color;                   /* Couleur du fond             */
+    size_t i;                               /* Boucle de parcours          */
+    GBinPortion *sub;                       /* Portion incluse à montrer   */
+    GdkRectangle sub_area;                  /* Etendue d'une sous-portion  */
+
+    /* Dessin de la portion courante */
+
+    cairo_set_line_width(cr, 1.0);
+
+    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+
+    color = find_binary_portion_color(portion->code);
+
+    if (color != NULL)
+        cairo_set_source_rgba(cr,
+                              color->red, color->green, color->blue,
+                              color->alpha);
+
+    cairo_rectangle(cr, area->x, area->y, area->width, area->height);
+    cairo_fill(cr);
+
+    if (color != NULL)
+        cairo_set_source_rgba(cr,
+                              color->red * 0.7, color->green * 0.7, color->blue * 0.7,
+                              color->alpha);
+
+    cairo_rectangle(cr, area->x, area->y, area->width, area->height);
+    cairo_stroke(cr);
+
+    /* Dessin des portions incluses */
+
+    sub_area.y = area->y;
+    sub_area.height = area->height;
+
+    for (i = 0; i < portion->sub_count; i++)
+    {
+        sub = portion->sub_portions[i];
+
+        if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area))
+            continue;
+
+        g_binary_portion_draw(sub, cr, &sub_area);
+
+    }
+
+}
diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h
new file mode 100644
index 0000000..826d65f
--- /dev/null
+++ b/src/glibext/gbinportion.h
@@ -0,0 +1,148 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * binportion.h - prototypes pour la représentation graphique de portions de binaire
+ *
+ * Copyright (C) 2013 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 _GLIBEXT_BINPORTION_H
+#define _GLIBEXT_BINPORTION_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <gtk/gtk.h>
+
+
+#include "../arch/archbase.h"
+#include "../common/fnv1a.h"
+
+
+
+/* --------------------------- COULEURS DE REPRESENTATION --------------------------- */
+
+
+/* Converion code -> identifiant unique */
+typedef fnv64_t bp_color_t;
+
+/* Identifiant non valide */
+#define BP_NO_COLOR 0
+
+/* Identifiant pour la transparence */
+#define BP_INHERIT_COLOR 1
+
+
+
+#define BPC_RAW             "raw"
+#define BPC_CODE            "code"
+#define BPC_DATA            "data"
+#define BPC_DATA_RO         "data-ro"
+#define BPC_DISASS_ERROR    "disassembly-error"
+
+
+
+
+
+/* Enregistre une couleur pour le dessin de portions. */
+bool register_binary_portion_color(const char *, uint8_t, uint8_t, uint8_t, uint8_t);
+
+/* Supprime une couleur pour le dessin de portions. */
+void unregister_binary_portion_color(const char *);
+
+/* Enregistre les couleurs de base pour le dessin des portions. */
+void init_binary_portion_colors(void);
+
+/* Supprime les couleurs de base pour le dessin des portions. */
+void exit_binary_portion_colors(void);
+
+
+
+
+
+#define G_TYPE_BIN_PORTION                (g_binary_portion_get_type())
+#define G_BIN_PORTION(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BIN_PORTION, GBinPortion))
+#define G_IS_BIN_PORTION(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BIN_PORTION))
+#define G_BIN_PORTION_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BIN_PORTION, GBinPortionClass))
+#define G_IS_BIN_PORTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BIN_PORTION))
+#define G_BIN_PORTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_PORTION, GBinPortionClass))
+
+
+/* Portion de données binaires quelconques (instance) */
+typedef struct _GBinPortion GBinPortion;
+
+/* Portion de données binaires quelconques (classe) */
+typedef struct _GBinPortionClass GBinPortionClass;
+
+
+/* Droits d'accès à une portion */
+typedef enum _PortionAccessRights
+{
+    PAC_NONE    = (0 << 0),                 /* Aucun                       */
+    PAC_READ    = (1 << 0),                 /* Lecture                     */
+    PAC_WRITE   = (1 << 1),                 /* Ecriture                    */
+    PAC_EXEC    = (1 << 2)                  /* Exécution                   */
+
+} PortionAccessRights;
+
+
+/* Indique le type défini par la GLib pour les blocs de données. */
+GType g_binary_portion_get_type(void);
+
+/* Crée une description de partie de code vierge. */
+GBinPortion *g_binary_portion_new(const char *);
+
+/* Attribue une description humaine à une partie de code. */
+void g_binary_portion_set_desc(GBinPortion *, const char *);
+
+/* Fournit la description attribuée à une partie de code. */
+const char *g_binary_portion_get_desc(const GBinPortion *);
+
+/* Définit les valeurs utiles d'une partie de code. */
+void g_binary_portion_set_values(GBinPortion *, off_t, off_t, vmpa_t);
+
+/* Définit les droits associés à une partie de code. */
+void g_binary_portion_set_rights(GBinPortion *, PortionAccessRights);
+
+/* Fournit les droits associés à une partie de code. */
+PortionAccessRights g_binary_portion_get_rights(const GBinPortion *);
+
+/* Procède à l'inclusion d'une portion dans une autre. */
+void g_binary_portion_include(GBinPortion *, GBinPortion *);
+
+/* Recherche la portion présente à un point donné. */
+GBinPortion *g_binary_portion_find_at_pos(GBinPortion *, gint, GdkRectangle *);
+
+/* Recherche la portion présente à une adresse donnée. */
+GBinPortion *g_binary_portion_find_at_addr(GBinPortion *, vmpa_t, GdkRectangle *);
+
+/* Fournit la position correspondant à une adresse donnée. */
+bool g_binary_portion_get_addr_from_pos(GBinPortion *, gint, const GdkRectangle *, vmpa_t *);
+
+/* Fournit l'adresse correspondant à une position donnée. */
+bool g_binary_portion_get_pos_from_addr(GBinPortion *, vmpa_t, const GdkRectangle *, gint *);
+
+/* Prépare une astuce concernant une portion pour son affichage. */
+gboolean g_binary_portion_query_tooltip(GBinPortion *, gint, gint, const GdkRectangle *, GtkTooltip *);
+
+/* Représente la portion sur une bande dédiée. */
+void g_binary_portion_draw(GBinPortion *, cairo_t *, const GdkRectangle *);
+
+
+
+#endif  /* _GLIBEXT_BINPORTION_H */
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 6478b87..18678b8 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libgtkext.la
 
 libgtkext_la_SOURCES =					\
 	easygtk.h easygtk.c					\
+	gtkbinarystrip.h gtkbinarystrip.c	\
 	gtkextstatusbar.h gtkextstatusbar.c	\
 	gtkblockview.h gtkblockview.c		\
 	gtkbufferview-int.h					\
diff --git a/src/gtkext/graph/nodes/flow.c b/src/gtkext/graph/nodes/flow.c
index fad520d..6bb2617 100644
--- a/src/gtkext/graph/nodes/flow.c
+++ b/src/gtkext/graph/nodes/flow.c
@@ -581,6 +581,10 @@ void g_flow_node_link(GFlowNode *node, GGraphLayout *layout, GGraphNode *nodes)
 
 void g_flow_node_place(const GFlowNode *node, GtkGraphView *view)
 {
+    printf("[put] %p (%d ; %d) - (%d ; %d)\n", node,
+           G_GRAPH_NODE(node)->alloc.x, G_GRAPH_NODE(node)->alloc.y,
+           G_GRAPH_NODE(node)->alloc.width, G_GRAPH_NODE(node)->alloc.height);
+
     gtk_graph_view_put(view, GTK_WIDGET(node->view), &G_GRAPH_NODE(node)->alloc);
 
 }
diff --git a/src/gtkext/graph/nodes/virtual.c b/src/gtkext/graph/nodes/virtual.c
index 48cc1fb..de0e75e 100644
--- a/src/gtkext/graph/nodes/virtual.c
+++ b/src/gtkext/graph/nodes/virtual.c
@@ -473,7 +473,7 @@ static void g_virtual_node_apply_position(GVirtualNode *node)
 {
     gint min;                               /* Valeur minimale rencontrée  */
     size_t i;                               /* Boucle de parcours          */
-    gint pos_x;                             /* Nouvelle position #1        */
+    gint x_pos;                             /* Nouvelle position #1        */
     gint offset;                            /* Décallage à faire suivre    */
 
     g_virtual_node_apply_x_line(node);
@@ -484,8 +484,8 @@ static void g_virtual_node_apply_position(GVirtualNode *node)
 
     for (i = 0; i < node->count; i++)
     {
-        g_graph_node_get_position(node->children[i], &pos_x, NULL);
-        min = MIN(min, pos_x);
+        g_graph_node_get_position(node->children[i], &x_pos, NULL);
+        min = MIN(min, x_pos);
     }
 
     /* Espace pour les liens remontants */
@@ -503,10 +503,14 @@ static void g_virtual_node_apply_position(GVirtualNode *node)
     {
         /* BUG_ON(node->children[i]->alloc.x != UNINITIALIZED_NODE_POS); */
 
-        g_graph_node_get_position(node->children[i], &pos_x, NULL);
-        pos_x += offset;
+        g_graph_node_get_position(node->children[i], &x_pos, NULL);
+
+        printf(" == vapply ==  %p : %d + %d -> %d\n",
+               node->children[i], x_pos, offset, (int)(x_pos + offset));
 
-        g_graph_node_set_x_position(node->children[i], pos_x);
+        x_pos += offset;
+
+        g_graph_node_set_x_position(node->children[i], x_pos);
 
     }
 
diff --git a/src/gtkext/gtkbinarystrip.c b/src/gtkext/gtkbinarystrip.c
new file mode 100644
index 0000000..3f4a6a6
--- /dev/null
+++ b/src/gtkext/gtkbinarystrip.c
@@ -0,0 +1,462 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gtkbinarystrip.c - affichage d'un binaire sous forme de bande
+ *
+ * Copyright (C) 2013 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 "gtkbinarystrip.h"
+
+
+#include "../glibext/chrysamarshal.h"
+
+
+
+/* Affichage d'un binaire en bande (instance) */
+struct _GtkBinaryStrip
+{
+    GtkDrawingArea parent;                  /* A laisser en premier        */
+
+    GLoadedBinary *binary;                  /* Binaire à représenter       */
+    gint display_pos;                       /* Position à l'écran          */
+
+    gint cursor_addr;                       /* Adresse de la position      */
+    gint cursor_pos;                        /* Position à l'écran          */
+
+};
+
+/* Affichage d'un binaire en bande (classe) */
+struct _GtkBinaryStripClass
+{
+    GtkDrawingAreaClass parent;             /* A laisser en premier        */
+
+    void (* select_address) (GtkBinaryStrip *, vmpa_t);
+
+};
+
+
+/* Taille de l'encoche pour la position */
+#define STRIP_MARKER_SIZE 7
+
+
+/* Procède à l'initialisation de l'afficheur générique. */
+static void gtk_binary_strip_class_init(GtkBinaryStripClass *);
+
+/* Procède à l'initialisation de l'afficheur générique. */
+static void gtk_binary_strip_init(GtkBinaryStrip *);
+
+/* Encadre la préparation à l'affichage du composant. */
+static void gtk_binary_strip_realize(GtkWidget *);
+
+/* Réagit à un changement de taille du composant. */
+static void gtk_binary_strip_size_allocate(GtkWidget *, GtkAllocation *);
+
+/* Suit la progression de la souris sur le composant. */
+static gboolean gtk_binary_strip_button_release(GtkWidget *, GdkEventButton *);
+
+/* Met à jour l'affichage du composant d'affichage. */
+static gboolean gtk_binary_strip_expose(GtkWidget *, GdkEventExpose *);
+
+/* Prépare l'affichage d'une astuce. */
+static gboolean gtk_binary_strip_query_tooltip(GtkWidget *, gint, gint, gboolean, GtkTooltip *);
+
+
+
+/* Détermine le type du composant d'affichage générique. */
+G_DEFINE_TYPE(GtkBinaryStrip, gtk_binary_strip, GTK_TYPE_DRAWING_AREA)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe GTK à initialiser.                            *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'afficheur générique.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_binary_strip_class_init(GtkBinaryStripClass *class)
+{
+    GtkWidgetClass *widget_class;           /* Classe de haut niveau       */
+
+    widget_class = GTK_WIDGET_CLASS(class);
+
+    widget_class->realize = gtk_binary_strip_realize;
+    widget_class->size_allocate = gtk_binary_strip_size_allocate;
+    widget_class->button_release_event = gtk_binary_strip_button_release;
+    widget_class->expose_event = gtk_binary_strip_expose;
+    widget_class->query_tooltip = gtk_binary_strip_query_tooltip;
+
+    g_signal_new("select-address",
+                 GTK_TYPE_BINARY_STRIP,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GtkBinaryStripClass, select_address),
+                 NULL, NULL,
+                 g_cclosure_user_marshal_VOID__UINT64,
+                 G_TYPE_NONE, 1, G_TYPE_UINT64);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : strip = composant GTK à initialiser.                         *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'afficheur générique.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_binary_strip_init(GtkBinaryStrip *strip)
+{
+    GObject *object;                        /* Autre version de l'instance */
+    GtkWidget *widget;                      /* Autre version de l'instance */
+
+    object = G_OBJECT(strip);
+    widget = GTK_WIDGET(strip);
+
+    g_object_set(object, "has-tooltip", TRUE, NULL);
+
+    gtk_widget_set_size_request(widget, 400, 30);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un nouveau composant pour l'affichage d'une bande.      *
+*                                                                             *
+*  Retour      : Composant GTK créé.                                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *gtk_binary_strip_new(void)
+{
+    GtkBinaryStrip *result;                 /* Composant à retourner       */
+
+    result = g_object_new(GTK_TYPE_BINARY_STRIP, NULL);
+
+    return GTK_WIDGET(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK à préparer.                           *
+*                                                                             *
+*  Description : Encadre la préparation à l'affichage du composant.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_binary_strip_realize(GtkWidget *widget)
+{
+    GdkCursor *cursor;                      /* Pointeur pour la surface    */
+
+    GTK_WIDGET_CLASS(gtk_binary_strip_parent_class)->realize(widget);
+
+    cursor = gdk_cursor_new(GDK_HAND1);
+    gdk_window_set_cursor(widget->window, cursor);
+    gdk_cursor_unref(cursor);
+
+    gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget     = composant GTK à préparer.                       *
+*                allocation = nouvelle taille à considérer.                   *
+*                                                                             *
+*  Description : Réagit à un changement de taille du composant.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_binary_strip_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+{
+    GtkBinaryStrip *strip;                  /* Autre version du composant  */
+    GExeFormat *format;                     /* Format du binaire           */
+    GBinPortion *portions;                  /* Portions binaires à dessiner*/
+    GdkRectangle area;                      /* Surface du composant        */
+
+    GTK_WIDGET_CLASS(gtk_binary_strip_parent_class)->size_allocate(widget, allocation);
+
+    strip = GTK_BINARY_STRIP(widget);
+
+    if (strip->binary == NULL)
+        return;
+
+    format = g_loaded_binary_get_format(strip->binary);
+    portions = g_exe_format_get_portions(format);
+
+    area.x = 0;
+    area.y = 0;
+    area.width = allocation->width;
+    area.height = allocation->height;
+
+    if (!g_binary_portion_get_pos_from_addr(portions, strip->cursor_addr, &area, &strip->cursor_pos))
+        strip->cursor_pos = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK visé par l'opération.                 *
+*                event  = informations liées à l'événement.                   *
+*                                                                             *
+*  Description : Suit la progression de la souris sur le composant.           *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_binary_strip_button_release(GtkWidget *widget, GdkEventButton *event)
+{
+    GtkBinaryStrip *strip;                  /* Autre version du composant  */
+    GExeFormat *format;                     /* Format du binaire           */
+    GBinPortion *portions;                  /* Portions binaires à dessiner*/
+    GdkRectangle area;                      /* Surface du composant        */
+    vmpa_t addr;                            /* Adresse à sélectionner      */
+
+    if (event->x < 0 || event->y < 0)
+        return FALSE;
+    if (event->x >= widget->allocation.width || event->y >= widget->allocation.height)
+        return FALSE;
+
+    strip = GTK_BINARY_STRIP(widget);
+    format = g_loaded_binary_get_format(strip->binary);
+    portions = g_exe_format_get_portions(format);
+
+    area.x = 0;
+    area.y = 0;
+    area.width = widget->allocation.width;
+    area.height = widget->allocation.height;
+
+    if (g_binary_portion_get_addr_from_pos(portions, event->x, &area, &addr))
+    {
+        strip->cursor_addr = addr;
+        strip->cursor_pos = event->x;
+
+        gtk_widget_queue_draw(GTK_WIDGET(strip));
+
+        g_signal_emit_by_name(strip, "select-address", addr);
+
+    }
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK à redessiner.                         *
+*                event  = informations liées à l'événement.                   *
+*                                                                             *
+*  Description : Met à jour l'affichage du composant d'affichage.             *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_binary_strip_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+    GtkBinaryStrip *strip;                  /* Autre vision du composant   */
+    cairo_t *cr;                            /* Contexte graphique          */
+    GExeFormat *format;                     /* Format du binaire           */
+    GBinPortion *portions;                  /* Portions binaires à dessiner*/
+    GdkRectangle full;                      /* Taille totale de la surface */
+
+    strip = GTK_BINARY_STRIP(widget);
+
+    if (strip->binary == NULL)
+        return FALSE;
+
+    format = g_loaded_binary_get_format(strip->binary);
+    portions = g_exe_format_get_portions(format);
+
+    cr = gdk_cairo_create(widget->window);
+
+    cairo_rectangle(cr,
+                    event->area.x, event->area.y,
+                    event->area.width, event->area.height);
+    cairo_clip(cr);
+
+    /* Dessin des portions de binaire */
+
+    full.x = 0;
+    full.y = 1;
+    full.width = widget->allocation.width;
+    full.height = widget->allocation.height - 1;
+
+    g_binary_portion_draw(portions, cr, &full);
+
+    /* Dessin de la position */
+
+    if (strip->cursor_pos != -1)
+    {
+        cairo_set_line_width(cr, 1);
+
+        cairo_set_source_rgb(cr, 
+                             (1.0 * widget->style->bg[GTK_STATE_NORMAL].red) / USHRT_MAX,
+                             (1.0 * widget->style->bg[GTK_STATE_NORMAL].green) / USHRT_MAX,
+                             (1.0 * widget->style->bg[GTK_STATE_NORMAL].blue )/ USHRT_MAX);
+
+        cairo_move_to(cr, strip->cursor_pos, STRIP_MARKER_SIZE);
+        cairo_line_to(cr, strip->cursor_pos + STRIP_MARKER_SIZE, 0);
+        cairo_line_to(cr, strip->cursor_pos - STRIP_MARKER_SIZE, 0);
+        cairo_line_to(cr, strip->cursor_pos, STRIP_MARKER_SIZE);
+        cairo_fill(cr);
+
+        cairo_move_to(cr, strip->cursor_pos, full.height - STRIP_MARKER_SIZE + 1);
+        cairo_line_to(cr, strip->cursor_pos + STRIP_MARKER_SIZE, full.height + 1);
+        cairo_line_to(cr, strip->cursor_pos - STRIP_MARKER_SIZE, full.height + 1);
+        cairo_line_to(cr, strip->cursor_pos, full.height - STRIP_MARKER_SIZE + 1);
+        cairo_fill(cr);
+
+    }
+
+    /* Clôture */
+
+    cairo_destroy (cr);
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget   = composant GTK visé par l'opération.               *
+*                x        = abscisse de la position du message.               *
+*                y        = ordonnée de la position du message.               *
+*                keyboard = indique une demande suite à obtiention du focus.  *
+*                tooltip  = astuce à compléter. [OUT]                         *
+*                                                                             *
+*  Description : Prépare l'affichage d'une astuce.                            *
+*                                                                             *
+*  Retour      : TRUE pour un affichage validé, FALSE sinon.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean gtk_binary_strip_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip *tooltip)
+{
+    gboolean result;                        /* Bilan à retourner           */
+    GtkBinaryStrip *strip;                  /* Autre version du composant  */
+    GExeFormat *format;                     /* Format du binaire           */
+    GBinPortion *portions;                  /* Portions binaires à dessiner*/
+    GdkRectangle area;                      /* Surface du composant        */
+
+    if (keyboard) return FALSE;
+
+    strip = GTK_BINARY_STRIP(widget);
+
+    if (strip->binary != NULL)
+    {
+        format = g_loaded_binary_get_format(strip->binary);
+        portions = g_exe_format_get_portions(format);
+
+        area.x = 0;
+        area.y = 0;
+        area.width = widget->allocation.width;
+        area.height = widget->allocation.height;
+
+        result = g_binary_portion_query_tooltip(portions, x, y, &area, tooltip);
+
+    }
+    else result = FALSE;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : strip  = composant GTK à mettre à jour.                      *
+*                binary = nouveau contenu binaire à représenter.              *
+*                                                                             *
+*  Description : Attache un nouveau binaire à la barre de représentation.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_binary_strip_attach(GtkBinaryStrip *strip, GLoadedBinary *binary)
+{
+    if (strip->binary != NULL)
+        g_object_unref(G_OBJECT(strip->binary));
+
+    strip->binary = binary;
+    g_object_ref(G_OBJECT(strip->binary));
+
+    gtk_widget_queue_draw(GTK_WIDGET(strip));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : strip  = composant GTK à mettre à jour.                      *
+*                binary = nouveau contenu binaire à représenter.              *
+*                                                                             *
+*  Description : Place le curseur dans la barre de représentation.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+#if 0
+void gtk_binary_strip_locate_cursor(GtkBinaryStrip *strip, vmpa_t addr, bool emit)
+{
+    //srip->cursor_pos = pos;
+
+    gtk_widget_queue_draw(GTK_WIDGET(strip));
+
+}
+#endif
diff --git a/src/gtkext/gtkbinarystrip.h b/src/gtkext/gtkbinarystrip.h
new file mode 100644
index 0000000..58c31f0
--- /dev/null
+++ b/src/gtkext/gtkbinarystrip.h
@@ -0,0 +1,62 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gtkbinarystrip.h - prototypes pour l'affichage d'un binaire sous forme de bande
+ *
+ * Copyright (C) 2013 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 _GTKEXT_BINARYSTRIP_H
+#define _GTKEXT_BINARYSTRIP_H
+
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+
+#include "../analysis/binary.h"
+
+
+
+#define GTK_TYPE_BINARY_STRIP                  (gtk_binary_strip_get_type())
+#define GTK_BINARY_STRIP(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BINARY_STRIP, GtkBinaryStrip))
+#define GTK_BINARY_STRIP_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BINARY_STRIP, GtkBinaryStripClass))
+#define GTK_IS_BINARY_STRIP(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BINARY_STRIP))
+#define GTK_IS_BINARY_STRIP_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BINARY_STRIP))
+#define GTK_BINARY_STRIP_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BINARY_STRIP, GtkBinaryStripClass))
+
+
+/* Affichage d'un binaire en bande (instance) */
+typedef struct _GtkBinaryStrip GtkBinaryStrip;
+
+/* Affichage d'un binaire en bande (classe) */
+typedef struct _GtkBinaryStripClass GtkBinaryStripClass;
+
+
+/* Détermine le type du composant d'affichage générique. */
+GType gtk_binary_strip_get_type(void);
+
+/* Crée un nouveau composant pour l'affichage d'une bande. */
+GtkWidget *gtk_binary_strip_new(void);
+
+/* Attache un nouveau binaire à la barre de représentation. */
+void gtk_binary_strip_attach(GtkBinaryStrip *, GLoadedBinary *);
+
+
+
+#endif  /* _GTKEXT_BINARYSTRIP_H */
diff --git a/src/gui/editem-int.h b/src/gui/editem-int.h
index 594b6fd..80fe699 100644
--- a/src/gui/editem-int.h
+++ b/src/gui/editem-int.h
@@ -42,6 +42,9 @@ typedef void (* update_item_binary_fc) (GEditorItem *, GLoadedBinary *);
 /* Réagit à un changement d'affichage principal de contenu. */
 typedef void (* update_item_view_fc) (GEditorItem *, GtkViewPanel *);
 
+/* Concentre l'attention de l'ensemble sur une adresse donnée. */
+typedef void (* focus_addr_fc) (GEditorItem *, vmpa_t, GtkWidget *);
+
 /* Lance une actualisation relative à l'étendue du projet. */
 typedef void (* update_project_fc) (GEditorItem *, GStudyProject *);
 
@@ -61,6 +64,7 @@ struct _GEditorItem
     update_item_binary_fc update_binary;    /* Changement de binaire       */
     update_item_view_fc update_view;        /* Rechargement dû à une vue   */
     update_item_view_fc update_content;     /* Rechargement dû à un contenu*/
+    focus_addr_fc focus_addr;               /* Prête attention à une addr. */
     update_project_fc update_project;       /* Actualisation des binaires  */
 
 };
diff --git a/src/gui/editem.c b/src/gui/editem.c
index d658428..882bd3e 100644
--- a/src/gui/editem.c
+++ b/src/gui/editem.c
@@ -273,6 +273,30 @@ void change_editor_items_current_view_content(GtkViewPanel *view)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : addr   = adresse mémoire à mettre en avant.                  *
+*                source = composant à l'origine du changement.                *
+*                                                                             *
+*  Description : Concentre l'attention de l'ensemble sur une adresse donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void focus_address_in_editor_items(vmpa_t addr, GtkWidget *source)
+{
+    GEditorItem *iter;                     /* Boucle de parcours          */
+
+    editem_list_for_each(iter, _editem_list)
+        if (iter->focus_addr != NULL && iter->widget != source)
+            iter->focus_addr(iter, addr, source);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : project = projet concerné par l'évolution.                   *
 *                                                                             *
 *  Description : Lance une actualisation relative à l'étendue du projet.      *
diff --git a/src/gui/editem.h b/src/gui/editem.h
index 5321600..85f9022 100644
--- a/src/gui/editem.h
+++ b/src/gui/editem.h
@@ -85,6 +85,9 @@ void change_editor_items_current_view(GObject *, GtkViewPanel *);
 /* Lance une actualisation du fait d'un changement de contenu. */
 void change_editor_items_current_view_content(GtkViewPanel *);
 
+/* Concentre l'attention de l'ensemble sur une adresse donnée. */
+void focus_address_in_editor_items(vmpa_t, GtkWidget *);
+
 /* Lance une actualisation relative à l'étendue du projet. */
 void update_project_area(GStudyProject *);
 
diff --git a/src/gui/tb/Makefile.am b/src/gui/tb/Makefile.am
index 65679cb..5cd46a8 100644
--- a/src/gui/tb/Makefile.am
+++ b/src/gui/tb/Makefile.am
@@ -2,6 +2,7 @@
 noinst_LTLIBRARIES  = libguitb.la
 
 libguitb_la_SOURCES =					\
+	portions.h portions.c				\
 	source.h source.c					\
 	toolbar.h toolbar.c
 
diff --git a/src/gui/tb/portions.c b/src/gui/tb/portions.c
new file mode 100644
index 0000000..c53a3ea
--- /dev/null
+++ b/src/gui/tb/portions.c
@@ -0,0 +1,162 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * portions.c - navigation dans les portions de binaire
+ *
+ * Copyright (C) 2013 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "portions.h"
+
+
+#include <i18n.h>
+
+
+#include "toolbar.h"
+#include "../editem-int.h"
+#include "../../format/format.h"
+#include "../../gtkext/gtkbinarystrip.h"
+
+
+
+/* Construit l'élément GTK pour une barre d'outils. */
+static GtkWidget *build_portions_tb_widget(GObject *);
+
+/* Fait suivre un changement d'adresse dans la barre. */
+static void track_address_on_binary_strip(GtkBinaryStrip *, vmpa_t, GObject *);
+
+/* Réagit à un changement du binaire courant. */
+static void update_portions_item_binary(GEditorItem *, GLoadedBinary *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ref = espace de référencement global.                        *
+*                                                                             *
+*  Description : Construit l'élément GTK pour une barre d'outils.             *
+*                                                                             *
+*  Retour      : Adresse du composant mis en place.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GtkWidget *build_portions_tb_widget(GObject *ref)
+{
+    GtkWidget *result;                      /* Composant à retourner       */
+    GtkWidget *handlebox;                   /* Support relocalisable       */
+    GtkWidget *strip;                       /* Bande pour binaire          */
+
+    result = GTK_WIDGET(gtk_tool_item_new());
+    gtk_tool_item_set_expand(GTK_TOOL_ITEM(result), TRUE);
+    gtk_widget_show(result);
+
+    handlebox = gtk_handle_box_new();
+    gtk_widget_show(handlebox);
+    gtk_container_add(GTK_CONTAINER(result), handlebox);
+
+    strip = gtk_binary_strip_new();
+    gtk_widget_show(strip);
+    gtk_container_add(GTK_CONTAINER(handlebox), strip);
+
+    g_object_set_data(G_OBJECT(result), "strip", strip);
+
+    g_signal_connect(strip, "select-address",
+                     G_CALLBACK(track_address_on_binary_strip),
+                     ref);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : strip = composant d'affichage parcouru.                      *
+*                addr  = nouvelle adresse du curseur courant.                 *
+*                ref   = espace de référencement global.                      *
+*                                                                             *
+*  Description : Fait suivre un changement d'adresse dans la barre.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void track_address_on_binary_strip(GtkBinaryStrip *strip, vmpa_t addr, GObject *ref)
+{
+
+    printf("===> CHANGE TO 0x%08llx\n", addr);
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ref = espace de référencement global.                        *
+*                                                                             *
+*  Description : Crée une sélection de fichier réactive pour barre d'outils.  *
+*                                                                             *
+*  Retour      : Adresse de la structure d'encadrement mise en place.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GEditorItem *create_portions_tb_item(GObject *ref)
+{
+    GEditorItem *result;                    /* Structure à retourner       */
+    GtkWidget *widget;                      /* Composant affiché à l'écran */
+
+    widget = build_portions_tb_widget(ref);
+
+    result = g_toolbar_item_new(ref, "portions", widget, _("Portions"));
+
+    result->update_binary = update_portions_item_binary;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = élément réactif sollicité.                          *
+*                binary = binaire chargé nouvellement affiché.                *
+*                                                                             *
+*  Description : Réagit à un changement du binaire courant.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void update_portions_item_binary(GEditorItem *item, GLoadedBinary *binary)
+{
+    GtkBinaryStrip *strip;                  /* Bande pour binaire          */
+
+    strip = GTK_BINARY_STRIP(g_object_get_data(G_OBJECT(item->widget), "strip"));
+
+    gtk_binary_strip_attach(strip, binary);
+
+}
diff --git a/src/gui/tb/portions.h b/src/gui/tb/portions.h
new file mode 100644
index 0000000..a2a2041
--- /dev/null
+++ b/src/gui/tb/portions.h
@@ -0,0 +1,38 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * portions.h - prototypes pour la navigation dans les portions de binaire
+ *
+ * Copyright (C) 2013 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _GUI_TB_PORTIONS_H
+#define _GUI_TB_PORTIONS_H
+
+
+#include "../editem.h"
+
+
+
+/* Crée une sélection de fichier réactive pour barre d'outils. */
+GEditorItem *create_portions_tb_item(GObject *ref);
+
+
+
+#endif  /* _GUI_TB_PORTIONS_H */
diff --git a/src/main.c b/src/main.c
index 9efc94d..7dbb055 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,6 +35,7 @@
 #include "arch/processor.h"
 #include "format/format.h"
 #include "glibext/delayed.h"
+#include "glibext/gbinportion.h"
 #include "glibext/gfontcache.h"
 #include "gtkext/support.h"
 #include "plugins/pglist.h"
@@ -136,6 +137,7 @@ int main(int argc, char **argv)
     /* Initialisation du programme */
     init_all_processors();
     init_all_formats();
+    init_binary_portion_colors();
     init_global_pango_context();
 
     /* Création de l'interface */
@@ -167,6 +169,7 @@ int main(int argc, char **argv)
     exit_all_plugins();
 
     exit_global_pango_context();
+    exit_binary_portion_colors();
 
     unload_configuration(config);
 
-- 
cgit v0.11.2-87-g4458