From 15c0cc127f0f4551c88de6c0d46b7d38f4b3ed4b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 21 Sep 2014 21:26:42 +0000
Subject: Showed information about a selected address in the status bar.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@407 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog             |  15 ++++++++
 src/format/format.c   |  94 ++++++++++++++++++++++------------------------
 src/format/format.h   |   6 +--
 src/gui/editem-int.h  |   2 +-
 src/gui/editem.c      |   9 +++--
 src/gui/editem.h      |   2 +-
 src/gui/status.c      | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/gui/tb/portions.c |   2 +
 8 files changed, 174 insertions(+), 58 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index acf8a9f..2eb182c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+14-09-21  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/format/format.c:
+	* src/format/format.h:
+	Update the way symbols are resolved.
+
+	* src/gui/editem.c:
+	* src/gui/editem.h:
+	* src/gui/editem-int.h:
+	Focus on a given memory address on demand.
+
+	* src/gui/status.c:
+	* src/gui/tb/portions.c:
+	Show information about a selected address in the status bar.
+
 14-09-17  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/fetch.c:
diff --git a/src/format/format.c b/src/format/format.c
index 4fec391..ff62b80 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -225,6 +225,51 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : format = informations chargées à consulter.                  *
+*                addr   = adresse à cibler lors des recherches.               *
+*                symbol = éventuel symbole trouvé à déréfenrencer. [OUT]      *
+*                diff   = décallage entre l'adresse et le symbole. [OUT]      *
+*                                                                             *
+*  Description : Recherche le symbole correspondant à une adresse.            *
+*                                                                             *
+*  Retour      : true si l'opération a été un succès, false sinon.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol, phys_t *diff)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    const mrange_t *range;                  /* Espace mémoire parcouru     */
+
+    result = false;
+
+    for (i = 0; i < format->symbols_count && !result; i++)
+    {
+        range = g_binary_symbol_get_range(format->symbols[i]);
+
+        if (mrange_contains_addr(range, addr))
+        {
+            *symbol = format->symbols[i];
+            g_object_ref(G_OBJECT(*symbol));
+
+            *diff = compute_vmpa_diff(get_mrange_addr(range), addr);
+
+            result = true;
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : format  = informations chargées à compléter.                 *
 *                routine = routine à ajouter à la liste.                      *
 *                                                                             *
@@ -351,55 +396,6 @@ void g_binary_format_decompile(const GBinFormat *format, GCodeBuffer *buffer, co
 *                                                                             *
 *  Paramètres  : format  = informations chargées à consulter.                 *
 *                label   = étiquette du symbole si trouvé. [OUT]              *
-*                type    = type du symbole trouvé. [OUT]                      *
-*                address = adresse à cibler, puis décallage final. [OUT]      *
-*                                                                             *
-*  Description : Recherche le symbole correspondant à une adresse.            *
-*                                                                             *
-*  Retour      : true si l'opération a été un succès, false sinon.            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_binary_format_resolve_symbol(const GBinFormat *format, const char **label, SymbolType *type, vmpa_t *address)
-{
-    bool result;                            /* Bilan à retourner           */
-    size_t i;                               /* Boucle de parcours          */
-    vmpa_t addr;                            /* Adresse de symbole          */
-    off_t size;                             /* Taille du symole            */
-
-    result = false;
-
-    for (i = 0; i < format->symbols_count && !result; i++)
-    {
-        addr = g_binary_symbol_get_address(format->symbols[i]);
-        size = 0;//////g_binary_symbol_get_size(format->symbols[i]);
-
-        if (addr <= *address && *address < (addr + size))
-        {
-            *label = g_binary_symbol_to_string(format->symbols[i]);
-            *type = g_binary_symbol_get_target_type(format->symbols[i]);
-            *address -= addr;
-
-            if (*type == STP_STRING)
-                *label += *address;
-
-            result = true;
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : format  = informations chargées à consulter.                 *
-*                label   = étiquette du symbole si trouvé. [OUT]              *
 *                address = adresse à cibler, puis décallage final. [OUT]      *
 *                                                                             *
 *  Description : Recherche une position dans une routine selon une adresse.   *
diff --git a/src/format/format.h b/src/format/format.h
index 2eed669..3c74b50 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -64,6 +64,9 @@ void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
 /* Fournit la liste de tous les symboles détectés. */
 GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *);
 
+/* Recherche le symbole correspondant à une adresse. */
+bool g_binary_format_resolve_symbol(const GBinFormat *, const vmpa2t *, GBinSymbol **, phys_t *);
+
 /* Ajoute une routine à la collection du format binaire. */
 void g_binary_format_add_routine(GBinFormat *, GBinRoutine *) __attribute__ ((deprecated));
 
@@ -76,9 +79,6 @@ const char * const *g_binary_format_get_source_files(const GBinFormat *, size_t
 /* Procède à la décompilation complète du format. */
 void g_binary_format_decompile(const GBinFormat *, GCodeBuffer *, const char *filename);
 
-/* Recherche le symbole correspondant à une adresse. */
-bool g_binary_format_resolve_symbol(const GBinFormat *, const char **, SymbolType *, vmpa_t *);
-
 /* Recherche une position dans une routine selon une adresse. */
 bool g_binary_format_resolve_relative_routine(const GBinFormat *, const char **, vmpa_t *);
 
diff --git a/src/gui/editem-int.h b/src/gui/editem-int.h
index eafac04..7dc3ad4 100644
--- a/src/gui/editem-int.h
+++ b/src/gui/editem-int.h
@@ -43,7 +43,7 @@ typedef void (* update_item_binary_fc) (GEditorItem *, GLoadedBinary *);
 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 *);
+typedef void (* focus_addr_fc) (GEditorItem *, GLoadedBinary *, const vmpa2t *);
 
 /* Lance une actualisation relative à l'étendue du projet. */
 typedef void (* update_project_fc) (GEditorItem *, GStudyProject *);
diff --git a/src/gui/editem.c b/src/gui/editem.c
index c8befec..cde5d7f 100644
--- a/src/gui/editem.c
+++ b/src/gui/editem.c
@@ -292,7 +292,8 @@ void change_editor_items_current_view_content(GtkViewPanel *view)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : addr   = adresse mémoire à mettre en avant.                  *
+*  Paramètres  : binary = binaire contenant l'adresse à représenter.          *
+*                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.  *
@@ -303,7 +304,7 @@ void change_editor_items_current_view_content(GtkViewPanel *view)
 *                                                                             *
 ******************************************************************************/
 
-void focus_address_in_editor_items(vmpa_t addr, GtkWidget *source)
+void focus_address_in_editor_items(GLoadedBinary *binary, const vmpa2t *addr, GEditorItem *source)
 {
     GEditorItem *iter;                      /* Boucle de parcours          */
     GEditorItemClass *klass;                /* Classe correspondante       */
@@ -312,8 +313,8 @@ void focus_address_in_editor_items(vmpa_t addr, GtkWidget *source)
     {
         klass = G_EDITOR_ITEM_GET_CLASS(iter);
 
-        if (klass->focus_addr != NULL && iter->widget != source)
-            klass->focus_addr(iter, addr, source);
+        if (klass->focus_addr != NULL && iter != source)
+            klass->focus_addr(iter, binary, addr);
 
     }
 
diff --git a/src/gui/editem.h b/src/gui/editem.h
index 1d64534..d1b91a5 100644
--- a/src/gui/editem.h
+++ b/src/gui/editem.h
@@ -86,7 +86,7 @@ void change_editor_items_current_view(GObject *, GtkViewPanel *);
 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 *);
+void focus_address_in_editor_items(GLoadedBinary *, const vmpa2t *, GEditorItem *);
 
 /* Lance une actualisation relative à l'étendue du projet. */
 void update_project_area(GStudyProject *);
diff --git a/src/gui/status.c b/src/gui/status.c
index c29a69e..2633ba6 100644
--- a/src/gui/status.c
+++ b/src/gui/status.c
@@ -25,6 +25,7 @@
 #include "status.h"
 
 
+#include <ctype.h>
 #include <string.h>
 
 
@@ -76,6 +77,8 @@ static void update_status_info_for_view(GStatusInfo *, GtkViewPanel *);
 /* Imprime la position du parcours courant dans le statut. */
 static void track_caret_address_on_buffer_views(GtkBufferView *, vmpa_t, GStatusInfo *);
 
+/* Concentre l'attention de l'ensemble sur une adresse donnée. */
+static void focus_address_in_status_info(GStatusInfo *, GLoadedBinary *, const vmpa2t *);
 
 
 
@@ -108,6 +111,7 @@ static void g_status_info_class_init(GStatusInfoClass *klass)
     editem = G_EDITOR_ITEM_CLASS(klass);
 
     editem->update_view = (update_item_view_fc)update_status_info_for_view;
+    editem->focus_addr = (focus_addr_fc)focus_address_in_status_info;
 
 }
 
@@ -318,3 +322,101 @@ static void track_caret_address_on_buffer_views(GtkBufferView *view, vmpa_t addr
     free(msg);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : info   = composant réactif à mettre à jour.                  *
+*                binary = binaire contenant l'adresse à représenter.          *
+*                addr   = adresse mémoire à mettre en avant.                  *
+*                                                                             *
+*  Description : Concentre l'attention de l'ensemble sur une adresse donnée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void focus_address_in_status_info(GStatusInfo *info, GLoadedBinary *binary, const vmpa2t *addr)
+{
+    GExeFormat *format;                     /* Format associé au binaire   */
+    GArchProcessor *proc;                   /* Architecture du binaire     */
+    MemoryDataSize msize;                   /* Taille du bus d'adresses    */
+    char *msg;                              /* Message à transmettre       */
+    VMPA_BUFFER(tmp);                       /* Traduction d'adresses       */
+    GBinSymbol *symbol;                     /* Symbole présent à l'adresse */
+    phys_t diff;                            /* Décallage de l'adresse      */
+    const char *label;                      /* Description d'un symbole    */
+    GBinPortion *portions;                  /* Portions binaires existantes*/
+    GBinPortion *portion;                   /* Zone mémoire d'appartenance */
+    size_t len;                             /* Caractère à faire basculer  */
+
+    format = g_loaded_binary_get_format(binary);
+    proc = get_arch_processor_from_format(format);
+    msize = g_arch_processor_get_memory_size(proc);
+
+    msg = strdup(_("Localisation:"));
+
+    /* Adresses de base */
+
+    msg = stradd(msg, " phys:");
+    vmpa2_phys_to_string(addr, msize, tmp, NULL);
+    msg = stradd(msg, tmp);
+
+    msg = stradd(msg, " virt:");
+    vmpa2_virt_to_string(addr, msize, tmp, NULL);
+    msg = stradd(msg, tmp);
+
+    /* Symbole présent ? */
+
+    if (g_binary_format_resolve_symbol(G_BIN_FORMAT(format), addr, &symbol, &diff))
+    {
+        label = g_binary_symbol_to_string(symbol);
+
+        if (label != NULL)
+        {
+            msg = stradd(msg, _(" at "));
+            msg = stradd(msg, label);
+            msg = stradd(msg, _("+"));
+
+            snprintf(tmp, VMPA_MAX_SIZE, "0x%x", diff);
+            msg = stradd(msg, tmp);
+
+        }
+
+        g_object_unref(G_OBJECT(symbol));
+
+    }
+
+    /* Zone d'appartenance */
+
+    portions = g_exe_format_get_portions(format);
+
+    portion = g_binary_portion_find_at_addr(portions, addr, (GdkRectangle []) { });
+
+    label = g_binary_portion_get_desc(portion);
+
+    msg = stradd(msg, _(" ("));
+
+    /**
+     * Pas très propre : on bascule de majuscule en minuscule ici...
+     * FIXME ?
+     */
+
+    len = strlen(msg);
+    msg = stradd(msg, label);
+    msg[len] = tolower(msg[len]);
+
+    msg = stradd(msg, _(")"));
+
+    /* Impression */
+
+    if (info->msg_id > 0)
+        gtk_extended_status_bar_remove(GTK_EXT_STATUS_BAR(G_EDITOR_ITEM(info)->widget), info->msg_id);
+
+    info->msg_id = gtk_extended_status_bar_push(GTK_EXT_STATUS_BAR(G_EDITOR_ITEM(info)->widget), msg, FALSE);
+
+    free(msg);
+
+}
diff --git a/src/gui/tb/portions.c b/src/gui/tb/portions.c
index 53c7dea..3d30a9e 100644
--- a/src/gui/tb/portions.c
+++ b/src/gui/tb/portions.c
@@ -253,4 +253,6 @@ static void track_address_on_binary_strip(GtkBinaryStrip *strip, GEditorItem *it
     vpanel = g_editor_item_get_current_view(item);
     gtk_view_panel_scroll_to_address(vpanel, addr);
 
+    focus_address_in_editor_items(g_editor_item_get_current_binary(item), addr, item);
+
 }
-- 
cgit v0.11.2-87-g4458