From 2d95ce74200c8cb7c328535235a8c8e74686794e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 2 Jan 2010 01:48:30 +0000
Subject: Provided ways to load, save and edit some binary parts selection.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@141 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                   |  28 ++++
 src/analysis/binary.c       |   2 +-
 src/analysis/binary.h       |   2 +-
 src/dialogs/Makefile.am     |  16 +++
 src/dialogs/binparts.c      | 327 ++++++++++++++++++++++++++++++++++----------
 src/dialogs/binparts.h      |   2 +-
 src/editor.c                |   2 +-
 src/format/elf/elf.c        |  34 ++++-
 src/format/elf/section.c    |  40 ++++++
 src/format/elf/section.h    |   3 +
 src/format/executable-int.h |   6 +-
 src/format/executable.c     |  23 +++-
 src/format/executable.h     |   3 +
 src/format/part.c           |  29 ++++
 src/format/part.h           |   3 +
 15 files changed, 437 insertions(+), 83 deletions(-)
 create mode 100644 src/dialogs/Makefile.am

diff --git a/ChangeLog b/ChangeLog
index f5f5ab2..1a1ff62 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+10-01-02  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/binary.c:
+	* src/analysis/binary.h:
+	Fix the prototype of the function giving access to disassembled parts.
+
+	* src/dialogs/binparts.c:
+	* src/dialogs/binparts.h:
+	Load, save and edit some binary parts selection.
+
+	* src/dialogs/Makefile.am:
+	News entry: add this missing file.
+
+	* src/editor.c:
+	Fix a call.
+
+	* src/format/elf/elf.c:
+	* src/format/elf/section.c:
+	* src/format/elf/section.h:
+	* src/format/executable.c:
+	* src/format/executable.h:
+	* src/format/executable-int.h:
+	Provide a way to translate addresses into file positions.
+
+	* src/format/part.c:
+	* src/format/part.h:
+	Create a function to dump parts.
+
 09-12-13  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/binary.c:
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 56265f2..58979d0 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -1044,7 +1044,7 @@ void g_openida_binary_set_parts(GOpenidaBinary *binary, BinaryPartModel model, G
 *                                                                             *
 ******************************************************************************/
 
-GBinPart **g_openida_binary_get_parts(const GOpenidaBinary *binary, BinaryPartModel *model, size_t *count)
+GBinPart ***g_openida_binary_get_parts(const GOpenidaBinary *binary, BinaryPartModel *model, size_t **count)
 {
     *model = binary->model;
     *count = binary->parts_count;
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index d195fef..533264b 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -78,7 +78,7 @@ bool g_openida_binary_save(const GOpenidaBinary *, xmlDocPtr, xmlXPathContextPtr
 void g_openida_binary_set_parts(GOpenidaBinary *, BinaryPartModel, GBinPart **, size_t);
 
 /* Fournit les parties de binaire analysées. */
-GBinPart **g_openida_binary_get_parts(const GOpenidaBinary *, BinaryPartModel *, size_t *);
+GBinPart ***g_openida_binary_get_parts(const GOpenidaBinary *, BinaryPartModel *, size_t **);
 
 /* Lance l'analyse d'un élément binaire chargé. */
 void g_openida_binary_analyse(GOpenidaBinary *);
diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am
new file mode 100644
index 0000000..181f418
--- /dev/null
+++ b/src/dialogs/Makefile.am
@@ -0,0 +1,16 @@
+
+lib_LIBRARIES = libdialogs.a
+
+libdialogs_a_SOURCES =					\
+	binparts.h binparts.c
+
+libdialogs_a_LDFLAGS = 
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CPPFLAGS = 
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = 
diff --git a/src/dialogs/binparts.c b/src/dialogs/binparts.c
index 1135348..a88232e 100644
--- a/src/dialogs/binparts.c
+++ b/src/dialogs/binparts.c
@@ -24,6 +24,9 @@
 #include "binparts.h"
 
 
+#include <stdio.h>
+
+
 #include "../format/format.h"
 #include "../gtkext/easygtk.h"
 
@@ -46,7 +49,6 @@ typedef enum _PartsColumn
 } PartsColumn;
 
 
-
 /* Mémoire d'un modèle */
 typedef struct _parts_model
 {
@@ -56,15 +58,17 @@ typedef struct _parts_model
 } parts_model;
 
 
+/* Sélectionne ou non tous les éléments de la liste courante. */
+static void select_all_items_or_none(GtkButton *, GObject *);
 
+/* Sauvegarde l'état courant des sélections et clôt la fenêtre. */
+static void save_current_selection(GtkButton *, GObject *);
 
+/* Ferme la fenêtre de dialogue. */
+static void close_editor(GtkButton *, GtkWidget *);
 
-/* Charge les sections sélectionnées pour le projet courant. */
-void load_project_sections(void *, GObject *);
-
-
-
-
+/* Charge les parties courantes d'un binaire donné. */
+static void load_binary_current_parts(GOpenidaBinary *binary, GObject *ref);
 
 /* Affiche les parties désassemblées par défaut. */
 static void load_default_parts(GObject *);
@@ -85,6 +89,7 @@ static void on_part_selection_toggle(GtkCellRendererToggle *, gchar *, GObject *
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : binary = informations sur le binaire actuellement ouvert.    *
+*                parent = fenêtre parente à surpasser.                        *
 *                                                                             *
 *  Description : Construit la fenêtre de sélection des sections.              *
 *                                                                             *
@@ -94,7 +99,7 @@ static void on_part_selection_toggle(GtkCellRendererToggle *, gchar *, GObject *
 *                                                                             *
 ******************************************************************************/
 
-GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
+GtkWidget *create_sections_dialog(GOpenidaBinary *binary, GtkWindow *parent)
 {
     GtkWidget *result;                      /* Fenêtre à renvoyer          */
     GObject *ref;                           /* Espace de référencements    */
@@ -104,19 +109,13 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
 
 
   GtkWidget *vbox1;
-  //GtkWidget *hbox1;
-
-
-    GtkWidget *label;                       /* Etiquette à afficher        */
-
 
-  GtkWidget *combobox;
 
-    GtkWidget *alignment;                   /* Adaptation de disposition   */
-    GtkWidget *frame;                       /* Support avec encadrement    */
 
   GtkWidget *vbox2;
   GtkWidget *hbox2;
+    GtkWidget *label;                       /* Etiquette à afficher        */
+
   GtkWidget *comboboxentry;
   GtkWidget *hbox3;
   GtkWidget *scrolledwindow1;
@@ -131,14 +130,15 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
   GtkWidget *hbuttonbox1;
 
     GtkWidget *button;                      /* Bouton de commande          */
+    GtkWidget *sep;                         /* Barre de séparation         */
 
-  result = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-  gtk_widget_set_size_request(result, 600, 400);
-  gtk_container_set_border_width(GTK_CONTAINER(result), 8);
-  gtk_window_set_title(GTK_WINDOW(result), _("Sections selection"));
-  gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER);
-  gtk_window_set_default_size(GTK_WINDOW(result), 600, 400);
-  gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG);
+    result = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_widget_set_size_request(result, 600, 400);
+    gtk_container_set_border_width(GTK_CONTAINER(result), 8);
+    gtk_window_set_title(GTK_WINDOW(result), _("Content to display"));
+    gtk_window_set_transient_for(GTK_WINDOW(result), parent);
+    gtk_window_set_default_size(GTK_WINDOW(result), 600, 400);
+    gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG);
 
     ref= G_OBJECT(result);
     g_object_set_data(ref, "binary", binary);
@@ -147,28 +147,11 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
   gtk_widget_show(vbox1);
   gtk_container_add(GTK_CONTAINER(result), vbox1);
 
-  /*
-  hbox1 = gtk_hbox_new(FALSE, 8);
-  gtk_widget_show(hbox1);
-  gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0);
-
-    label = qck_create_label(NULL, NULL, _("Binary :"));
-    gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 0);
-
-  combobox = gtk_combo_box_new_text();
-  gtk_widget_show(combobox);
-  gtk_box_pack_start(GTK_BOX(hbox1), combobox, TRUE, TRUE, 0);
-  */
-
-    frame = qck_create_frame(_("<b>Content to display</b>"), &alignment, 4, 4, 12, 0);
-    gtk_box_pack_start(GTK_BOX(vbox1), frame, TRUE, TRUE, 0);
-
-
-
-
   vbox2 = gtk_vbox_new(FALSE, 8);
   gtk_widget_show(vbox2);
-  gtk_container_add(GTK_CONTAINER(alignment), vbox2);
+  gtk_container_add(GTK_CONTAINER(vbox1), vbox2);
+
+
 
   hbox2 = gtk_hbox_new(FALSE, 8);
   gtk_widget_show(hbox2);
@@ -182,9 +165,11 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
 
 
     button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(NULL), NULL);
+    gtk_widget_set_sensitive(button, FALSE);
     gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0);
 
     button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(NULL), NULL);
