diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/db/collection.c | 46 | ||||
| -rw-r--r-- | src/analysis/db/items/bookmark.c | 52 | ||||
| -rw-r--r-- | src/analysis/db/items/comment.c | 4 | ||||
| -rw-r--r-- | src/analysis/db/items/switcher.c | 138 | ||||
| -rw-r--r-- | src/analysis/db/misc/rlestr.c | 6 | ||||
| -rw-r--r-- | src/analysis/db/misc/timestamp.c | 6 | ||||
| -rw-r--r-- | src/arch/immediate.c | 86 | ||||
| -rw-r--r-- | src/arch/immediate.h | 15 | ||||
| -rw-r--r-- | src/arch/vmpa.c | 14 | ||||
| -rw-r--r-- | src/common/sqlite.h | 5 | ||||
| -rw-r--r-- | src/format/symbol.h | 13 | ||||
| -rw-r--r-- | src/glibext/gbufferline.c | 115 | ||||
| -rw-r--r-- | src/glibext/gbufferline.h | 3 | ||||
| -rw-r--r-- | src/glibext/gbuffersegment.c | 42 | ||||
| -rw-r--r-- | src/glibext/gbuffersegment.h | 3 | ||||
| -rw-r--r-- | src/glibext/gcodebuffer.c | 132 | ||||
| -rw-r--r-- | src/gui/menus/edition.c | 38 | 
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));      }  | 
