From 52ac5b1b340335f56ceb599dba63164a26f10b10 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 16 Jan 2016 22:12:08 +0100 Subject: Changed the display of a segment containing the value of an immediate. --- ChangeLog | 46 +++++++++++++ src/analysis/db/collection.c | 46 +++++++++++-- src/analysis/db/items/bookmark.c | 52 +++++++-------- src/analysis/db/items/comment.c | 4 -- src/analysis/db/items/switcher.c | 138 ++++++++++++++++++++++++++++++++++----- src/analysis/db/misc/rlestr.c | 6 +- src/analysis/db/misc/timestamp.c | 6 +- src/arch/immediate.c | 86 ++++++++++++++++++++++-- src/arch/immediate.h | 15 +++++ src/arch/vmpa.c | 14 +++- src/common/sqlite.h | 5 +- src/format/symbol.h | 13 ++-- src/glibext/gbufferline.c | 115 ++++++++++++++++++++++++++++++-- src/glibext/gbufferline.h | 3 + src/glibext/gbuffersegment.c | 42 ++++++++++++ src/glibext/gbuffersegment.h | 3 + src/glibext/gcodebuffer.c | 132 +++++++++++++++++++++++++++++++++++-- src/gui/menus/edition.c | 38 ++++++----- tools/d2c/syntax.c | 2 +- 19 files changed, 662 insertions(+), 104 deletions(-) diff --git a/ChangeLog b/ChangeLog index c83a6b2..2f3e291 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,49 @@ +16-01-16 Cyrille Bagard + + * src/analysis/db/collection.c: + Remove debug code. Deal with simple integer values and SQLite. + + * src/analysis/db/items/bookmark.c: + Clean the code. Set DBF_BOOKMARKS as feature of the collection. + + * src/analysis/db/items/comment.c: + Typo. + + * src/analysis/db/items/switcher.c: + Change the display of a segment containing the value of an immediate. + + * src/analysis/db/misc/rlestr.c: + * src/analysis/db/misc/timestamp.c: + Define the expected type of the loaded values. + + * src/arch/immediate.c: + * src/arch/immediate.h: + Add (useless ?) signals. Define a default display for immediate values. + Fix the binary display output. Prevent an overflow when displaying in + binary mode. + + * src/arch/vmpa.c: + Define the expected type of the loaded values. + + * src/common/sqlite.h: + Rely on SQLite DB types using a new macro called SQLITE_NATIVE. + + * src/format/symbol.h: + Update code when displaying immediate values. + + * src/glibext/gbufferline.c: + * src/glibext/gbufferline.h: + * src/glibext/gbuffersegment.c: + * src/glibext/gbuffersegment.h: + * src/glibext/gcodebuffer.c: + Allow to update a text segment and refresh the display automatically. + + * src/gui/menus/edition.c: + Use the DB connection as proxy when changing an immediate value display. + + * tools/d2c/syntax.c: + Update code when displaying immediate values. + 16-01-12 Cyrille Bagard * src/arch/Makefile.am: 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 +#include + + #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 #include #include #include @@ -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)); } diff --git a/tools/d2c/syntax.c b/tools/d2c/syntax.c index 2dad772..96fffc5 100644 --- a/tools/d2c/syntax.c +++ b/tools/d2c/syntax.c @@ -365,7 +365,7 @@ bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, con dprintf(fd, "\n"); if (item->flags & SIF_DECIMAL) - dprintf(fd, "\t\tg_imm_operand_set_display(G_IMM_OPERAND(op), IOD_DEC);\n"); + dprintf(fd, "\t\tg_imm_operand_set_default_display(G_IMM_OPERAND(op), IOD_DEC);\n"); dprintf(fd, "\t\tg_arch_instruction_attach_extra_operand(instr, op);\n"); -- cgit v0.11.2-87-g4458