+    gtk_widget_set_sensitive(button, FALSE);
     gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0);
 
 
@@ -244,19 +229,32 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
 
 
 
+    /* Boutons d'édition de la liste */
+
+    vbuttonbox1 = gtk_vbutton_box_new();
+    gtk_widget_show(vbuttonbox1);
+    gtk_box_pack_start(GTK_BOX(hbox3), vbuttonbox1, FALSE, FALSE, 0);
+    gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox1), GTK_BUTTONBOX_SPREAD);
 
-  vbuttonbox1 = gtk_vbutton_box_new();
-  gtk_widget_show(vbuttonbox1);
-  gtk_box_pack_start(GTK_BOX(hbox3), vbuttonbox1, FALSE, FALSE, 0);
-  gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox1), GTK_BUTTONBOX_SPREAD);
 
+    button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(select_all_items_or_none), ref);
+    gtk_container_add(GTK_CONTAINER(vbuttonbox1), button);
 
+    g_object_set_data(G_OBJECT(button), "all", button);
+
+    button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(select_all_items_or_none), ref);
+    gtk_container_add(GTK_CONTAINER(vbuttonbox1), button);
 
+    sep = gtk_hseparator_new();
+    gtk_widget_show(sep);
+    gtk_container_add(GTK_CONTAINER(vbuttonbox1), sep);
 
     button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(NULL), NULL);
