summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-12-16 17:20:06 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-12-16 17:20:06 (GMT)
commit7c40b70d6c1e1e13dadf876c8dda60b525616d47 (patch)
tree743d0b1981a13fb2de0d2eaacc4f644cf84204c0 /src
parent4d313d845a60e908b9e2723cc1fe2bdbbdded315 (diff)
Built a new improved status bar for instructions information.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/disass/area.c5
-rw-r--r--src/format/format.c126
-rw-r--r--src/format/format.h6
-rw-r--r--src/glibext/gbinportion.c2
-rw-r--r--src/gtkext/Makefile.am1
-rw-r--r--src/gtkext/gtkstatusstack.c609
-rw-r--r--src/gtkext/gtkstatusstack.h79
-rw-r--r--src/gui/editor.c2
-rw-r--r--src/gui/status.c163
9 files changed, 777 insertions, 216 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 86c41d3..d2a03c6 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -1485,7 +1485,6 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph
static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr)
{
GBinSymbol *symbol; /* Symbole présent ou créé */
- phys_t offset; /* Décallage trouvé */
bool found; /* Détection de symbole */
SymbolType sym_type; /* Type de symbole en place */
bool wrong_type; /* Analyse plus fine de ce type*/
@@ -1494,7 +1493,7 @@ static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr)
char name[5 + VMPA_MAX_LEN]; /* Nom de symbole nouveau */
GBinRoutine *routine; /* Nouvelle routine trouvée */
- found = g_binary_format_resolve_symbol(format, addr, &symbol, &offset);
+ found = g_binary_format_find_symbol_at(format, addr, &symbol);
if (found)
{
@@ -1502,7 +1501,7 @@ static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr)
wrong_type = (sym_type != STP_ROUTINE && sym_type != STP_ENTRY_POINT);
}
- if (!found || (found && offset == 0 && wrong_type))
+ if (!found || (found && wrong_type))
{
init_mrange(&range, addr, 0);
diff --git a/src/format/format.c b/src/format/format.c
index 9c42508..82d9e42 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -52,6 +52,9 @@ static void g_binary_format_init(GBinFormat *);
/* Retire un symbole de la collection du format binaire. */
static void _g_binary_format_remove_symbol(GBinFormat *, size_t);
+/* Recherche le symbole associé à une adresse. */
+static bool _g_binary_format_find_symbol(const GBinFormat *, const vmpa2t *, __compar_fn_t, GBinSymbol **);
+
/* Indique le type défini pour un format binaire générique. */
@@ -623,9 +626,10 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *format, const char *
* *
* Paramètres : format = informations chargées à consulter. *
* addr = adresse à cibler lors des recherches. *
+* fn = méthode de comparaison des symboles. *
* symbol = éventuel symbole trouvé à déréfenrencer. [OUT] *
* *
-* Description : Recherche le symbole correspondant à une adresse. *
+* Description : Recherche le symbole associé à une adresse. *
* *
* Retour : true si l'opération a été un succès, false sinon. *
* *
@@ -633,7 +637,7 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *format, const char *
* *
******************************************************************************/
-bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol)
+static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t *addr, __compar_fn_t fn, GBinSymbol **symbol)
{
bool result; /* Bilan à retourner */
void *found; /* Résultat de recherches */
@@ -642,6 +646,40 @@ bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr
*symbol = NULL; /* TODO : vérifier les doublons côtés appelants */
+ found = bsearch(addr, format->symbols, format->symbols_count, sizeof(GBinSymbol *), fn);
+
+ if (found != NULL)
+ {
+ *symbol = *(GBinSymbol **)found;
+
+ g_object_ref(G_OBJECT(*symbol));
+ result = true;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* addr = adresse à cibler lors des recherches. *
+* symbol = éventuel symbole trouvé à déréfenrencer. [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_find_symbol_at(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol)
+{
+ bool result; /* Bilan à retourner */
+
int find_symbol(const vmpa2t *addr, const GBinSymbol **sym)
{
const mrange_t *range; /* Espace mémoire parcouru */
@@ -652,19 +690,43 @@ bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr
}
- found = bsearch(addr, format->symbols,
- format->symbols_count, sizeof(GBinSymbol *),
- (__compar_fn_t)find_symbol);
+ result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, symbol);
- if (found != NULL)
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* addr = adresse à cibler lors des recherches. *
+* symbol = éventuel symbole trouvé à déréfenrencer. [OUT] *
+* *
+* Description : Recherche le symbole contenant une adresse. *
+* *
+* Retour : true si l'opération a été un succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_format_find_symbol_for(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol)
+{
+ bool result; /* Bilan à retourner */
+
+ int find_symbol(const vmpa2t *addr, const GBinSymbol **sym)
{
- *symbol = *(GBinSymbol **)found;
+ const mrange_t *range; /* Espace mémoire parcouru */
- g_object_ref(G_OBJECT(*symbol));
- result = true;
+ range = g_binary_symbol_get_range(*sym);
+
+ return cmp_mrange_with_vmpa(range, addr);
}
+ result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, symbol);
+
return result;
}
@@ -734,7 +796,7 @@ bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr
bool result; /* Bilan à retourner */
const mrange_t *range; /* Espace mémoire parcouru */
- result = g_binary_format_find_symbol_at(format, addr, symbol);
+ result = g_binary_format_find_symbol_for(format, addr, symbol);
if (result)
{
@@ -916,47 +978,3 @@ 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] *
-* address = adresse à cibler, puis décallage final. [OUT] *
-* *
-* Description : Recherche une position dans une routine selon une adresse. *
-* *
-* Retour : true si l'opération a été un succès, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_binary_format_resolve_relative_routine(const GBinFormat *format, const char **label, 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->routines_count && !result; i++)
- {
- addr = g_binary_routine_get_address(format->routines[i]);
- size = g_binary_routine_get_size(format->routines[i]);
-
- if (addr <= *address && *address < (addr + size))
- {
- *label = g_binary_routine_get_long_name(format->routines[i]);
- *address -= addr;
-
- result = true;
-
- }
-
- }
-
- return result;
-
-}
diff --git a/src/format/format.h b/src/format/format.h
index 314306e..18dfda1 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -86,6 +86,9 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *, const char *, GBin
/* Recherche le symbole correspondant à une adresse. */
bool g_binary_format_find_symbol_at(const GBinFormat *, const vmpa2t *, GBinSymbol **);
+/* Recherche le symbole contenant une adresse. */
+bool g_binary_format_find_symbol_for(const GBinFormat *, const vmpa2t *, GBinSymbol **);
+
/* Recherche le symbole suivant celui lié à une adresse. */
bool g_binary_format_find_next_symbol_at(const GBinFormat *, const vmpa2t *, GBinSymbol **);
@@ -107,9 +110,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 une position dans une routine selon une adresse. */
-bool g_binary_format_resolve_relative_routine(const GBinFormat *, const char **, vmpa_t *);
-
#endif /* _FORMAT_FORMAT_H */
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index bd4702b..920fcfe 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -578,7 +578,7 @@ GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *a
result = NULL;
- for (i = 0; i < portion->sub_count && !result; i++)
+ for (i = 0; i < portion->sub_count && result == NULL; i++)
{
sub = portion->sub_portions[i];
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 6849585..bdd0a31 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -13,6 +13,7 @@ libgtkext_la_SOURCES = \
gtkdockstation.h gtkdockstation.c \
gtkgraphview.h gtkgraphview.c \
gtksourceview.h gtksourceview.c \
+ gtkstatusstack.h gtkstatusstack.c \
gtkviewpanel-int.h \
gtkviewpanel.h gtkviewpanel.c \
support.h support.c \
diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c
new file mode 100644
index 0000000..e9a61d8
--- /dev/null
+++ b/src/gtkext/gtkstatusstack.c
@@ -0,0 +1,609 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkstatusstack.c - empilement d'informations de statut
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * 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 "gtkstatusstack.h"
+
+
+#include <inttypes.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include <i18n.h>
+
+
+#include "easygtk.h"
+#include "../common/extstr.h"
+
+
+
+/* ------------------------- GESTION EXTERIEURE DE LA BARRE ------------------------- */
+
+
+/* Navigation au sein d'assemblage */
+typedef struct _assembly_info assembly_info;
+
+
+/* Abstration d'une gestion de barre de statut (instance) */
+struct _GtkStatusStack
+{
+ GtkBin parent; /* A laisser en premier */
+
+ GtkWidget *asm_status; /* Barre de status d'assemblage*/
+ assembly_info *asm_info; /* Informations courantes */
+
+};
+
+/* Abstration d'une gestion de barre de statut (classe) */
+struct _GtkStatusStackClass
+{
+ GtkBinClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des barres de statut améliorées. */
+static void gtk_status_stack_class_init(GtkStatusStackClass *);
+
+/* Initialise une instance de barre de statut améliorée. */
+static void gtk_status_stack_init(GtkStatusStack *);
+
+/* Supprime toutes les références externes. */
+static void gtk_status_stack_dispose(GtkStatusStack *);
+
+/* Procède à la libération totale de la mémoire. */
+static void gtk_status_stack_finalize(GtkStatusStack *);
+
+/* S'assure de l'affichage du niveau de pile attendu. */
+static void gtk_status_stack_switch(GtkStatusStack *, GtkWidget *);
+
+
+
+/* -------------------- STATUT DES INFORMATIONS DE DESASSEMBLAGE -------------------- */
+
+
+/* Navigation au sein d'assemblage */
+struct _assembly_info
+{
+ mrange_t current; /* Emplacement correspondant */
+
+ char *segment; /* Segment d'appartenance */
+
+ VMPA_BUFFER(phys); /* Localisation physique */
+ VMPA_BUFFER(virt); /* Localisation virtuelle */
+
+ char *symbol; /* Eventuel symbole concerné */
+
+ const char *encoding; /* Encodage de l'instruction */
+ phys_t size; /* Taille de l'instruction */
+
+};
+
+
+/* Supprime l'empreinte mémoire d'informations d'assemblage. */
+static void reset_assembly_info(assembly_info *);
+
+/* Construit une barre d'état pour language d'assemblage. */
+static GtkWidget *build_assembly_status_stack(GtkStatusStack *);
+
+/* Réagit à un redimensionnement de la barre de désassemblage. */
+static void on_size_allocate_for_asm_status(GtkWidget *, GdkRectangle *, GObject *);
+
+/* Réagit à un clic sur l'icône de zoom. */
+static void on_zoom_icon_press(GtkEntry *, GtkEntryIconPosition, GdkEventButton *, GtkStatusStack *);
+
+/* S'assure de l'affichage à jour de la partie "assemblage". */
+static void gtk_status_stack_show_current_instruction(GtkStatusStack *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GESTION EXTERIEURE DE LA BARRE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type de la barre de statut améliorée. */
+G_DEFINE_TYPE(GtkStatusStack, gtk_status_stack, GTK_TYPE_BIN)
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe GTK à initialiser. *
+* *
+* Description : Initialise la classe des barres de statut améliorées. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_class_init(GtkStatusStackClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)gtk_status_stack_dispose;
+ object->finalize = (GObjectFinalizeFunc)gtk_status_stack_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = instance GTK à initialiser. *
+* *
+* Description : Initialise une instance de barre de statut améliorée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_init(GtkStatusStack *stack)
+{
+ stack->asm_status = build_assembly_status_stack(stack);
+ stack->asm_info = (assembly_info *)calloc(1, sizeof(assembly_info));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_dispose(GtkStatusStack *stack)
+{
+ g_object_unref(G_OBJECT(stack->asm_status));
+
+ G_OBJECT_CLASS(gtk_status_stack_parent_class)->dispose(G_OBJECT(stack));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : view = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_finalize(GtkStatusStack *stack)
+{
+ reset_assembly_info(stack->asm_info);
+
+ free(stack->asm_info);
+
+ G_OBJECT_CLASS(gtk_status_stack_parent_class)->finalize(G_OBJECT(stack));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée une nouvelle instance de barre de statut. *
+* *
+* Retour : Composant GTK mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GtkWidget *gtk_status_stack_new(void)
+{
+ return g_object_new(GTK_TYPE_STATUS_STACK, NULL);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = pile de statuts à considérer. *
+* next = niveau de pile à afficher désormais. *
+* *
+* Description : S'assure de l'affichage du niveau de pile attendu. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_switch(GtkStatusStack *stack, GtkWidget *next)
+{
+ GtkWidget *child; /* Support courant */
+
+ child = gtk_bin_get_child(GTK_BIN(stack));
+
+ if (child != next)
+ {
+ if (child != NULL)
+ gtk_container_remove(GTK_CONTAINER(stack), child);
+
+ g_object_ref(G_OBJECT(next));
+ gtk_container_add(GTK_CONTAINER(stack), next);
+
+ }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* STATUT DES INFORMATIONS DE DESASSEMBLAGE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations à réinitialiser. *
+* *
+* Description : Supprime l'empreinte mémoire d'informations d'assemblage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void reset_assembly_info(assembly_info *info)
+{
+ if (info->segment != NULL)
+ {
+ free(info->segment);
+ info->segment = NULL;
+ }
+
+ if (info->symbol != NULL)
+ {
+ free(info->symbol);
+ info->symbol = NULL;
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = composant global en cours de construction. *
+* *
+* Description : Construit une barre d'état pour language d'assemblage. *
+* *
+* Retour : Composant GTK mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkWidget *build_assembly_status_stack(GtkStatusStack *stack)
+{
+ GtkWidget *result; /* Support à retourner */
+ GObject *ref; /* Espace de référencements */
+ GtkWidget *hbox; /* Sous-division horizontale */
+ GtkWidget *label; /* Etiquette pour impression */
+ GtkWidget *zoom; /* Sélection du zoom courant */
+
+ result = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_show(result);
+
+ ref = G_OBJECT(result);
+
+ g_signal_connect(result, "size-allocate", G_CALLBACK(on_size_allocate_for_asm_status), ref);
+
+ /* Première partie : navigation */
+
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 16);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(result), hbox, TRUE, TRUE, 8);
+
+ label = qck_create_label(ref, "segment", NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ label = qck_create_label(ref, "phys", NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ label = qck_create_label(ref, "virt", NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ label = qck_create_label(ref, "offset", NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ /* Seconde partie : architecture */
+
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
+ g_object_set_data(ref, "arch_box", hbox);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(result), hbox, FALSE, TRUE, 8);
+
+ label = qck_create_label(ref, "arch", NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ label = qck_create_label(ref, "size", NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ /* Troisième partie : affichage */
+
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(result), hbox, FALSE, FALSE, 8);
+
+ zoom = qck_create_entry(ref, "zoom", "100%");
+ gtk_entry_set_icon_from_icon_name(GTK_ENTRY(zoom), GTK_ENTRY_ICON_SECONDARY, "go-up-symbolic");
+
+ g_signal_connect(zoom, "icon-press", G_CALLBACK(on_zoom_icon_press), stack);
+
+ gtk_box_pack_start(GTK_BOX(hbox), zoom, FALSE, TRUE, 0);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant graphique qui vient d'évoluer. *
+* allocation = espace réservé pour le composant visé. *
+* ref = espace de référencement global. *
+* *
+* Description : Réagit à un redimensionnement de la barre de désassemblage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_size_allocate_for_asm_status(GtkWidget *widget, GdkRectangle *allocation, GObject *ref)
+{
+ GtkWidget *hbox; /* Sous-division horizontale */
+
+ hbox = GTK_WIDGET(g_object_get_data(ref, "arch_box"));
+
+ gtk_widget_set_size_request(hbox, (allocation->width * 40) / 100, -1);
+
+ /**
+ * On intervient après que le containeur soit passer collecter les tailles
+ * de ses enfants lors de son redimensionnement.
+ *
+ * Donc on force un prise en compte des changements.
+ */
+ gtk_container_check_resize(GTK_CONTAINER(widget));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : entry = zone de texte visée par la procédure. *
+* icon_pos = position de l'image associée à l'entrée. *
+* event = informations liées à l'événement. *
+* stack = composant graphique de gestion des statuts. *
+* *
+* Description : Réagit à un clic sur l'icône de zoom. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_zoom_icon_press(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEventButton *event, GtkStatusStack *stack)
+{
+ GtkWidget *popup; /* Popup à faire surgir */
+ GdkRectangle rect; /* Zone précise à cibler */
+
+ if (event->button != GDK_BUTTON_PRIMARY)
+ return;
+
+ popup = gtk_popover_new(GTK_WIDGET(entry));
+
+ gtk_entry_get_icon_area(entry, GTK_ENTRY_ICON_SECONDARY, &rect);
+ gtk_popover_set_pointing_to(GTK_POPOVER(popup), &rect);
+
+ gtk_widget_show(popup);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = barre de statut à actualiser. *
+* binary = binaire chargé rassemblant l'ensemble des infos. *
+* instr = instruction désassemblée ciblée graphiquement. *
+* *
+* Description : Actualise les informations liées une position d'assemblage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GLoadedBinary *binary, const GArchInstruction *instr)
+{
+ assembly_info *info; /* Informations à constituer */
+ GExeFormat *format; /* Format de binaire à traiter */
+ const mrange_t *range; /* Emplacement d'instruction */
+ const vmpa2t *addr; /* Localisation de départ */
+ GBinPortion *portions; /* Portions binaires existantes*/
+ GBinPortion *portion; /* Zone mémoire d'appartenance */
+ const char *text; /* Texte au contenu à copier */
+ GBinSymbol *symbol; /* Symbole présent à l'adresse */
+ phys_t diff; /* Décallage de l'adresse */
+ const char *label; /* Description d'un symbole */
+ vmpa2t tmp; /* Zone de construction temp. */
+ VMPA_BUFFER(offset); /* Décalage physique */
+
+ info = stack->asm_info;
+
+ format = g_loaded_binary_get_format(binary);
+
+ /* Bascule vers une zone courante nouvelle ? */
+
+ range = g_arch_instruction_get_range(instr);
+ addr = get_mrange_addr(range);
+
+ if (cmp_mrange(&info->current, range) == 0)
+ goto gssuci_useless;
+
+ /* Réinitialisation */
+
+ reset_assembly_info(info);
+
+ copy_mrange(&info->current, range);
+
+ /* Zone d'appartenance */
+
+ portions = g_exe_format_get_portions(format);
+
+ portion = g_binary_portion_find_at_addr(portions, addr, (GdkRectangle []) { });
+
+ text = g_binary_portion_get_desc(portion);
+
+ if (text != NULL)
+ info->segment = strdup(text);
+ else
+ info->segment = strdup(_("Binary"));
+
+ /* Adresses de base */
+
+ vmpa2_phys_to_string(addr, MDS_UNDEFINED, info->phys, NULL);
+
+ vmpa2_virt_to_string(addr, MDS_UNDEFINED, info->virt, NULL);
+
+ info->encoding = g_arch_instruction_get_encoding(instr);
+
+ info->size = get_mrange_length(range);
+
+ /* Symbole concerné */
+
+ if (g_binary_format_resolve_symbol(G_BIN_FORMAT(format), addr, &symbol, &diff))
+ {
+ label = g_binary_symbol_get_label(symbol);
+
+ if (label != NULL)
+ {
+ info->symbol = strdup(label);
+
+ info->symbol = stradd(info->symbol, "+");
+
+ init_vmpa(&tmp, diff, VMPA_NO_VIRTUAL);
+ vmpa2_phys_to_string(&tmp, MDS_UNDEFINED, offset, NULL);
+
+ info->symbol = stradd(info->symbol, offset);
+
+ }
+
+ g_object_unref(G_OBJECT(symbol));
+
+ }
+
+ /* Nettoyage et conclusion */
+
+ gtk_status_stack_show_current_instruction(stack);
+
+ gssuci_useless:
+
+ //g_object_unref(G_OBJECT(format));
+
+ ;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = pile de statuts à manipuler. *
+* *
+* Description : S'assure de l'affichage à jour de la partie "assemblage". *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_show_current_instruction(GtkStatusStack *stack)
+{
+ GObject *ref; /* Espace de référencements */
+ assembly_info *info; /* Informations à consulter */
+ GtkLabel *label; /* Etiquette à actualiser */
+ char raw_pos[6 + VMPA_MAX_LEN + 1]; /* Formatage final en direct */
+ char *content; /* Contenu dynamique */
+
+ gtk_status_stack_switch(stack, stack->asm_status);
+
+ ref = G_OBJECT(stack->asm_status);
+ info = stack->asm_info;
+
+ /* Première partie : navigation */
+
+ label = GTK_LABEL(g_object_get_data(ref, "segment"));
+ gtk_label_set_text(label, info->segment);
+
+ snprintf(raw_pos, sizeof(raw_pos), "phys: %s", info->phys);
+
+ label = GTK_LABEL(g_object_get_data(ref, "phys"));
+ gtk_label_set_text(label, raw_pos);
+
+ snprintf(raw_pos, sizeof(raw_pos), "virt: %s", info->virt);
+
+ label = GTK_LABEL(g_object_get_data(ref, "virt"));
+ gtk_label_set_text(label, raw_pos);
+
+ label = GTK_LABEL(g_object_get_data(ref, "offset"));
+ gtk_label_set_text(label, info->symbol != NULL ? info->symbol : "");
+
+ /* Seconde partie : architecture */
+
+ label = GTK_LABEL(g_object_get_data(ref, "arch"));
+ gtk_label_set_text(label, info->encoding);
+
+ if (info->size > 1)
+ asprintf(&content, "%" PRIu64 " %s", (uint64_t)info->size, _("bytes"));
+ else
+ asprintf(&content, "%" PRIu64 " %s", (uint64_t)info->size, _("byte"));
+
+ label = GTK_LABEL(g_object_get_data(ref, "size"));
+ gtk_label_set_text(label, content);
+
+ free(content);
+
+}
diff --git a/src/gtkext/gtkstatusstack.h b/src/gtkext/gtkstatusstack.h
new file mode 100644
index 0000000..9d25c8f
--- /dev/null
+++ b/src/gtkext/gtkstatusstack.h
@@ -0,0 +1,79 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkstatusstack.h - prototypes pour un empilement d'informations de statut
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * 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_GTKSTATUSSTACK_H
+#define _GTKEXT_GTKSTATUSSTACK_H
+
+
+
+#include <gtk/gtk.h>
+
+
+#include "../analysis/binary.h"
+
+
+
+/* FIXME */
+typedef int bstatus_id_t;
+
+
+
+
+/* ------------------------- GESTION EXTERIEURE DE LA BARRE ------------------------- */
+
+
+#define GTK_TYPE_STATUS_STACK (gtk_status_stack_get_type())
+#define GTK_STATUS_STACK(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GTK_TYPE_STATUS_STACK, GtkStatusStack))
+#define GTK_STATUS_STACK_CLASS(klass) (G_LOADED_BINARY_GET_CLASS(klass, GTK_TYPE_STATUS_STACK, GtkStatusStackClass))
+#define GTK_IS_STATUS_STACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GTK_TYPE_STATUS_STACK))
+#define GTK_IS_STATUS_STACK_CLASS(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GTK_TYPE_STATUS_STACK))
+#define GTK_STATUS_STACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_STATUS_STACK, GtkStatusStackClass))
+
+
+/* Abstration d'une gestion de barre de statut (instance) */
+typedef struct _GtkStatusStack GtkStatusStack;
+
+/* Abstration d'une gestion de barre de statut (classe) */
+typedef struct _GtkStatusStackClass GtkStatusStackClass;
+
+
+/* Détermine le type de la barre de statut améliorée. */
+GType gtk_status_stack_get_type(void);
+
+/* Crée une nouvelle instance de barre de statut. */
+GtkWidget *gtk_status_stack_new(void);
+
+
+
+/* -------------------- STATUT DES INFORMATIONS DE DESASSEMBLAGE -------------------- */
+
+
+/* Actualise les informations liées une position d'assemblage. */
+void gtk_status_stack_update_current_instruction(GtkStatusStack *, const GLoadedBinary *, const GArchInstruction *);
+
+
+
+
+
+
+#endif /* _GTKEXT_GTKSTATUSSTACK_H */
diff --git a/src/gui/editor.c b/src/gui/editor.c
index 1742596..bc4f144 100644
--- a/src/gui/editor.c
+++ b/src/gui/editor.c
@@ -177,7 +177,7 @@ GtkWidget *create_editor(void)
- vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
+ vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
gtk_widget_show(vbox1);
gtk_container_add(GTK_CONTAINER(result), vbox1);
diff --git a/src/gui/status.c b/src/gui/status.c
index 41cad1a..f466193 100644
--- a/src/gui/status.c
+++ b/src/gui/status.c
@@ -36,7 +36,7 @@
#include "../common/extstr.h"
#include "../gtkext/gtkbufferview.h"
#include "../gtkext/gtkblockview.h"
-#include "../gtkext/gtkextstatusbar.h"
+#include "../gtkext/gtkstatusstack.h"
@@ -136,7 +136,7 @@ static void g_status_info_init(GStatusInfo *bar)
item->name = "status";
- item->widget = gtk_extended_status_bar_new();
+ item->widget = gtk_status_stack_new();
gtk_widget_show(item->widget);
}
@@ -271,89 +271,12 @@ static void track_caret_address_on_buffer_views(GtkBufferView *view, const vmpa2
{
GEditorItem *item; /* Autre version de l'élément */
GLoadedBinary *binary; /* Binaire courant */
- GExeFormat *format; /* Format du fichier binaire */
- GArchProcessor *proc; /* Architecture du binaire */
- MemoryDataSize msize; /* Taille par défaut */
- char *msg; /* Message à transmettre */
- VMPA_BUFFER(conv); /* Zone de conversion */
-
- vmpa_t rel; /* Adresse relative à un symb. */
- const char *label; /* Désignation d'un symbole */
item = G_EDITOR_ITEM(info);
binary = g_editor_item_get_current_binary(item);
- proc = g_loaded_binary_get_processor(binary);
- msize = g_arch_processor_get_memory_size(proc);
- g_object_unref(G_OBJECT(proc));
-
- /* Réinitiation seule si il n'y a plus d'adresse... */
-
- if (addr == NULL)
- {
- if (info->msg_id > 0)
- gtk_extended_status_bar_remove(GTK_EXT_STATUS_BAR(item->widget), info->msg_id);
-
- return;
-
- }
-
- /* Adresse brute */
-
- msize = g_arch_processor_get_memory_size(proc);
-
- msg = strdup(_("Location phys:"));
-
- vmpa2_phys_to_string(addr, msize, conv, NULL);
- msg = stradd(msg, conv);
-
- msg = stradd(msg, " virt:");
-
- vmpa2_virt_to_string(addr, msize, conv, NULL);
- msg = stradd(msg, conv);
-
-
-
-#if 0
-
- /* Relation avec les symboles */
-
- binary = G_LOADED_BINARY(g_object_get_data(item->ref, "current_binary"));
- format = g_loaded_binary_get_format(binary);
-
- rel = addr;
-
- if (g_binary_format_resolve_relative_routine(G_BIN_FORMAT(format), &label, &rel))
- {
- msg = stradd(msg, _(" at "));
- msg = stradd(msg, label);
- msg = stradd(msg, _("+"));
-
- snprintf(tmp, VMPA_MAX_SIZE, VMPA_FMT, rel);
- msg = stradd(msg, tmp);
-
- }
-
-#endif
-
-
- /* Impression */
-
- if (info->msg_id > 0)
- gtk_extended_status_bar_remove(GTK_EXT_STATUS_BAR(item->widget), info->msg_id);
-
- info->msg_id = gtk_extended_status_bar_push(GTK_EXT_STATUS_BAR(item->widget), msg, FALSE);
-
-
- printf("---- moved to 0x%08llx\n", addr);
-
- printf(" MSG '%s'\n", msg);
-
- //update_menu_project_for_project(bar->project, project, bar);
-
-
- free(msg);
+ focus_address_in_status_info(info, binary, addr);
}
@@ -374,85 +297,17 @@ static void track_caret_address_on_buffer_views(GtkBufferView *view, const vmpa2
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);
+ GArchInstruction *instr; /* Instruction présente */
+ GEditorItem *item; /* Autre version de l'élément */
proc = g_loaded_binary_get_processor(binary);
- msize = g_arch_processor_get_memory_size(proc);
- g_object_unref(G_OBJECT(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_get_label(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);
+ instr = g_arch_processor_find_instr_by_address(proc, addr);
- }
-
- 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);
+ item = G_EDITOR_ITEM(info);
+ gtk_status_stack_update_current_instruction(GTK_STATUS_STACK(item->widget), binary, instr);
- free(msg);
+ g_object_unref(G_OBJECT(proc));
}