summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-01-16 21:12:08 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-01-16 21:12:08 (GMT)
commit52ac5b1b340335f56ceb599dba63164a26f10b10 (patch)
tree275104896dffa65e7887284857fa8fed831e9ea8 /src
parent2ddb5c26af896b10517a89abf0c9498c598b7697 (diff)
Changed the display of a segment containing the value of an immediate.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/db/collection.c46
-rw-r--r--src/analysis/db/items/bookmark.c52
-rw-r--r--src/analysis/db/items/comment.c4
-rw-r--r--src/analysis/db/items/switcher.c138
-rw-r--r--src/analysis/db/misc/rlestr.c6
-rw-r--r--src/analysis/db/misc/timestamp.c6
-rw-r--r--src/arch/immediate.c86
-rw-r--r--src/arch/immediate.h15
-rw-r--r--src/arch/vmpa.c14
-rw-r--r--src/common/sqlite.h5
-rw-r--r--src/format/symbol.h13
-rw-r--r--src/glibext/gbufferline.c115
-rw-r--r--src/glibext/gbufferline.h3
-rw-r--r--src/glibext/gbuffersegment.c42
-rw-r--r--src/glibext/gbuffersegment.h3
-rw-r--r--src/glibext/gcodebuffer.c132
-rw-r--r--src/gui/menus/edition.c38
17 files changed, 615 insertions, 103 deletions
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index 117a2d5..d5518dd 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -559,12 +559,8 @@ bool g_db_collection_has_item(GDbCollection *collec, GDbItem *item)
* Il n'y a pas d'assert() possible pour le vérifier...
*/
- printf(" --- has\n");
-
found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_with_timestamp);
- printf(" --- has: %p\n", found);
-
result = (found != NULL);
return result;
@@ -950,6 +946,7 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db)
size_t i; /* Boucle de parcours */
sqlite3_stmt *stmt; /* Déclaration mise en place */
int ret; /* Bilan d'un appel à SQLite */
+ int native_type; /* Type de valeur dans la base */
GDbItem *new; /* Nouvel élément à insérer */
if (!g_db_collection_setup_load(collec, &values, &count))
@@ -990,12 +987,39 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db)
for (i = 0; i < count; i++)
{
- values[i].type = sqlite3_column_type(stmt, i);
+ native_type = sqlite3_column_type(stmt, i);
+
+ /**
+ * On réalise une petite conversion selon le champ.
+ *
+ * Le filtre SQLITE_NATIVE est destiné à conserver un champ sur 32 bits
+ * quand il s'agit du format utilisé, même si toutes les valeurs sont
+ * enregistrées en 64 bits.
+ *
+ * C'est par exemple le cas dans les bascules d'affichage.
+ *
+ * D'autres éléments, comme les localisations en mémoire, peuvent
+ * avoir un champ éventuellement nul, donc la définition à partir des
+ * indications de la base de données reste importante.
+ */
+
+ if (native_type == SQLITE_INTEGER)
+ native_type = SQLITE_INT64;
+
+ if (values[i].type == SQLITE_NATIVE)
+ values[i].type = native_type;
+
+ else
+ assert(values[i].type == native_type || values[i].type == SQLITE_INTEGER);
+
switch (values[i].type)
{
case SQLITE_INTEGER:
- values[i].type = SQLITE_INT64;
+ values[i].integer = (int)sqlite3_column_int64(stmt, i);
+ break;
+
+ case SQLITE_INT64:
values[i].integer64 = sqlite3_column_int64(stmt, i);
break;
@@ -1118,6 +1142,11 @@ static bool g_db_collection_store_item(const GDbCollection *collec, const GDbIte
{
switch (values[i].type)
{
+ case SQLITE_INTEGER:
+ ret = sqlite3_bind_int(stmt, index, values[i].integer);
+ index++;
+ break;
+
case SQLITE_INT64:
ret = sqlite3_bind_int64(stmt, index, values[i].integer64);
index++;
@@ -1272,6 +1301,11 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons
switch (values[i].type)
{
+ case SQLITE_INTEGER:
+ ret = sqlite3_bind_int(stmt, index, values[i].integer);
+ index++;
+ break;
+
case SQLITE_INT64:
ret = sqlite3_bind_int64(stmt, index, values[i].integer64);
index++;
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index ba64491..6914bc3 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -80,12 +80,12 @@ static bool g_db_bookmark_recv_from_fd(GDbBookmark *, int, int);
/* Exporte la définition d'un signet dans un flux réseau. */
static bool g_db_bookmark_send_to_fd(const GDbBookmark *, int, int);
-/* Exécute un signet sur un tampon de binaire chargé. */
-static bool g_db_bookmark_run(GDbBookmark *, GLoadedBinary *, bool *, bool);
-
/* Construit la description humaine d'un signet sur un tampon. */
static void g_db_bookmark_build_label(GDbBookmark *);
+/* Exécute un signet sur un tampon de binaire chargé. */
+static bool g_db_bookmark_run(GDbBookmark *, GLoadedBinary *, bool *, bool);
+
/* Applique un signet sur un tampon de binaire chargé. */
static bool g_db_bookmark_apply(GDbBookmark *, GLoadedBinary *);
@@ -179,7 +179,7 @@ static void g_db_bookmark_class_init(GDbBookmarkClass *klass)
item->recv = (recv_db_item_fc)g_db_bookmark_recv_from_fd;
item->send = (send_db_item_fc)g_db_bookmark_send_to_fd;
- item->build_label = (build_item_label_fc)g_db_bookmark_build_label;
+ item->build_label = (build_item_label_fc)g_db_bookmark_build_label;
item->apply = (run_item_fc)g_db_bookmark_apply;
item->cancel = (run_item_fc)g_db_bookmark_cancel;
@@ -373,6 +373,25 @@ static bool g_db_bookmark_send_to_fd(const GDbBookmark *bookmark, int fd, int fl
/******************************************************************************
* *
* Paramètres : bookmark = signet à manipuler. *
+* *
+* Description : Construit la description humaine d'un signet sur un tampon. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_bookmark_build_label(GDbBookmark *bookmark)
+{
+ asprintf(&G_DB_ITEM(bookmark)->label, _("Bookmark \"%s\""), get_rle_string(&bookmark->comment));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : bookmark = signet à manipuler. *
* binary = binaire chargé en mémoire à modifier. *
* prev = état précédent de la présence du drapeau. *
* set = précision quant au nouvel état du drapeau. *
@@ -422,25 +441,6 @@ static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool
/******************************************************************************
* *
* Paramètres : bookmark = signet à manipuler. *
-* *
-* Description : Construit la description humaine d'un signet sur un tampon. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_db_bookmark_build_label(GDbBookmark *bookmark)
-{
- asprintf(&G_DB_ITEM(bookmark)->label, _("Bookmark \"%s\""), get_rle_string(&bookmark->comment));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : bookmark = signet à manipuler. *
* binary = binaire chargé en mémoire à modifier. *
* *
* Description : Applique un signet sur un tampon de binaire chargé. *
@@ -663,14 +663,10 @@ static void g_bookmark_collection_class_init(GBookmarkCollectionClass *klass)
static void g_bookmark_collection_init(GBookmarkCollection *collec)
{
-
-
- G_DB_COLLECTION(collec)->featuring = 0;
+ G_DB_COLLECTION(collec)->featuring = DBF_BOOKMARKS;
G_DB_COLLECTION(collec)->type = G_TYPE_DB_BOOKMARK;
G_DB_COLLECTION(collec)->name = "Bookmarks";
-
-
}
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 249620b..9212cae 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -526,14 +526,10 @@ static void g_comment_collection_class_init(GCommentCollectionClass *klass)
static void g_comment_collection_init(GCommentCollection *collec)
{
-
-
G_DB_COLLECTION(collec)->featuring = 0;
G_DB_COLLECTION(collec)->type = G_TYPE_DB_COMMENT;
G_DB_COLLECTION(collec)->name = "Comments";
-
-
}
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 67187aa..7b72cf2 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -29,6 +29,9 @@
#include <sys/socket.h>
+#include <i18n.h>
+
+
#include "../collection-int.h"
#include "../item-int.h"
#include "../../../common/io.h"
@@ -83,6 +86,9 @@ static bool g_db_switcher_recv_from_fd(GDbSwitcher *, int, int);
/* Exporte la définition d'un signet dans un flux réseau. */
static bool g_db_switcher_send_to_fd(const GDbSwitcher *, int, int);
+/* Construit la description humaine d'un signet sur un tampon. */
+static void g_db_switcher_build_label(GDbSwitcher *);
+
/* Exécute une bascule d'affichage d'opérande sur un binaire. */
static bool g_db_switcher_run(GDbSwitcher *, GLoadedBinary *, ImmOperandDisplay *, ImmOperandDisplay);
@@ -180,6 +186,7 @@ static void g_db_switcher_class_init(GDbSwitcherClass *klass)
item->recv = (recv_db_item_fc)g_db_switcher_recv_from_fd;
item->send = (send_db_item_fc)g_db_switcher_send_to_fd;
+ item->build_label = (build_item_label_fc)g_db_switcher_build_label;
item->apply = (run_item_fc)g_db_switcher_apply;
item->cancel = (run_item_fc)g_db_switcher_cancel;
@@ -364,7 +371,6 @@ static bool g_db_switcher_recv_from_fd(GDbSwitcher *switcher, int fd, int flags)
{
bool status; /* Bilan d'opération initiale */
uint32_t val32; /* Valeur sur 32 bits */
- ssize_t got; /* Quantité de données reçues */
status = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->recv(G_DB_ITEM(switcher), fd, flags);
if (!status) return false;
@@ -372,17 +378,17 @@ static bool g_db_switcher_recv_from_fd(GDbSwitcher *switcher, int fd, int flags)
if (!recv_vmpa(&switcher->addr, fd, flags))
return false;
- got = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL);
- if (got != sizeof(uint32_t)) return false;
+ status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags);
+ if (!status) return false;
switcher->index = be32toh(val32);
- got = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL);
- if (got != sizeof(uint32_t)) return false;
+ status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags);
+ if (!status) return false;
switcher->display = be32toh(val32);
- if (switcher->display >= IOD_COUNT)
+ if (switcher->display > IOD_COUNT)
return false;
return true;
@@ -428,6 +434,52 @@ static bool g_db_switcher_send_to_fd(const GDbSwitcher *switcher, int fd, int fl
/******************************************************************************
* *
* Paramètres : switcher = bascule d'affichage à manipuler. *
+* *
+* Description : Construit la description humaine d'un signet sur un tampon. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_switcher_build_label(GDbSwitcher *switcher)
+{
+ VMPA_BUFFER(loc); /* Indication de position */
+
+ if (has_virt_addr(&switcher->addr))
+ vmpa2_virt_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL);
+ else
+ vmpa2_phys_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL);
+
+ switch (switcher->display)
+ {
+ case IOD_BIN:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Switch to binary display at %s"), loc);
+ break;
+ case IOD_OCT:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc);
+ break;
+ case IOD_DEC:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc);
+ break;
+ case IOD_HEX:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Switch to octal display at %s"), loc);
+ break;
+ case IOD_COUNT:
+ asprintf(&G_DB_ITEM(switcher)->label, _("Reset to default display at %s"), loc);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : switcher = bascule d'affichage à manipuler. *
* binary = binaire chargé en mémoire à modifier. *
* old = état précédent à conserver. *
* new = nouvel état à appliquer. *
@@ -446,31 +498,78 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
GArchProcessor *proc; /* Propriétaire d'instructions */
GArchInstruction *instr; /* Instruction à traiter */
GArchOperand *op; /* Opérande à modifier */
+ GCodeBuffer *buffer; /* Tampon de lignes à traiter */
+ GBufferLine *line; /* Ligne de tampon à marquer */
+ GBufferSegment *segment; /* Segment de texte à modifier*/
+ GImmOperand *operand; /* Opérande de valeur immédiate*/
+ char value[IMM_MAX_SIZE]; /* Chaîne à imprimer */
+ size_t len; /* Taille de l'élément inséré */
result = true;
+ /* Traitement au niveau des instructions */
+
proc = g_loaded_binary_get_processor(binary);
instr = g_arch_processor_find_instr_by_address(proc, &switcher->addr);
if (instr == NULL)
{
result = false;
- goto exit;
+ goto exit_instr;
}
op = g_arch_instruction_get_operand(instr, switcher->index);
if (op == NULL)
{
result = false;
- goto exit;
+ goto exit_instr;
}
result = G_IS_IMM_OPERAND(op);
+ if (!result) goto exit_instr;
+
+ /* Traitement au niveau du rendu graphique */
+
+ buffer = g_loaded_binary_get_disassembled_buffer(binary);
+
+ line = g_code_buffer_find_line_by_addr(buffer, &switcher->addr, BLF_HAS_CODE, NULL);
+ if (line == NULL)
+ {
+ result = false;
+ goto exit_gui;
+ }
+
+ segment = g_buffer_line_find_segment_from_creator(line, G_OBJECT(op));
+ result = (segment != NULL);
+
+ /* Applications globales finales */
if (result)
- g_imm_operand_set_display(G_IMM_OPERAND(op), new);
+ {
+ operand = G_IMM_OPERAND(op);
+
+ *old = g_imm_operand_get_display(operand);
+
+ if (new == IOD_COUNT)
+ new = g_imm_operand_get_default_display(operand);
+
+ g_imm_operand_set_display(operand, new);
+
+ len = g_imm_operand_to_string(operand, ASX_INTEL, value);
+
+ g_buffer_segment_update_text(segment, value, len);
+
+ g_object_unref(G_OBJECT(segment));
+
+ }
- exit:
+ g_object_unref(G_OBJECT(line));
+
+ exit_gui:
+
+ /* TODO g_object_unref(G_OBJECT(buffer));*/
+
+ exit_instr:
g_object_unref(G_OBJECT(proc));
@@ -562,7 +661,7 @@ static bool g_db_switcher_prepare_db_statement(const GDbSwitcher *switcher, boun
value->integer = switcher->index;
value->delete = NULL;
- value = &(*values)[*count - 2];
+ value = &(*values)[*count - 1];
value->name = "type";
value->type = SQLITE_INTEGER;
@@ -677,14 +776,10 @@ static void g_switcher_collection_class_init(GSwitcherCollectionClass *klass)
static void g_switcher_collection_init(GSwitcherCollection *collec)
{
-
-
- G_DB_COLLECTION(collec)->featuring = 0;
+ G_DB_COLLECTION(collec)->featuring = DBF_DISPLAY_SWITCHERS;
G_DB_COLLECTION(collec)->type = G_TYPE_DB_SWITCHER;
G_DB_COLLECTION(collec)->name = "Switchers";
-
-
}
@@ -804,6 +899,7 @@ static bool g_switcher_collection_create_db_table(const GSwitcherCollection *col
static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_value **values, size_t *count)
{
bool status; /* Bilan d'une préparation */
+ bound_value *value; /* Valeur à éditer / définir */
status = G_DB_COLLECTION_CLASS(g_switcher_collection_parent_class)->setup_load(G_DB_COLLECTION(collec), \
values, count);
@@ -815,9 +911,15 @@ static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_
*count += 2;
*values = (bound_value *)realloc(*values, *count * sizeof(bound_value));
- (*values)[*count - 2].name = "op_index";
+ value = &(*values)[*count - 2];
+
+ value->name = "op_index";
+ value->type = SQLITE_INTEGER;
+
+ value = &(*values)[*count - 1];
- (*values)[*count - 1].name = "type";
+ value->name = "type";
+ value->type = SQLITE_INTEGER;
return true;
diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c
index cbf9291..3f45df6 100644
--- a/src/analysis/db/misc/rlestr.c
+++ b/src/analysis/db/misc/rlestr.c
@@ -294,9 +294,13 @@ bool prepare_db_statement_for_rle_string(const rle_string *str, const char *name
bool setup_load_of_rle_string(const rle_string *str, const char *name, bound_value **values, size_t *count)
{
+ bound_value *value; /* Valeur à éditer / définir */
+
*values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value));
+ value = &(*values)[*count - 1];
- (*values)[*count - 1].name = name;
+ value->name = name;
+ value->type = SQLITE_NATIVE;
return true;
diff --git a/src/analysis/db/misc/timestamp.c b/src/analysis/db/misc/timestamp.c
index 624c811..d3ff474 100644
--- a/src/analysis/db/misc/timestamp.c
+++ b/src/analysis/db/misc/timestamp.c
@@ -223,9 +223,13 @@ bool prepare_db_statement_for_timestamp(const timestamp_t *timestamp, const char
bool setup_load_of_timestamp(const timestamp_t *timestamp, const char *name, bound_value **values, size_t *count)
{
+ bound_value *value; /* Valeur à éditer / définir */
+
*values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value));
+ value = &(*values)[*count - 1];
- (*values)[*count - 1].name = name;
+ value->name = name;
+ value->type = SQLITE_INT64;
return true;
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index 4c9ea84..288b364 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -24,6 +24,7 @@
#include "immediate.h"
+#include <assert.h>
#include <inttypes.h>
#include <malloc.h>
#include <stdarg.h>
@@ -71,6 +72,7 @@ struct _GImmOperand
} signed_imm;
bool zpad; /* Ajoute des 0 à l'impression */
+ ImmOperandDisplay def_display; /* Type par défaut d'affichage */
ImmOperandDisplay display; /* Format général d'affichage */
};
@@ -81,6 +83,11 @@ struct _GImmOperandClass
{
GArchOperandClass parent; /* Classe parente */
+ /* Signaux */
+
+ void (* value_changed) (GImmOperand *);
+ void (* output_changed) (GImmOperand *);
+
};
@@ -96,9 +103,6 @@ static void g_imm_operand_dispose(GImmOperand *);
/* Procède à la libération totale de la mémoire. */
static void g_imm_operand_finalize(GImmOperand *);
-/* Construit la chaîne de caractères correspondant à l'opérande. */
-static size_t g_imm_operand_to_string(const GImmOperand *, AsmSyntax, char [VMPA_MAX_SIZE]);
-
/* Traduit un opérande en version humainement lisible. */
static void g_imm_operand_print(const GImmOperand *, GBufferLine *, AsmSyntax);
@@ -134,6 +138,22 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)
operand->print = (operand_print_fc)g_imm_operand_print;
+ g_signal_new("value-changed",
+ G_TYPE_IMM_OPERAND,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GImmOperandClass, value_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_signal_new("output-changed",
+ G_TYPE_IMM_OPERAND,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GImmOperandClass, output_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
}
@@ -575,6 +595,8 @@ bool g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t
operand->size = size;
operand->raw = value;
+ g_signal_emit_by_name(operand, "value-changed");
+
return true;
}
@@ -597,6 +619,8 @@ void g_imm_operand_pad(GImmOperand *operand, bool state)
{
operand->zpad = state;
+ g_signal_emit_by_name(operand, "output-changed");
+
}
@@ -621,6 +645,45 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)
/******************************************************************************
* *
+* Paramètres : operand = structure dont le contenu par défaut est à définir.*
+* display = format global d'un affichage de valeur. *
+* *
+* Description : Définit le format textuel par défaut de la valeur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display)
+{
+ operand->def_display = display;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* *
+* Description : Indique le format textuel par défaut de la valeur. *
+* *
+* Retour : Format global d'un affichage de valeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
+{
+ return operand->def_display;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = structure dont le contenu est à définir. *
* display = format global d'un affichage de valeur. *
* *
@@ -636,6 +699,8 @@ void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
{
operand->display = display;
+ g_signal_emit_by_name(operand, "output-changed");
+
}
@@ -730,13 +795,14 @@ bool g_imm_operand_is_null(const GImmOperand *operand)
* *
******************************************************************************/
-static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[VMPA_MAX_SIZE])
+size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[IMM_MAX_SIZE])
{
size_t result; /* Longueur à retourner */
unsigned int range; /* Catégorie de la taille */
const char *prefix; /* Entrée en matière */
const char *suffix; /* Sortie de matière */
const char *alternate; /* Préfixe de forme alternative*/
+ const char *intro; /* Introduction du formatage */
const char *zpad; /* Remplissage par des zéros */
const char *lmod; /* Modification de longueur */
const char *conv; /* Opérateur de conversion */
@@ -783,6 +849,12 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
break;
}
+ /* Va-t-on réellement avoir besoin d'un formatage ? */
+ if (operand->display != IOD_BIN)
+ intro = "%";
+ else
+ intro = "";
+
/* Drapeau de remplissage ? */
switch (operand->display)
{
@@ -838,7 +910,7 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
/* Impression finale */
- snprintf(format, sizeof(format), "%s%s%%%s%s%s%s", prefix, alternate, zpad, lmod, conv, suffix);
+ snprintf(format, sizeof(format), "%s%s%s%s%s%s%s", prefix, alternate, intro, zpad, lmod, conv, suffix);
switch (operand->size)
{
@@ -888,6 +960,8 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
}
+ assert(((int)result) > 0);
+
return result;
}
@@ -909,7 +983,7 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
static void g_imm_operand_print(const GImmOperand *operand, GBufferLine *line, AsmSyntax syntax)
{
- char value[VMPA_MAX_SIZE]; /* Chaîne à imprimer */
+ char value[IMM_MAX_SIZE]; /* Chaîne à imprimer */
size_t len; /* Taille de l'élément inséré */
GBufferSegment *segment; /* Nouveau segment mis en place*/
diff --git a/src/arch/immediate.h b/src/arch/immediate.h
index 1a587ad..32d2a07 100644
--- a/src/arch/immediate.h
+++ b/src/arch/immediate.h
@@ -98,6 +98,12 @@ void g_imm_operand_pad(GImmOperand *, bool);
/* Indique le signe d'une valeur immédiate. */
bool g_imm_operand_does_padding(const GImmOperand *);
+/* Définit le format textuel par défaut de la valeur. */
+void g_imm_operand_set_default_display(GImmOperand *, ImmOperandDisplay);
+
+/* Indique le format textuel par défaut de la valeur. */
+ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *);
+
/* Définit la grande ligne du format textuel de la valeur. */
void g_imm_operand_set_display(GImmOperand *, ImmOperandDisplay);
@@ -110,6 +116,15 @@ bool g_imm_operand_is_negative(const GImmOperand *);
/* Indique si une valeur immédiate est nulle ou non. */
bool g_imm_operand_is_null(const GImmOperand *);
+/**
+ * La taille d'impression d'un opérande n'est pas VMPA_MAX_SIZE,
+ * mais 1 + 64 caractères + octet nul final en cas d'impression en binaire.
+ */
+#define IMM_MAX_SIZE 66
+
+/* Construit la chaîne de caractères correspondant à l'opérande. */
+size_t g_imm_operand_to_string(const GImmOperand *, AsmSyntax, char [IMM_MAX_SIZE]);
+
/* Convertit une valeur immédiate en adresse de type virt_t. */
bool g_imm_operand_to_virt_t(const GImmOperand *, virt_t *);
diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c
index 25b01c3..3b1bcec 100644
--- a/src/arch/vmpa.c
+++ b/src/arch/vmpa.c
@@ -566,12 +566,20 @@ vmpa2t *string_to_vmpa_virt(const char *buffer)
bool setup_load_for_vmpa(const vmpa2t *addr, bound_value **values, size_t *count)
{
- (*count) += 2;
+ bound_value *value; /* Valeur à éditer / définir */
+ (*count) += 2;
*values = (bound_value *)realloc(*values, (*count) * sizeof(bound_value));
- (*values)[*count - 2].name = "phys";
- (*values)[*count - 1].name = "virt";
+ value = &(*values)[*count - 2];
+
+ value->name = "phys";
+ value->type = SQLITE_NATIVE;
+
+ value = &(*values)[*count - 1];
+
+ value->name = "virt";
+ value->type = SQLITE_NATIVE;
return true;
diff --git a/src/common/sqlite.h b/src/common/sqlite.h
index 26dbd33..2036589 100644
--- a/src/common/sqlite.h
+++ b/src/common/sqlite.h
@@ -31,8 +31,9 @@
/* Type pour les insertions brutes */
-#define SQLITE_RAW 0
-#define SQLITE_INT64 10
+#define SQLITE_RAW 0 /* En dur dans une requête */
+#define SQLITE_INT64 10 /* Entier sur 64 bits */
+#define SQLITE_NATIVE 11 /* Déterminé par la base */
/* Description des champs et de leur valeur associée */
diff --git a/src/format/symbol.h b/src/format/symbol.h
index 6f38020..94003bb 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -120,12 +120,13 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *);
* Confort pour l'ajout de symboles basés sur des formats.
*/
-#define SET_IMM_DISPLAY(_ins, _op, _idx, _dsp) \
- do \
- { \
- _op = g_arch_instruction_get_operand(_ins, _idx); \
- g_imm_operand_set_display(G_IMM_OPERAND(_op), _dsp); \
- } \
+#define SET_IMM_DISPLAY(_ins, _op, _idx, _dsp) \
+ do \
+ { \
+ _op = g_arch_instruction_get_operand(_ins, _idx); \
+ g_imm_operand_set_default_display(G_IMM_OPERAND(_op), _dsp); \
+ g_imm_operand_set_display(G_IMM_OPERAND(_op), _dsp); \
+ } \
while (0)
#define ADD_RAW_AS_SYM(_fmt, _sym, _pos, _ins, _cmt, _txt) \
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 2680dae..1a17a9c 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -74,6 +74,9 @@ static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, GdkScr
/* Fournit le segment voisin d'un autre segment identifié. */
static GBufferSegment *find_near_segment(const buffer_line_column *, GBufferSegment *, GdkScrollDirection);
+/* Fournit le segment créé par un objet particulier. */
+static GBufferSegment *find_segment_from_creator(const buffer_line_column *, GObject *);
+
/* Imprime le contenu d'une colonne de ligne de texte. */
static void draw_segments_of_column(buffer_line_column *, cairo_t *, gint, gint, const segcnt_list *);
@@ -121,6 +124,8 @@ struct _GBufferLineClass
/* Signaux */
+ void (* content_changed) (GBufferLine *, GBufferSegment *);
+
void (* flip_flag) (GBufferLine *, BufferLineFlags, BufferLineFlags);
};
@@ -138,6 +143,9 @@ static void g_buffer_line_dispose(GBufferLine *);
/* Procède à la libération totale de la mémoire. */
static void g_buffer_line_finalize(GBufferLine *);
+/* Réagit au changement de contenu d'un segment encapsulé. */
+static void on_line_segment_changed(GBufferSegment *, GBufferLine *);
+
/* ---------------------------------------------------------------------------------- */
@@ -145,9 +153,6 @@ static void g_buffer_line_finalize(GBufferLine *);
/* ---------------------------------------------------------------------------------- */
-
-
-
/******************************************************************************
* *
* Paramètres : column = colonne de ligne à mettre à jour. *
@@ -333,13 +338,14 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x,
static GBufferSegment *find_near_segment(const buffer_line_column *column, GBufferSegment *target, GdkScrollDirection dir)
{
GBufferSegment *result; /* Trouvaille à retourner */
+ bool found; /* Le segment est bien présent */
size_t i; /* Boucle de parcours */
result = NULL;
- column_has_segment(column, target, &i);
+ found = column_has_segment(column, target, &i);
- if (i < column->count)
+ if (found)
switch (dir)
{
case GDK_SCROLL_LEFT:
@@ -364,6 +370,41 @@ static GBufferSegment *find_near_segment(const buffer_line_column *column, GBuff
/******************************************************************************
* *
+* Paramètres : column = colonne de ligne de texte à consulter. *
+* creator = créateur à l'origine du segment recherché. *
+* *
+* Description : Fournit le segment créé par un objet particulier. *
+* *
+* Retour : Segment trouvé ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBufferSegment *find_segment_from_creator(const buffer_line_column *column, GObject *creator)
+{
+ GBufferSegment *result; /* Trouvaille à retourner */
+ size_t i; /* Boucle de parcours #1 */
+ GBufferSegment *iter; /* Boucle de parcours #2 */
+
+ result = NULL;
+
+ for (i = 0; i < column->count && result == NULL; i++)
+ {
+ iter = column->segments[i];
+
+ if (g_buffer_segment_get_creator(iter) == creator)
+ result = iter;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : column = colonne de ligne de texte à manipuler. *
* cairo = contexte graphique à utiliser pour les pinceaux. *
* x_init = abscisse du point d'impression de départ. *
@@ -491,6 +532,14 @@ static void g_buffer_line_class_init(GBufferLineClass *class)
g_free(filename);
+ g_signal_new("content-changed",
+ G_TYPE_BUFFER_LINE,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GBufferLineClass, content_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
g_signal_new("flip-flag",
G_TYPE_BUFFER_LINE,
G_SIGNAL_RUN_LAST,
@@ -1097,6 +1146,57 @@ GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBuffer
/******************************************************************************
* *
+* Paramètres : line = ligne à venir consulter. *
+* creator = créateur à l'origine du segment recherché. *
+* *
+* Description : Fournit le segment créé par un objet particulier. *
+* *
+* Retour : Segment trouvé dans la ligne ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferSegment *g_buffer_line_find_segment_from_creator(const GBufferLine *line, GObject *creator)
+{
+ GBufferSegment *result; /* Trouvaille à retourner */
+ BufferLineColumn i; /* Boucle de parcours */
+
+ result = NULL;
+
+ for (i = 0; i < BLC_COUNT && result == NULL; i++)
+ result = find_segment_from_creator(&line->columns[i], creator);
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : segment = segment de texte dont le contenu vient de changer. *
+* line = ligne contenant ce segment. *
+* *
+* Description : Réagit au changement de contenu d'un segment encapsulé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_line_segment_changed(GBufferSegment *segment, GBufferLine *line)
+{
+ g_signal_emit_by_name(line, "content-changed");
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne à venir compléter. *
* column = colonne de la ligne visée par l'insertion. *
* text = texte à insérer dans l'existant. *
@@ -1115,8 +1215,7 @@ GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn co
{
GBufferSegment *result; /* Portion de texte à renvoyer */
- if (length == 0)
- return;
+ assert(length > 0);
if (column == BLC_MAIN)
column = line->main_column;
@@ -1129,6 +1228,8 @@ GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn co
result = g_buffer_segment_new(type, text, length);
g_buffer_line_add_segment(line, column, result);
+ g_signal_connect(result, "content-changed", G_CALLBACK(on_line_segment_changed), line);
+
return result;
}
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 7ba5467..13ba87b 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -122,6 +122,9 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BL
/* Fournit le segment voisin d'un autre segment identifié. */
GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *, GBufferSegment *, const gint [BLC_COUNT], const bool *, GdkScrollDirection, gint *);
+/* Fournit le segment créé par un objet particulier. */
+GBufferSegment *g_buffer_line_find_segment_from_creator(const GBufferLine *, GObject *);
+
/* Ajoute du texte à formater dans une ligne donnée. */
GBufferSegment *g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType);
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
index 8e7613f..af77c38 100644
--- a/src/glibext/gbuffersegment.c
+++ b/src/glibext/gbuffersegment.c
@@ -125,6 +125,10 @@ struct _GBufferSegmentClass
double x_advances[CAIRO_FONTS_COUNT]; /* Largeurs par caractère */
rendering_pattern_t patterns[RTT_COUNT];/* Modèles d'impression */
+ /* Signaux */
+
+ void (* content_changed) (GBufferSegment *);
+
};
@@ -296,6 +300,16 @@ static void g_buffer_segment_class_init(GBufferSegmentClass *class)
gtk_widget_path_free(path);
g_object_unref(context);
+ /* Signaux */
+
+ g_signal_new("content-changed",
+ G_TYPE_BUFFER_SEGMENT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GBufferSegmentClass, content_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
}
@@ -478,6 +492,34 @@ GObject *g_buffer_segment_get_creator(const GBufferSegment *segment)
/******************************************************************************
* *
+* Paramètres : segment = fragment de texte à mettre à jour. *
+* text = chaîne de caractères à traiter. *
+* length = quantité de ces caractères. *
+* *
+* Description : Met à jour le contenu d'un fragment de texte. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_segment_update_text(GBufferSegment *segment, const char *text, size_t length)
+{
+ free(segment->text);
+
+ segment->text = strndup(text, length);
+ segment->hash = fnv_64a_hash(segment->text);
+
+ g_buffer_segment_prepare(segment, length);
+
+ g_signal_emit_by_name(segment, "content-changed");
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : segment = fragment de texte à consulter. *
* ref = segment de référence servant à la comparaison. *
* *
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
index 67091fb..57e3575 100644
--- a/src/glibext/gbuffersegment.h
+++ b/src/glibext/gbuffersegment.h
@@ -109,6 +109,9 @@ void g_buffer_segment_set_creator(GBufferSegment *, GObject *);
/* Renvoie vers un éventuel objet lié en tant que créateur. */
GObject *g_buffer_segment_get_creator(const GBufferSegment *);
+/* Met à jour le contenu d'un fragment de texte. */
+void g_buffer_segment_update_text(GBufferSegment *, const char *, size_t);
+
/* Indique si les textes de deux segments sont identiques. */
bool g_buffer_segment_compare(const GBufferSegment *, const GBufferSegment *);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index b211c4a..1654a72 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -111,6 +111,10 @@ struct _GCodeBufferClass
{
GObjectClass parent; /* A laisser en premier */
+ /* Signaux */
+
+ void (* line_changed) (GCodeBuffer *, GBufferLine *, GBufferSegment *);
+
};
@@ -136,6 +140,15 @@ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, const vmpa2t *
/* Actualise les largeurs maximales par groupes de lignes. */
static void g_code_buffer_update_line_max_widths(const GCodeBuffer *, size_t, size_t);
+/* Réagit à un changement de contenu d'une ligne donnée. */
+static void on_line_content_change(GBufferLine *, GBufferSegment *, GCodeBuffer *);
+
+/* Réagit à un changement de propriété rattachée à une ligne. */
+static void on_line_flag_flip(GBufferLine *, BufferLineFlags, BufferLineFlags, GCodeBuffer *);
+
+/* Ajoute une nouvelle ligne à une position donnée. */
+static GBufferLine *g_code_buffer_create_new_line(GCodeBuffer *, size_t, const mrange_t *);
+
/* ---------------------- VUE PARTICULIERE D'UN TAMPON DE CODE ---------------------- */
@@ -191,6 +204,9 @@ static void g_buffer_view_dispose(GBufferView *);
/* Procède à la libération totale de la mémoire. */
static void g_buffer_view_finalize(GBufferView *);
+/* Réagit à un changement de contenu d'une ligne donnée. */
+static void on_buffer_line_changed(GCodeBuffer *, GBufferLine *, GBufferSegment *, GBufferView *);
+
/* Réinitialise le cache de la hauteur des lignes. */
static void g_buffer_view_reset_required_height(GBufferView *);
@@ -366,6 +382,13 @@ G_DEFINE_TYPE(GCodeBuffer, g_code_buffer, G_TYPE_OBJECT);
static void g_code_buffer_class_init(GCodeBufferClass *class)
{
+ g_signal_new("line-changed",
+ G_TYPE_CODE_BUFFER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GCodeBufferClass, line_changed),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
}
@@ -691,10 +714,53 @@ static void g_code_buffer_update_line_max_widths(const GCodeBuffer *buffer, size
/******************************************************************************
* *
-* Paramètres : buffer = composant GTK à mettre à jour. *
+* Paramètres : line = ligne dont la définition vient d'évoluer. *
+* segment = éventuel segment qui vient d'évoluer ou NULL. *
+* buffer = tampon de lignes cohérentes à manipuler. *
+* *
+* Description : Réagit à un changement de contenu d'une ligne donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_line_content_change(GBufferLine *line, GBufferSegment *segment, GCodeBuffer *buffer)
+{
+ g_signal_emit_by_name(buffer, "line-changed", line, segment);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont la définition vient d'évoluer. *
+* old = ancien groupe de propriétés associées. *
+* old = nouveau groupe de propriétés associées. *
+* buffer = tampon de lignes cohérentes à manipuler. *
+* *
+* Description : Réagit à un changement de propriété rattachée à une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_line_flag_flip(GBufferLine *line, BufferLineFlags old, BufferLineFlags new, GCodeBuffer *buffer)
+{
+ g_signal_emit_by_name(buffer, "line-changed", line, NULL);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : buffer = composant GLib à mettre à jour. *
* range = emplacement où va se situer la ligne. *
* *
-* Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. *
+* Description : Ajoute une nouvelle ligne à une position donnée. *
* *
* Retour : Nouvelle ligne vierge à écrire. *
* *
@@ -702,7 +768,7 @@ static void g_code_buffer_update_line_max_widths(const GCodeBuffer *buffer, size
* *
******************************************************************************/
-GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t *range)
+static GBufferLine *g_code_buffer_create_new_line(GCodeBuffer *buffer, size_t index, const mrange_t *range)
{
GBufferLine *result; /* Instance à retourner */
size_t i; /* Boucle de parcours */
@@ -714,12 +780,42 @@ GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t *
buffer->count * sizeof(GBufferLine *));
}
+ buffer->used++;
+ assert(index < buffer->used);
+
result = g_buffer_line_new(range, buffer->main_column);
- buffer->lines[buffer->used++] = result;
+ buffer->lines[index] = result;
for (i = 0; i < buffer->indent; i++)
g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 4, RTT_RAW);
+ g_signal_connect(result, "content-changed", G_CALLBACK(on_line_content_change), buffer);
+ g_signal_connect(result, "flip-flag", G_CALLBACK(on_line_flag_flip), buffer);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : buffer = composant GLib à mettre à jour. *
+* range = emplacement où va se situer la ligne. *
+* *
+* Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. *
+* *
+* Retour : Nouvelle ligne vierge à écrire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t *range)
+{
+ GBufferLine *result; /* Instance à retourner */
+
+ result = g_code_buffer_create_new_line(buffer, buffer->used, range);
+
return result;
}
@@ -1031,6 +1127,8 @@ static void g_buffer_view_init(GBufferView *buffer)
static void g_buffer_view_dispose(GBufferView *view)
{
+ g_object_unref(G_OBJECT(view->buffer));
+
G_OBJECT_CLASS(g_buffer_view_parent_class)->dispose(G_OBJECT(view));
}
@@ -1083,6 +1181,8 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
g_buffer_view_restrict(result, NULL, NULL);
+ g_signal_connect(buffer, "line-changed", G_CALLBACK(on_buffer_line_changed), result);
+
if (highlighted != NULL)
result->highlighted = highlighted;
else
@@ -1097,6 +1197,30 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
/******************************************************************************
* *
+* Paramètres : buffer = tampon de lignes cohérentes à manipuler. *
+* line = ligne dont la définition vient d'évoluer. *
+* segment = éventuel segment qui vient d'évoluer ou NULL. *
+* view = vue active du tampon de lignes concerné. *
+* *
+* Description : Réagit à un changement de contenu d'une ligne donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, GBufferSegment *segment, GBufferView *view)
+{
+ /* TODO : regarder si la vue et concernée et cibler d'avantage l'actualisation */
+
+ g_signal_emit_by_name(view, "need-redraw");
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = visualisateur à mettre à jour. *
* first = première ligne à imprimer. *
* last = première ligne hors cadre. *
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index 9e4077d..c524891 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -219,41 +219,45 @@ static void mcb_edition_goto(GtkMenuItem *menuitem, GMenuBar *bar)
static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, GMenuBar *bar)
{
ImmOperandDisplay display; /* Type de basculement */
+ GEditorItem *editem; /* Autre version de la barre */
GtkViewPanel *vpanel; /* Afficheur effectif de code */
GBufferLine *line; /* Ligne de position courante */
GBufferSegment *segment; /* Segment actif s'il existe */
GObject *creator; /* Créateur à l'orgine du seg. */
- virt_t virt; /* Adresse virtuelle */
- vmpa2t addr; /* Adresse de destination */
+ GDbSwitcher *switcher; /* Bascule à mettre en place */
+ const mrange_t *range; /* Emplacement de la ligne */
+ GLoadedBinary *binary; /* Binaire en cours d'étude */
+ GArchProcessor *proc; /* Propriétaire d'instructions */
+ GArchInstruction *instr; /* Instruction liée à la ligne */
display = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_switch"));
- vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar));
+ editem = G_EDITOR_ITEM(bar);
+
+ vpanel = g_editor_item_get_current_view(editem);
if (gtk_view_panel_get_position(vpanel, &line, &segment))
{
- if (segment != NULL)
- creator = g_buffer_segment_get_creator(segment);
- else
- creator = NULL;
-
- if (creator != NULL)
- {
- assert(G_IS_TARGET_OPERAND(creator));
-
-
-
+ creator = g_buffer_segment_get_creator(segment);
+ assert(G_IS_IMM_OPERAND(creator));
+ range = g_buffer_line_get_range(line);
+ binary = g_editor_item_get_current_binary(editem);
+ proc = g_loaded_binary_get_processor(binary);
+ instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
+ assert(instr != NULL);
+ switcher = g_db_switcher_new(instr, G_IMM_OPERAND(creator), display);
+ g_loaded_binary_add_to_collection(binary, DBF_DISPLAY_SWITCHERS, G_DB_ITEM(switcher));
- g_object_unref(creator);
+ g_object_unref(G_OBJECT(proc));
- }
+ g_object_unref(creator);
- if (segment != NULL) g_object_unref(G_OBJECT(segment));
+ g_object_unref(G_OBJECT(segment));
g_object_unref(G_OBJECT(line));
}