+    gtk_widget_set_sensitive(button, FALSE);
     gtk_container_add(GTK_CONTAINER(vbuttonbox1), button);
 
     button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(NULL), NULL);
+    gtk_widget_set_sensitive(button, FALSE);
     gtk_container_add(GTK_CONTAINER(vbuttonbox1), button);
 
 
@@ -269,16 +267,15 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
   gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox1), GTK_BUTTONBOX_END);
 
 
-    button = qck_create_button_from_stock(NULL, NULL, "gtk-ok", G_CALLBACK(NULL), NULL);
-    gtk_container_add(GTK_CONTAINER(hbuttonbox1), button);
+    /* Boutons de contrôle principaux */
 
-    button = qck_create_button_from_stock(NULL, NULL, "gtk-cancel", G_CALLBACK(NULL), NULL);
+    button = qck_create_button_from_stock(NULL, NULL, "gtk-ok", G_CALLBACK(save_current_selection), ref);
     gtk_container_add(GTK_CONTAINER(hbuttonbox1), button);
 
+    button = qck_create_button_from_stock(NULL, NULL, "gtk-cancel", G_CALLBACK(close_editor), result);
+    gtk_container_add(GTK_CONTAINER(hbuttonbox1), button);
 
-
-
-
+    /* Actualisation de l'interface */
 
     g_signal_connect(G_OBJECT(comboboxentry), "changed", G_CALLBACK(on_model_change), ref);
 
@@ -286,22 +283,52 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
     gtk_combo_box_append_text(GTK_COMBO_BOX(comboboxentry), _("Routines"));
     gtk_combo_box_append_text(GTK_COMBO_BOX(comboboxentry), _("User"));
 
+    load_binary_current_parts(binary, ref);
+
     return result;
 
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : button = bouton d'édition de la sélection.                   *
+*                ref    = espace de référencement principal.                  *
+*                                                                             *
+*  Description : Sélectionne ou non tous les éléments de la liste courante.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
+static void select_all_items_or_none(GtkButton *button, GObject *ref)
+{
+    gboolean state;                         /* Etat de sélection à donner  */
+    GtkTreeModel *model;                    /* Modèle de représentation    */
+    GtkTreeIter iter;                       /* Point de modification       */
+
+    state = (g_object_get_data(G_OBJECT(button), "all") != NULL);
+
+    model = GTK_TREE_MODEL(g_object_get_data(ref, "store"));
 
+    if (gtk_tree_model_get_iter_first(model, &iter))
+        do
+            gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
+                           PTC_ACTIVE, state,
+                           -1);
+        while (gtk_tree_model_iter_next(model, &iter));
 
