summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-08-31 15:56:10 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-08-31 15:56:10 (GMT)
commited4bb73e5d68c1f81b8e0c3210aa221ec6f2675b (patch)
tree006a4641fc7a5c820d6a4253ff75e79ef01e368b
parent4658d4fa406bad4abe36a76746412cf02c984af0 (diff)
Loaded a binary strip into the editor.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@358 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog54
-rw-r--r--src/arch/archbase.h5
-rw-r--r--src/common/xml.h2
-rw-r--r--src/editor.c4
-rw-r--r--src/format/elf/elf.c135
-rw-r--r--src/format/elf/elf_def.h25
-rw-r--r--src/format/elf/program.c51
-rw-r--r--src/format/elf/program.h5
-rw-r--r--src/format/elf/symbols.c6
-rw-r--r--src/format/executable-int.h6
-rw-r--r--src/format/executable.c29
-rw-r--r--src/format/executable.h4
-rw-r--r--src/glibext/Makefile.am1
-rw-r--r--src/glibext/gbinportion.c938
-rw-r--r--src/glibext/gbinportion.h148
-rw-r--r--src/gtkext/Makefile.am1
-rw-r--r--src/gtkext/graph/nodes/flow.c4
-rw-r--r--src/gtkext/graph/nodes/virtual.c16
-rw-r--r--src/gtkext/gtkbinarystrip.c462
-rw-r--r--src/gtkext/gtkbinarystrip.h62
-rw-r--r--src/gui/editem-int.h4
-rw-r--r--src/gui/editem.c24
-rw-r--r--src/gui/editem.h3
-rw-r--r--src/gui/tb/Makefile.am1
-rw-r--r--src/gui/tb/portions.c162
-rw-r--r--src/gui/tb/portions.h38
-rw-r--r--src/main.c3
27 files changed, 2177 insertions, 16 deletions
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);