+}
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : project = informations sur le project actuellement ouvert.   *
-*                ref     = espace de référencement principal.                 *
+*  Paramètres  : button = bouton 'OK'.                                        *
+*                ref    = espace de référencement principal.                  *
 *                                                                             *
-*  Description : Charge les sections sélectionnées pour le projet courant.    *
+*  Description : Sauvegarde l'état courant des sélections et clôt la fenêtre. *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -309,27 +336,189 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary)
 *                                                                             *
 ******************************************************************************/
 
-void load_project_sections(void *project, GObject *ref)
+static void save_current_selection(GtkButton *button, GObject *ref)
 {
 
 
 
-    /*
-    gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("Never automatically"));
-    gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("When the window gets the focus"));
-    gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("On click on the window"));
 
-    */
+
+
+
+    GOpenidaBinary *binary;                 /* Binaire à traiter           */
+
+    GExeFormat *format;                     /* Format associé au binaire   */
+    GArchProcessor *proc;                   /* Architecture utilisée       */
+
+
+    GBinPart **parts;                       /* Parcelles à désassembler    */
+    size_t parts_count;                     /* Quantité de ces parcelles   */
+    GBinPart *part;                         /* Nouvelle partie à lister    */
+
+
+    GBinRoutine **routines;                 /* Liste des routines trouvées */
+    size_t routines_count;                  /* Nombre de ces routines      */
+    parts_model *model;                     /* Mémoire du modèle           */
+    size_t i;                               /* Boucle de parcours          */
+    off_t offset;                           /* Position dans le binaire    */
+
+
+    binary = G_OPENIDA_BINARY(g_object_get_data(ref, "binary"));
+
+    format = g_openida_binary_get_format(binary);
+    proc = get_arch_processor_from_format(format);
+
+
+
+
+    /* Routines */
+
+    parts = NULL;
+    parts_count = 0;
+
+    routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count);
+    qsort(routines, routines_count, sizeof(GBinRoutine *), g_binary_routine_compare);
+
+    model = (parts_model *)g_object_get_data(ref, "routines_model");
+
+    for (i = 0; i < routines_count; i++)
+    {
+        if (!model->selected[i]) continue;
+
+        part = g_binary_part_new();
+
+        g_binary_part_set_name(part, g_binary_routine_get_name(routines[i]));
+
+        g_exe_format_translate_address_into_offset(format,
+                                                   g_binary_routine_get_address(routines[i]),
+                                                   &offset);
+
+        g_binary_part_set_values(part, offset,
+                                 g_binary_routine_get_size(routines[i]),
+                                 g_binary_routine_get_address(routines[i]));
+
+        parts = (GBinPart **)realloc(parts, ++parts_count * sizeof(GBinPart *));
+        parts[parts_count - 1] = part;
+
+    }
+
+    g_openida_binary_set_parts(binary, BPM_ROUTINES, parts, parts_count);
+
+
+
+
+
+
+
+
+    /* Fin */
+
+    gtk_widget_destroy(GTK_WIDGET(ref));
 
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : button = bouton 'Annuler'.                                   *
+*                widget = adresse de la fenêtre de l'éditeur à fermer.        *
+*                                                                             *
+*  Description : Ferme la fenêtre de dialogue.                                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
+static void close_editor(GtkButton *button, GtkWidget *widget)
+{
+    gtk_widget_destroy(widget);
 
+}
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = informations sur le binaire actuellement ouvert.    *
+*                ref    = espace de référencement principal.                  *
+*                                                                             *
+*  Description : Charge les parties courantes d'un binaire donné.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
+static void load_binary_current_parts(GOpenidaBinary *binary, GObject *ref)
+{
+    GtkTreeModel *store;                    /* Modèle de représentation    */
+    GBinPart ***list;                       /* Tableau de parties choisies */
+    BinaryPartModel model;                  /* Sélection courante          */
+    size_t *count;                          /* Taille de chaque liste      */
+    unsigned int i;                         /* Boucle de parcours #1       */
+    parts_model *parts;                     /* Liste de sélection courante */
+    size_t j;                               /* Boucle de parcours #2       */
+    GtkTreeIter iter;                       /* Lieu de lecture d'adresse   */
+    char path[11 /* UINT_MAX */];           /* Chemin d'accès pour GTK     */
+    gchar *value;                           /* Valeur d'adresse présentée  */
+    vmpa_t addr_dlg;                        /* Adresse côté local          */
+    size_t k;                               /* Boucle de parcours #3       */
+    vmpa_t addr_bin;                        /* Adresse côté binaire        */
+    GtkComboBox *combo;                     /* Liste de tous les modèles   */
+
+    /* Lecture des sélections courantes */
+
+    store = GTK_TREE_MODEL(g_object_get_data(ref, "store"));
+
+    list = g_openida_binary_get_parts(binary, &model, &count);
+
+    for (i = 0; i < (BPM_COUNT - 1 /* TODO*/); i++)
+    {
+        gtk_tree_store_clear(GTK_TREE_STORE(store));
+
+        switch (i)
+        {
+            case BPM_DEFAULT:
+                load_default_parts(ref);
+                parts = (parts_model *)g_object_get_data(ref, "default_model");
+                break;
+            case BPM_ROUTINES:
+                load_routines_parts(ref);
+                parts = (parts_model *)g_object_get_data(ref, "routines_model");
+                break;
+            case BPM_USER:
+                //parts = 
+                break;
+        }
+
+        for (j = 0; j < parts->count; j++)
+        {
+            snprintf(path, 11, "%u", j);
+
+            gtk_tree_model_get_iter_from_string(store, &iter, path);
+            gtk_tree_model_get(store, &iter, PTC_START, &value, -1);
+            addr_dlg = strtoll(value, NULL, 16);
+            g_free(value);
+
+            for (k = 0; k < count[i]; k++)
+            {
+                g_binary_part_get_values(list[i][k], NULL, NULL, &addr_bin);
+                if (addr_bin == addr_dlg) break;
+            }
 
+            parts->selected[j] = (count[i] == 0 || k < count[i]);
+
+        }
+
+    }
+
+    /* Sélection courante */
+    combo = GTK_COMBO_BOX(g_object_get_data(ref, "models"));
+    gtk_combo_box_set_active(combo, model);
+
+}
 
 
 /******************************************************************************
@@ -483,20 +672,6 @@ static void load_routines_parts(GObject *ref)
 
 
 
-static void user_function(GtkButton *button, GObject *ref)
-{
-
-
-
-
-
-
-
-
-}
-
-
-
 
 
 
diff --git a/src/dialogs/binparts.h b/src/dialogs/binparts.h
index dd7fa5e..8a86bf6 100644
--- a/src/dialogs/binparts.h
+++ b/src/dialogs/binparts.h
@@ -33,7 +33,7 @@
 
 
 /* Construit la fenêtre de sélection des sections. */
-GtkWidget *create_sections_dialog(GOpenidaBinary *);
+GtkWidget *create_sections_dialog(GOpenidaBinary *, GtkWindow *);
 
 
 
diff --git a/src/editor.c b/src/editor.c
index 5e39f27..8291a2e 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -1099,7 +1099,7 @@ static void mcb_binary_select_parts(GtkMenuItem *menuitem, GObject *ref)
 
     binary = G_OPENIDA_BINARY(g_object_get_data(ref, "current_binary"));
 
-    dialog = create_sections_dialog(binary);
+    dialog = create_sections_dialog(binary, GTK_WINDOW(ref));
     gtk_widget_show(dialog);
 
 }
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 878bf51..b703dcf 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -62,6 +62,9 @@ static vmpa_t g_elf_format_get_entry_point(const GElfFormat *);
 /* Fournit les références aux zones binaires à analyser. */
 static GBinPart **g_elf_format_get_parts(const GElfFormat *, size_t *);
 
+/* Fournit la position correspondant à une adresse virtuelle. */
+static bool g_elf_format_translate_address_into_offset(const GElfFormat *, vmpa_t, off_t *);
+
 /* Fournit l'adresse virtuelle correspondant à une position. */
 static bool g_elf_format_translate_offset_into_address(const GElfFormat *, off_t, vmpa_t *);
 
@@ -139,7 +142,8 @@ static void g_elf_format_init(GElfFormat *format)
     exe_format->get_entry_point = (get_entry_point_fc)g_elf_format_get_entry_point;
     exe_format->get_parts = (get_parts_fc)g_elf_format_get_parts;
 
-    exe_format->translate = (translate_off_fc)g_elf_format_translate_offset_into_address;
+    exe_format->translate_addr = (translate_addr_fc)g_elf_format_translate_address_into_offset;
+    exe_format->translate_off = (translate_off_fc)g_elf_format_translate_offset_into_address;
 
 }
 
@@ -496,6 +500,34 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format  = description de l'exécutable à consulter.           *
+*                addr    = adresse virtuelle à retrouver.                     *
+*                pos     = position correspondante. [OUT]                     *
+*                                                                             *
+*  Description : Fournit la position correspondant à une adresse virtuelle.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_elf_format_translate_address_into_offset(const GElfFormat *format, vmpa_t addr, off_t *pos)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = translate_address_into_offset_using_elf_sections(format, addr, pos);
+
+    if (!result)
+        /* TODO : prgm... */;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format  = description de l'exécutable à consulter.           *
 *                pos     = position dans le flux binaire à retrouver.         *
 *                addr    = adresse virtuelle correspondante. [OUT]            *
 *                                                                             *
diff --git a/src/format/elf/section.c b/src/format/elf/section.c
index b8d6a50..cb6a04a 100644
--- a/src/format/elf/section.c
+++ b/src/format/elf/section.c
@@ -280,6 +280,46 @@ const char *extract_name_from_elf_string_section(const GElfFormat *format, const
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format  = description de l'exécutable à consulter.           *
+*                addr    = adresse virtuelle à retrouver.                     *
+*                pos     = position correspondante. [OUT]                     *
+*                                                                             *
+*  Description : Fournit la position correspondant à une adresse virtuelle.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool translate_address_into_offset_using_elf_sections(const GElfFormat *format, vmpa_t addr, off_t *pos)
+{
+    bool result;                            /* Bilan à retourner           */
+    uint16_t i;                             /* Boucle de parcours          */
+    elf_shdr section;                       /* Section à analyser          */
+
+    result = false;
+
+    for (i = 0; i < format->header.e_shnum && !result; i++)
+    {
+        find_elf_section_by_index(format, i, &section);
+
+        if (ELF_SHDR(format, section, sh_addr) <= addr
+            && addr < (ELF_SHDR(format, section, sh_addr) + ELF_SHDR(format, section, sh_size)))
+        {
+            *pos = ELF_SHDR(format, section, sh_offset) + addr - ELF_SHDR(format, section, sh_addr);
+            result = true;
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format  = description de l'exécutable à consulter.           *
 *                pos     = position dans le flux binaire à retrouver.         *
 *                addr    = adresse virtuelle correspondante. [OUT]            *
 *                                                                             *
diff --git a/src/format/elf/section.h b/src/format/elf/section.h
index ca91097..811e32b 100644
--- a/src/format/elf/section.h
+++ b/src/format/elf/section.h
@@ -51,6 +51,9 @@ bool find_elf_section_content_by_name(const GElfFormat *, const char *, off_t *,
 /* Identifie une chaîne de caractères dans une section adéquate. */
 const char *extract_name_from_elf_string_section(const GElfFormat *, const elf_shdr *, off_t);
 
+/* Fournit la position correspondant à une adresse virtuelle. */
+bool translate_address_into_offset_using_elf_sections(const GElfFormat *, vmpa_t, off_t *);
+
 /* Fournit l'adresse virtuelle correspondant à une position. */
 bool translate_offset_into_address_using_elf_sections(const GElfFormat *, off_t, vmpa_t *);
 
diff --git a/src/format/executable-int.h b/src/format/executable-int.h
index e4b18a4..224e193 100644
--- a/src/format/executable-int.h
+++ b/src/format/executable-int.h
@@ -41,6 +41,9 @@ typedef vmpa_t (* get_entry_point_fc) (const GExeFormat *);
 /* Fournit les références aux zones de code à analyser. */
 typedef GBinPart ** (* get_parts_fc) (const GExeFormat *, size_t *);
 
+/* Fournit la position correspondant à une adresse virtuelle. */
+typedef bool (* translate_addr_fc) (const GExeFormat *, vmpa_t, off_t *);
+
 /* Fournit l'adresse virtuelle correspondant à une position. */
 typedef bool (* translate_off_fc) (const GExeFormat *, off_t, vmpa_t *);
 
@@ -56,7 +59,8 @@ struct _GExeFormat
     get_entry_point_fc get_entry_point;     /* Obtention du point d'entrée */
     get_parts_fc get_parts;                 /* Liste des parties binaires  */
 
-    translate_off_fc translate;             /* Correspondance pos -> addr  */
+    translate_addr_fc translate_addr;       /* Correspondance addr -> pos  */
+    translate_off_fc translate_off;         /* Correspondance pos -> addr  */
 
 };
 
diff --git a/src/format/executable.c b/src/format/executable.c
index 4af587f..76efaa1 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -147,6 +147,27 @@ GBinPart **g_exe_format_get_parts(const GExeFormat *format, size_t *count)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : format  = description de l'exécutable à consulter.           *
+*                addr    = adresse virtuelle à retrouver.                     *
+*                pos     = position correspondante. [OUT]                     *
+*                                                                             *
+*  Description : Fournit la position correspondant à une adresse virtuelle.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_exe_format_translate_address_into_offset(const GExeFormat *format, vmpa_t addr, off_t *pos)
+{
+    return format->translate_addr(format, addr, pos);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format  = description de l'exécutable à consulter.           *
 *                pos     = position dans le flux binaire à retrouver.         *
 *                addr    = adresse virtuelle correspondante. [OUT]            *
 *                                                                             *
@@ -160,6 +181,6 @@ GBinPart **g_exe_format_get_parts(const GExeFormat *format, size_t *count)
 
 bool g_exe_format_translate_offset_into_address(const GExeFormat *format, off_t pos, vmpa_t *addr)
 {
-    return format->translate(format, pos, addr);
+    return format->translate_off(format, pos, addr);
 
 }
diff --git a/src/format/executable.h b/src/format/executable.h
index 4d3f759..2042df4 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -75,6 +75,9 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *);
 /* Fournit les références aux zones binaires à analyser. */
 GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *);
 
+/* Fournit la position correspondant à une adresse virtuelle. */
+bool g_exe_format_translate_address_into_offset(const GExeFormat *, vmpa_t, off_t *);
+
 /* Fournit l'adresse virtuelle correspondant à une position. */
 bool g_exe_format_translate_offset_into_address(const GExeFormat *, off_t, vmpa_t *);
 
diff --git a/src/format/part.c b/src/format/part.c
index 63747d9..006cb75 100644
--- a/src/format/part.c
+++ b/src/format/part.c
@@ -124,6 +124,35 @@ GBinPart *g_binary_part_new(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : src = partie de code à copier.                               *
+*                                                                             *
+*  Description : Crée une description de partie de code à partir d'une autre. *
+*                                                                             *
+*  Retour      : Partie de code copiée.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinPart *g_binary_part_dump(const GBinPart *src)
+{
+    GBinPart *result;                   /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_BIN_PART, NULL);
+
+    result->name = (src->name != NULL ? strdup(src->name) : NULL);
+
+    result->offset = result->offset;
+    result->size = result->size;
+    result->addr = result->addr;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : node = noeud XML contenant les données à charger.            *
 *                                                                             *
 *  Description : Crée une description de partie de code vierge à partir d'XML.*
diff --git a/src/format/part.h b/src/format/part.h
index 5c1c904..32d1903 100644
--- a/src/format/part.h
+++ b/src/format/part.h
@@ -55,6 +55,9 @@ GType g_binary_part_get_type(void);
 /* Crée une description de partie de code vierge. */
 GBinPart *g_binary_part_new(void);
 
+/* Crée une description de partie de code à partir d'une autre. */
+GBinPart *g_binary_part_dump(const GBinPart *);
+
 /* Crée une description de partie de code vierge à partir d'XML. */
 GBinPart *g_binary_part_load_from_xml(xmlNodePtr);
 
-- 
cgit v0.11.2-87-g4458