diff options
Diffstat (limited to 'src/arch')
36 files changed, 3588 insertions, 2361 deletions
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index 5118296..bdfceb7 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -1,30 +1,29 @@  noinst_LTLIBRARIES = libarch.la -libarch_la_SOURCES =					\ -	archbase.h archbase.c				\ -	context-int.h						\ -	context.h context.c					\ -	instriter.h instriter.c				\ -	instruction-int.h					\ -	instruction.h instruction.c			\ -	link.h link.c						\ -	meta.h meta.c						\ -	operand-int.h						\ -	operand.h operand.c					\ -	post.h post.c						\ -	processor-int.h						\ -	processor.h processor.c				\ -	register-int.h						\ -	register.h register.c				\ -	storage.h storage.c					\ +libarch_la_SOURCES =						\ +	archbase.h archbase.c					\ +	context-int.h							\ +	context.h context.c						\ +	instriter.h instriter.c					\ +	instruction-int.h						\ +	instruction.h instruction.c				\ +	link.h link.c							\ +	operand-int.h operand-int.c				\ +	operand.h operand.c						\ +	post.h post.c							\ +	processor-int.h							\ +	processor.h processor.c					\ +	register-int.h							\ +	register.h register.c					\ +	storage.h storage.c						\  	vmpa.h vmpa.c -libarch_la_LIBADD =						\ -	instructions/libarchinstructions.la	\ -	operands/libarchoperands.la +libarch_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -libarch_la_LDFLAGS =  +libarch_la_LIBADD =							\ +	instructions/libarchinstructions.la		\ +	operands/libarchoperands.la  devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) @@ -32,9 +31,4 @@ devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)  dev_HEADERS = $(libarch_la_SOURCES:%c=) -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) - -  SUBDIRS = instructions operands diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 6a3ccea..7dbbe27 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -26,6 +26,7 @@  #include "instruction.h" +#include "../analysis/storage/storage.h"  #include "../common/array.h"  #include "../glibext/objhole.h" @@ -58,27 +59,50 @@ typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBuffe  /* Liste les registres lus et écrits par l'instruction. */  typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *); +/* Charge un contenu depuis une mémoire tampon. */ +typedef bool (* load_instruction_fc) (GArchInstruction *, GObjectStorage *, packed_buffer_t *); -/* Informations glissées dans la structure GObject de GArchInstruction */ -typedef union _instr_obj_extra +/* Sauvegarde un contenu dans une mémoire tampon. */ +typedef bool (* store_instruction_fc) (GArchInstruction *, GObjectStorage *, packed_buffer_t *); + + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _instr_extra_data_t  { -    struct -    { -        itid_t uid;                         /* Identifiant unique du type  */ +    itid_t uid;                             /* Identifiant unique du type  */ -        ArchInstrFlag flags;                /* Informations complémentaires*/ +    ArchInstrFlag flags;                    /* Informations complémentaires*/ -    }; +} instr_extra_data_t; + +/* Informations glissées dans la structure GObject de GArchInstruction */ +typedef union _instr_obj_extra_t +{ +    instr_extra_data_t data;                /* Données embarquées          */ +    lockable_obj_extra_t lockable;          /* Gestion d'accès aux fanions */ -    gint lock;                              /* Gestion d'accès aux fanions */ +} instr_obj_extra_t; -} instr_obj_extra;  /* Définition générique d'une instruction d'architecture (instance) */  struct _GArchInstruction  {      GObject parent;                         /* A laisser en premier        */ +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +    /** +     * L'inclusion des informations suivantes dépend de l'architecture. +     * +     * Si la structure GObject possède un trou, on remplit de préférence +     * ce dernier. +     */ + +    instr_obj_extra_t extra;                /* Externalisation embarquée   */ + +#endif +      mrange_t range;                         /* Emplacement en mémoire      */      flat_array_t *operands;                 /* Liste des opérandes         */ @@ -108,39 +132,8 @@ struct _GArchInstruction      flat_array_t *from;                     /* Origines des références     */      flat_array_t *to;                       /* Instructions visées         */ -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -    /** -     * L'inclusion des informations suivantes dépend de l'architecture. -     * -     * Si la structure GObject possède un trou, on remplit de préférence -     * ce dernier. -     */ - -    instr_obj_extra extra;                  /* Externalisation embarquée   */ - -#endif -  }; -/** - * Accès aux informations éventuellement déportées. - */ - -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -#   define INIT_ARCH_INSTR_EXTRA(ins) ins->extra.lock = 0 - -#   define GET_ARCH_INSTR_EXTRA(ins) &ins->extra - -#else - -#   define INIT_ARCH_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins)) - -#   define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_obj_extra) - -#endif -  /* Définition générique d'une instruction d'architecture (classe) */  struct _GArchInstructionClass  { @@ -157,12 +150,30 @@ struct _GArchInstructionClass      print_instruction_fc print;             /* Imprime l'ensemble          */ +    load_instruction_fc load;               /* Chargement depuis un tampon */ +    store_instruction_fc store;             /* Conservation dans un tampon */ +      //get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés    */  };  /** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +#   define GET_ARCH_INSTR_EXTRA(ins) (instr_extra_data_t *)&ins->extra + +#else + +#   define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_extra_data_t) + +#endif + + +/**   * Fournit une marge pour toutes les instructions particulières communes   * à l'ensemble des architectures (GRawInstruction, GUndefInstruction).   */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 4079e82..cd1e9c7 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -34,10 +34,12 @@  #include "instruction-int.h"  #include "storage.h" +#include "../analysis/storage/serialize-int.h" +#include "../core/columns.h"  #include "../core/logs.h" +#include "../core/processors.h"  #include "../glibext/gbinarycursor.h"  #include "../glibext/linegen-int.h" -#include "../gtkext/gtkblockdisplay.h" @@ -48,7 +50,10 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);  static void g_arch_instruction_init(GArchInstruction *);  /* Procède à l'initialisation de l'interface de génération. */ -static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *); +static void g_arch_instruction_generator_init(GLineGeneratorInterface *); + +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_arch_instruction_serializable_init(GSerializableObjectInterface *);  /* Supprime toutes les références externes. */  static void g_arch_instruction_dispose(GArchInstruction *); @@ -58,14 +63,15 @@ static void g_arch_instruction_finalize(GArchInstruction *); -/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ -/* Charge une instruction depuis une mémoire tampon. */ -static bool g_arch_instruction_unserialize(GArchInstruction *, GAsmStorage *, GBinFormat *, packed_buffer_t *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_arch_instruction_load_destinations(GArchInstruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde toutes les destinations d'une instruction. */ +bool g_arch_instruction_store_destinations(GArchInstruction *, GObjectStorage *, packed_buffer_t *); + -/* Sauvegarde une instruction dans une mémoire tampon. */ -static bool g_arch_instruction_serialize(GArchInstruction *, GAsmStorage *, packed_buffer_t *); @@ -75,12 +81,16 @@ static bool g_arch_instruction_serialize(GArchInstruction *, GAsmStorage *, pack  /* Indique le nombre de ligne prêtes à être générées. */  static size_t g_arch_instruction_count_lines(const GArchInstruction *); +#ifdef INCLUDE_GTK_SUPPORT +  /* Retrouve l'emplacement correspondant à une position donnée. */  static void g_arch_instruction_compute_cursor(const GArchInstruction *, gint, size_t, size_t, GLineCursor **);  /* Détermine si le conteneur s'inscrit dans une plage donnée. */  static int g_arch_instruction_contain_cursor(const GArchInstruction *, size_t, size_t, const GLineCursor *); +#endif +  /* Renseigne sur les propriétés liées à un générateur. */  static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *, size_t, size_t); @@ -91,10 +101,27 @@ static void _g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t,  static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t, const GBinContent *); +/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool _g_arch_instruction_load(GArchInstruction *, GObjectStorage *, packed_buffer_t *); + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_arch_instruction_load(GArchInstruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool _g_arch_instruction_store(GArchInstruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_arch_instruction_store(GArchInstruction *, GObjectStorage *, packed_buffer_t *); + +  /* Indique le type défini pour une instruction d'architecture. */  G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT, -                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_interface_init)); +                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_instruction_serializable_init));  /****************************************************************************** @@ -121,11 +148,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)      instr = G_ARCH_INSTRUCTION_CLASS(klass); -    instr->unserialize = (unserialize_instruction_fc)g_arch_instruction_unserialize; -    instr->serialize = (serialize_instruction_fc)g_arch_instruction_serialize; -      instr->print = (print_instruction_fc)_g_arch_instruction_print; +    instr->load = (load_instruction_fc)_g_arch_instruction_load; +    instr->store = (store_instruction_fc)_g_arch_instruction_store; +  } @@ -143,7 +170,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)  static void g_arch_instruction_init(GArchInstruction *instr)  { -    INIT_ARCH_INSTR_EXTRA(instr); +    instr_extra_data_t *extra;              /* Données insérées à modifier */ + +    extra = GET_ARCH_INSTR_EXTRA(instr); + +    INIT_GOBJECT_EXTRA_LOCK(extra);      instr->operands = NULL; @@ -165,11 +196,13 @@ static void g_arch_instruction_init(GArchInstruction *instr)  *                                                                             *  ******************************************************************************/ -static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *iface) +static void g_arch_instruction_generator_init(GLineGeneratorInterface *iface)  {      iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines; +#ifdef INCLUDE_GTK_SUPPORT      iface->compute = (linegen_compute_fc)g_arch_instruction_compute_cursor;      iface->contain = (linegen_contain_fc)g_arch_instruction_contain_cursor; +#endif      iface->get_flags = (linegen_get_flags_fc)g_arch_instruction_get_flags2;      iface->print = (linegen_print_fc)g_arch_instruction_print; @@ -178,6 +211,26 @@ static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface  /******************************************************************************  *                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de sérialisation.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_instruction_serializable_init(GSerializableObjectInterface *iface) +{ +    iface->load = (load_serializable_object_cb)g_arch_instruction_load; +    iface->store = (store_serializable_object_cb)g_arch_instruction_store; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : instr = instance d'objet GLib à traiter.                     *  *                                                                             *  *  Description : Supprime toutes les références externes.                     * @@ -285,19 +338,19 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr)  bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)  {      bool result;                            /* Bilan à retourner           */ -    instr_obj_extra *extra;                 /* Données insérées à modifier */ +    instr_extra_data_t *extra;              /* Données insérées à modifier */      assert(flag <= AIF_HIGH_USER);      extra = GET_ARCH_INSTR_EXTRA(instr); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra); -    extra->flags |= flag; +    result = !(extra->flags & flag); -    result = true; +    extra->flags |= flag; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -320,19 +373,19 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)  bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)  {      bool result;                            /* Bilan à retourner           */ -    instr_obj_extra *extra;                 /* Données insérées à modifier */ +    instr_extra_data_t *extra;              /* Données insérées à modifier */      assert(flag <= AIF_HIGH_USER);      extra = GET_ARCH_INSTR_EXTRA(instr); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra); -    extra->flags &= ~flag; +    result = (extra->flags & flag); -    result = true; +    extra->flags &= ~flag; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -355,17 +408,17 @@ bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)  bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag flag)  {      bool result;                            /* Bilan à retourner           */ -    instr_obj_extra *extra;                 /* Données insérées à consulter*/ +    instr_extra_data_t *extra;              /* Données insérées à modifier */      assert(flag <= AIF_HIGH_USER);      extra = GET_ARCH_INSTR_EXTRA(instr); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      result = (extra->flags & flag); -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -387,27 +440,15 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl  ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)  {      ArchInstrFlag result;                   /* Fanions à retourner         */ -    instr_obj_extra *extra;                 /* Données insérées à consulter*/ +    instr_extra_data_t *extra;              /* Données insérées à modifier */      extra = GET_ARCH_INSTR_EXTRA(instr); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      result = extra->flags; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -    /** -     * La pose du verrou a entraîné la mise à 1 du bit de poids fort de la zone -     * couverte par le champ "extra". -     * -     * Même si les fanions ne couvrent pas cet emplacement, leur stockage s'étend -     * sur 16 bits, et contient donc le fameux bit de verrouillage. -     * -     * On efface ce marqueur après-coup ici. -     */ - -    result &= ((AIF_HIGH_USER << 1) - 1); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -429,15 +470,15 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)  void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)  { -    instr_obj_extra *extra;                 /* Données insérées à modifier */ +    instr_extra_data_t *extra;              /* Données insérées à modifier */      extra = GET_ARCH_INSTR_EXTRA(instr); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      extra->uid = uid; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);  } @@ -457,15 +498,15 @@ void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)  itid_t g_arch_instruction_get_unique_id(const GArchInstruction *instr)  {      itid_t result;                          /* Numéro à retourner          */ -    instr_obj_extra *extra;                 /* Données insérées à consulter*/ +    instr_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_ARCH_INSTR_EXTRA(instr); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      result = extra->uid; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -666,9 +707,19 @@ void g_arch_instruction_unlock_operands(GArchInstruction *instr)  void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand)  { +    GSingletonFactory *factory;             /* Unise à instances uniques   */ +    GArchOperand *singleton;                /* Instance retenue            */ + +    factory = get_operands_factory(); + +    singleton = G_ARCH_OPERAND(g_singleton_factory_get_instance(factory, G_SINGLETON_CANDIDATE(operand))); + +    g_object_unref(G_OBJECT(operand)); +    g_object_unref(G_OBJECT(factory)); +      g_arch_instruction_lock_operands(instr); -    add_item_to_flat_array(&instr->operands, &operand, sizeof(GArchOperand *)); +    add_item_to_flat_array(&instr->operands, &singleton, sizeof(GArchOperand *));      g_arch_instruction_unlock_operands(instr); @@ -1557,59 +1608,54 @@ instr_link_t *g_arch_instruction_get_destinations(GArchInstruction *instr, size_  } - -/* ---------------------------------------------------------------------------------- */ -/*                       CONVERSIONS DU FORMAT DES INSTRUCTIONS                       */ -/* ---------------------------------------------------------------------------------- */ - -  /******************************************************************************  *                                                                             * -*  Paramètres  : instr = instruction d'assemblage à consulter.                * +*  Paramètres  : instr   = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                *  *                                                                             * -*  Description : Fournit le nom humain de l'instruction manipulée.            * +*  Description : Charge un contenu depuis une mémoire tampon.                 *  *                                                                             * -*  Retour      : Mot clef de bas niveau.                                      * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -const char *g_arch_instruction_get_keyword(GArchInstruction *instr) +static bool g_arch_instruction_load_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)  { -    const char *result;                     /* Désignation à retourner     */ - -    result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_keyword(instr); - -    return result; +    bool result;                            /* Bilan à retourner           */ +    uleb128_t count;                        /* Nombre de liens à charger   */ +    uleb128_t i;                            /* Boucle de parcours          */ +    GArchInstruction *linked;               /* Lien vers une instruction   */ +    uleb128_t type;                         /* Valeur ULEB128 à charger    */ -} +    g_arch_instruction_lock_dest(instr); +    result = unpack_uleb128(&count, pbuf); -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr = instruction d'assemblage à consulter.                * -*                                                                             * -*  Description : Construit un petit résumé concis de l'instruction.           * -*                                                                             * -*  Retour      : Chaîne de caractères à libérer après usage ou NULL.          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    for (i = 0; i < count && result; i++) +    { +        linked = G_ARCH_INSTRUCTION(g_object_storage_unpack_object(storage, "instructions", pbuf)); +        if (linked == NULL) +        { +            result = false; +            break; +        } -char *g_arch_instruction_build_tooltip(const GArchInstruction *instr) -{ -    char *result;                           /* Description à retourner     */ -    GArchInstructionClass *class;           /* Classe des instructions     */ +        result = unpack_uleb128(&type, pbuf); +        if (!result) +        { +            g_object_unref(G_OBJECT(linked)); +            break; +        } -    class = G_ARCH_INSTRUCTION_GET_CLASS(instr); +        g_arch_instruction_link_with(instr, linked, type); +        g_object_unref(G_OBJECT(linked)); -    if (class->build_tooltip != NULL) -        result = class->build_tooltip(instr); +    } -    else -        result = NULL; +    g_arch_instruction_unlock_dest(instr);      return result; @@ -1618,41 +1664,11 @@ char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)  /******************************************************************************  *                                                                             * -*  Paramètres  : instr = instruction d'assemblage à consulter.                * -*                                                                             * -*  Description : Fournit une description pour l'instruction manipulée.        * -*                                                                             * -*  Retour      : Chaîne de caractères avec balises éventuelles.               * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -const char *g_arch_instruction_get_description(const GArchInstruction *instr) -{ -    const char *result;                     /* Description à retourner     */ - -    result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_desc(instr); - -    return result; -   -} - - - -/* ---------------------------------------------------------------------------------- */ -/*                      CONSERVATION SUR DISQUE DES INSTRUCTIONS                      */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr   = instruction d'assemblage à consulter.              * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * +*  Paramètres  : instr   = instruction dont les informations sont à consulter.* +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Charge une instruction depuis une mémoire tampon.            * +*  Description : Sauvegarde toutes les destinations d'une instruction.        *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -1660,148 +1676,87 @@ const char *g_arch_instruction_get_description(const GArchInstruction *instr)  *                                                                             *  ******************************************************************************/ -static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +bool g_arch_instruction_store_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ -    packed_buffer_t op_pbuf;                /* Tampon des données à écrire */      size_t count;                           /* Nombre d'éléments à traiter */ +    size_t kept;                            /* Nombre de liens conservés   */      size_t i;                               /* Boucle de parcours          */ -    off64_t pos;                            /* Position dans le flux       */ -    GArchOperand *op;                       /* Opérande à traiter          */ -    instr_link_t link;                      /* Lien vers une instruction   */ -    packed_buffer_t ins_pbuf;               /* Tampon des données à écrire */ -    instr_obj_extra *extra;                 /* Données insérées à consulter*/ - -    result = unpack_mrange(&instr->range, pbuf); - -    if (result) -    { -        init_packed_buffer(&op_pbuf); - -        result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); - -        for (i = 0; i < count && result; i++) -        { -            result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true); - -            if (result) -                result = g_asm_storage_load_operand_data(storage, &op_pbuf, pos); - -            if (result) -            { -                op = g_arch_operand_load(storage, format, &op_pbuf); -                result = (op != NULL); -            } +    const instr_link_t *link;               /* Lien vers une instruction   */ -            if (result) -                g_arch_instruction_attach_extra_operand(instr, op); +    g_arch_instruction_lock_dest(instr); -        } +    count = g_arch_instruction_count_destinations(instr); -        exit_packed_buffer(&op_pbuf); +    /** +     * Le type de lien ILT_REF n'est mis en place que lors de la création +     * d'opérandes de type G_TYPE_TARGET_OPERAND, et sera donc remis en place +     * dynamiquement lors de la restauration de ces derniers. +     */ -    } +    kept = 0; -    bool unserialize_link(instr_link_t *lk) +    for (i = 0; i < count; i++)      { -        bool status;                        /* Bilan d'une conservation    */ -        phys_t lk_phys;                     /* Position physique courante  */ - -        status = extract_packed_buffer(pbuf, &lk_phys, sizeof(phys_t), true); - -        if (status) -        { -            lk->linked = g_asm_storage_get_instruction_at(storage, format, lk_phys, &ins_pbuf); -            status = (lk->linked != NULL); -        } - -        if (status) -        { -            status = extract_packed_buffer(pbuf, &lk->type, sizeof(InstructionLinkType), true); +        link = g_arch_instruction_get_destination(instr, i); -            if (!status) -                g_object_unref(G_OBJECT(lk->linked)); +        if (link->type != ILT_REF) +            kept++; -        } - -        return status; +        unref_instr_link(link);      } -    if (result) -    { -        init_packed_buffer(&ins_pbuf); +    result = pack_uleb128((uleb128_t []){ kept }, pbuf); -        result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); +    for (i = 0; i < count && result; i++) +    { +        link = g_arch_instruction_get_destination(instr, i); -        for (i = 0; i < count && result; i++) +        if (link->type != ILT_REF)          { -            result = unserialize_link(&link); +            result = g_object_storage_pack_object(storage, "instructions", +                                                  G_SERIALIZABLE_OBJECT(link->linked), pbuf);              if (result) -            { -                g_arch_instruction_link_with(instr, link.linked, link.type); -                g_object_unref(G_OBJECT(link.linked)); -            } +                result = pack_uleb128((uleb128_t []){ link->type }, pbuf);          } -        exit_packed_buffer(&ins_pbuf); +        unref_instr_link(link);      } -    if (result) -    { -        extra = GET_ARCH_INSTR_EXTRA(instr); - -        g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -        result = extract_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true); +    g_arch_instruction_unlock_dest(instr); -        if (result) -            result = extract_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true); +    return result; -        g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +} -    } -    return result; -} +/* ---------------------------------------------------------------------------------- */ +/*                       CONVERSIONS DU FORMAT DES INSTRUCTIONS                       */ +/* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             * -*  Paramètres  : storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : instr = instruction d'assemblage à consulter.                *  *                                                                             * -*  Description : Charge une instruction depuis une mémoire tampon.            * +*  Description : Fournit le nom humain de l'instruction manipulée.            *  *                                                                             * -*  Retour      : Instruction d'assemblage constitué ou NULL en cas d'échec.   * +*  Retour      : Mot clef de bas niveau.                                      *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchInstruction *g_arch_instruction_load(GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +const char *g_arch_instruction_get_keyword(GArchInstruction *instr)  { -    GArchInstruction *result;               /* Instance à retourner        */ -    bool status;                            /* Bilan du chargement         */ - -    result = G_ARCH_INSTRUCTION(g_asm_storage_create_object(storage, pbuf)); - -    if (result != NULL) -    { -        status = G_ARCH_INSTRUCTION_GET_CLASS(result)->unserialize(result, storage, format, pbuf); - -        if (!status) -        { -            g_object_unref(G_OBJECT(result)); -            result = NULL; -        } +    const char *result;                     /* Désignation à retourner     */ -    } +    result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_keyword(instr);      return result; @@ -1810,142 +1765,28 @@ GArchInstruction *g_arch_instruction_load(GAsmStorage *storage, GBinFormat *form  /******************************************************************************  *                                                                             * -*  Paramètres  : instr   = instruction d'assemblage à consulter.              * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : instr = instruction d'assemblage à consulter.                *  *                                                                             * -*  Description : Sauvegarde une instruction dans une mémoire tampon.          * +*  Description : Construit un petit résumé concis de l'instruction.           *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : Chaîne de caractères à libérer après usage ou NULL.          *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf) +char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)  { -    bool result;                            /* Bilan à retourner           */ -    packed_buffer_t op_pbuf;                /* Tampon des données à écrire */ -    size_t count;                           /* Nombre d'éléments à traiter */ -    size_t i;                               /* Boucle de parcours          */ -    GArchOperand *op;                       /* Opérande à traiter          */ -    off64_t pos;                            /* Position dans le flux       */ -    size_t kept;                            /* Nombre de liens conservés   */ -    const instr_link_t *link;               /* Lien vers une instruction   */ -    instr_obj_extra *extra;                 /* Données insérées à consulter*/ - -    result = pack_mrange(&instr->range, pbuf); - -    if (result) -    { -        init_packed_buffer(&op_pbuf); - -        g_arch_instruction_lock_operands(instr); - -        count = _g_arch_instruction_count_operands(instr); - -        result = extend_packed_buffer(pbuf, &count, sizeof(size_t), true); - -        for (i = 0; i < count && result; i++) -        { -            op = _g_arch_instruction_get_operand(instr, i); - -            result = g_arch_operand_store(op, storage, &op_pbuf); - -            if (result) -                result = g_asm_storage_store_operand_data(storage, &op_pbuf, &pos); - -            if (result) -                result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true); - -            g_object_unref(G_OBJECT(op)); - -        } - -        g_arch_instruction_unlock_operands(instr); - -        exit_packed_buffer(&op_pbuf); - -    } - -    bool serialize_link(const instr_link_t *lk) -    { -        bool status;                        /* Bilan d'une conservation    */ -        const mrange_t *range;              /* Emplacement d'une instruct° */ -        phys_t lk_phys;                     /* Position physique courante  */ - -        if (lk->type == ILT_REF) -            status = true; - -        else -        { -            range = g_arch_instruction_get_range(lk->linked); - -            lk_phys = get_phy_addr(get_mrange_addr(range)); - -            status = extend_packed_buffer(pbuf, &lk_phys, sizeof(phys_t), true); - -            if (status) -                status = extend_packed_buffer(pbuf, &lk->type, sizeof(InstructionLinkType), true); - -        } - -        return status; - -    } - -    if (result) -    { -        g_arch_instruction_lock_dest(instr); - -        count = g_arch_instruction_count_destinations(instr); - -        /** -         * Le type de lien ILT_REF n'est mis en place que lors de la création -         * d'opérandes de type G_TYPE_TARGET_OPERAND, et sera donc remis en place -         * dynamiquement lors de la restauration de ces derniers. -         */ - -        kept = 0; - -        for (i = 0; i < count && result; i++) -        { -            link = g_arch_instruction_get_destination(instr, i); - -            if (link->type != ILT_REF) -                kept++; - -            unref_instr_link(link); - -        } - -        result = extend_packed_buffer(pbuf, &kept, sizeof(size_t), true); - -        for (i = 0; i < count && result; i++) -        { -            link = g_arch_instruction_get_destination(instr, i); -            result = serialize_link(link); -            unref_instr_link(link); -        } - -        g_arch_instruction_unlock_dest(instr); - -    } - -    if (result) -    { -        extra = GET_ARCH_INSTR_EXTRA(instr); - -        g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -        result = extend_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true); +    char *result;                           /* Description à retourner     */ +    GArchInstructionClass *class;           /* Classe des instructions     */ -        if (result) -            result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true); +    class = G_ARCH_INSTRUCTION_GET_CLASS(instr); -        g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    if (class->build_tooltip != NULL) +        result = class->build_tooltip(instr); -    } +    else +        result = NULL;      return result; @@ -1954,29 +1795,24 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s  /******************************************************************************  *                                                                             * -*  Paramètres  : instr   = instruction d'assemblage à consulter.              * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : instr = instruction d'assemblage à consulter.                *  *                                                                             * -*  Description : Sauvegarde une instruction dans une mémoire tampon.          * +*  Description : Fournit une description pour l'instruction manipulée.        *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : Chaîne de caractères avec balises éventuelles.               *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool g_arch_instruction_store(GArchInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf) +const char *g_arch_instruction_get_description(const GArchInstruction *instr)  { -    bool result;                            /* Bilan à retourner           */ - -    result = g_asm_storage_store_object_gtype(storage, G_OBJECT(instr), pbuf); +    const char *result;                     /* Description à retourner     */ -    if (result) -        result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->serialize(instr, storage, pbuf); +    result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_desc(instr);      return result; - +    } @@ -2005,6 +1841,9 @@ static size_t g_arch_instruction_count_lines(const GArchInstruction *instr)  } +#ifdef INCLUDE_GTK_SUPPORT + +  /******************************************************************************  *                                                                             *  *  Paramètres  : instr  = générateur à consulter.                             * @@ -2061,6 +1900,9 @@ static int g_arch_instruction_contain_cursor(const GArchInstruction *instr, size  } +#endif + +  /******************************************************************************  *                                                                             *  *  Paramètres  : instr  = générateur à consulter.                             * @@ -2172,3 +2014,201 @@ static void g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line,      G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, line, index, repeat, content);  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                      CONSERVATION ET RECHARGEMENT DES DONNEES                      */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                * +*                                                                             * +*  Description : Charge un contenu depuis une mémoire tampon.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool _g_arch_instruction_load(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    instr_extra_data_t *extra;              /* Données insérées à consulter*/ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ +    uleb128_t count;                        /* Nombre d'éléments à traiter */ +    uleb128_t i;                            /* Boucle de parcours          */ +    GArchOperand *op;                       /* Opérande à traiter          */ + +    extra = GET_ARCH_INSTR_EXTRA(instr); + +    LOCK_GOBJECT_EXTRA(extra); + +    result = unpack_uleb128(&value, pbuf); + +    if (result) +        extra->uid = value; + +    if (result) +    { +        result = unpack_uleb128(&value, pbuf); + +        if (result) +            extra->flags = value; + +    } + +    UNLOCK_GOBJECT_EXTRA(extra); + +    if (result) +        result = unpack_mrange(&instr->range, pbuf); + +    if (result) +    { +        result = unpack_uleb128(&count, pbuf); + +        for (i = 0; i < count && result; i++) +        { +            op = G_ARCH_OPERAND(g_object_storage_unpack_object(storage, "operands", pbuf)); +            result = (op != NULL); + +            if (result) +                g_arch_instruction_attach_extra_operand(instr, op); + +        } + +    } + +    if (result) +        result = g_arch_instruction_load_destinations(instr, storage, pbuf); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                * +*                                                                             * +*  Description : Charge un contenu depuis une mémoire tampon.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_instruction_load(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *class;           /* Classe à activer            */ + +    class = G_ARCH_INSTRUCTION_GET_CLASS(instr); + +    result = class->load(instr, storage, pbuf); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool _g_arch_instruction_store(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    instr_extra_data_t *extra;              /* Données insérées à consulter*/ +    size_t count;                           /* Nombre d'éléments à traiter */ +    size_t i;                               /* Boucle de parcours          */ +    GArchOperand *op;                       /* Opérande à traiter          */ + +    extra = GET_ARCH_INSTR_EXTRA(instr); + +    LOCK_GOBJECT_EXTRA(extra); + +    result = pack_uleb128((uleb128_t []){ extra->uid }, pbuf); + +    if (result) +        result = pack_uleb128((uleb128_t []){ extra->flags }, pbuf); + +    UNLOCK_GOBJECT_EXTRA(extra); + +    if (result) +        result = pack_mrange(&instr->range, pbuf); + +    if (result) +    { +        g_arch_instruction_lock_operands(instr); + +        count = _g_arch_instruction_count_operands(instr); + +        result = pack_uleb128((uleb128_t []){ count }, pbuf); + +        for (i = 0; i < count && result; i++) +        { +            op = _g_arch_instruction_get_operand(instr, i); + +            result = g_object_storage_pack_object(storage, "operands", G_SERIALIZABLE_OBJECT(op), pbuf); + +            g_object_unref(G_OBJECT(op)); + +        } + +        g_arch_instruction_unlock_operands(instr); + +    } + +    if (result) +        result = g_arch_instruction_store_destinations(instr, storage, pbuf); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_instruction_store(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *class;           /* Classe à activer            */ + +    class = G_ARCH_INSTRUCTION_GET_CLASS(instr); + +    result = class->store(instr, storage, pbuf); + +    return result; + +} diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 80c500b..3c9c149 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -38,12 +38,12 @@ -#define G_TYPE_ARCH_INSTRUCTION               g_arch_instruction_get_type() -#define G_ARCH_INSTRUCTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction)) -#define G_IS_ARCH_INSTRUCTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type())) -#define G_ARCH_INSTRUCTION_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass)) -#define G_IS_ARCH_INSTRUCTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARCH_INSTRUCTION)) -#define G_ARCH_INSTRUCTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass)) +#define G_TYPE_ARCH_INSTRUCTION            g_arch_instruction_get_type() +#define G_ARCH_INSTRUCTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction)) +#define G_IS_ARCH_INSTRUCTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type())) +#define G_ARCH_INSTRUCTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass)) +#define G_IS_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARCH_INSTRUCTION)) +#define G_ARCH_INSTRUCTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))  /* Définition générique d'une instruction d'architecture (instance) */ @@ -66,7 +66,7 @@ typedef enum _ArchInstrFlag      AIF_CALL              = (1 << 3),       /* Instruction d'appel         */      AIF_LOW_USER          = (1 << AIF_USER_BIT), /* Premier bit disponible */ -    AIF_HIGH_USER         = (1 << 14),      /* Dernier bit disponible      */ +    AIF_HIGH_USER         = (1 << 7),      /* Dernier bit disponible      */  } ArchInstrFlag; @@ -310,19 +310,4 @@ const char *g_arch_instruction_get_description(const GArchInstruction *); -/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ - - -/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */ -typedef struct _GAsmStorage GAsmStorage; - - -/* Charge une instruction depuis une mémoire tampon. */ -GArchInstruction *g_arch_instruction_load(GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde une instruction dans une mémoire tampon. */ -bool g_arch_instruction_store(GArchInstruction *, GAsmStorage *, packed_buffer_t *); - - -  #endif  /* _ARCH_INSTRUCTION_H */ diff --git a/src/arch/instructions/Makefile.am b/src/arch/instructions/Makefile.am index 24d3eb5..28cf90f 100644 --- a/src/arch/instructions/Makefile.am +++ b/src/arch/instructions/Makefile.am @@ -1,24 +1,14 @@  noinst_LTLIBRARIES = libarchinstructions.la -libarchinstructions_la_SOURCES =		\ -	raw.h raw.c							\ -	undefined-int.h						\ +libarchinstructions_la_SOURCES =			\ +	raw.h raw.c								\ +	undefined-int.h							\  	undefined.h undefined.c -libarchinstructions_la_LIBADD =	 - -libarchinstructions_la_LDFLAGS =  +libarchinstructions_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)  devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)  dev_HEADERS = $(libarchinstructions_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) - - -SUBDIRS =  diff --git a/src/arch/instructions/raw.c b/src/arch/instructions/raw.c index 481dd1c..26282fa 100644 --- a/src/arch/instructions/raw.c +++ b/src/arch/instructions/raw.c @@ -35,7 +35,7 @@  #include "../instruction-int.h"  #include "../operands/immediate.h"  #include "../operands/target.h" -#include "../../gtkext/gtkblockdisplay.h" +#include "../../core/columns.h" @@ -213,17 +213,17 @@ static void g_raw_instruction_finalize(GRawInstruction *instr)  GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value)  {      GArchInstruction *result;               /* Instruction à retourner     */ -    GImmOperand *operand;                   /* Octet non décodé à afficher */ +    GArchOperand *operand;                  /* Octet non décodé à afficher */      mrange_t range;                         /* Couverture de l'instruction */      result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); -    operand = G_IMM_OPERAND(g_imm_operand_new_from_value(size, value)); -    if (operand == NULL) goto grinfv_error; +    operand = g_imm_operand_new_from_value(size, value); +    if (operand == NULL) goto error; -    g_imm_operand_pad(operand, true); +    g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); -    g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand)); +    g_arch_instruction_attach_extra_operand(result, operand);      switch (size)      { @@ -249,7 +249,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat          default:              assert(false); -            goto grinfv_error; +            goto error;              break;      } @@ -258,7 +258,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat      return result; - grinfv_error: + error:      g_object_unref(G_OBJECT(result)); @@ -287,13 +287,15 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa      uleb128_t value;                        /* Valeur uleb128 à représenter*/      phys_t diff;                            /* Couverture de la lecture    */      MemoryDataSize leb_size;                /* Taille de la valeur         */ -    GImmOperand *operand;                   /* Octet non décodé à afficher */ +    GArchOperand *operand;                  /* Octet non décodé à afficher */      mrange_t range;                         /* Couverture de l'instruction */ +    result = NULL; +      copy_vmpa(&start, addr);      if (!g_binary_content_read_uleb128(content, addr, &value)) -        goto grinu_error; +        goto error;      diff = compute_vmpa_diff(&start, addr); @@ -305,16 +307,18 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa      init_mrange(&range, &start, diff);      g_arch_instruction_set_range(result, &range); -    operand = G_IMM_OPERAND(g_imm_operand_new_from_value(leb_size, (uint64_t)value)); -    if (operand == NULL) goto grinu_error; +    operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value); +    if (operand == NULL) goto error; -    g_imm_operand_pad(operand, true); +    g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); -    g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand)); +    g_arch_instruction_attach_extra_operand(result, operand);      return result; - grinu_error: + error: + +    g_clear_object(&result);      return NULL; @@ -341,13 +345,15 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa      uleb128_t value;                        /* Valeur uleb128 à représenter*/      phys_t diff;                            /* Couverture de la lecture    */      MemoryDataSize leb_size;                /* Taille de la valeur         */ -    GImmOperand *operand;                   /* Octet non décodé à afficher */ +    GArchOperand *operand;                  /* Octet non décodé à afficher */      mrange_t range;                         /* Couverture de l'instruction */ +    result = NULL; +      copy_vmpa(&start, addr);      if (!g_binary_content_read_uleb128(content, addr, &value)) -        goto grins_error; +        goto error;      diff = compute_vmpa_diff(&start, addr); @@ -359,16 +365,18 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa      init_mrange(&range, &start, diff);      g_arch_instruction_set_range(result, &range); -    operand = G_IMM_OPERAND(g_imm_operand_new_from_value(leb_size, (uint64_t)value)); -    if (operand == NULL) goto grins_error; +    operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value); +    if (operand == NULL) goto error; -    g_imm_operand_pad(operand, true); +    g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); -    g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand)); +    g_arch_instruction_attach_extra_operand(result, operand);      return result; - grins_error: + error: + +    g_clear_object(&result);      return NULL; @@ -396,7 +404,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory      GArchInstruction *result;               /* Instruction à retourner     */      vmpa2t old;                             /* Sauvegarde de la position   */      size_t i;                               /* Boucle de parcours          */ -    GImmOperand *operand;                   /* Octet non décodé à afficher */ +    GArchOperand *operand;                  /* Octet non décodé à afficher */      mrange_t range;                         /* Couverture de l'instruction */      /* Par soucis de cohérence */ @@ -408,12 +416,12 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory      for (i = 0; i < count; i++)      { -        operand = G_IMM_OPERAND(g_imm_operand_new_from_data(size, content, addr, endian)); -        if (operand == NULL) goto grina_error; +        operand = g_imm_operand_new_from_data(size, content, addr, endian); +        if (operand == NULL) goto error; -        g_imm_operand_pad(operand, true); +        g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); -        g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand)); +        g_arch_instruction_attach_extra_operand(result, operand);      } @@ -423,7 +431,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory      return result; - grina_error: + error:      g_object_unref(G_OBJECT(result)); diff --git a/src/arch/instructions/undefined-int.h b/src/arch/instructions/undefined-int.h index 8a648cf..a9b7627 100644 --- a/src/arch/instructions/undefined-int.h +++ b/src/arch/instructions/undefined-int.h @@ -32,63 +32,57 @@  /* Informations glissées dans la structure GObject de GArchInstruction */ -typedef union _undef_obj_extra +typedef struct _undef_extra_data_t  { -    struct -    { -        InstrExpectedBehavior behavior;     /* Conséquences réelles        */ +    /** +     * Le champ uid de la structure parente attendue conduit à une taille +     * alignée sur 2 octets, donc à une taille totale de 4 octets ce qui +     * représente la limite maximale de taille supportée. +     * +     * Pour 3 octets à la base, qui devraient laisser 8 - 1 octets disponbibles +     * en incluant le bit de verrouillage. +     * +     * On reproduit donc la structure instr_extra_data_t ici, en basculant +     * l'énumération InstrExpectedBehavior en champ de bits. +     */ -    }; +    itid_t uid;                             /* Identifiant unique du type  */ +    ArchInstrFlag flags;                    /* Informations complémentaires*/ -    gint lock;                              /* Gestion d'accès aux fanions */ +    unsigned int behavior : 2;              /* Conséquences réelles        */ + +} undef_extra_data_t; -} undef_obj_extra;  /* Définition générique d'une instruction au comportement non défini (instance) */  struct _GUndefInstruction  {      GArchInstruction parent;                /* A laisser en premier        */ -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -    /** -     * L'inclusion des informations suivantes dépend de l'architecture. -     * -     * Si la structure GObject possède un trou, on remplit de préférence -     * ce dernier. -     */ - -    undef_obj_extra extra;                  /* Externalisation embarquée   */ +}; -#endif +/* Définition générique d'une instruction au comportement non défini (classe) */ +struct _GUndefInstructionClass +{ +    GArchInstructionClass parent;           /* A laisser en premier        */  }; +  /**   * Accès aux informations éventuellement déportées.   */ -#if __SIZEOF_INT__ == __SIZEOF_LONG__ +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ -#   define INIT_UNDEF_INSTR_EXTRA(ins) ins->extra.lock = 0 - -#   define GET_UNDEF_INSTR_EXTRA(ins) &ins->extra +#   define GET_UNDEF_INSTR_EXTRA(ins) ((undef_extra_data_t *)&((GArchInstruction *)ins)->extra)  #else -#   define INIT_UNDEF_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins)) - -#   define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_obj_extra) +#   define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_extra_data_t)  #endif -/* Définition générique d'une instruction au comportement non défini (classe) */ -struct _GUndefInstructionClass -{ -    GArchInstructionClass parent;           /* A laisser en premier        */ - -}; -  #endif  /* _ARCH_INSTRUCTIONS_UNDEFINED_INT_H */ diff --git a/src/arch/instructions/undefined.c b/src/arch/instructions/undefined.c index 880e338..15c63e7 100644 --- a/src/arch/instructions/undefined.c +++ b/src/arch/instructions/undefined.c @@ -31,7 +31,7 @@  #include "undefined-int.h" -#include "../../gtkext/gtkblockdisplay.h" +#include "../../core/columns.h" @@ -74,6 +74,17 @@ static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_undef_instruction_load(GUndefInstruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_undef_instruction_store(GUndefInstruction *, GObjectStorage *, packed_buffer_t *); + + +  /* ---------------------------------------------------------------------------------- */  /*                           INSTRUCTION INCONNUE / DONNEES                           */  /* ---------------------------------------------------------------------------------- */ @@ -115,6 +126,9 @@ static void g_undef_instruction_class_init(GUndefInstructionClass *klass)      instr->print = (print_instruction_fc)g_undef_instruction_print; +    instr->load = (load_instruction_fc)g_undef_instruction_load; +    instr->store = (store_instruction_fc)g_undef_instruction_store; +  } @@ -132,7 +146,7 @@ static void g_undef_instruction_class_init(GUndefInstructionClass *klass)  static void g_undef_instruction_init(GUndefInstruction *instr)  { -    INIT_ARCH_INSTR_EXTRA(instr); +    GET_UNDEF_INSTR_EXTRA(instr)->behavior = IEB_UNDEFINED;  } @@ -190,7 +204,7 @@ static void g_undef_instruction_finalize(GUndefInstruction *instr)  GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior behavior)  {      GArchInstruction *result;               /* Instruction à retourner     */ -    undef_obj_extra *extra;                 /* Données insérées à modifier */ +    undef_extra_data_t *extra;              /* Données insérées à modifier */      result = g_object_new(G_TYPE_UNDEF_INSTRUCTION, NULL); @@ -241,7 +255,7 @@ static const char *g_undef_instruction_get_encoding(const GUndefInstruction *ins  const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr)  {      const char *result;                     /* Désignation à retourner     */ -    undef_obj_extra *extra;                 /* Données insérées à consulter*/ +    undef_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_UNDEF_INSTR_EXTRA(instr); @@ -300,7 +314,8 @@ static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorag  {      bool result;                            /* Bilan à retourner           */      GArchInstructionClass *parent;          /* Classe parente à consulter  */ -    undef_obj_extra *extra;                 /* Données insérées à modifier */ +    undef_extra_data_t *extra;              /* Données insérées à consulter*/ +    uint8_t val;                            /* Champ de bits manipulé      */      parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); @@ -310,7 +325,12 @@ static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorag      {          extra = GET_UNDEF_INSTR_EXTRA(instr); -        result = extract_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true); +        LOCK_GOBJECT_EXTRA(extra); + +        result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); +        extra->behavior = val; + +        UNLOCK_GOBJECT_EXTRA(extra);      } @@ -337,7 +357,7 @@ static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage  {      bool result;                            /* Bilan à retourner           */      GArchInstructionClass *parent;          /* Classe parente à consulter  */ -    undef_obj_extra *extra;                 /* Données insérées à consulter*/ +    undef_extra_data_t *extra;              /* Données insérées à consulter*/      parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); @@ -347,7 +367,11 @@ static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage      {          extra = GET_UNDEF_INSTR_EXTRA(instr); -        result = extend_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true); +        LOCK_GOBJECT_EXTRA(extra); + +        result = extend_packed_buffer(pbuf, (uint8_t []){ extra->behavior }, sizeof(uint8_t), false); + +        UNLOCK_GOBJECT_EXTRA(extra);      } @@ -417,12 +441,106 @@ static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *lin  InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *instr)  {      InstrExpectedBehavior result;           /* Comportement à retourner    */ -    undef_obj_extra *extra;                 /* Données insérées à consulter*/ +    undef_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_UNDEF_INSTR_EXTRA(instr); +    LOCK_GOBJECT_EXTRA(extra); +      result = extra->behavior; +    UNLOCK_GOBJECT_EXTRA(extra); + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                * +*                                                                             * +*  Description : Charge un contenu depuis une mémoire tampon.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_undef_instruction_load(GUndefInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *parent;          /* Classe parente à consulter  */ +    undef_extra_data_t *extra;              /* Données insérées à consulter*/ +    uint8_t val;                            /* Champ de bits manipulé      */ + +    parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); + +    result = parent->load(G_ARCH_INSTRUCTION(instr), storage, pbuf); + +    if (result) +    { +        extra = GET_UNDEF_INSTR_EXTRA(instr); + +        LOCK_GOBJECT_EXTRA(extra); + +        result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); +        extra->behavior = val; + +        UNLOCK_GOBJECT_EXTRA(extra); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_undef_instruction_store(GUndefInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *parent;          /* Classe parente à consulter  */ +    undef_extra_data_t *extra;              /* Données insérées à consulter*/ + +    parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); + +    result = parent->store(G_ARCH_INSTRUCTION(instr), storage, pbuf); + +    if (result) +    { +        extra = GET_UNDEF_INSTR_EXTRA(instr); + +        LOCK_GOBJECT_EXTRA(extra); + +        result = extend_packed_buffer(pbuf, (uint8_t []){ extra->behavior }, sizeof(uint8_t), false); + +        UNLOCK_GOBJECT_EXTRA(extra); + +    } +      return result;  } diff --git a/src/arch/meta.c b/src/arch/meta.c deleted file mode 100644 index 137a043..0000000 --- a/src/arch/meta.c +++ /dev/null @@ -1,428 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * artificial.c - instructions pures vues de l'esprit - * - * Copyright (C) 2018 Cyrille Bagard - * - *  This file is part of Chrysalide. - * - *  Chrysalide is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 3 of the License, or - *  (at your option) any later version. - * - *  Chrysalide is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "meta.h" - - -#include <malloc.h> - - -#include "instruction-int.h" - - - -/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */ - - -/* Définition d'une instruction de rassemblement (instance) */ -struct _GMetaInstruction -{ -    GArchInstruction parent;                /* A laisser en premier        */ - -    GArchInstruction *fake;                 /* Instruction simulée         */ - -    GArchInstruction **children;            /* Instructions représentées   */ -    size_t count;                           /* Taille de cette liste       */ - -}; - -/* Définition d'une instruction de rassemblement (classe) */ -struct _GMetaInstructionClass -{ -    GArchInstructionClass parent;           /* A laisser en premier        */ - -}; - - -/* Initialise la classe des instructions de rassemblement. */ -static void g_meta_instruction_class_init(GMetaInstructionClass *); - -/* Initialise une instance d'instruction de rassemblement. */ -static void g_meta_instruction_init(GMetaInstruction *); - -/* Supprime toutes les références externes. */ -static void g_meta_instruction_dispose(GMetaInstruction *); - -/* Procède à la libération totale de la mémoire. */ -static void g_meta_instruction_finalize(GMetaInstruction *); - -/* Indique l'encodage d'une instruction de façon détaillée. */ -static const char *g_meta_instruction_get_encoding(const GMetaInstruction *); - -/* Fournit le nom humain de l'instruction manipulée. */ -static const char *g_meta_instruction_get_keyword(const GMetaInstruction *); - - - -/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ - - -/* Charge une instruction depuis une mémoire tampon. */ -static bool g_meta_instruction_unserialize(GMetaInstruction *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde une instruction dans une mémoire tampon. */ -static bool g_meta_instruction_serialize(GMetaInstruction *, GAsmStorage *, packed_buffer_t *); - - - -/* ---------------------------------------------------------------------------------- */ -/*                           INSTRUCTION INCONNUE / DONNEES                           */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini pour une instruction inconnue d'architecture. */ -G_DEFINE_TYPE(GMetaInstruction, g_meta_instruction, G_TYPE_ARCH_INSTRUCTION); - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : klass = classe à initialiser.                                * -*                                                                             * -*  Description : Initialise la classe des instructions de rassemblement.      * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_meta_instruction_class_init(GMetaInstructionClass *klass) -{ -    GObjectClass *object;                   /* Autre version de la classe  */ -    GArchInstructionClass *instr;           /* Encore une autre vision...  */ - -    object = G_OBJECT_CLASS(klass); - -    object->dispose = (GObjectFinalizeFunc/* ! */)g_meta_instruction_dispose; -    object->finalize = (GObjectFinalizeFunc)g_meta_instruction_finalize; - -    instr = G_ARCH_INSTRUCTION_CLASS(klass); - -    instr->get_encoding = (get_instruction_encoding_fc)g_meta_instruction_get_encoding; -    instr->get_keyword = (get_instruction_keyword_fc)g_meta_instruction_get_keyword; - -    instr->unserialize = (unserialize_instruction_fc)g_meta_instruction_unserialize; -    instr->serialize = (serialize_instruction_fc)g_meta_instruction_serialize; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr = instance à initialiser.                              * -*                                                                             * -*  Description : Initialise une instance d'instruction de rassemblement.      * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_meta_instruction_init(GMetaInstruction *instr) -{ -    GArchInstruction *parent;               /* Version parente             */ -    vmpa2t invalid;                         /* Absence de position         */ - -    parent = G_ARCH_INSTRUCTION(instr); - -    init_vmpa(&invalid, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); -    init_mrange(&parent->range, &invalid, 0); - -    instr->fake = NULL; - -    instr->children = NULL; -    instr->count = 0; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr = instance d'objet GLib à traiter.                     * -*                                                                             * -*  Description : Supprime toutes les références externes.                     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_meta_instruction_dispose(GMetaInstruction *instr) -{ -    size_t i;                               /* Boucle de parcours          */ - -    if (instr->fake != NULL) -        g_object_unref(G_OBJECT(instr->fake)); - -    for (i = 0; i < instr->count; i++) -        g_object_unref(G_OBJECT(instr->children[i])); - -    G_OBJECT_CLASS(g_meta_instruction_parent_class)->dispose(G_OBJECT(instr)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr = instance d'objet GLib à traiter.                     * -*                                                                             * -*  Description : Procède à la libération totale de la mémoire.                * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_meta_instruction_finalize(GMetaInstruction *instr) -{ -    if (instr->children != NULL) -        free(instr->children); - -    G_OBJECT_CLASS(g_meta_instruction_parent_class)->finalize(G_OBJECT(instr)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : fake = instruction à simuler.                                * -*                                                                             * -*  Description : Crée une instruction rassemblant d'autres instructions.      * -*                                                                             * -*  Retour      : Instruction mise en place.                                   * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GArchInstruction *g_meta_instruction_new(GArchInstruction *fake) -{ -    GMetaInstruction *result;               /* Instruction à retourner     */ - -    result = g_object_new(G_TYPE_META_INSTRUCTION, NULL); - -    result->fake = fake; - -    return G_ARCH_INSTRUCTION(result); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr = instruction quelconque à consulter.                  * -*                                                                             * -*  Description : Indique l'encodage d'une instruction de façon détaillée.     * -*                                                                             * -*  Retour      : Description humaine de l'encodage utilisé.                   * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static const char *g_meta_instruction_get_encoding(const GMetaInstruction *instr) -{ -    const char *result;                     /* Description à retourner     */ - -    result = g_arch_instruction_get_encoding(instr->fake); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr = instruction d'assemblage à consulter.                * -*                                                                             * -*  Description : Fournit le nom humain de l'instruction manipulée.            * -*                                                                             * -*  Retour      : Mot clef de bas niveau.                                      * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static const char *g_meta_instruction_get_keyword(const GMetaInstruction *instr) -{ -    const char *result;                     /* Désignation à renvoyer      */ - -    result = g_arch_instruction_get_keyword(instr->fake); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr = instruction d'assemblage à compléter.                * -*                child = instruction à intégrer au rassemblement.             * -*                last  = marque l'instruction comme étant la dernière du lot. * -*                                                                             * -*  Description : Intègre une nouvelle instruction dans un rassemblement.      * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_meta_instruction_add_child(GMetaInstruction *instr, GArchInstruction *child, bool last) -{ -    GArchInstruction *parent;               /* Autre version de l'instruct°*/ -    const mrange_t *base;                   /* Base d'une couverture       */ -    vmpa2t start;                           /* Position de départ          */ -    vmpa2t end;                             /* Position d'arrivée          */ -    mrange_t range;                         /* Couverture nouvelle         */ -    instr_link_t *links;                    /* Liens présents à copier     */ -    size_t count;                           /* Quantité de ces liens       */ -    size_t i;                               /* Boucle de parcours          */ - -    instr->children = (GArchInstruction **)realloc(instr->children, -                                                   ++instr->count * sizeof(GArchInstruction *)); - -    instr->children[instr->count - 1] = child; - -    parent = G_ARCH_INSTRUCTION(instr); - -    /* Mise à jour de la couverture totale */ - -    if (last) -    { -        if (instr->count == 1) -            g_arch_instruction_set_range(parent, g_arch_instruction_get_range(child)); - -        else -        { -            base = g_arch_instruction_get_range(instr->children[0]); -            copy_vmpa(&start, get_mrange_addr(base)); - -            base = g_arch_instruction_get_range(child); -            compute_mrange_end_addr(base, &end); - -            init_mrange(&range, &start, compute_vmpa_diff(&start, &end)); - -            g_arch_instruction_set_range(parent, &range); - -        } - -    } - -    /* Appropriation des liens contenus */ - -    links = g_arch_instruction_get_sources(child, &count); - -    for (i = 0; i < count; i++) -    { -        if (instr->count == 1 || links[i].type == ILT_REF) -            g_arch_instruction_link_with(links[i].linked, parent, links[i].type); - -        unref_instr_link((&links[i])); - -    } - -    if (links != NULL) -        free(links); - -    links = g_arch_instruction_get_destinations(child, &count); - -    for (i = 0; i < count; i++) -    { -        if (last || links[i].type == ILT_REF) -            g_arch_instruction_link_with(parent, links[i].linked, links[i].type); - -        unref_instr_link((&links[i])); - -    } - -    if (links != NULL) -        free(links); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/*                      CONSERVATION SUR DISQUE DES INSTRUCTIONS                      */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr   = instruction d'assemblage à consulter.              * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * -*                pbuf    = zone tampon à remplir.                             * -*                                                                             * -*  Description : Charge une instruction depuis une mémoire tampon.            * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_meta_instruction_unserialize(GMetaInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) -{ -    bool result;                            /* Bilan à retourner           */ -    GArchInstructionClass *parent;          /* Classe parente à consulter  */ - -    parent = G_ARCH_INSTRUCTION_CLASS(g_meta_instruction_parent_class); - -    result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr   = instruction d'assemblage à consulter.              * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                pbuf    = zone tampon à remplir.                             * -*                                                                             * -*  Description : Sauvegarde une instruction dans une mémoire tampon.          * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_meta_instruction_serialize(GMetaInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf) -{ -    bool result;                            /* Bilan à retourner           */ -    GArchInstructionClass *parent;          /* Classe parente à consulter  */ - -    parent = G_ARCH_INSTRUCTION_CLASS(g_meta_instruction_parent_class); - -    result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf); - -    return result; - -} diff --git a/src/arch/meta.h b/src/arch/meta.h deleted file mode 100644 index 6c62654..0000000 --- a/src/arch/meta.h +++ /dev/null @@ -1,65 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * meta.h - prototypes pour les instructions qui en rassemblent d'autres - * - * Copyright (C) 2018 Cyrille Bagard - * - *  This file is part of Chrysalide. - * - *  Chrysalide is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 3 of the License, or - *  (at your option) any later version. - * - *  Chrysalide is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. - */ - - -#ifndef _ARCH_META_H -#define _ARCH_META_H - - -#include <glib-object.h> -#include <stdbool.h> - - -#include "instruction.h" - - - -/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */ - - -#define G_TYPE_META_INSTRUCTION            g_meta_instruction_get_type() -#define G_META_INSTRUCTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_META_INSTRUCTION, GMetaInstruction)) -#define G_IS_META_INSTRUCTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_META_INSTRUCTION)) -#define G_META_INSTRUCTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_META_INSTRUCTION, GMetaInstructionClass)) -#define G_IS_META_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_META_INSTRUCTION)) -#define G_META_INSTRUCTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_META_INSTRUCTION, GMetaInstructionClass)) - - -/* Définition d'une instruction de rassemblement (instance) */ -typedef struct _GMetaInstruction GMetaInstruction; - -/* Définition d'une instruction de rassemblement (classe) */ -typedef struct _GMetaInstructionClass GMetaInstructionClass; - - -/* Indique le type défini pour une instruction inconnue d'architecture. */ -GType g_meta_instruction_get_type(void); - -/* Crée une instruction rassemblant d'autres instructions. */ -GArchInstruction *g_meta_instruction_new(GArchInstruction *); - -/* Intègre une nouvelle instruction dans un rassemblement. */ -void g_meta_instruction_add_child(GMetaInstruction *, GArchInstruction *, bool); - - - -#endif  /* _ARCH_META_H */ diff --git a/src/arch/operand-int.c b/src/arch/operand-int.c new file mode 100644 index 0000000..51e8d44 --- /dev/null +++ b/src/arch/operand-int.c @@ -0,0 +1,308 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * operand-int.c - définition générique interne des opérandes + * + * Copyright (C) 2021 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "operand-int.h" + + + +/* ---------------------------------------------------------------------------------- */ +/*                      CONSERVATION ET RECHARGEMENT DES DONNEES                      */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à consulter.                           * +*                count   = quantité d'opérandes à extraire du tampon.         * +*                                                                             * +*  Description : Charge une série d'opérandes internes depuis un tampon.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool _g_arch_operand_load_inner_instances(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf, size_t count) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchOperand **instances;               /* Liste d'opérandes à charger */ +    size_t i;                               /* Boucle de parcours          */ + +    result = true; + +    instances = calloc(count, sizeof(GArchOperand *)); + +    for (i = 0; i < count && result; i++) +        result = g_object_storage_unpack_object_2(storage, "operands", pbuf, G_TYPE_ARCH_OPERAND, &instances[i]); + +    if (result) +        g_arch_operand_update_inner_instances(operand, instances, count); + +    for (i = 0; i < count; i++) +        g_clear_object(&instances[i]); + +    free(instances); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à consulter.                           * +*                                                                             * +*  Description : Charge une série d'opérandes internes depuis un tampon.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_arch_operand_load_generic_fixed_1(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GType type;                             /* Type d'opérande manipulé    */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ + +    type = G_TYPE_FROM_INSTANCE(operand); + +    parent = g_type_class_peek_parent(g_type_class_peek(type)); + +    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); + +    if (result) +        result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, 1); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à consulter.                           * +*                                                                             * +*  Description : Charge une série d'opérandes internes depuis un tampon.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_arch_operand_load_generic_fixed_3(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GType type;                             /* Type d'opérande manipulé    */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ + +    type = G_TYPE_FROM_INSTANCE(operand); + +    parent = g_type_class_peek_parent(g_type_class_peek(type)); + +    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); + +    if (result) +        result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, 3); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à consulter.                           * +*                                                                             * +*  Description : Charge une série d'opérandes internes depuis un tampon.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_arch_operand_load_generic_variadic(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GType type;                             /* Type d'opérande manipulé    */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ + +    type = G_TYPE_FROM_INSTANCE(operand); + +    parent = g_type_class_peek_parent(g_type_class_peek(type)); + +    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); + +    if (result) +        result = unpack_uleb128(&value, pbuf); + +    if (result) +        result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, value); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                fixed   = précise si le nombre d'opérande est fixe ou non.   * +*                                                                             * +*  Description : Sauvegarde une série d'opérandes internes dans un tampon.    * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool _g_arch_operand_store_inner_instances(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf, bool fixed) +{ +    bool result;                            /* Bilan à retourner           */ +    size_t count;                           /* Nombre d'opérandes listées  */ +    GArchOperand **instances;               /* Liste d'opérandes à traiter */ +    size_t i;                               /* Boucle de parcours          */ +    GSerializableObject *obj;               /* Objet à conserver           */ + +    result = true; + +    instances = g_arch_operand_list_inner_instances(operand, &count); + +    if (!fixed) +        result = pack_uleb128((uleb128_t []){ count }, pbuf); + +    if (instances != NULL) +    { +        for (i = 0; i < count && result; i++) +        { +            if (instances[i] == NULL) +                result = g_object_storage_pack_object(storage, "operands", NULL, pbuf); + +            else +            { +                obj = G_SERIALIZABLE_OBJECT(instances[i]); + +                result = g_object_storage_pack_object(storage, "operands", obj, pbuf); + +                g_object_unref(G_OBJECT(instances[i])); + +            } + +        } + +        for (; i < count && result; i++) +            g_clear_object(&instances[i]); + +        free(instances); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                fixed   = précise si le nombre d'opérande est fixe ou non.   * +*                                                                             * +*  Description : Sauvegarde un opérande dans un tampon de façon générique.    * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_arch_operand_store_generic_fixed(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GType type;                             /* Type d'opérande manipulé    */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ + +    type = G_TYPE_FROM_INSTANCE(operand); + +    parent = g_type_class_peek_parent(g_type_class_peek(type)); + +    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); + +    if (result) +        result = _g_arch_operand_store_inner_instances(operand, storage, pbuf, true); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                fixed   = précise si le nombre d'opérande est fixe ou non.   * +*                                                                             * +*  Description : Sauvegarde un opérande dans un tampon de façon générique.    * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_arch_operand_store_generic_variadic(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GType type;                             /* Type d'opérande manipulé    */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ + +    type = G_TYPE_FROM_INSTANCE(operand); + +    parent = g_type_class_peek_parent(g_type_class_peek(type)); + +    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); + +    if (result) +        result = _g_arch_operand_store_inner_instances(operand, storage, pbuf, false); + +    return result; + +} diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h index a50ec73..e6c1232 100644 --- a/src/arch/operand-int.h +++ b/src/arch/operand-int.h @@ -28,9 +28,16 @@  #include "operand.h" +#include <stdbool.h> + + +#include "../analysis/storage/storage.h" +#include "../glibext/objhole.h" + +  /* Compare un opérande avec un autre. */ -typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *); +typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *, bool);  /* Détermine le chemin conduisant à un opérande interne. */  typedef char * (* find_inner_operand_fc) (const GArchOperand *, const GArchOperand *); @@ -41,14 +48,43 @@ typedef GArchOperand * (* get_inner_operand_fc) (const GArchOperand *, const cha  /* Traduit un opérande en version humainement lisible. */  typedef void (* operand_print_fc) (const GArchOperand *, GBufferLine *); +#ifdef INCLUDE_GTK_SUPPORT +  /* Construit un petit résumé concis de l'opérande. */  typedef char * (* operand_build_tooltip_fc) (const GArchOperand *, const GLoadedBinary *); -/* Charge un opérande depuis une mémoire tampon. */ -typedef bool (* unserialize_operand_fc) (GArchOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); +#endif + +/* Fournit une liste de candidats embarqués par un candidat. */ +typedef GArchOperand ** (* operand_list_inners_fc) (const GArchOperand *, size_t *); + +/* Met à jour une liste de candidats embarqués par un candidat. */ +typedef void (* operand_update_inners_fc) (GArchOperand *, GArchOperand **, size_t); -/* Sauvegarde un opérande dans une mémoire tampon. */ -typedef bool (* serialize_operand_fc) (const GArchOperand *, GAsmStorage *, packed_buffer_t *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +typedef guint (* operand_hash_fc) (const GArchOperand *, bool); + +/* Charge un contenu depuis une mémoire tampon. */ +typedef bool (* load_operand_fc) (GArchOperand *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +typedef bool (* store_operand_fc) (GArchOperand *, GObjectStorage *, packed_buffer_t *); + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _operand_extra_data_t +{ +    ArchOperandFlag flags;                  /* Informations diverses       */ + +} operand_extra_data_t; + +/* Encapsulation avec un verrou d'accès */ +typedef union _operand_obj_extra_t +{ +    operand_extra_data_t data;              /* Données embarquées          */ +    lockable_obj_extra_t lockable;          /* Gestion d'accès aux fanions */ + +} operand_obj_extra_t;  /* Définition générique d'un opérande d'architecture (instance) */ @@ -56,8 +92,20 @@ struct _GArchOperand  {      GObject parent;                         /* A laisser en premier        */ -}; +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +    /** +     * L'inclusion des informations suivantes dépend de l'architecture. +     * +     * Si la structure GObject possède un trou, on remplit de préférence +     * ce dernier. +     */ + +    operand_obj_extra_t extra;              /* Externalisation embarquée   */ +#endif + +};  /* Définition générique d'un opérande d'architecture (classe) */  struct _GArchOperandClass @@ -69,13 +117,78 @@ struct _GArchOperandClass      get_inner_operand_fc get_inner;         /* Récupération d'un opérande  */      operand_print_fc print;                 /* Texte humain équivalent     */ +#ifdef INCLUDE_GTK_SUPPORT      operand_build_tooltip_fc build_tooltip; /* Construction de description */ +#endif + +    operand_list_inners_fc list_inner;      /* Récupération d'internes     */ +    operand_update_inners_fc update_inner;  /* Mise à jour des éléments    */ +    operand_hash_fc hash;                   /* Prise d'empreinte           */ -    unserialize_operand_fc unserialize;     /* Chargement depuis un tampon */ -    serialize_operand_fc serialize;         /* Conservation dans un tampon */ +    load_operand_fc load;                   /* Chargement depuis un tampon */ +    store_operand_fc store;                 /* Conservation dans un tampon */  }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +#   define GET_ARCH_OP_EXTRA(op) (operand_extra_data_t *)&op->extra + +#else + +#   define GET_ARCH_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), operand_extra_data_t) + +#endif + + +/* Ajoute une information complémentaire à un opérande. */ +bool _g_arch_operand_set_flag(GArchOperand *, ArchOperandFlag, bool); + +/* Retire une information complémentaire à un opérande. */ +bool _g_arch_operand_unset_flag(GArchOperand *, ArchOperandFlag, bool); + + + +/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */ + + +/* Fournit une liste de candidats embarqués par un candidat. */ +GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, size_t *); + +/* Met à jour une liste de candidats embarqués par un candidat. */ +void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t); + + + +/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ + + +/* Charge une série d'opérandes internes depuis un tampon. */ +bool _g_arch_operand_load_inner_instances(GArchOperand *, GObjectStorage *, packed_buffer_t *, size_t); + +/* Charge une série d'opérandes internes depuis un tampon. */ +bool g_arch_operand_load_generic_fixed_1(GArchOperand *, GObjectStorage *, packed_buffer_t *); + +/* Charge une série d'opérandes internes depuis un tampon. */ +bool g_arch_operand_load_generic_fixed_3(GArchOperand *, GObjectStorage *, packed_buffer_t *); + +/* Charge une série d'opérandes internes depuis un tampon. */ +bool g_arch_operand_load_generic_variadic(GArchOperand *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde une série d'opérandes internes dans un tampon. */ +bool _g_arch_operand_store_inner_instances(GArchOperand *, GObjectStorage *, packed_buffer_t *, bool); + +/* Sauvegarde un opérande dans un tampon de façon générique. */ +bool g_arch_operand_store_generic_fixed(GArchOperand *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un opérande dans un tampon de façon générique. */ +bool g_arch_operand_store_generic_variadic(GArchOperand *, GObjectStorage *, packed_buffer_t *); + +  #endif  /* _ARCH_OPERAND_INT_H */ diff --git a/src/arch/operand.c b/src/arch/operand.c index 3758d7f..0f5ffd5 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -31,14 +31,15 @@  #include "operand-int.h"  #include "storage.h" +#include "../analysis/storage/serialize-int.h" +#include "../common/fnv1a.h"  #include "../common/sort.h"  #include "../core/logs.h" +#include "../glibext/singleton-int.h" -/* ---------------------------------------------------------------------------------- */ -/*                          DEFINITION D'OPERANDE QUELCONQUE                          */ -/* ---------------------------------------------------------------------------------- */ +/* ------------------------ DEFINITION D'OPERANDE QUELCONQUE ------------------------ */  /* Initialise la classe générique des opérandes. */ @@ -47,29 +48,76 @@ static void g_arch_operand_class_init(GArchOperandClass *);  /* Initialise une instance d'opérande d'architecture. */  static void g_arch_operand_init(GArchOperand *); +/* Procède à l'initialisation de l'interface de singleton. */ +static void g_arch_operand_singleton_init(GSingletonCandidateInterface *); + +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_arch_operand_serializable_init(GSerializableObjectInterface *); +  /* Supprime toutes les références externes. */  static void g_arch_operand_dispose(GArchOperand *);  /* Procède à la libération totale de la mémoire. */  static void g_arch_operand_finalize(GArchOperand *); +/* Compare un opérande avec un autre. */ +static int _g_arch_operand_compare(const GArchOperand *, const GArchOperand *, bool); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */ -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_arch_operand_unserialize(GArchOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_arch_operand_serialize(const GArchOperand *, GAsmStorage *, packed_buffer_t *); +/* Fournit une liste de candidats embarqués par un candidat. */ +GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, size_t *); +/* Met à jour une liste de candidats embarqués par un candidat. */ +void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint _g_arch_operand_hash(const GArchOperand *, bool); -/* Indique le type défini pour un opérande d'architecture. */ -G_DEFINE_TYPE(GArchOperand, g_arch_operand, G_TYPE_OBJECT); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_arch_operand_hash(const GArchOperand *); + +/* Détermine si deux candidats à l'unicité sont identiques. */ +static gboolean g_arch_operand_is_equal(const GArchOperand *, const GArchOperand *); + +/* Marque un candidat comme figé. */ +static void g_arch_operand_set_read_only(GArchOperand *); + +/* Indique si le candidat est figé. */ +static bool g_arch_operand_is_read_only(GArchOperand *); + + + +/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ +/* Charge un contenu depuis une mémoire tampon. */ +static bool _g_arch_operand_load(GArchOperand *, GObjectStorage *, packed_buffer_t *); + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_arch_operand_load(GArchOperand *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool _g_arch_operand_store(GArchOperand *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_arch_operand_store(GArchOperand *, GObjectStorage *, packed_buffer_t *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                          DEFINITION D'OPERANDE QUELCONQUE                          */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un opérande d'architecture. */ +G_DEFINE_TYPE_WITH_CODE(GArchOperand, g_arch_operand, G_TYPE_OBJECT, +                        G_IMPLEMENT_INTERFACE(G_TYPE_SINGLETON_CANDIDATE, g_arch_operand_singleton_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_operand_serializable_init)); +  /******************************************************************************  *                                                                             * @@ -95,8 +143,12 @@ static void g_arch_operand_class_init(GArchOperandClass *klass)      operand = G_ARCH_OPERAND_CLASS(klass); -    operand->unserialize = (unserialize_operand_fc)g_arch_operand_unserialize; -    operand->serialize = (serialize_operand_fc)g_arch_operand_serialize; +    operand->compare = (operand_compare_fc)_g_arch_operand_compare; + +    operand->hash = _g_arch_operand_hash; + +    operand->load = (load_operand_fc)_g_arch_operand_load; +    operand->store = (store_operand_fc)_g_arch_operand_store;  } @@ -115,6 +167,57 @@ static void g_arch_operand_class_init(GArchOperandClass *klass)  static void g_arch_operand_init(GArchOperand *operand)  { +    operand_extra_data_t *extra;            /* Données insérées à modifier */ + +    extra = GET_ARCH_OP_EXTRA(operand); + +    INIT_GOBJECT_EXTRA_LOCK(extra); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de singleton.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_operand_singleton_init(GSingletonCandidateInterface *iface) +{ +    iface->list_inner = (list_inner_instances_fc)g_arch_operand_list_inner_instances; +    iface->update_inner = (update_inner_instances_fc)g_arch_operand_update_inner_instances; + +    iface->hash = (hash_candidate_fc)g_arch_operand_hash; +    iface->is_equal = (is_candidate_equal_fc)g_arch_operand_is_equal; + +    iface->set_ro = (set_candidate_ro_fc)g_arch_operand_set_read_only; +    iface->is_ro = (is_candidate_ro_fc)g_arch_operand_is_read_only; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de sérialisation.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_operand_serializable_init(GSerializableObjectInterface *iface) +{ +    iface->load = (load_serializable_object_cb)g_arch_operand_load; +    iface->store = (store_serializable_object_cb)g_arch_operand_store;  } @@ -159,6 +262,38 @@ static void g_arch_operand_finalize(GArchOperand *operand)  /******************************************************************************  *                                                                             * +*  Paramètres  : a    = premier opérande à consulter.                         * +*                b    = second opérande à consulter.                          * +*                lock = précise le besoin en verrouillage.                    * +*                                                                             * +*  Description : Compare un opérande avec un autre.                           * +*                                                                             * +*  Retour      : Bilan de la comparaison.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static int _g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b, bool lock) +{ +    int result;                             /* Bilan à faire remonter      */ +    operand_extra_data_t *ea;               /* Données insérées à consulter*/ +    operand_extra_data_t *eb;               /* Données insérées à consulter*/ + +    assert(!lock); + +    ea = GET_ARCH_OP_EXTRA(a); +    eb = GET_ARCH_OP_EXTRA(b); + +    result = sort_unsigned_long(ea->flags, eb->flags); + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : a = premier opérande à consulter.                            *  *                b = second opérande à consulter.                             *  *                                                                             * @@ -184,7 +319,7 @@ int g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b)      result = sort_unsigned_long(type_a, type_b);      if (result == 0) -        result = G_ARCH_OPERAND_GET_CLASS(a)->compare(a, b); +        result = G_ARCH_OPERAND_GET_CLASS(a)->compare(a, b, true);      return result; @@ -273,6 +408,9 @@ void g_arch_operand_print(const GArchOperand *operand, GBufferLine *line)  } +#ifdef INCLUDE_GTK_SUPPORT + +  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = opérande à consulter.                              * @@ -303,20 +441,53 @@ char *g_arch_operand_build_tooltip(const GArchOperand *operand, const GLoadedBin  } +#endif -/* ---------------------------------------------------------------------------------- */ -/*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */ -/* ---------------------------------------------------------------------------------- */ + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à venir modifier.                         * +*                flag    = drapeau d'information complémentaire à planter.    * +*                lock    = indique un besoin de verrouillage des données.     * +*                                                                             * +*  Description : Ajoute une information complémentaire à un opérande.         * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool _g_arch_operand_set_flag(GArchOperand *operand, ArchOperandFlag flag, bool lock) +{ +    bool result;                            /* Bilan à retourner           */ +    operand_extra_data_t *extra;            /* Données insérées à modifier */ + +    assert(flag <= AOF_HIGH_USER); + +    extra = GET_ARCH_OP_EXTRA(operand); + +    if (lock) +        LOCK_GOBJECT_EXTRA(extra); + +    result = !(extra->flags & flag); + +    extra->flags |= flag; + +    if (lock) +        UNLOCK_GOBJECT_EXTRA(extra); + +    return result; + +}  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à constituer.                * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : operand = opérande à venir modifier.                         * +*                flag    = drapeau d'information complémentaire à planter.    *  *                                                                             * -*  Description : Charge un opérande depuis une mémoire tampon.                * +*  Description : Ajoute une information complémentaire à un opérande.         *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -324,11 +495,11 @@ char *g_arch_operand_build_tooltip(const GArchOperand *operand, const GLoadedBin  *                                                                             *  ******************************************************************************/ -static bool g_arch_operand_unserialize(GArchOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +bool g_arch_operand_set_flag(GArchOperand *operand, ArchOperandFlag flag)  {      bool result;                            /* Bilan à retourner           */ -    result = true; +    result = _g_arch_operand_set_flag(operand, flag, true);      return result; @@ -337,37 +508,231 @@ static bool g_arch_operand_unserialize(GArchOperand *operand, GAsmStorage *stora  /******************************************************************************  *                                                                             * -*  Paramètres  : storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : operand = opérande à venir modifier.                         * +*                flag    = drapeau d'information complémentaire à planter.    * +*                lock    = indique un besoin de verrouillage des données.     * +*                                                                             * +*  Description : Retire une information complémentaire à un opérande.         * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool _g_arch_operand_unset_flag(GArchOperand *operand, ArchOperandFlag flag, bool lock) +{ +    bool result;                            /* Bilan à retourner           */ +    operand_extra_data_t *extra;            /* Données insérées à modifier */ + +    assert(flag <= AOF_HIGH_USER); + +    extra = GET_ARCH_OP_EXTRA(operand); + +    LOCK_GOBJECT_EXTRA(extra); + +    result = (extra->flags & flag); + +    extra->flags &= ~flag; + +    UNLOCK_GOBJECT_EXTRA(extra); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à venir modifier.                         * +*                flag    = drapeau d'information complémentaire à planter.    * +*                                                                             * +*  Description : Retire une information complémentaire à un opérande.         * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            *  *                                                                             * -*  Description : Charge un opérande depuis une mémoire tampon.                * +******************************************************************************/ + +bool g_arch_operand_unset_flag(GArchOperand *operand, ArchOperandFlag flag) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = _g_arch_operand_unset_flag(operand, flag, true); + +    return result; + +} + + +/******************************************************************************  *                                                                             * -*  Retour      : Opérande d'assemblage constitué ou NULL en cas d'échec.      * +*  Paramètres  : operand = opérande à venir consulter.                        * +*                flag    = drapeau d'information à rechercher.                * +*                                                                             * +*  Description : Détermine si un opérande possède un fanion particulier.      * +*                                                                             * +*  Retour      : Bilan de la détection.                                       *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchOperand *g_arch_operand_load(GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +bool g_arch_operand_has_flag(const GArchOperand *operand, ArchOperandFlag flag)  { -    GArchOperand *result;                   /* Instance à retourner        */ -    bool status;                            /* Bilan du chargement         */ +    bool result;                            /* Bilan à retourner           */ +    operand_extra_data_t *extra;            /* Données insérées à modifier */ + +    assert(flag <= AOF_HIGH_USER); + +    extra = GET_ARCH_OP_EXTRA(operand); + +    LOCK_GOBJECT_EXTRA(extra); + +    result = (extra->flags & flag); + +    UNLOCK_GOBJECT_EXTRA(extra); + +    return result; + +} -    result = G_ARCH_OPERAND(g_asm_storage_create_object(storage, pbuf)); -    if (result != NULL) +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à venir consulter.                        * +*                                                                             * +*  Description : Fournit les particularités de l'opérande.                    * +*                                                                             * +*  Retour      : Somme de tous les fanions associés à l'opérande.             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *operand) +{ +    ArchOperandFlag result;                 /* Fanions à retourner         */ +    operand_extra_data_t *extra;            /* Données insérées à modifier */ + +    extra = GET_ARCH_OP_EXTRA(operand); + +    LOCK_GOBJECT_EXTRA(extra); + +    result = extra->flags; + +    UNLOCK_GOBJECT_EXTRA(extra); + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                          CONTROLE DU VOLUME DES INSTANCES                          */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                count   = quantité d'instances à l'unicité internes.         * +*                                                                             * +*  Description : Fournit une liste de candidats embarqués par un candidat.    * +*                                                                             * +*  Retour      : Liste de candidats internes ou NULL si aucun.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *operand, size_t *count) +{ +    GArchOperand **result;                  /* Instances à retourner       */ +    GArchOperandClass *class;               /* Classe associée à l'objet   */ + +    class = G_ARCH_OPERAND_GET_CLASS(operand); + +    if (class->list_inner == NULL)      { -        status = G_ARCH_OPERAND_GET_CLASS(result)->unserialize(result, storage, format, pbuf); +        *count = 0; +        result = NULL; +    } + +    else +        result = class->list_inner(operand, count); + +    return result; + +} -        if (!status) -        { -            g_object_unref(G_OBJECT(result)); -            result = NULL; -        } +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand   = objet dont l'instance se veut unique.            * +*                instances = liste de candidats internes devenus singletons.  * +*                count     = quantité d'instances à l'unicité internes.       * +*                                                                             * +*  Description : Met à jour une liste de candidats embarqués par un candidat. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_arch_operand_update_inner_instances(GArchOperand *operand, GArchOperand **instances, size_t count) +{ +    GArchOperandClass *class;               /* Classe associée à l'objet   */ + +    class = G_ARCH_OPERAND_GET_CLASS(operand); + +    if (class->update_inner == NULL) +        assert(class->list_inner == NULL); + +    else +    { +        assert(class->list_inner != NULL); +        class->update_inner(operand, instances, count);      } +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                lock    = précise le besoin en verrouillage.                 * +*                                                                             * +*  Description : Fournit l'empreinte d'un candidat à une centralisation.      * +*                                                                             * +*  Retour      : Empreinte de l'élément représenté.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static guint _g_arch_operand_hash(const GArchOperand *operand, bool lock) +{ +    guint result;                           /* Valeur à retourner          */ +    const char *name;                       /* Désignation du type d'object*/ +    fnv64_t name_hash;                      /* Empreinte du nom            */ +    operand_extra_data_t *extra;            /* Données insérées à modifier */ + +    assert(!lock); + +    name = G_OBJECT_TYPE_NAME(G_OBJECT(operand)); +    name_hash = fnv_64a_hash(name); + +    result = (name_hash & 0xffffffff); +    result ^= (name_hash >> 32); + +    extra = GET_ARCH_OP_EXTRA(operand); + +    result ^= extra->flags; +      return result;  } @@ -375,11 +740,176 @@ GArchOperand *g_arch_operand_load(GAsmStorage *storage, GBinFormat *format, pack  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à consulter.                 * -*                storage = mécanisme de sauvegarde à manipuler.               * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                                                                             * +*  Description : Fournit l'empreinte d'un candidat à une centralisation.      * +*                                                                             * +*  Retour      : Empreinte de l'élément représenté.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static guint g_arch_operand_hash(const GArchOperand *operand) +{ +    guint result;                           /* Valeur à retourner          */ +    GArchOperandClass *class;               /* Classe associée à l'objet   */ + +    class = G_ARCH_OPERAND_GET_CLASS(operand); + +    result = class->hash(operand, true); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                other   = second élément à analyser.                         * +*                                                                             * +*  Description : Détermine si deux candidats à l'unicité sont identiques.     * +*                                                                             * +*  Retour      : Bilan de la comparaison.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static gboolean g_arch_operand_is_equal(const GArchOperand *operand, const GArchOperand *other) +{ +    gboolean result;                        /* Bilan à renvoyer            */ +    int ret;                                /* Bilan d'une comparaison     */ + +    ret = g_arch_operand_compare(operand, other); + +    result = (ret == 0); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                                                                             * +*  Description : Marque un candidat comme figé.                               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_operand_set_read_only(GArchOperand *operand) +{ +    g_arch_operand_set_flag(operand, AOF_READ_ONLY); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                                                                             * +*  Description : Indique si le candidat est figé.                             * +*                                                                             * +*  Retour      : true si le contenu du candidat ne peut plus être modifié.    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_operand_is_read_only(GArchOperand *operand) +{ +    bool result;                            /* Etat à retourner            */ + +    result = g_arch_operand_has_flag(operand, AOF_READ_ONLY); + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                      CONSERVATION ET RECHARGEMENT DES DONNEES                      */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                * +*                                                                             * +*  Description : Charge un contenu depuis une mémoire tampon.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool _g_arch_operand_load(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    operand_extra_data_t *extra;            /* Données insérées à consulter*/ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ + +    extra = GET_ARCH_OP_EXTRA(operand); + +    LOCK_GOBJECT_EXTRA(extra); + +    result = unpack_uleb128(&value, pbuf); + +    if (result) +        extra->flags = value; + +    UNLOCK_GOBJECT_EXTRA(extra); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                * +*                                                                             * +*  Description : Charge un contenu depuis une mémoire tampon.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_operand_load(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchOperandClass *class;               /* Classe à activer            */ + +    class = G_ARCH_OPERAND_GET_CLASS(operand); + +    result = class->load(operand, storage, pbuf); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -387,11 +917,18 @@ GArchOperand *g_arch_operand_load(GAsmStorage *storage, GBinFormat *format, pack  *                                                                             *  ******************************************************************************/ -static bool g_arch_operand_serialize(const GArchOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool _g_arch_operand_store(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ +    operand_extra_data_t *extra;            /* Données insérées à consulter*/ -    result = true; +    extra = GET_ARCH_OP_EXTRA(operand); + +    LOCK_GOBJECT_EXTRA(extra); + +    result = pack_uleb128((uleb128_t []){ extra->flags }, pbuf); + +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -400,11 +937,11 @@ static bool g_arch_operand_serialize(const GArchOperand *operand, GAsmStorage *s  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = instruction d'assemblage à consulter.              * -*                storage = mécanisme de sauvegarde à manipuler.               * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -412,14 +949,14 @@ static bool g_arch_operand_serialize(const GArchOperand *operand, GAsmStorage *s  *                                                                             *  ******************************************************************************/ -bool g_arch_operand_store(const GArchOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_arch_operand_store(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ +    GArchOperandClass *class;               /* Classe à activer            */ -    result = g_asm_storage_store_object_gtype(storage, G_OBJECT(operand), pbuf); +    class = G_ARCH_OPERAND_GET_CLASS(operand); -    if (result) -        result = G_ARCH_OPERAND_GET_CLASS(operand)->serialize(operand, storage, pbuf); +    result = class->store(operand, storage, pbuf);      return result; diff --git a/src/arch/operand.h b/src/arch/operand.h index 9e1b5a8..234ee64 100644 --- a/src/arch/operand.h +++ b/src/arch/operand.h @@ -41,6 +41,23 @@  typedef struct _GLoadedBinary GLoadedBinary; +/* Indications supplémentaires liées aux opérandes */ + +#define AOF_USER_BIT 1 + +typedef enum _ArchOperandFlag +{ +    AOF_NONE      = (0 << 0),               /* Aucune propriété            */ +    AOF_READ_ONLY = (1 << 0),               /* Indication de nature        */ + +    AOF_LOW_USER  = (1 << AOF_USER_BIT),    /* Premier bit disponible      */ +    AOF_HIGH_USER = (1 << 7),               /* Dernier bit disponible      */ + +} ArchOperandFlag; + +#define AOF_USER_FLAG(n) (1 << (AOF_USER_BIT + n)) + +  #define G_TYPE_ARCH_OPERAND            g_arch_operand_get_type()  #define G_ARCH_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARCH_OPERAND, GArchOperand))  #define G_IS_ARCH_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARCH_OPERAND)) @@ -71,23 +88,32 @@ GArchOperand *g_arch_operand_get_inner_operand_from_path(const GArchOperand *, c  /* Traduit un opérande en version humainement lisible. */  void g_arch_operand_print(const GArchOperand *, GBufferLine *); +#ifdef INCLUDE_GTK_SUPPORT +  /* Construit un petit résumé concis de l'opérande. */  char *g_arch_operand_build_tooltip(const GArchOperand *, const GLoadedBinary *); +#endif +/* Ajoute une information complémentaire à un opérande. */ +bool g_arch_operand_set_flag(GArchOperand *, ArchOperandFlag); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Retire une information complémentaire à un opérande. */ +bool g_arch_operand_unset_flag(GArchOperand *, ArchOperandFlag); +/* Détermine si un opérande possède un fanion particulier. */ +bool g_arch_operand_has_flag(const GArchOperand *, ArchOperandFlag); + +/* Fournit les particularités de l'opérande. */ +ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *); -/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */ -typedef struct _GAsmStorage GAsmStorage; -/* Charge un opérande depuis une mémoire tampon. */ -GArchOperand *g_arch_operand_load(GAsmStorage *, GBinFormat *, packed_buffer_t *); +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + -/* Sauvegarde un opérande dans une mémoire tampon. */ -bool g_arch_operand_store(const GArchOperand *, GAsmStorage *, packed_buffer_t *); +/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */ +typedef struct _GAsmStorage GAsmStorage; diff --git a/src/arch/operands/Makefile.am b/src/arch/operands/Makefile.am index 0cb5b02..f2a8767 100644 --- a/src/arch/operands/Makefile.am +++ b/src/arch/operands/Makefile.am @@ -4,7 +4,9 @@ noinst_LTLIBRARIES = libarchoperands.la  libarchoperands_la_SOURCES =			\  	feeder-int.h						\  	feeder.h feeder.c					\ +	immediate-int.h						\  	immediate.h immediate.c				\ +	known.h known.c						\  	register-int.h						\  	register.h register.c				\  	proxy-int.h							\ @@ -16,19 +18,9 @@ libarchoperands_la_SOURCES =			\  	targetable-int.h					\  	targetable.h targetable.c -libarchoperands_la_LIBADD =	 - -libarchoperands_la_LDFLAGS =  +libarchoperands_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)  devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)  dev_HEADERS = $(libarchoperands_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) - - -SUBDIRS =  diff --git a/src/arch/operands/feeder-int.h b/src/arch/operands/feeder-int.h index 86bc98f..f2f2566 100644 --- a/src/arch/operands/feeder-int.h +++ b/src/arch/operands/feeder-int.h @@ -28,6 +28,9 @@  #include "feeder.h" +#include "../../analysis/storage/serialize-int.h" + +  /* Compare un fournisseur avec un autre. */  typedef int (* compare_proxy_operand_fc) (const GProxyFeeder *, const GProxyFeeder *); @@ -35,26 +38,17 @@ typedef int (* compare_proxy_operand_fc) (const GProxyFeeder *, const GProxyFeed  /* Traduit un fournisseur en version humainement lisible. */  typedef void (* print_proxy_feeder_fc) (const GProxyFeeder *, GBufferLine *); -/* Charge un fournisseur depuis une mémoire tampon. */ -typedef bool (* unserialize_proxy_feeder_fc) (GProxyFeeder *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un fournisseur dans une mémoire tampon. */ -typedef bool (* serialize_proxy_feeder_fc) (const GProxyFeeder *, packed_buffer_t *); -  /* Fournisseur d'élément non architectural (interface) */  struct _GProxyFeederIface  { -    GTypeInterface base_iface;              /* A laisser en premier        */ +    GSerializableObjectInterface base_iface;/* A laisser en premier        */      compare_proxy_operand_fc compare;       /* Comparaison entre éléments  */      print_proxy_feeder_fc print;            /* Affichage sur une ligne     */ -    unserialize_proxy_feeder_fc unserialize;/* Restauration de l'élément   */ -    serialize_proxy_feeder_fc serialize;    /* Sauvegarder de l'élément    */ -  }; diff --git a/src/arch/operands/feeder.c b/src/arch/operands/feeder.c index f34475c..af23fea 100644 --- a/src/arch/operands/feeder.c +++ b/src/arch/operands/feeder.c @@ -28,13 +28,32 @@ +/* -------------------- DEFINITION DE L'INTERFACE DE FOURNISSEUR -------------------- */ + +  /* Procède à l'initialisation de l'interface de rassemblement. */  static void g_proxy_feeder_default_init(GProxyFeederInterface *); +/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_proxy_feeder_load(GProxyFeeder *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_proxy_feeder_store(GProxyFeeder *, GObjectStorage *, packed_buffer_t *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                      DEFINITION DE L'INTERFACE DE FOURNISSEUR                      */ +/* ---------------------------------------------------------------------------------- */ + +  /* Détermine le type d'une interface pour la Fourniture d'éléments non architecturaux. */ -G_DEFINE_INTERFACE(GProxyFeeder, g_proxy_feeder, G_TYPE_OBJECT) +G_DEFINE_INTERFACE(GProxyFeeder, g_proxy_feeder, G_TYPE_SERIALIZABLE_OBJECT)  /****************************************************************************** @@ -104,58 +123,3 @@ void g_proxy_feeder_print(const GProxyFeeder *feeder, GBufferLine *line)      iface->print(feeder, line);  } - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : feeder = fournisseur à constituer.                           * -*                format = format binaire chargé associé à l'architecture.     * -*                pbuf   = zone tampon à remplir.                              * -*                                                                             * -*  Description : Charge un fournisseur depuis une mémoire tampon.             * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool g_proxy_feeder_unserialize(GProxyFeeder *feeder, GBinFormat *format, packed_buffer_t *pbuf) -{ -    bool result;                            /* Bilan à retourner           */ -    GProxyFeederIface *iface;               /* Interface utilisée          */ - -    iface = G_PROXY_FEEDER_GET_IFACE(feeder); - -    result = iface->unserialize(feeder, format, pbuf); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : feeder = fournisseur à consulter.                            * -*                pbuf   = zone tampon à remplir.                              * -*                                                                             * -*  Description : Sauvegarde un fournisseur dans une mémoire tampon.           * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool g_proxy_feeder_serialize(const GProxyFeeder *feeder, packed_buffer_t *pbuf) -{ -    bool result;                            /* Bilan à retourner           */ -    GProxyFeederIface *iface;               /* Interface utilisée          */ - -    iface = G_PROXY_FEEDER_GET_IFACE(feeder); - -    result = iface->serialize(feeder, pbuf); - -    return result; - -} diff --git a/src/arch/operands/feeder.h b/src/arch/operands/feeder.h index 2d8559e..685323b 100644 --- a/src/arch/operands/feeder.h +++ b/src/arch/operands/feeder.h @@ -26,11 +26,8 @@  #include <glib-object.h> -#include <stdbool.h> -#include "../../common/packed.h" -#include "../../format/format.h"  #include "../../glibext/bufferline.h" @@ -59,12 +56,6 @@ int g_proxy_feeder_compare(const GProxyFeeder *, const GProxyFeeder *);  /* Traduit un fournisseur en version humainement lisible. */  void g_proxy_feeder_print(const GProxyFeeder *, GBufferLine *); -/* Charge un fournisseur depuis une mémoire tampon. */ -bool g_proxy_feeder_unserialize(GProxyFeeder *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un fournisseur dans une mémoire tampon. */ -bool g_proxy_feeder_serialize(const GProxyFeeder *, packed_buffer_t *); -  #endif  /* _ARCH_OPERANDS_FEEDER_H */ diff --git a/src/arch/operands/immediate-int.h b/src/arch/operands/immediate-int.h new file mode 100644 index 0000000..d2313f5 --- /dev/null +++ b/src/arch/operands/immediate-int.h @@ -0,0 +1,85 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * immediate-int.h - définitions internes propres aux opérandes représentant des valeurs numériques + * + * Copyright (C) 2021 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_IMMEDIATE_INT_H +#define _ARCH_OPERANDS_IMMEDIATE_INT_H + + +#include "immediate.h" +#include "../operand-int.h" + + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _immop_extra_data_t +{ +    operand_extra_data_t parent;            /* A laisser en premier        */ + +    MemoryDataSize size;                    /* Taille de l'opérande        */ + +    /** +     * Les deux éléments suivants sont de type ImmOperandDisplay ; +     * leur espace de conservation est réduit au maximum afin d'éviter +     * un recouvrement . +     */ + +    unsigned int def_display : 3;           /* Type par défaut d'affichage */ +    unsigned int display : 3;               /* Format général d'affichage  */ + +} immop_extra_data_t; + + +/* Définition d'un opérande de valeur numérique (instance) */ +struct _GImmOperand +{ +    GArchOperand parent;                    /* Instance parente            */ + +    uint64_t raw;                           /* Valeur transtypée           */ + +}; + +/* Définition d'un opérande de valeur numérique (classe) */ +struct _GImmOperandClass +{ +    GArchOperandClass parent;               /* Classe parente              */ + +}; + + +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +#   define GET_IMM_OP_EXTRA(op) ((immop_extra_data_t *)&((GArchOperand *)op)->extra) + +#else + +#   define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_extra_data_t) + +#endif + + + +#endif  /* _ARCH_OPERANDS_IMMEDIATE_INT_H */ diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c index cb39fce..f40c645 100644 --- a/src/arch/operands/immediate.c +++ b/src/arch/operands/immediate.c @@ -31,100 +31,25 @@  #include <malloc.h>  #include <stdarg.h>  #include <stdio.h> -#include <string.h>  #include <i18n.h> +#include "immediate-int.h" +#include "known.h"  #include "rename-int.h"  #include "targetable-int.h" -#include "../operand-int.h"  #include "../../common/asm.h"  #include "../../common/extstr.h" -#include "../../core/logs.h" -#include "../../format/format.h" -#include "../../glibext/objhole.h" -#include "../../gtkext/gtkblockdisplay.h" +#include "../../common/sort.h" +#include "../../core/columns.h"  /* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */ -/* Etats particuliers d'un opérande de valeur immédiate */ -typedef enum _ImmOpFlag -{ -    IOF_ZERO_PADDING_BY_DEFAULT,            /* Bourrage avec 0 par défaut ?*/ -    IOF_ZERO_PADDING,                       /* Bourrage avec 0 ?           */ - -} ImmOpFlag; - -/* Informations glissées dans la structure GObject de GArchInstruction */ -typedef union _immop_obj_extra -{ -    struct -    { -        MemoryDataSize size;                /* Taille de l'opérande        */ - -        ImmOperandDisplay def_display;      /* Type par défaut d'affichage */ -        ImmOperandDisplay display;          /* Format général d'affichage  */ -        ImmOpFlag flags;                    /* Informations diverses       */ - -    }; - -    gint lock;                              /* Gestion d'accès aux fanions */ - -} immop_obj_extra; - -/* Définition d'un opérande de valeur numérique (instance) */ -struct _GImmOperand -{ -    GArchOperand parent;                    /* Instance parente            */ - -    uint64_t raw;                           /* Valeur transtypée           */ - -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -    /** -     * L'inclusion des informations suivantes dépend de l'architecture. -     * -     * Si la structure GObject possède un trou, on remplit de préférence -     * ce dernier. -     */ - -    immop_obj_extra extra;                  /* Externalisation embarquée   */ - -#endif - -}; - -/** - * Accès aux informations éventuellement déportées. - */ - -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -#   define INIT_IMM_OP_EXTRA(op) op->extra.lock = 0 - -#   define GET_IMM_OP_EXTRA(op) &op->extra - -#else - -#   define INIT_IMM_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op)) - -#   define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_obj_extra) - -#endif - -/* Définition d'un opérande de valeur numérique (classe) */ -struct _GImmOperandClass -{ -    GArchOperandClass parent;               /* Classe parente              */ - -}; - -  /* Initialise la classe des opérandes de valeur immédiate. */  static void g_imm_operand_class_init(GImmOperandClass *); @@ -143,81 +68,51 @@ static void g_imm_operand_dispose(GImmOperand *);  /* Procède à la libération totale de la mémoire. */  static void g_imm_operand_finalize(GImmOperand *); -/* Compare un opérande avec un autre. */ -static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *); -  /* Construit la chaîne de caractères correspondant à l'opérande. */  static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]);  /* Traduit un opérande en version humainement lisible. */  static void g_imm_operand_print(const GImmOperand *, GBufferLine *); -/* Construit un petit résumé concis de l'opérande. */ -static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *); - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_imm_operand_unserialize(GImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_imm_operand_serialize(const GImmOperand *, GAsmStorage *, packed_buffer_t *); -/* Obtient l'adresse de la cible visée par un opérande. */ -static bool g_imm_operand_get_addr(const GImmOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); - -/* Construit un opérande de représentation alternative. */ -static GRenamedOperand *g_imm_operand_build(const GImmOperand *, const char *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */ - +/* Compare un opérande avec un autre. */ +static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *, bool); -/* Définition d'un remplacement d'opérande de valeur numérique (instance) */ -struct _GKnownImmOperand -{ -    GImmOperand parent;                     /* Instance parente            */ +#ifdef INCLUDE_GTK_SUPPORT -    char *alt_text;                         /* Alternative humaine         */ +/* Construit un petit résumé concis de l'opérande. */ +static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *); -}; +#endif -/* Définition d'un remplacement d'opérande de valeur numérique (classe) */ -struct _GKnownImmOperandClass -{ -    GImmOperandClass parent;                /* Classe parente              */ +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_imm_operand_hash(const GImmOperand *, bool); -}; +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_imm_operand_load(GImmOperand *, GObjectStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_imm_operand_store(GImmOperand *, GObjectStorage *, packed_buffer_t *); -/* Initialise la classe des remplacements d'opérandes. */ -static void g_known_imm_operand_class_init(GKnownImmOperandClass *); -/* Initialise un remplacement d'opérande de valeur immédiate. */ -static void g_known_imm_operand_init(GKnownImmOperand *); -/* Procède à l'initialisation de l'interface de renommage. */ -static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *); +/* ---------------------- COMMUNICATION D'UN CIBLAGE POTENTIEL ---------------------- */ -/* Supprime toutes les références externes. */ -static void g_known_imm_operand_dispose(GKnownImmOperand *); -/* Procède à la libération totale de la mémoire. */ -static void g_known_imm_operand_finalize(GKnownImmOperand *); +/* Obtient l'adresse de la cible visée par un opérande. */ +static bool g_imm_operand_get_addr(const GImmOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); -/* Compare un opérande avec un autre. */ -static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *); -/* Traduit un opérande en version humainement lisible. */ -static void g_known_imm_operand_print(const GKnownImmOperand *, GBufferLine *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_known_imm_operand_unserialize(GKnownImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); +/* ---------------------- CONSTRUCTION D'UN CONTENU ALTERNATIF ---------------------- */ -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_known_imm_operand_serialize(const GKnownImmOperand *, GAsmStorage *, packed_buffer_t *); -/* Fournit un texte comme représentation alternative d'opérande. */ -static const char *g_known_imm_operand_get_text(const GKnownImmOperand *); +/* Construit un opérande de représentation alternative. */ +static GRenamedOperand *g_imm_operand_build(const GImmOperand *, const char *); @@ -257,10 +152,14 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)      operand->compare = (operand_compare_fc)g_imm_operand_compare;      operand->print = (operand_print_fc)g_imm_operand_print; +#ifdef INCLUDE_GTK_SUPPORT      operand->build_tooltip = (operand_build_tooltip_fc)g_imm_operand_build_tooltip; +#endif + +    operand->hash = (operand_hash_fc)g_imm_operand_hash; -    operand->unserialize = (unserialize_operand_fc)g_imm_operand_unserialize; -    operand->serialize = (serialize_operand_fc)g_imm_operand_serialize; +    operand->load = (load_operand_fc)g_imm_operand_load; +    operand->store = (store_operand_fc)g_imm_operand_store;  } @@ -279,13 +178,13 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)  static void g_imm_operand_init(GImmOperand *operand)  { -    operand->raw = 0; - -    INIT_IMM_OP_EXTRA(operand); +    GET_IMM_OP_EXTRA(operand)->size = MDS_UNDEFINED;      GET_IMM_OP_EXTRA(operand)->def_display = IOD_HEX;      GET_IMM_OP_EXTRA(operand)->display = IOD_COUNT; +    operand->raw = 0; +  } @@ -384,7 +283,7 @@ static void g_imm_operand_finalize(GImmOperand *operand)  GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian)  {      GImmOperand *result;                    /* Opérande à retourner        */ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ +    immop_extra_data_t *extra;              /* Données insérées à modifier */      uint8_t uval8;                          /* Valeur sur 8 bits           */      uint16_t uval16;                        /* Valeur sur 16 bits          */      uint32_t uval32;                        /* Valeur sur 32 bits          */ @@ -495,7 +394,7 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten  GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)  {      GImmOperand *result;                    /* Opérande à retourner        */ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ +    immop_extra_data_t *extra;              /* Données insérées à modifier */      if (size == MDS_UNDEFINED)          result = NULL; @@ -519,98 +418,6 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)  /******************************************************************************  *                                                                             * -*  Paramètres  : a = premier opérande à consulter.                            * -*                b = second opérande à consulter.                             * -*                                                                             * -*  Description : Compare un opérande avec un autre.                           * -*                                                                             * -*  Retour      : Bilan de la comparaison.                                     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b) -{ -    int result;                             /* Bilan à retourner           */ -    immop_obj_extra *ea;                    /* Données insérées à modifier */ -    immop_obj_extra *eb;                    /* Données insérées à modifier */ - -    ea = GET_IMM_OP_EXTRA(a); -    eb = GET_IMM_OP_EXTRA(b); - -    g_bit_lock(&ea->lock, HOLE_LOCK_BIT); -    g_bit_lock(&eb->lock, HOLE_LOCK_BIT); - -    if (ea->size < eb->size) -    { -        result = -1; -        goto done; -    } -    else if (ea->size > eb->size) -    { -        result = 1; -        goto done; -    } - -    if (a->raw < b->raw) -    { -        result = -1; -        goto done; -    } -    else if (a->raw > b->raw) -    { -        result = 1; -        goto done; -    } - -    if (ea->def_display < eb->def_display) -    { -        result = -1; -        goto done;  -   } -    else if (ea->def_display > eb->def_display) -    { -        result = 1; -        goto done; -    } - -    if (ea->display < eb->display) -    { -        result = -1; -        goto done; -    } -    else if (ea->display > eb->display) -    { -        result = 1; -        goto done; -    } - -    if (ea->flags < eb->flags) -    { -        result = -1; -        goto done; -    } -    else if (ea->flags > eb->flags) -    { -        result = 1; -        goto done; -    } - -    result = 0; - - done: - -    g_bit_unlock(&eb->lock, HOLE_LOCK_BIT); -    g_bit_unlock(&ea->lock, HOLE_LOCK_BIT); - -    return result; - -} - - -/****************************************************************************** -*                                                                             *  *  Paramètres  : operand = structure dont le contenu est à consulter.         *  *                                                                             *  *  Description : Renseigne la taille de la valeur indiquée à la construction. * @@ -624,15 +431,15 @@ static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b)  MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)  {      MemoryDataSize result;                  /* Taille à retourner          */ -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      result = extra->size; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -656,7 +463,7 @@ MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)  bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...)  {      bool result;                            /* Bilan à retourner           */ -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      va_list ap;                             /* Liste des compléments       */      uint8_t *uval8;                         /* Valeur sur 8 bits           */      uint16_t *uval16;                       /* Valeur sur 16 bits          */ @@ -671,7 +478,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      if (extra->size != size)          goto exit; @@ -726,7 +533,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..   exit: -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -768,141 +575,19 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand)  void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value)  { -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      assert(size != MDS_UNDEFINED);      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      extra->size = size;      operand->raw = value; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = structure dont le contenu est à consulter.         * -*                                                                             * -*  Description : Indique si une valeur est complétée par des zéros par défaut.* -*                                                                             * -*  Retour      : true si des zéro sont ajoutés à l'affichage, false sinon.    * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool g_imm_operand_get_default_padding(const GImmOperand *operand) -{ -    bool result;                            /* Statut à retourner          */ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ - -    extra = GET_IMM_OP_EXTRA(operand); - -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -    result = (extra->flags & IOF_ZERO_PADDING_BY_DEFAULT); - -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = structure dont le contenu est à actualiser. [OUT]  * -*                state   = true si des zéro sont à ajouter, false sinon.      * -*                                                                             * -*  Description : Précise si des zéro doivent compléter l'affichage ou non.    * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_imm_operand_set_default_padding(GImmOperand *operand, bool state) -{ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ - -    extra = GET_IMM_OP_EXTRA(operand); - -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -    if (state) -        extra->flags |= IOF_ZERO_PADDING_BY_DEFAULT; -    else -        extra->flags &= ~IOF_ZERO_PADDING_BY_DEFAULT; - -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = structure dont le contenu est à actualiser. [OUT]  * -*                state   = true si des zéro sont à ajouter, false sinon.      * -*                                                                             * -*  Description : Précise si des zéro doivent compléter l'affichage ou non.    * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_imm_operand_pad(GImmOperand *operand, bool state) -{ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ - -    extra = GET_IMM_OP_EXTRA(operand); - -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -    if (state) -        extra->flags |= (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); -    else -        extra->flags &= ~(IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING); - -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = structure dont le contenu est à consulter.         * -*                                                                             * -*  Description : Indique si une valeur est complétée par des zéros.           * -*                                                                             * -*  Retour      : true si des zéro sont ajoutés à l'affichage, false sinon.    * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool g_imm_operand_does_padding(const GImmOperand *operand) -{ -    bool result;                            /* Statut à retourner          */ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ - -    extra = GET_IMM_OP_EXTRA(operand); - -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -    result = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING)); - -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -    return result; +    UNLOCK_GOBJECT_EXTRA(extra);  } @@ -922,15 +607,15 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)  void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display)  { -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      extra->def_display = display; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);  } @@ -950,15 +635,15 @@ void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay d  ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)  {      ImmOperandDisplay result;               /* Affichage à retourner       */ -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      result = extra->def_display; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -980,15 +665,15 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)  void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)  { -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      extra->display = display; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);  } @@ -1008,18 +693,18 @@ void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)  ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)  {      ImmOperandDisplay result;               /* Affichage à retourner       */ -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      if (extra->display != IOD_COUNT)          result = extra->display;      else          result = extra->def_display; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -1041,11 +726,11 @@ ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)  bool g_imm_operand_is_negative(const GImmOperand *operand)  {      bool result;                            /* Bilan à renvoyer            */ -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      switch (extra->size)      { @@ -1065,7 +750,7 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)              break;      } -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -1108,7 +793,7 @@ bool g_imm_operand_is_null(const GImmOperand *operand)  static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE])  {      size_t result;                          /* Longueur à retourner        */ -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      unsigned int range;                     /* Catégorie de la taille      */      const char *prefix;                     /* Entrée en matière           */      const char *suffix;                     /* Sortie de matière           */ @@ -1132,7 +817,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    //LOCK_GOBJECT_EXTRA(extra);      range = MDS_RANGE(extra->size); @@ -1173,7 +858,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis      /* Drapeau de remplissage ? */ -    do_padding = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING)); +    do_padding = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);      if (do_padding)      { @@ -1297,7 +982,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis      } -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    //UNLOCK_GOBJECT_EXTRA(extra);      assert(result > 0); @@ -1361,94 +1046,6 @@ static void g_imm_operand_print(const GImmOperand *operand, GBufferLine *line)  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à consulter.                              * -*                binary  = informations relatives au binaire chargé.          * -*                                                                             * -*  Description : Construit un petit résumé concis de l'opérande.              * -*                                                                             * -*  Retour      : Chaîne de caractères à libérer après usage ou NULL.          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary) -{ -    char *result;                           /* Description à retourner     */ -    char value[IMM_MAX_SIZE];               /* Conversion artificielle     */ -    char *conv;                             /* Affichage de la Conversion  */ - -    if (operand->raw <= UCHAR_MAX && isprint(operand->raw)) -        switch (operand->raw) -        { -            case '&': -                asprintf(&result, _("Character: '&'")); -                break; -            case '<': -                asprintf(&result, _("Character: '<'")); -                break; -            case '>': -                asprintf(&result, _("Character: '>'")); -                break; -            default: -                asprintf(&result, _("Character: '%c'"), (char)operand->raw); -                break; -        } - -    else -        asprintf(&result, _("Character: <not printable>")); - -    /* Binaire */ - -    _g_imm_operand_to_string(operand, IOD_BIN, value); - -    asprintf(&conv, _("Binary: %s"), value); - -    result = stradd(result, "\n"); -    result = stradd(result, conv); - -    free(conv); - -    /* Octal */ - -    _g_imm_operand_to_string(operand, IOD_OCT, value); - -    asprintf(&conv, _("Octal: %s"), value); - -    result = stradd(result, "\n"); -    result = stradd(result, conv); - -    free(conv); - -    /* Décimal */ - -    _g_imm_operand_to_string(operand, IOD_DEC, value); - -    asprintf(&conv, _("Decimal: %s"), value); - -    result = stradd(result, "\n"); -    result = stradd(result, conv); - -    free(conv); - -    /* Hexadécimal */ - -    _g_imm_operand_to_string(operand, IOD_HEX, value); - -    asprintf(&conv, _("Hexadecimal: %s"), value); - -    result = stradd(result, "\n"); -    result = stradd(result, conv); - -    free(conv); - -    return result; - -} - - -/****************************************************************************** -*                                                                             *  *  Paramètres  : operand = opérande à traiter.                                *  *                pos     = valeur résultante. [OUT]                           *  *                                                                             * @@ -1463,18 +1060,18 @@ static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoad  bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos)  {      bool result;                            /* Bilan à renvoyer            */ -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      result = !MDS_IS_SIGNED(extra->size);      if (result)          *pos = operand->raw; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -1497,18 +1094,18 @@ bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos)  bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr)  {      bool result;                            /* Bilan à renvoyer            */ -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      result = !MDS_IS_SIGNED(extra->size);      if (result)          *addr = operand->raw; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);      return result; @@ -1530,15 +1127,15 @@ bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr)  void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val)  { -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      *val = operand->raw; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);  } @@ -1558,119 +1155,76 @@ void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val)  void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val)  { -    immop_obj_extra *extra;                 /* Données insérées à consulter*/ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(extra);      *val = operand->raw; -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    UNLOCK_GOBJECT_EXTRA(extra);  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande d'assemblage à constituer.                * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * -*                pbuf    = zone tampon à remplir.                             * -*                                                                             * -*  Description : Charge un opérande depuis une mémoire tampon.                * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) -{ -    bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ - -    parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); - -    result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - -    if (result) -        result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); - -    if (result) -    { -        extra = GET_IMM_OP_EXTRA(operand); - -        g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -        result = extract_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true); - -        if (result) -            result = extract_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true); -        if (result) -            result = extract_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true); - -        if (result) -            result = extract_packed_buffer(pbuf, &extra->flags, sizeof(uint8_t), false); - -        g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -    } - -    return result; - -} +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à consulter.                 * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : a    = premier opérande à consulter.                         * +*                b    = second opérande à consulter.                          * +*                lock = précise le besoin en verrouillage.                    *  *                                                                             * -*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*  Description : Compare un opérande avec un autre.                           *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : Bilan de la comparaison.                                     *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b, bool lock)  { -    bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ - -    parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); - -    result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); +    int result;                             /* Bilan à retourner           */ +    immop_extra_data_t *ea;                 /* Données insérées à modifier */ +    immop_extra_data_t *eb;                 /* Données insérées à modifier */ +    GArchOperandClass *class;               /* Classe parente normalisée   */ -    if (result) -        result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); +    ea = GET_IMM_OP_EXTRA(a); +    eb = GET_IMM_OP_EXTRA(b); -    if (result) +    if (lock)      { -        extra = GET_IMM_OP_EXTRA(operand); - -        g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +        LOCK_GOBJECT_EXTRA(ea); +        LOCK_GOBJECT_EXTRA(eb); +    } -        result = extend_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true); +    result = sort_unsigned_long(ea->size, eb->size); -        if (result) -            result = extend_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true); +    if (result == 0) +        sort_uint64_t(a->raw, b->raw); -        if (result) -            result = extend_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true); +    if (result == 0) +        result = sort_unsigned_long(ea->def_display, eb->def_display); -        if (result) -            result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ImmOpFlag), true); +    if (result == 0) +        result = sort_unsigned_long(ea->display, eb->display); -        g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    if (result == 0) +    { +        class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); +        result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); +    } +    if (lock) +    { +        UNLOCK_GOBJECT_EXTRA(eb); +        UNLOCK_GOBJECT_EXTRA(ea);      }      return result; @@ -1678,246 +1232,199 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = operande à consulter.                              * -*                src     = localisation de l'instruction mère.                * -*                format  = format reconnu pour le binaire chargé.             * -*                proc    = architecture associée à ce même binaire.           * -*                addr    = localisation de la cible. [OUT]                    * -*                                                                             * -*  Description : Obtient l'adresse de la cible visée par un opérande.         * -*                                                                             * -*  Retour      : true si la cible est valide, false sinon.                    * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_imm_operand_get_addr(const GImmOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) -{ -    bool result;                            /* Bilan à retourner           */ -    virt_t virt;                            /* Adresse virtuelle           */ - -    result = g_imm_operand_to_virt_t(operand, &virt); - -    if (result) -        result = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, addr); - -    return result; - -} +#ifdef INCLUDE_GTK_SUPPORT  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = operande à consulter.                              * -*                text    = texte alternatif de représentation.                * +*  Paramètres  : operand = opérande à consulter.                              * +*                binary  = informations relatives au binaire chargé.          *  *                                                                             * -*  Description : Construit un opérande de représentation alternative.         * +*  Description : Construit un petit résumé concis de l'opérande.              *  *                                                                             * -*  Retour      : Nouvel opérande, en version renommée.                        * +*  Retour      : Chaîne de caractères à libérer après usage ou NULL.          *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static GRenamedOperand *g_imm_operand_build(const GImmOperand *operand, const char *text) +static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary)  { -    GRenamedOperand *result;                /* Instance à retourner        */ +    char *result;                           /* Description à retourner     */ +    char value[IMM_MAX_SIZE];               /* Conversion artificielle     */ +    char *conv;                             /* Affichage de la Conversion  */ -    result = G_RENAMED_OPERAND(g_known_imm_operand_new(operand, text)); +    if (operand->raw <= UCHAR_MAX && isprint(operand->raw)) +        switch (operand->raw) +        { +            case '&': +                asprintf(&result, _("Character: '&'")); +                break; +            case '<': +                asprintf(&result, _("Character: '<'")); +                break; +            case '>': +                asprintf(&result, _("Character: '>'")); +                break; +            default: +                asprintf(&result, _("Character: '%c'"), (char)operand->raw); +                break; +        } -    return result; +    else +        asprintf(&result, _("Character: <not printable>")); -} +    /* Binaire */ +    _g_imm_operand_to_string(operand, IOD_BIN, value); +    asprintf(&conv, _("Binary: %s"), value); -/* ---------------------------------------------------------------------------------- */ -/*                         REMPLACEMENT DE VALEURS IMMEDIATES                         */ -/* ---------------------------------------------------------------------------------- */ +    result = stradd(result, "\n"); +    result = stradd(result, conv); +    free(conv); -/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */ -G_DEFINE_TYPE_WITH_CODE(GKnownImmOperand, g_known_imm_operand, G_TYPE_IMM_OPERAND, -                        G_IMPLEMENT_INTERFACE(G_TYPE_RENAMED_OPERAND, g_known_imm_operand_renamed_interface_init)); +    /* Octal */ +    _g_imm_operand_to_string(operand, IOD_OCT, value); -/****************************************************************************** -*                                                                             * -*  Paramètres  : klass = classe à initialiser.                                * -*                                                                             * -*  Description : Initialise la classe des remplacements d'opérandes.          * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    asprintf(&conv, _("Octal: %s"), value); -static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass) -{ -    GObjectClass *object;                   /* Autre version de la classe  */ -    GArchOperandClass *operand;             /* Version de classe parente   */ +    result = stradd(result, "\n"); +    result = stradd(result, conv); -    object = G_OBJECT_CLASS(klass); -    operand = G_ARCH_OPERAND_CLASS(klass); +    free(conv); -    object->dispose = (GObjectFinalizeFunc/* ! */)g_known_imm_operand_dispose; -    object->finalize = (GObjectFinalizeFunc)g_known_imm_operand_finalize; +    /* Décimal */ -    operand->compare = (operand_compare_fc)g_known_imm_operand_compare; -    operand->print = (operand_print_fc)g_known_imm_operand_print; +    _g_imm_operand_to_string(operand, IOD_DEC, value); -    operand->unserialize = (unserialize_operand_fc)g_known_imm_operand_unserialize; -    operand->serialize = (serialize_operand_fc)g_known_imm_operand_serialize; +    asprintf(&conv, _("Decimal: %s"), value); -} +    result = stradd(result, "\n"); +    result = stradd(result, conv); +    free(conv); -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = instance à initialiser.                            * -*                                                                             * -*  Description : Initialise un remplacement d'opérande de valeur immédiate.   * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    /* Hexadécimal */ -static void g_known_imm_operand_init(GKnownImmOperand *operand) -{ -    operand->alt_text = NULL; +    _g_imm_operand_to_string(operand, IOD_HEX, value); -} +    asprintf(&conv, _("Hexadecimal: %s"), value); +    result = stradd(result, "\n"); +    result = stradd(result, conv); -/****************************************************************************** -*                                                                             * -*  Paramètres  : iface = interface GLib à initialiser.                        * -*                                                                             * -*  Description : Procède à l'initialisation de l'interface de renommage.      * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    free(conv); -static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *iface) -{ -    iface->get_text = (get_renamed_text_fc)g_known_imm_operand_get_text; +    return result;  } +#endif + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = instance d'objet GLib à traiter.                   * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                lock    = précise le besoin en verrouillage.                 *  *                                                                             * -*  Description : Supprime toutes les références externes.                     * +*  Description : Fournit l'empreinte d'un candidat à une centralisation.      *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Empreinte de l'élément représenté.                           *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void g_known_imm_operand_dispose(GKnownImmOperand *operand) +static guint g_imm_operand_hash(const GImmOperand *operand, bool lock)  { -    if (operand->alt_text != NULL) -        free(operand->alt_text); +    guint result;                           /* Valeur à retourner          */ +    immop_extra_data_t *extra;              /* Données insérées à modifier */ +    GArchOperandClass *class;               /* Classe parente normalisée   */ -    G_OBJECT_CLASS(g_known_imm_operand_parent_class)->dispose(G_OBJECT(operand)); +    extra = GET_IMM_OP_EXTRA(operand); -} +    if (lock) +        LOCK_GOBJECT_EXTRA(extra); +    class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); +    result = class->hash(G_ARCH_OPERAND(operand), false); -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = instance d'objet GLib à traiter.                   * -*                                                                             * -*  Description : Procède à la libération totale de la mémoire.                * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    result ^= (operand->raw & 0xffffffff); +    result ^= (operand->raw >> 32); -static void g_known_imm_operand_finalize(GKnownImmOperand *operand) -{ -    G_OBJECT_CLASS(g_known_imm_operand_parent_class)->finalize(G_OBJECT(operand)); +    if (lock) +        UNLOCK_GOBJECT_EXTRA(extra); + +    return result;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : old = opérande à venir copier avant son remplacement.        * -*                alt = texte alternatif à présenter pour l'impression.        * +*  Paramètres  : operand = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                *  *                                                                             * -*  Description : Crée un opérande remplaçant visuellement une valeur.         * +*  Description : Charge un contenu depuis une mémoire tampon.                 *  *                                                                             * -*  Retour      : Instruction mise en place.                                   * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt) +static bool g_imm_operand_load(GImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  { -    GKnownImmOperand *result;               /* Remplacement à retourner    */ -    immop_obj_extra *src;                   /* Données insérées à consulter*/ -    immop_obj_extra *dest;                  /* Données insérées à modifier */ +    bool result;                            /* Bilan à retourner           */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ +    immop_extra_data_t *extra;              /* Données insérées à modifier */ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ +    uint8_t val;                            /* Champ de bits manipulé      */ -    result = g_object_new(G_TYPE_KNOWN_IMM_OPERAND, NULL); +    parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); -    result->parent.raw = old->raw; +    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); -    src = GET_IMM_OP_EXTRA(old); -    dest = GET_IMM_OP_EXTRA(&result->parent); +    if (result) +    { +        extra = GET_IMM_OP_EXTRA(operand); -    g_bit_lock(&src->lock, HOLE_LOCK_BIT); +        LOCK_GOBJECT_EXTRA(extra); -    *dest = *src; +        result = unpack_uleb128(&value, pbuf); -    g_bit_unlock(&src->lock, HOLE_LOCK_BIT); +        if (result) +            extra->size = value; -    result->alt_text = strdup(alt); +        if (result) +        { +            result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); -    return G_ARCH_OPERAND(result); +            if (result) +                extra->def_display = val; -} +        } +        if (result) +        { +            result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); -/****************************************************************************** -*                                                                             * -*  Paramètres  : a = premier opérande à consulter.                            * -*                b = second opérande à consulter.                             * -*                                                                             * -*  Description : Compare un opérande avec un autre.                           * -*                                                                             * -*  Retour      : Bilan de la comparaison.                                     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +            if (result) +                extra->display = val; -static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b) -{ -    int result;                             /* Bilan à retourner           */ -    GArchOperandClass *class;               /* Classe parente à consulter  */ +        } -    class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); +        UNLOCK_GOBJECT_EXTRA(extra); -    result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b)); +    } -    if (result == 0) -        result = strcmp(a->alt_text, b->alt_text); +    if (result) +        result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true);      return result; @@ -1926,36 +1433,11 @@ static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownIm  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                line    = ligne tampon où imprimer l'opérande donné.         * -*                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLine *line) -{ -    size_t len;                             /* Taille de l'élément inséré  */ - -    len = strlen(operand->alt_text); - -    g_buffer_line_append_text(line, DLC_ASSEMBLY, operand->alt_text, len, RTT_IMMEDIATE, G_OBJECT(operand)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande d'assemblage à constituer.                * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Charge un opérande depuis une mémoire tampon.                * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -1963,101 +1445,103 @@ static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLi  *                                                                             *  ******************************************************************************/ -static bool g_known_imm_operand_unserialize(GKnownImmOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_imm_operand_store(GImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */      GArchOperandClass *parent;              /* Classe parente à consulter  */ -    unsigned short len;                     /* Taille du contenu alternatif*/ +    immop_extra_data_t *extra;              /* Données insérées à modifier */ -    parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); +    parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); -    result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); +    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);      if (result) -        result = extract_packed_buffer(pbuf, &len, sizeof(unsigned short), true); +    { +        extra = GET_IMM_OP_EXTRA(operand); -    if (result) -        result = (len > 0); +        LOCK_GOBJECT_EXTRA(extra); -    if (result) -    { -        operand->alt_text = malloc(len); +        result = pack_uleb128((uleb128_t []){ extra->size }, pbuf); -        result = extract_packed_buffer(pbuf, operand->alt_text, len, false); +        if (result) +            result = extend_packed_buffer(pbuf, (uint8_t []) { extra->def_display }, sizeof(uint8_t), false); + +        if (result) +            result = extend_packed_buffer(pbuf, (uint8_t []) { extra->display }, sizeof(uint8_t), false); + +        UNLOCK_GOBJECT_EXTRA(extra);      } +    if (result) +        result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); +      return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                        COMMUNICATION D'UN CIBLAGE POTENTIEL                        */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à consulter.                 * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : operand = operande à consulter.                              * +*                src     = localisation de l'instruction mère.                * +*                format  = format reconnu pour le binaire chargé.             * +*                proc    = architecture associée à ce même binaire.           * +*                addr    = localisation de la cible. [OUT]                    *  *                                                                             * -*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*  Description : Obtient l'adresse de la cible visée par un opérande.         *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : true si la cible est valide, false sinon.                    *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static bool g_known_imm_operand_serialize(const GKnownImmOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_imm_operand_get_addr(const GImmOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    size_t len;                             /* Taille du contenu alternatif*/ - -    parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); +    virt_t virt;                            /* Adresse virtuelle           */ -    result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); +    result = g_imm_operand_to_virt_t(operand, &virt);      if (result) -    { -        len = strlen(operand->alt_text) + 1; -        assert(len > 1); - -        if (len > (2 << (sizeof(unsigned short) * 8 - 1))) -        { -            log_variadic_message(LMT_ERROR, "Alternative text too long: '%s' (%zu bytes)", -                                 operand->alt_text, len); -            result = false; -        } +        result = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, addr); -        else -            result = extend_packed_buffer(pbuf, (unsigned short []) { len }, sizeof(unsigned short), true); +    return result; -        if (result) -            result = extend_packed_buffer(pbuf, operand->alt_text, len, false); +} -    } -    return result; -} +/* ---------------------------------------------------------------------------------- */ +/*                        CONSTRUCTION D'UN CONTENU ALTERNATIF                        */ +/* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = operande à consulter.                              * +*                text    = texte alternatif de représentation.                *  *                                                                             * -*  Description : Fournit un texte comme représentation alternative d'opérande.* +*  Description : Construit un opérande de représentation alternative.         *  *                                                                             * -*  Retour      : Chaîne de caractère de représentation alternative.           * +*  Retour      : Nouvel opérande, en version renommée.                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static const char *g_known_imm_operand_get_text(const GKnownImmOperand *operand) +static GRenamedOperand *g_imm_operand_build(const GImmOperand *operand, const char *text)  { -    const char *result;                     /* Texte à retourner           */ +    GRenamedOperand *result;                /* Instance à retourner        */ -    result = operand->alt_text; +    result = G_RENAMED_OPERAND(g_known_imm_operand_new(operand, text));      return result; diff --git a/src/arch/operands/immediate.h b/src/arch/operands/immediate.h index e6fab96..7c1ff03 100644 --- a/src/arch/operands/immediate.h +++ b/src/arch/operands/immediate.h @@ -36,8 +36,13 @@ -/* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _ImmOpFlag +{ +    IOF_ZERO_PADDING_BY_DEFAULT = AOF_USER_FLAG(0), /* Bourrage avec 0 par défaut ?*/ +    IOF_ZERO_PADDING = AOF_USER_FLAG(1),    /* Bourrage avec 0 ?           */ +} ImmOpFlag;  /* Grande ligne d'un format d'affichage */  typedef enum _ImmOperandDisplay @@ -52,7 +57,6 @@ typedef enum _ImmOperandDisplay  } ImmOperandDisplay; -  #define IOD_LAST_VALID IOD_CHAR @@ -95,18 +99,6 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *);  /* Définit la nouvelle valeur de l'opérande à une valeur. */  void g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t); -/* Indique si une valeur est complétée par des zéros par défaut. */ -bool g_imm_operand_get_default_padding(const GImmOperand *); - -/* Précise si des zéro doivent compléter l'affichage ou non. */ -void g_imm_operand_set_default_padding(GImmOperand *, bool); - -/* Précise si des zéro doivent compléter l'affichage ou non. */ -void g_imm_operand_pad(GImmOperand *, bool); - -/* Indique si une valeur est complétée par des zéros. */ -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); @@ -148,30 +140,4 @@ void g_imm_operand_as_uleb128(const GImmOperand *, uleb128_t *); -/* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */ - - -#define G_TYPE_KNOWN_IMM_OPERAND            g_known_imm_operand_get_type() -#define G_KNOWN_IMM_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperand)) -#define G_IS_KNOWN_IMM_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KNOWN_IMM_OPERAND)) -#define G_KNOWN_IMM_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass)) -#define G_IS_KNOWN_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KNOWN_IMM_OPERAND)) -#define G_KNOWN_IMM_OPERAND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass)) - - -/* Définition d'un remplacement d'opérande de valeur numérique (instance) */ -typedef struct _GKnownImmOperand GKnownImmOperand; - -/* Définition d'un remplacement d'opérande de valeur numérique (classe) */ -typedef struct _GKnownImmOperandClass GKnownImmOperandClass; - - -/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */ -GType g_known_imm_operand_get_type(void); - -/* Crée un opérande remplaçant visuellement une valeur. */ -GArchOperand *g_known_imm_operand_new(const GImmOperand *, const char *); - - -  #endif  /* _ARCH_OPERANDS_IMMEDIATE_H */ diff --git a/src/arch/operands/known.c b/src/arch/operands/known.c new file mode 100644 index 0000000..5402879 --- /dev/null +++ b/src/arch/operands/known.c @@ -0,0 +1,499 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * known.c - opérandes représentant des valeurs numériques avec sémantique + * + * Copyright (C) 2020 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "known.h" + + +#include <assert.h> +#include <malloc.h> +#include <string.h> + + +#include "immediate-int.h" +#include "rename-int.h" +#include "../../analysis/db/misc/rlestr.h" +#include "../../core/columns.h" +#include "../../core/logs.h" + + + +/* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */ + + +/* Définition d'un remplacement d'opérande de valeur numérique (instance) */ +struct _GKnownImmOperand +{ +    GImmOperand parent;                     /* Instance parente            */ + +    char *alt_text;                         /* Alternative humaine         */ + +}; + +/* Définition d'un remplacement d'opérande de valeur numérique (classe) */ +struct _GKnownImmOperandClass +{ +    GImmOperandClass parent;                /* Classe parente              */ + +}; + + +/* Initialise la classe des remplacements d'opérandes. */ +static void g_known_imm_operand_class_init(GKnownImmOperandClass *); + +/* Initialise un remplacement d'opérande de valeur immédiate. */ +static void g_known_imm_operand_init(GKnownImmOperand *); + +/* Procède à l'initialisation de l'interface de renommage. */ +static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *); + +/* Supprime toutes les références externes. */ +static void g_known_imm_operand_dispose(GKnownImmOperand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_known_imm_operand_finalize(GKnownImmOperand *); + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Compare un opérande avec un autre. */ +static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *, bool); + +/* Traduit un opérande en version humainement lisible. */ +static void g_known_imm_operand_print(const GKnownImmOperand *, GBufferLine *); + +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_known_imm_operand_hash(const GKnownImmOperand *, bool); + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_known_imm_operand_load(GKnownImmOperand *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_known_imm_operand_store(GKnownImmOperand *, GObjectStorage *, packed_buffer_t *); + + + +/* ------------------------- AFFICHAGE D'UN CONTENU RENOMME ------------------------- */ + + +/* Fournit un texte comme représentation alternative d'opérande. */ +static const char *g_known_imm_operand_get_text(const GKnownImmOperand *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                         REMPLACEMENT DE VALEURS IMMEDIATES                         */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */ +G_DEFINE_TYPE_WITH_CODE(GKnownImmOperand, g_known_imm_operand, G_TYPE_IMM_OPERAND, +                        G_IMPLEMENT_INTERFACE(G_TYPE_RENAMED_OPERAND, g_known_imm_operand_renamed_interface_init)); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des remplacements d'opérandes.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GArchOperandClass *operand;             /* Version de classe parente   */ + +    object = G_OBJECT_CLASS(klass); +    operand = G_ARCH_OPERAND_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_known_imm_operand_dispose; +    object->finalize = (GObjectFinalizeFunc)g_known_imm_operand_finalize; + +    operand->compare = (operand_compare_fc)g_known_imm_operand_compare; +    operand->print = (operand_print_fc)g_known_imm_operand_print; + +    operand->hash = (operand_hash_fc)g_known_imm_operand_hash; + +    operand->load = (load_operand_fc)g_known_imm_operand_load; +    operand->store = (store_operand_fc)g_known_imm_operand_store; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance à initialiser.                            * +*                                                                             * +*  Description : Initialise un remplacement d'opérande de valeur immédiate.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_known_imm_operand_init(GKnownImmOperand *operand) +{ +    operand->alt_text = NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de renommage.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *iface) +{ +    iface->get_text = (get_renamed_text_fc)g_known_imm_operand_get_text; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_known_imm_operand_dispose(GKnownImmOperand *operand) +{ +    if (operand->alt_text != NULL) +        free(operand->alt_text); + +    G_OBJECT_CLASS(g_known_imm_operand_parent_class)->dispose(G_OBJECT(operand)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_known_imm_operand_finalize(GKnownImmOperand *operand) +{ +    G_OBJECT_CLASS(g_known_imm_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : old = opérande à venir copier avant son remplacement.        * +*                alt = texte alternatif à présenter pour l'impression.        * +*                                                                             * +*  Description : Crée un opérande remplaçant visuellement une valeur.         * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt) +{ +    GKnownImmOperand *result;               /* Remplacement à retourner    */ +    immop_extra_data_t *src;                /* Données insérées à consulter*/ +    immop_extra_data_t *dest;               /* Données insérées à modifier */ + +    result = g_object_new(G_TYPE_KNOWN_IMM_OPERAND, NULL); + +    result->parent.raw = old->raw; + +    src = GET_IMM_OP_EXTRA(old); +    dest = GET_IMM_OP_EXTRA(&result->parent); + +    LOCK_GOBJECT_EXTRA(src); + +    *(&dest->parent) = *(&src->parent); + +    dest->size = src->size; + +    dest->def_display = src->def_display; +    dest->display = src->display; + +    UNLOCK_GOBJECT_EXTRA(src); + +    result->alt_text = strdup(alt); + +    return G_ARCH_OPERAND(result); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a    = premier opérande à consulter.                         * +*                b    = second opérande à consulter.                          * +*                lock = précise le besoin en verrouillage.                    * +*                                                                             * +*  Description : Compare un opérande avec un autre.                           * +*                                                                             * +*  Retour      : Bilan de la comparaison.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b, bool lock) +{ +    int result;                             /* Bilan à retourner           */ +    immop_extra_data_t *ea;                 /* Données insérées à consulter*/ +    immop_extra_data_t *eb;                 /* Données insérées à consulter*/ +    GArchOperandClass *class;               /* Classe parente normalisée   */ + +    ea = GET_IMM_OP_EXTRA(G_IMM_OPERAND(a)); +    eb = GET_IMM_OP_EXTRA(G_IMM_OPERAND(b)); + +    if (lock) +    { +        LOCK_GOBJECT_EXTRA(ea); +        LOCK_GOBJECT_EXTRA(eb); +    } + +    result = strcmp(a->alt_text, b->alt_text); + +    if (result == 0) +    { +        class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); +        result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); +    } + +    if (lock) +    { +        UNLOCK_GOBJECT_EXTRA(eb); +        UNLOCK_GOBJECT_EXTRA(ea); +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à traiter.                                * +*                line    = ligne tampon où imprimer l'opérande donné.         * +*                                                                             * +*  Description : Traduit un opérande en version humainement lisible.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLine *line) +{ +    size_t len;                             /* Taille de l'élément inséré  */ + +    len = strlen(operand->alt_text); + +    g_buffer_line_append_text(line, DLC_ASSEMBLY, operand->alt_text, len, RTT_IMMEDIATE, G_OBJECT(operand)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                lock    = précise le besoin en verrouillage.                 * +*                                                                             * +*  Description : Fournit l'empreinte d'un candidat à une centralisation.      * +*                                                                             * +*  Retour      : Empreinte de l'élément représenté.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static guint g_known_imm_operand_hash(const GKnownImmOperand *operand, bool lock) +{ +    guint result;                           /* Valeur à retourner          */ +    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    GArchOperandClass *class;               /* Classe parente normalisée   */ + +    extra = GET_IMM_OP_EXTRA(G_IMM_OPERAND(operand)); + +    if (lock) +        LOCK_GOBJECT_EXTRA(extra); + +    class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); +    result = class->hash(G_ARCH_OPERAND(operand), false); + +    result ^= g_str_hash(operand->alt_text); + +    if (lock) +        UNLOCK_GOBJECT_EXTRA(extra); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                * +*                                                                             * +*  Description : Charge un contenu depuis une mémoire tampon.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_known_imm_operand_load(GKnownImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ +    rle_string str;                         /* Chaîne à charger            */ + +    parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); + +    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); + +    if (result) +    { +        setup_empty_rle_string(&str); + +        result = unpack_rle_string(&str, pbuf); + +        if (result) +        { +            if (get_rle_string(&str) != NULL) +                operand->alt_text = strdup(get_rle_string(&str)); + +            exit_rle_string(&str); + +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_known_imm_operand_store(GKnownImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ +    rle_string str;                         /* Chaîne à conserver          */ + +    parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); + +    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); + +    if (result) +    { +        init_static_rle_string(&str, operand->alt_text); + +        result = pack_rle_string(&str, pbuf); + +        exit_rle_string(&str); + +    } + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                           AFFICHAGE D'UN CONTENU RENOMME                           */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = operande à consulter.                              * +*                                                                             * +*  Description : Fournit un texte comme représentation alternative d'opérande.* +*                                                                             * +*  Retour      : Chaîne de caractère de représentation alternative.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static const char *g_known_imm_operand_get_text(const GKnownImmOperand *operand) +{ +    const char *result;                     /* Texte à retourner           */ + +    result = operand->alt_text; + +    return result; + +} diff --git a/src/arch/operands/known.h b/src/arch/operands/known.h new file mode 100644 index 0000000..eb84d3b --- /dev/null +++ b/src/arch/operands/known.h @@ -0,0 +1,59 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * known.h - prototypes pour les opérandes représentant des valeurs numériques avec sémantique + * + * Copyright (C) 2021 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_KNOWN_H +#define _ARCH_OPERANDS_KNOWN_H + + +#include <glib-object.h> + + +#include "immediate.h" +#include "../operand.h" + + + +#define G_TYPE_KNOWN_IMM_OPERAND            g_known_imm_operand_get_type() +#define G_KNOWN_IMM_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperand)) +#define G_IS_KNOWN_IMM_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KNOWN_IMM_OPERAND)) +#define G_KNOWN_IMM_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass)) +#define G_IS_KNOWN_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KNOWN_IMM_OPERAND)) +#define G_KNOWN_IMM_OPERAND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass)) + + +/* Définition d'un remplacement d'opérande de valeur numérique (instance) */ +typedef struct _GKnownImmOperand GKnownImmOperand; + +/* Définition d'un remplacement d'opérande de valeur numérique (classe) */ +typedef struct _GKnownImmOperandClass GKnownImmOperandClass; + + +/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */ +GType g_known_imm_operand_get_type(void); + +/* Crée un opérande remplaçant visuellement une valeur. */ +GArchOperand *g_known_imm_operand_new(const GImmOperand *, const char *); + + + +#endif  /* _ARCH_OPERANDS_KNOWN_H */ diff --git a/src/arch/operands/proxy.c b/src/arch/operands/proxy.c index bf26a4f..c71f96f 100644 --- a/src/arch/operands/proxy.c +++ b/src/arch/operands/proxy.c @@ -43,22 +43,25 @@ static void g_proxy_operand_dispose(GProxyOperand *);  /* Procède à la libération totale de la mémoire. */  static void g_proxy_operand_finalize(GProxyOperand *); -/* Compare un opérande avec un autre. */ -static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *); -/* Traduit un opérande en version humainement lisible. */ -static void g_proxy_operand_print(const GProxyOperand *, GBufferLine *); + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +/* Compare un opérande avec un autre. */ +static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *, bool); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Traduit un opérande en version humainement lisible. */ +static void g_proxy_operand_print(const GProxyOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_proxy_operand_hash(const GProxyOperand *, bool); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_proxy_operand_unserialize(GProxyOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_proxy_operand_load(GProxyOperand *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_proxy_operand_serialize(const GProxyOperand *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_proxy_operand_store(GProxyOperand *, GObjectStorage *, packed_buffer_t *); @@ -98,8 +101,10 @@ static void g_proxy_operand_class_init(GProxyOperandClass *klass)      operand->compare = (operand_compare_fc)g_proxy_operand_compare;      operand->print = (operand_print_fc)g_proxy_operand_print; -    operand->unserialize = (unserialize_operand_fc)g_proxy_operand_unserialize; -    operand->serialize = (serialize_operand_fc)g_proxy_operand_serialize; +    operand->hash = (operand_hash_fc)g_proxy_operand_hash; + +    operand->load = (load_operand_fc)g_proxy_operand_load; +    operand->store = (store_operand_fc)g_proxy_operand_store;  } @@ -190,8 +195,40 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder)  /******************************************************************************  *                                                                             * -*  Paramètres  : a = premier opérande à consulter.                            * -*                b = second opérande à consulter.                             * +*  Paramètres  : operand = opérande à consulter.                              * +*                                                                             * +*  Description : Fournit le fournisseur représenté par l'opérande.            * +*                                                                             * +*  Retour      : Fournisseur associé à l'opérande.                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GProxyFeeder *g_proxy_operand_get_feeder(const GProxyOperand *operand) +{ +    GProxyFeeder *result;                   /* Instance à retourner        */ + +    result = operand->feeder; + +    g_object_ref(G_OBJECT(result)); + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a    = premier opérande à consulter.                         * +*                b    = second opérande à consulter.                          * +*                lock = précise le besoin en verrouillage.                    *  *                                                                             *  *  Description : Compare un opérande avec un autre.                           *  *                                                                             * @@ -201,12 +238,36 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder)  *                                                                             *  ******************************************************************************/ -static int g_proxy_operand_compare(const GProxyOperand *a, const GProxyOperand *b) +static int g_proxy_operand_compare(const GProxyOperand *a, const GProxyOperand *b, bool lock)  {      int result;                             /* Bilan à retourner           */ +    operand_extra_data_t *ea;               /* Données insérées à consulter*/ +    operand_extra_data_t *eb;               /* Données insérées à consulter*/ +    GArchOperandClass *class;               /* Classe parente normalisée   */ + +    ea = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(a)); +    eb = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(b)); + +    if (lock) +    { +        LOCK_GOBJECT_EXTRA(ea); +        LOCK_GOBJECT_EXTRA(eb); +    }      result = g_proxy_feeder_compare(a->feeder, b->feeder); +    if (result == 0) +    { +        class = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class); +        result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); +    } + +    if (lock) +    { +        UNLOCK_GOBJECT_EXTRA(eb); +        UNLOCK_GOBJECT_EXTRA(ea); +    } +      return result;  } @@ -234,43 +295,48 @@ static void g_proxy_operand_print(const GProxyOperand *operand, GBufferLine *lin  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à consulter.                              * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                lock    = précise le besoin en verrouillage.                 *  *                                                                             * -*  Description : Fournit le fournisseur représenté par l'opérande.            * +*  Description : Fournit l'empreinte d'un candidat à une centralisation.      *  *                                                                             * -*  Retour      : Fournisseur associé à l'opérande.                            * +*  Retour      : Empreinte de l'élément représenté.                           *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GProxyFeeder *g_proxy_operand_get_feeder(const GProxyOperand *operand) +static guint g_proxy_operand_hash(const GProxyOperand *operand, bool lock)  { -    GProxyFeeder *result;                   /* Instance à retourner        */ +    guint result;                           /* Valeur à retourner          */ +    operand_extra_data_t *extra;            /* Données insérées à consulter*/ +    GArchOperandClass *class;               /* Classe parente normalisée   */ -    result = operand->feeder; +    extra = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(operand)); -    g_object_ref(G_OBJECT(result)); +    if (lock) +        LOCK_GOBJECT_EXTRA(extra); -    return result; +    class = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class); +    result = class->hash(G_ARCH_OPERAND(operand), false); -} +    result ^= g_direct_hash(operand->feeder); +    if (lock) +        UNLOCK_GOBJECT_EXTRA(extra); +    return result; -/* ---------------------------------------------------------------------------------- */ -/*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */ -/* ---------------------------------------------------------------------------------- */ +}  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à constituer.                * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : operand = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                *  *                                                                             * -*  Description : Charge un opérande depuis une mémoire tampon.                * +*  Description : Charge un contenu depuis une mémoire tampon.                 *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -278,17 +344,26 @@ GProxyFeeder *g_proxy_operand_get_feeder(const GProxyOperand *operand)  *                                                                             *  ******************************************************************************/ -static bool g_proxy_operand_unserialize(GProxyOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_proxy_operand_load(GProxyOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */      GArchOperandClass *parent;              /* Classe parente à consulter  */ +    GSerializableObject *feeder;            /* Fournisseur manipulé        */      parent = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class); -    result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); +    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);      if (result) -        result = g_proxy_feeder_unserialize(operand->feeder, format, pbuf); +    { +        feeder = g_object_storage_unpack_object(storage, "operands", pbuf); + +        result = (feeder != NULL); + +        if (result) +            operand->feeder = G_PROXY_FEEDER(feeder); + +    }      return result; @@ -297,11 +372,11 @@ static bool g_proxy_operand_unserialize(GProxyOperand *operand, GAsmStorage *sto  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à consulter.                 * -*                storage = mécanisme de sauvegarde à manipuler.               * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -309,17 +384,21 @@ static bool g_proxy_operand_unserialize(GProxyOperand *operand, GAsmStorage *sto  *                                                                             *  ******************************************************************************/ -static bool g_proxy_operand_serialize(const GProxyOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_proxy_operand_store(GProxyOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */  +    GSerializableObject *feeder;            /* Fournisseur manipulé        */      parent = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class); -    result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); +    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);      if (result) -        result = g_proxy_feeder_serialize(operand->feeder, pbuf); +    { +        feeder = G_SERIALIZABLE_OBJECT(operand->feeder); +        result = g_object_storage_pack_object(storage, "operands", feeder, pbuf); +    }      return result; diff --git a/src/arch/operands/register-int.h b/src/arch/operands/register-int.h index bf3e9d4..a887567 100644 --- a/src/arch/operands/register-int.h +++ b/src/arch/operands/register-int.h @@ -29,23 +29,9 @@  #include "../operand-int.h" -#include "../../glibext/objhole.h" -/* Informations glissées dans la structure GObject de GArchInstruction */ -typedef union _regop_obj_extra -{ -    struct -    { -        bool is_written;                    /* Changement de contenu       */ - -    }; - -    gint lock;                              /* Gestion d'accès aux fanions */ - -} regop_obj_extra; -  /* Définition d'un opérande visant un registre (instance) */  struct _GRegisterOperand  { @@ -53,39 +39,8 @@ struct _GRegisterOperand      GArchRegister *reg;                     /* Registre représenté         */ -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -    /** -     * L'inclusion des informations suivantes dépend de l'architecture. -     * -     * Si la structure GObject possède un trou, on remplit de préférence -     * ce dernier. -     */ - -    regop_obj_extra extra;                  /* Externalisation embarquée   */ - -#endif -  }; -/** - * Accès aux informations éventuellement déportées. - */ - -#if __SIZEOF_INT__ == __SIZEOF_LONG__ - -#   define INIT_REG_OP_EXTRA(op) op->extra.lock = 0 - -#   define GET_REG_OP_EXTRA(op) &op->extra - -#else - -#   define INIT_REG_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op)) - -#   define GET_REG_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), regop_obj_extra) - -#endif -  /* Définition d'un opérande visant un registre (classe) */  struct _GRegisterOperandClass  { diff --git a/src/arch/operands/register.c b/src/arch/operands/register.c index 9a6de17..4615a99 100644 --- a/src/arch/operands/register.c +++ b/src/arch/operands/register.c @@ -24,6 +24,9 @@  #include "register.h" +#include <assert.h> + +  #include "register-int.h"  #include "../storage.h" @@ -44,22 +47,25 @@ static void g_register_operand_dispose(GRegisterOperand *);  /* Procède à la libération totale de la mémoire. */  static void g_register_operand_finalize(GRegisterOperand *); -/* Compare un opérande avec un autre. */ -static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *); -/* Traduit un opérande en version humainement lisible. */ -static void g_register_operand_print(const GRegisterOperand *, GBufferLine *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Compare un opérande avec un autre. */ +static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *, bool); +/* Traduit un opérande en version humainement lisible. */ +static void g_register_operand_print(const GRegisterOperand *, GBufferLine *); + +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_register_operand_hash(const GRegisterOperand *, bool); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_register_operand_unserialize(GRegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_register_operand_load(GRegisterOperand *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_register_operand_serialize(const GRegisterOperand *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_register_operand_store(GRegisterOperand *, GObjectStorage *, packed_buffer_t *); @@ -100,8 +106,10 @@ static void g_register_operand_class_init(GRegisterOperandClass *klass)      operand->compare = (operand_compare_fc)g_register_operand_compare;      operand->print = (operand_print_fc)g_register_operand_print; -    operand->unserialize = (unserialize_operand_fc)g_register_operand_unserialize; -    operand->serialize = (serialize_operand_fc)g_register_operand_serialize; +    operand->hash = (operand_hash_fc)g_register_operand_hash; + +    operand->load = (load_operand_fc)g_register_operand_load; +    operand->store = (store_operand_fc)g_register_operand_store;  } @@ -122,8 +130,6 @@ static void g_register_operand_init(GRegisterOperand *operand)  {      operand->reg = NULL; -    INIT_REG_OP_EXTRA(operand); -  } @@ -169,68 +175,61 @@ static void g_register_operand_finalize(GRegisterOperand *operand)  /******************************************************************************  *                                                                             * -*  Paramètres  : a = premier opérande à consulter.                            * -*                b = second opérande à consulter.                             * +*  Paramètres  : operand = opérande représentant un registre.                 *  *                                                                             * -*  Description : Compare un opérande avec un autre.                           * +*  Description : Fournit le registre associé à l'opérande.                    *  *                                                                             * -*  Retour      : Bilan de la comparaison.                                     * +*  Retour      : Représentation interne du registre.                          *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b) +GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)  { -    int result;                             /* Bilan à retourner           */ +    GArchRegister *result;                  /* Instance à retourner        */ -    result = g_arch_register_compare(a->reg, b->reg); +    result = operand->reg; + +    g_object_ref(G_OBJECT(result));      return result;  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                line    = ligne tampon où imprimer l'opérande donné.         * -*                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line) -{ -    g_arch_register_print(operand->reg, line); -} +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande représentant un registre.                 * +*  Paramètres  : a    = premier opérande à consulter.                         * +*                b    = second opérande à consulter.                          * +*                lock = précise le besoin en verrouillage.                    *  *                                                                             * -*  Description : Fournit le registre associé à l'opérande.                    * +*  Description : Compare un opérande avec un autre.                           *  *                                                                             * -*  Retour      : Représentation interne du registre.                          * +*  Retour      : Bilan de la comparaison.                                     *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand) +static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b, bool lock)  { -    GArchRegister *result;                  /* Instance à retourner        */ +    int result;                             /* Bilan à retourner           */ +    GArchOperandClass *class;               /* Classe parente normalisée   */ -    result = operand->reg; +    result = g_arch_register_compare(a->reg, b->reg); -    if (result != NULL) -        g_object_ref(G_OBJECT(result)); +    if (result == 0) +    { +        class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); +        result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); +    }      return result; @@ -239,9 +238,10 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande représentant un registre à mettre à jour. * +*  Paramètres  : operand = opérande à traiter.                                * +*                line    = ligne tampon où imprimer l'opérande donné.         *  *                                                                             * -*  Description : Marque l'opérande comme étant écrit plutôt que consulté.     * +*  Description : Traduit un opérande en version humainement lisible.          *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -249,65 +249,53 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)  *                                                                             *  ******************************************************************************/ -void g_register_operand_mark_as_written(GRegisterOperand *operand) +static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line)  { -    regop_obj_extra *extra;                 /* Données insérées à modifier */ - -    extra = GET_REG_OP_EXTRA(operand); - -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -    extra->is_written = true; - -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    g_arch_register_print(operand->reg, line);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande représentant un registre à consulter.     * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                lock    = précise le besoin en verrouillage.                 *  *                                                                             * -*  Description : Indique le type d'accès réalisé sur l'opérande.              * +*  Description : Fournit l'empreinte d'un candidat à une centralisation.      *  *                                                                             * -*  Retour      : Type d'accès : true en cas d'écriture, false sinon.          * +*  Retour      : Empreinte de l'élément représenté.                           *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool g_register_operand_is_written(const GRegisterOperand *operand) +static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)  { -    bool result;                            /* Statut à retourner          */ -    regop_obj_extra *extra;                 /* Données insérées à modifier */ +    guint result;                           /* Valeur à retourner          */ +    GArchOperandClass *class;               /* Classe parente normalisée   */ +    GArchRegister *reg;                     /* Registre visé par l'opérande*/ -    extra = GET_REG_OP_EXTRA(operand); +    class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); +    result = class->hash(G_ARCH_OPERAND(operand), false); -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +    reg = g_register_operand_get_register(operand); -    result = extra->is_written; +    result ^= g_arch_register_hash(reg); -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +    g_object_unref(G_OBJECT(reg));      return result;  } - -/* ---------------------------------------------------------------------------------- */ -/*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */ -/* ---------------------------------------------------------------------------------- */ - -  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à constituer.                * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : operand = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                *  *                                                                             * -*  Description : Charge un opérande depuis une mémoire tampon.                * +*  Description : Charge un contenu depuis une mémoire tampon.                 *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -315,37 +303,24 @@ bool g_register_operand_is_written(const GRegisterOperand *operand)  *                                                                             *  ******************************************************************************/ -static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_register_operand_load(GRegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */      GArchOperandClass *parent;              /* Classe parente à consulter  */ -    off64_t pos;                            /* Position dans le flux       */ -    packed_buffer_t reg_pbuf;               /* Tampon des données à écrire */ -    GArchRegister *reg;                     /* Registre restauré           */ +    GSerializableObject *reg;               /* Registre manipulé           */      parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); -    result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - -    if (result) -        result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true); +    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);      if (result)      { -        init_packed_buffer(®_pbuf); - -        result = g_asm_storage_load_register_data(storage, ®_pbuf, pos); +        reg = g_object_storage_unpack_object(storage, "registers", pbuf); -        if (result) -        { -            reg = g_arch_register_load(storage, ®_pbuf); -            result = (reg != NULL); -        } +        result = (reg != NULL);          if (result) -            operand->reg = reg; - -        exit_packed_buffer(®_pbuf); +            operand->reg = G_ARCH_REGISTER(reg);      } @@ -356,11 +331,11 @@ static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorag  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à consulter.                 * -*                storage = mécanisme de sauvegarde à manipuler.               * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -368,31 +343,20 @@ static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorag  *                                                                             *  ******************************************************************************/ -static bool g_register_operand_serialize(const GRegisterOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_register_operand_store(GRegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    off64_t pos;                            /* Position dans le flux       */ -    packed_buffer_t reg_pbuf;               /* Tampon des données à écrire */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */  +    GSerializableObject *reg;               /* Registre manipulé           */      parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); -    result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); +    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);      if (result)      { -        init_packed_buffer(®_pbuf); - -        result = g_arch_register_store(operand->reg, storage, ®_pbuf); - -        if (result) -            result = g_asm_storage_store_register_data(storage, ®_pbuf, &pos); - -        if (result) -            result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true); - -        exit_packed_buffer(®_pbuf); - +        reg = G_SERIALIZABLE_OBJECT(operand->reg); +        result = g_object_storage_pack_object(storage, "registers", reg, pbuf);      }      return result; diff --git a/src/arch/operands/register.h b/src/arch/operands/register.h index 7f746b6..e2f2c46 100644 --- a/src/arch/operands/register.h +++ b/src/arch/operands/register.h @@ -37,6 +37,14 @@  /* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ +/* Etats particuliers d'un opérande de registre */ +typedef enum _RegOpFlag +{ +    ROF_IS_WRITTEN = AOF_USER_FLAG(0),      /* Opération d'écriture ?      */ + +} RegOpFlag; + +  #define G_TYPE_REGISTER_OPERAND            g_register_operand_get_type()  #define G_REGISTER_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_REGISTER_OPERAND, GRegisterOperand))  #define G_IS_REGISTER_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_REGISTER_OPERAND)) @@ -58,12 +66,6 @@ GType g_register_operand_get_type(void);  /* Fournit le registre associé à l'opérande. */  GArchRegister *g_register_operand_get_register(const GRegisterOperand *); -/* Marque l'opérande comme étant écrit plutôt que consulté. */ -void g_register_operand_mark_as_written(GRegisterOperand *); - -/* Indique le type d'accès réalisé sur l'opérande. */ -bool g_register_operand_is_written(const GRegisterOperand *); -  #endif  /* _ARCH_OPERANDS_REGISTER_H */ diff --git a/src/arch/operands/target-int.h b/src/arch/operands/target-int.h index f3ed447..aa48b2b 100644 --- a/src/arch/operands/target-int.h +++ b/src/arch/operands/target-int.h @@ -30,15 +30,22 @@ +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _tarop_extra_data_t +{ +    operand_extra_data_t parent;            /* A laisser en premier        */ + +    MemoryDataSize size;                    /* Taille de l'opérande        */ + +} tarop_extra_data_t; +  /* Définition d'un opérande ciblant idéalement un symbole connu (instance) */  struct _GTargetOperand  {      GArchOperand parent;                    /* Instance parente            */ -    MemoryDataSize size;                    /* Taille de l'opérande        */      vmpa2t addr;                            /* Adresse de l'élément visé   */ -    bool strict;                            /* Résolution stricte          */      /* Référence circulaire */      GBinSymbol *symbol;                     /* Eventuel symbole associé    */      phys_t diff;                            /* Position dans le symbole    */ @@ -54,5 +61,20 @@ struct _GTargetOperandClass  }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +#   define GET_TARGET_OP_EXTRA(op) ((tarop_extra_data_t *)&((GArchOperand *)op)->extra) + +#else + +#   define GET_TARGET_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), tarop_extra_data_t) + +#endif + +  #endif  /* _ARCH_OPERANDS_TARGET_INT_H */ diff --git a/src/arch/operands/target.c b/src/arch/operands/target.c index 5edc805..61f683a 100644 --- a/src/arch/operands/target.c +++ b/src/arch/operands/target.c @@ -37,13 +37,17 @@  #include "targetable-int.h"  #include "../../analysis/routine.h"  #include "../../common/extstr.h" +#include "../../common/sort.h"  #include "../../format/format.h"  #include "../../format/strsym.h"  #include "../../glibext/gbinarycursor.h" -#include "../../gtkext/gtkblockdisplay.h" +#include "../../core/columns.h" +/* ------------------------- POINTAGE D'UN SYMBOLE EXISTANT ------------------------- */ + +  /* Initialise la classe des opérandes ciblant des symboles. */  static void g_target_operand_class_init(GTargetOperandClass *); @@ -59,25 +63,32 @@ static void g_target_operand_dispose(GTargetOperand *);  /* Procède à la libération totale de la mémoire. */  static void g_target_operand_finalize(GTargetOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + +  /* Compare un opérande avec un autre. */ -static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *); +static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *, bool);  /* Traduit un opérande en version humainement lisible. */  static void g_target_operand_print(const GTargetOperand *, GBufferLine *); +#ifdef INCLUDE_GTK_SUPPORT +  /* Construit un petit résumé concis de l'opérande. */  static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *); +#endif +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_target_operand_hash(const GTargetOperand *, bool); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_target_operand_unserialize(GTargetOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_target_operand_load(GTargetOperand *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_target_operand_serialize(const GTargetOperand *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_target_operand_store(GTargetOperand *, GObjectStorage *, packed_buffer_t *); @@ -89,6 +100,11 @@ static bool g_target_operand_get_addr(const GTargetOperand *, const vmpa2t *, GB +/* ---------------------------------------------------------------------------------- */ +/*                           POINTAGE D'UN SYMBOLE EXISTANT                           */ +/* ---------------------------------------------------------------------------------- */ + +  /* Indique le type défini pour un opérande de valeur numérique. */  G_DEFINE_TYPE_WITH_CODE(GTargetOperand, g_target_operand, G_TYPE_ARCH_OPERAND,                          G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_target_operand_targetable_interface_init)); @@ -120,10 +136,14 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)      operand->compare = (operand_compare_fc)g_target_operand_compare;      operand->print = (operand_print_fc)g_target_operand_print; +#ifdef INCLUDE_GTK_SUPPORT      operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip; +#endif + +    operand->hash = (operand_hash_fc)g_target_operand_hash; -    operand->unserialize = (unserialize_operand_fc)g_target_operand_unserialize; -    operand->serialize = (serialize_operand_fc)g_target_operand_serialize; +    operand->load = (load_operand_fc)g_target_operand_load; +    operand->store = (store_operand_fc)g_target_operand_store;  } @@ -142,10 +162,10 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)  static void g_target_operand_init(GTargetOperand *operand)  { -    operand->size = MDS_UNDEFINED; +    GET_TARGET_OP_EXTRA(operand)->size = MDS_UNDEFINED; +      init_vmpa(&operand->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); -    operand->strict = true;      operand->symbol = NULL;      operand->diff = 0; @@ -211,8 +231,9 @@ static void g_target_operand_finalize(GTargetOperand *operand)  /******************************************************************************  *                                                                             * -*  Paramètres  : a = premier opérande à consulter.                            * -*                b = second opérande à consulter.                             * +*  Paramètres  : a    = premier opérande à consulter.                         * +*                b    = second opérande à consulter.                          * +*                lock = précise le besoin en verrouillage.                    *  *                                                                             *  *  Description : Compare un opérande avec un autre.                           *  *                                                                             * @@ -222,56 +243,56 @@ static void g_target_operand_finalize(GTargetOperand *operand)  *                                                                             *  ******************************************************************************/ -static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b) +static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b, bool lock)  {      int result;                             /* Bilan à retourner           */ +    tarop_extra_data_t *ea;                 /* Données insérées à modifier */ +    tarop_extra_data_t *eb;                 /* Données insérées à modifier */ +    GArchOperandClass *class;               /* Classe parente normalisée   */ -    result = cmp_vmpa(&a->addr, &b->addr); -    if (result != 0) goto gtoc_done; +    ea = GET_TARGET_OP_EXTRA(a); +    eb = GET_TARGET_OP_EXTRA(b); -    if (a->size < b->size) +    if (lock)      { -        result = -1; -        goto gtoc_done; -    } -    else if (a->size > b->size) -    { -        result = 1; -        goto gtoc_done; +        LOCK_GOBJECT_EXTRA(ea); +        LOCK_GOBJECT_EXTRA(eb);      } -    if (a->symbol == NULL && b->symbol != NULL) -    { -        result = -1; -        goto gtoc_done; -    } -    else if (a->symbol != NULL && b->symbol == NULL) -    { -        result = 1; -        goto gtoc_done; -    } -    else if (a->symbol != NULL && b->symbol != NULL) +    result = sort_unsigned_long(ea->size, eb->size); + +    if (result == 0) +        result = cmp_vmpa(&a->addr, &b->addr); + +    if (result == 0)      { -        result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol }, -                                     (const GBinSymbol *[]) { b->symbol }); -        if (result != 0) goto gtoc_done; +        if (a->symbol == NULL && b->symbol != NULL) +            result = -1; + +        else if (a->symbol != NULL && b->symbol == NULL) +            result = 1; + +        else if (a->symbol != NULL && b->symbol != NULL) +            result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol }, +                                         (const GBinSymbol *[]) { b->symbol }); +      } -    if (a->diff < b->diff) +    if (result == 0) +        result = sort_uint64_t(a->diff, b->diff); + +    if (result == 0)      { -        result = -1; -        goto gtoc_done; +        class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class); +        result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);      } -    else if (a->diff > b->diff) + +    if (lock)      { -        result = 1; -        goto gtoc_done; +        UNLOCK_GOBJECT_EXTRA(eb); +        UNLOCK_GOBJECT_EXTRA(ea);      } -    result = 0; - - gtoc_done: -      return result;  } @@ -296,6 +317,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l      vmpa2t tmp;                             /* Coquille vide pour argument */      VMPA_BUFFER(value);                     /* Adresse brute à imprimer    */      size_t len;                             /* Taille de l'élément inséré  */ +    MemoryDataSize size;                    /* Taille retenue              */      label = g_binary_symbol_get_label(operand->symbol); @@ -322,7 +344,9 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l      }      else      { -        vmpa2_to_string(&operand->addr, operand->size, value, &len); +        size = g_target_operand_get_size(operand); + +        vmpa2_to_string(&operand->addr, size, value, &len);          g_buffer_line_append_text(line, DLC_ASSEMBLY, value, len, RTT_LABEL, G_OBJECT(operand)); @@ -355,7 +379,8 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)      assert(size != MDS_UNDEFINED); -    result->size = size; +    GET_TARGET_OP_EXTRA(result)->size = size; +      copy_vmpa(&result->addr, addr);      return G_ARCH_OPERAND(result); @@ -363,6 +388,9 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)  } +#ifdef INCLUDE_GTK_SUPPORT + +  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = opérande à consulter.                              * @@ -443,6 +471,9 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const  } +#endif + +  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = structure dont le contenu est à consulter.         * @@ -457,7 +488,18 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const  MemoryDataSize g_target_operand_get_size(const GTargetOperand *operand)  { -    return operand->size; +    MemoryDataSize result;                  /* Taille à retourner          */ +    tarop_extra_data_t *extra;              /* Données insérées à consulter*/ + +    extra = GET_TARGET_OP_EXTRA(operand); + +    LOCK_GOBJECT_EXTRA(extra); + +    result = extra->size; + +    UNLOCK_GOBJECT_EXTRA(extra); + +    return result;  } @@ -485,7 +527,10 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool      const mrange_t *range;                  /* Couverture du symbole       */  #endif -    operand->strict = strict; +    if (strict) +        g_arch_operand_set_flag(G_ARCH_OPERAND(operand), TOF_STRICT); +    else +        g_arch_operand_unset_flag(G_ARCH_OPERAND(operand), TOF_STRICT);      result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff); @@ -569,20 +614,55 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = objet dont l'instance se veut unique.              * +*                lock    = précise le besoin en verrouillage.                 * +*                                                                             * +*  Description : Fournit l'empreinte d'un candidat à une centralisation.      * +*                                                                             * +*  Retour      : Empreinte de l'élément représenté.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -/* ---------------------------------------------------------------------------------- */ -/*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */ -/* ---------------------------------------------------------------------------------- */ +static guint g_target_operand_hash(const GTargetOperand *operand, bool lock) +{ +    guint result;                           /* Valeur à retourner          */ +    tarop_extra_data_t *extra;              /* Données insérées à modifier */ +    GArchOperandClass *class;               /* Classe parente normalisée   */ + +    extra = GET_TARGET_OP_EXTRA(operand); + +    if (lock) +        LOCK_GOBJECT_EXTRA(extra); + +    class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class); +    result = class->hash(G_ARCH_OPERAND(operand), false); + +    result ^= extra->size; + +    result ^= g_direct_hash(operand->symbol); + +    result ^= (operand->diff & 0xffffffff); +    result ^= (operand->diff >> 32); + +    if (lock) +        UNLOCK_GOBJECT_EXTRA(extra); + +    return result; + +}  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à constituer.                * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : operand = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                *  *                                                                             * -*  Description : Charge un opérande depuis une mémoire tampon.                * +*  Description : Charge un contenu depuis une mémoire tampon.                 *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -590,7 +670,7 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d  *                                                                             *  ******************************************************************************/ -static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_target_operand_load(GTargetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ @@ -617,11 +697,11 @@ static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *s  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à consulter.                 * -*                storage = mécanisme de sauvegarde à manipuler.               * +*  Paramètres  : operand = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -629,9 +709,10 @@ static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *s  *                                                                             *  ******************************************************************************/ -static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_target_operand_store(GTargetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ +    MemoryDataSize size;                    /* Taille retenue              */      GArchOperand *original;                 /* Opérande d'origine          */      /** @@ -639,12 +720,14 @@ static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorag       * par la position physique.       */ +    size = g_target_operand_get_size(operand); +      if (has_virt_addr(&operand->addr)) -        original = g_imm_operand_new_from_value(operand->size, get_virt_addr(&operand->addr)); +        original = g_imm_operand_new_from_value(size, get_virt_addr(&operand->addr));      else -        original = g_imm_operand_new_from_value(operand->size, get_phy_addr(&operand->addr)); +        original = g_imm_operand_new_from_value(size, get_phy_addr(&operand->addr)); -    result = g_arch_operand_store(original, storage, pbuf); +    result = g_object_storage_pack_object(storage, "operands", G_SERIALIZABLE_OBJECT(original), pbuf);      g_object_unref(G_OBJECT(original)); diff --git a/src/arch/operands/target.h b/src/arch/operands/target.h index 8810efa..40db610 100644 --- a/src/arch/operands/target.h +++ b/src/arch/operands/target.h @@ -35,6 +35,14 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _TargetOpFlag +{ +    TOF_STRICT = AOF_USER_FLAG(0),          /* Résolution stricte          */ + +} TargetOpFlag; + +  #define G_TYPE_TARGET_OPERAND            g_target_operand_get_type()  #define G_TARGET_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TARGET_OPERAND, GTargetOperand))  #define G_IS_TARGET_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TARGET_OPERAND)) diff --git a/src/arch/processor.c b/src/arch/processor.c index 59af6cd..56a45a4 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -35,6 +35,8 @@  #include "instruction-int.h"  #include "processor-int.h" +#include "../analysis/db/misc/rlestr.h" +#include "../analysis/storage/serialize-int.h"  #include "../common/sort.h"  #include "../core/logs.h"  #include "../glibext/chrysamarshal.h" @@ -62,6 +64,9 @@ static void g_arch_processor_class_init(GArchProcessorClass *);  /* Initialise une instance de processeur d'architecture. */  static void g_arch_processor_init(GArchProcessor *); +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_arch_processor_serializable_init(GSerializableObjectInterface *); +  /* Supprime toutes les références externes. */  static void g_arch_processor_dispose(GArchProcessor *); @@ -73,10 +78,26 @@ static GProcContext *_g_arch_processor_get_context(const GArchProcessor *); +/* ------------------ CONSERVATION DES SOUCIS DURANT LE CHARGEMENT ------------------ */ + + +/* Procède à la libération totale de la mémoire. */ +static void g_arch_processor_finalize_errors(GArchProcessor *); + +/* Charge les erreurs de chargement depuis une mémoire tampon. */ +static bool g_arch_processor_load_errors(GArchProcessor *, packed_buffer_t *); + +/* Sauvegarde les erreurs de chargement dans une mémoire tampon. */ +static bool g_arch_processor_store_errors(GArchProcessor *, packed_buffer_t *); + +  /* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ +/* Procède à la libération totale de la mémoire. */ +static void g_arch_processor_finalize_coverages(GArchProcessor *); +  /* Démarre la définition d'un nouveau groupe d'instructions. */  static void g_arch_processor_add_new_coverage(GArchProcessor *, GArchInstruction *, size_t); @@ -92,17 +113,35 @@ static void g_arch_processor_merge_coverages(GArchProcessor *, instr_coverage *,  /* Met à jour une série de groupes d'instructions. */  static void g_arch_processor_update_coverages(GArchProcessor *, instr_coverage *, bool); +/* Charge les plages de couvertures depuis une mémoire tampon. */ +static bool g_arch_processor_load_coverages(GArchProcessor *, packed_buffer_t *); + +/* Sauvegarde les plages de couvertures dans une mémoire tampon. */ +static bool g_arch_processor_store_coverages(GArchProcessor *, packed_buffer_t *); +  /* Recherche rapidement un indice d'instruction via une adresse. */  static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool, size_t *); +/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_arch_processor_load(GArchProcessor *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_arch_processor_store(GArchProcessor *, GObjectStorage *, packed_buffer_t *); + +  /* Indique le type défini pour un processeur d'architecture. */ -G_DEFINE_TYPE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_CODE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT, +                        G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_processor_serializable_init)); +  /****************************************************************************** @@ -174,6 +213,26 @@ static void g_arch_processor_init(GArchProcessor *proc)  /******************************************************************************  *                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de sérialisation.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_processor_serializable_init(GSerializableObjectInterface *iface) +{ +    iface->load = (load_serializable_object_cb)g_arch_processor_load; +    iface->store = (store_serializable_object_cb)g_arch_processor_store; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc = instance d'objet GLib à traiter.                      *  *                                                                             *  *  Description : Supprime toutes les références externes.                     * @@ -224,23 +283,12 @@ static void g_arch_processor_dispose(GArchProcessor *proc)  static void g_arch_processor_finalize(GArchProcessor *proc)  { -    size_t i;                               /* Boucle de parcours          */ -      if (proc->instructions != NULL)          free(proc->instructions); -    if (proc->errors != NULL) -    { -        for (i = 0; i < proc->error_count; i++) -            if (proc->errors[i].desc != NULL) -                free(proc->errors[i].desc); - -        free(proc->errors); +    g_arch_processor_finalize_errors(proc); -    } - -    if (proc->coverages != NULL) -        free(proc->coverages); +    g_arch_processor_finalize_coverages(proc);      G_OBJECT_CLASS(g_arch_processor_parent_class)->finalize(G_OBJECT(proc)); @@ -923,6 +971,41 @@ GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *proc, s  /******************************************************************************  *                                                                             * +*  Paramètres  : proc = architecture à manipuler.                             * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_processor_finalize_errors(GArchProcessor *proc) +{ +    size_t i;                               /* Boucle de parcours          */ +    proc_error *error;                      /* Raccourci de confort        */ + +    if (proc->errors != NULL) +    { +        for (i = 0; i < proc->error_count; i++) +        { +            error = &proc->errors[i]; + +            if (error->desc != NULL) +                free(error->desc); + +        } + +        free(proc->errors); + +    } + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc  = architecture à manipuler.                            *  *                state = nouvel état de l'accès aux erreurs relevées.         *  *                                                                             * @@ -1066,6 +1149,118 @@ bool g_arch_processor_get_error(GArchProcessor *proc, size_t index, ArchProcessi  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc = architecture concernée par la procédure.              * +*                pbuf = zone tampon à vider.                                  * +*                                                                             * +*  Description : Charge les erreurs de chargement depuis une mémoire tampon.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_processor_load_errors(GArchProcessor *proc, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ +    size_t i;                               /* Boucle de parcours          */ +    proc_error *error;                      /* Raccourci de confort        */ +    rle_string str;                         /* Chaîne à charger            */ + +    g_arch_processor_lock_errors(proc); + +    result = unpack_uleb128(&value, pbuf); +    if (!result) goto exit; + +    proc->error_count = value; + +    proc->errors = calloc(proc->error_count, sizeof(proc_error)); + +    for (i = 0; i < proc->error_count && result; i++) +    { +        error = &proc->errors[i]; + +        result = unpack_uleb128(&value, pbuf); +        if (!result) break; + +        error->type = value; + +        result = unpack_vmpa(&error->addr, pbuf); +        if (!result) break; + +        setup_empty_rle_string(&str); + +        result = unpack_rle_string(&str, pbuf); +        if (!result) break; + +        if (get_rle_string(&str) != NULL) +            error->desc = strdup(get_rle_string(&str)); + +        exit_rle_string(&str); + +    } + + exit: + +    g_arch_processor_unlock_errors(proc); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc = architecture concernée par la procédure.              * +*                pbuf = zone tampon à remplir.                                * +*                                                                             * +*  Description : Sauvegarde les erreurs de chargement dans une mémoire tampon.* +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_processor_store_errors(GArchProcessor *proc, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    size_t i;                               /* Boucle de parcours          */ +    proc_error *error;                      /* Raccourci de confort        */ +    rle_string str;                         /* Chaîne à conserver          */ + +    g_arch_processor_lock_errors(proc); + +    result = pack_uleb128((uleb128_t []){ proc->error_count }, pbuf); + +    for (i = 0; i < proc->error_count && result; i++) +    { +        error = &proc->errors[i]; + +        result = pack_uleb128((uleb128_t []){ error->type }, pbuf); +        if (!result) break; + +        result = pack_vmpa(&error->addr, pbuf); +        if (!result) break; + +        init_static_rle_string(&str, error->desc); + +        result = pack_rle_string(&str, pbuf); + +        exit_rle_string(&str); + +    } + +    g_arch_processor_unlock_errors(proc); + +    return result; + +} + +  /* ---------------------------------------------------------------------------------- */  /*                    MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES                    */ @@ -1074,6 +1269,24 @@ bool g_arch_processor_get_error(GArchProcessor *proc, size_t index, ArchProcessi  /******************************************************************************  *                                                                             * +*  Paramètres  : proc = architecture à manipuler.                             * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_processor_finalize_coverages(GArchProcessor *proc) +{ +    if (proc->coverages != NULL) +        free(proc->coverages); + +} +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc  = architecture à comléter par la procédure.            *  *                first = première instruction d'un nouveau groupe.            *  *                start = indice de cette instruction dans l'ensemble global.  * @@ -1342,6 +1555,101 @@ static void g_arch_processor_update_coverages(GArchProcessor *proc, instr_covera  /******************************************************************************  *                                                                             * +*  Paramètres  : proc = architecture concernée par la procédure.              * +*                pbuf = zone tampon à vider.                                  * +*                                                                             * +*  Description : Charge les plages de couvertures depuis une mémoire tampon.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_processor_load_coverages(GArchProcessor *proc, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ +    size_t i;                               /* Boucle de parcours          */ +    instr_coverage *coverage;               /* Raccourci de confort        */ + +    result = unpack_uleb128(&value, pbuf); +    if (!result) goto exit; + +    proc->cov_allocated = value; +    proc->cov_count = value; + +    proc->coverages = calloc(proc->cov_count, sizeof(instr_coverage)); + +    for (i = 0; i < proc->cov_count && result; i++) +    { +        coverage = &proc->coverages[i]; + +        result = unpack_mrange(&coverage->range, pbuf); +        if (!result) break; + +        result = unpack_uleb128(&value, pbuf); +        if (!result) break; + +        coverage->start = value; + +        result = unpack_uleb128(&value, pbuf); +        if (!result) break; + +        coverage->count = value; + +    } + + exit: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc = architecture concernée par la procédure.              * +*                pbuf = zone tampon à remplir.                                * +*                                                                             * +*  Description : Sauvegarde les plages de couvertures dans une mémoire tampon.* +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_processor_store_coverages(GArchProcessor *proc, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    size_t i;                               /* Boucle de parcours          */ +    instr_coverage *coverage;               /* Raccourci de confort        */ + +    result = pack_uleb128((uleb128_t []){ proc->cov_count }, pbuf); + +    for (i = 0; i < proc->error_count && result; i++) +    { +        coverage = &proc->coverages[i]; + +        result = pack_mrange(&coverage->range, pbuf); +        if (!result) break; + +        result = pack_uleb128((uleb128_t []){ coverage->start }, pbuf); +        if (!result) break; + +        result = pack_uleb128((uleb128_t []){ coverage->count }, pbuf); +        if (!result) break; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc  = processeur recensant diverses instructions.          *  *                addr  = position en mémoire ou physique à chercher.          *  *                                                                             * @@ -1580,3 +1888,86 @@ instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *pr      return result;  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                      CONSERVATION ET RECHARGEMENT DES DONNEES                      */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc    = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                * +*                                                                             * +*  Description : Charge un contenu depuis une mémoire tampon.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_processor_load(GArchProcessor *proc, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ + +    result = unpack_uleb128(&value, pbuf); +    if (!result) goto exit; + +    proc->endianness = value; + + + + + + +    if (result) +        result = g_arch_processor_load_errors(proc, pbuf); + +    if (result) +        result = g_arch_processor_load_coverages(proc, pbuf); + + exit: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc    = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_processor_store(GArchProcessor *proc, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = pack_uleb128((uleb128_t []){ proc->endianness }, pbuf); + + + + + +    if (result) +        result = g_arch_processor_store_coverages(proc, pbuf); + +    if (result) +        result = g_arch_processor_store_errors(proc, pbuf); + +    return result; + +} diff --git a/src/arch/register-int.h b/src/arch/register-int.h index a162435..f0b9af9 100644 --- a/src/arch/register-int.h +++ b/src/arch/register-int.h @@ -26,9 +26,7 @@  #include "register.h" - - -#include "operand-int.h" +#include "../analysis/storage/serialize-int.h" @@ -47,11 +45,11 @@ typedef bool (* reg_is_base_pointer_fc) (const GArchRegister *);  /* Indique si le registre correspond à esp ou similaire. */  typedef bool (* reg_is_stack_pointer_fc) (const GArchRegister *); -/* Charge un registre depuis une mémoire tampon. */ -typedef GArchRegister * (* reg_unserialize_fc) (GArchRegister *, GAsmStorage *, packed_buffer_t *); +/* Charge un contenu depuis une mémoire tampon. */ +typedef bool (* load_register_fc) (GArchRegister *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un registre dans une mémoire tampon. */ -typedef bool (* reg_serialize_fc) (const GArchRegister *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +typedef bool (* store_register_fc) (GArchRegister *, GObjectStorage *, packed_buffer_t *);  /* Représentation d'un registre (instance) */ @@ -72,8 +70,8 @@ struct _GArchRegisterClass      reg_is_base_pointer_fc is_bp;           /* Correspondance avec ebp     */      reg_is_stack_pointer_fc is_sp;          /* Correspondance avec esp     */ -    reg_unserialize_fc unserialize;         /* Chargement depuis un tampon */ -    reg_serialize_fc serialize;             /* Conservation dans un tampon */ +    load_register_fc load;                  /* Chargement depuis un tampon */ +    store_register_fc store;                /* Conservation dans un tampon */  }; diff --git a/src/arch/register.c b/src/arch/register.c index 740a06b..f487419 100644 --- a/src/arch/register.c +++ b/src/arch/register.c @@ -25,7 +25,6 @@  #include "register-int.h" -#include "storage.h" @@ -38,6 +37,9 @@ static void g_arch_register_class_init(GArchRegisterClass *);  /* Initialise une instance de registre. */  static void g_arch_register_init(GArchRegister *); +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_arch_register_serializable_init(GSerializableObjectInterface *); +  /* Supprime toutes les références externes. */  static void g_arch_register_dispose(GArchRegister *); @@ -46,14 +48,20 @@ static void g_arch_register_finalize(GArchRegister *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ +/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ + +/* Charge un contenu depuis une mémoire tampon. */ +static bool _g_arch_register_load(GArchRegister *, GObjectStorage *, packed_buffer_t *); -/* Charge un registre depuis une mémoire tampon. */ -static GArchRegister *g_arch_register_unserialize(GArchRegister *, GAsmStorage *, packed_buffer_t *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_arch_register_load(GArchRegister *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un registre dans une mémoire tampon. */ -static bool g_arch_register_serialize(const GArchRegister *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool _g_arch_register_store(GArchRegister *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_arch_register_store(GArchRegister *, GObjectStorage *, packed_buffer_t *); @@ -63,7 +71,8 @@ static bool g_arch_register_serialize(const GArchRegister *, GAsmStorage *, pack  /* Indique le type défini pour une représentation d'un registre. */ -G_DEFINE_TYPE(GArchRegister, g_arch_register, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_CODE(GArchRegister, g_arch_register, G_TYPE_OBJECT, +                        G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_register_serializable_init));  /****************************************************************************** @@ -87,8 +96,8 @@ static void g_arch_register_class_init(GArchRegisterClass *klass)      object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_register_dispose;      object->finalize = (GObjectFinalizeFunc)g_arch_register_finalize; -    klass->unserialize = (reg_unserialize_fc)g_arch_register_unserialize; -    klass->serialize = (reg_serialize_fc)g_arch_register_serialize; +    klass->load = (load_register_fc)_g_arch_register_load; +    klass->store = (store_register_fc)_g_arch_register_store;  } @@ -113,6 +122,26 @@ static void g_arch_register_init(GArchRegister *reg)  /******************************************************************************  *                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de sérialisation.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_register_serializable_init(GSerializableObjectInterface *iface) +{ +    iface->load = (load_serializable_object_cb)g_arch_register_load; +    iface->store = (store_serializable_object_cb)g_arch_register_store; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : reg = instance d'objet GLib à traiter.                       *  *                                                                             *  *  Description : Supprime toutes les références externes.                     * @@ -262,17 +291,17 @@ bool g_arch_register_is_stack_pointer(const GArchRegister *reg)  /* ---------------------------------------------------------------------------------- */ -/*                       TRANSPOSITIONS VIA CACHE DES REGISTRES                       */ +/*                      CONSERVATION ET RECHARGEMENT DES DONNEES                      */  /* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             * -*  Paramètres  : reg     = registre d'architecture à constituer.              * -*                storage = mécanisme de sauvegarde à manipuler.               * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : reg     = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                *  *                                                                             * -*  Description : Charge un registre depuis une mémoire tampon.                * +*  Description : Charge un contenu depuis une mémoire tampon.                 *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -280,11 +309,11 @@ bool g_arch_register_is_stack_pointer(const GArchRegister *reg)  *                                                                             *  ******************************************************************************/ -static GArchRegister *g_arch_register_unserialize(GArchRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool _g_arch_register_load(GArchRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf)  { -    GArchRegister *result;                  /* Instance à retourner        */ +    bool result;                            /* Bilan à retourner           */ -    result = reg; +    result = true;      return result; @@ -293,36 +322,26 @@ static GArchRegister *g_arch_register_unserialize(GArchRegister *reg, GAsmStorag  /******************************************************************************  *                                                                             * -*  Paramètres  : storage = mécanisme de sauvegarde à manipuler.               * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : reg     = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à lire.                                *  *                                                                             * -*  Description : Charge un registre depuis une mémoire tampon.                * +*  Description : Charge un contenu depuis une mémoire tampon.                 *  *                                                                             * -*  Retour      : Registre d'architecture constitué ou NULL en cas d'échec.    * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchRegister *g_arch_register_load(GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_arch_register_load(GArchRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf)  { -    GArchRegister *result;                  /* Instance à retourner        */ -    GArchRegister *dummy;                   /* Patron du type de registre  */ - -    dummy = G_ARCH_REGISTER(g_asm_storage_create_object(storage, pbuf)); - -    if (dummy != NULL) -    { -        result = G_ARCH_REGISTER_GET_CLASS(dummy)->unserialize(dummy, storage, pbuf); - -        /* Si personne ne l'a fait avant... */ -        if (result != NULL) -            g_object_unref(G_OBJECT(dummy)); +    bool result;                            /* Bilan à retourner           */ +    GArchRegisterClass *class;              /* Classe à activer            */ -    } +    class = G_ARCH_REGISTER_GET_CLASS(reg); -    else -        result = NULL; +    result = class->load(reg, storage, pbuf);      return result; @@ -331,11 +350,11 @@ GArchRegister *g_arch_register_load(GAsmStorage *storage, packed_buffer_t *pbuf)  /******************************************************************************  *                                                                             * -*  Paramètres  : reg     = registre d'architecture à consulter.               * -*                storage = mécanisme de sauvegarde à manipuler.               * +*  Paramètres  : reg     = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Sauvegarde un registre dans une mémoire tampon.              * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -343,7 +362,7 @@ GArchRegister *g_arch_register_load(GAsmStorage *storage, packed_buffer_t *pbuf)  *                                                                             *  ******************************************************************************/ -static bool g_arch_register_serialize(const GArchRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool _g_arch_register_store(GArchRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ @@ -356,11 +375,11 @@ static bool g_arch_register_serialize(const GArchRegister *reg, GAsmStorage *sto  /******************************************************************************  *                                                                             * -*  Paramètres  : reg     = registre d'architecture à consulter.               * -*                storage = mécanisme de sauvegarde à manipuler.               * +*  Paramètres  : reg     = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Sauvegarde un registre dans une mémoire tampon.              * +*  Description : Sauvegarde un contenu dans une mémoire tampon.               *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -368,14 +387,14 @@ static bool g_arch_register_serialize(const GArchRegister *reg, GAsmStorage *sto  *                                                                             *  ******************************************************************************/ -bool g_arch_register_store(const GArchRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_arch_register_store(GArchRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ +    GArchRegisterClass *class;              /* Classe à activer            */ -    result = g_asm_storage_store_object_gtype(storage, G_OBJECT(reg), pbuf); +    class = G_ARCH_REGISTER_GET_CLASS(reg); -    if (result) -        result = G_ARCH_REGISTER_GET_CLASS(reg)->serialize(reg, storage, pbuf); +    result = class->store(reg, storage, pbuf);      return result; diff --git a/src/arch/register.h b/src/arch/register.h index 36bd9d9..0265a73 100644 --- a/src/arch/register.h +++ b/src/arch/register.h @@ -71,19 +71,4 @@ bool g_arch_register_is_stack_pointer(const GArchRegister *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ - - -/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */ -typedef struct _GAsmStorage GAsmStorage; - - -/* Charge un registre depuis une mémoire tampon. */ -GArchRegister *g_arch_register_load(GAsmStorage *, packed_buffer_t *); - -/* Sauvegarde un registre dans une mémoire tampon. */ -bool g_arch_register_store(const GArchRegister *, GAsmStorage *, packed_buffer_t *); - - -  #endif  /* _ARCH_REGISTER_H */ diff --git a/src/arch/storage.c b/src/arch/storage.c index 41fa602..73521df 100644 --- a/src/arch/storage.c +++ b/src/arch/storage.c @@ -486,7 +486,7 @@ static void g_ins_caching_process_store(GInsCaching *caching, GtkStatusStack *st          instr = g_arch_processor_get_instruction(proc, i); -        caching->status = g_arch_instruction_store(instr, storage, &pbuf); +        caching->status = false;//g_arch_instruction_store__old(instr, storage, &pbuf);          if (caching->status)              caching->status = g_asm_storage_store_instruction_data(storage, &pbuf, &pos); @@ -1544,7 +1544,7 @@ GArchInstruction *g_asm_storage_get_instruction_at(GAsmStorage *storage, GBinFor                  status = g_asm_storage_load_instruction_data(storage, pbuf, target);              if (status) -                storage->collected[index] = g_arch_instruction_load(storage, format, pbuf); +                storage->collected[index] = NULL;//g_arch_instruction_load__old(storage, format, pbuf);              if (storage->collected[index] != NULL)              { diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index f353ebd..4f35ebe 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -156,6 +156,62 @@ bool store_vmpa(const vmpa2t *, const char *, bound_value **, size_t *); +/* ------------------------ DEFINITION DE POSITION AVEC BITS ------------------------ */ + + +/* Adresse mémoire ou position physique */ +typedef struct _ext_vmpa_t +{ +    vmpa2t base;                            /* Vision macroscopique        */ + +    uint8_t consumed_extra_bits;            /* Avancée supplémentaire      */ + +} ext_vmpa_t; + + +#define init_evmpa_from_vmpa(d, s)      \ +    do                                  \ +    {                                   \ +        copy_vmpa(&(d)->base, (s));     \ +        (d)->consumed_extra_bits = 0;   \ +    }                                   \ +    while (0) + +#define copy_evmpa(d, s)                                        \ +    do                                                          \ +    {                                                           \ +        copy_vmpa(&(d)->base, &(s)->base);                      \ +        (d)->consumed_extra_bits = (s)->consumed_extra_bits;    \ +    }                                                           \ +    while (0) + +#define advance_evmpa_bits(a, q)                    \ +    do                                              \ +    {                                               \ +        uint8_t __sum;                              \ +        __sum = (a)->consumed_extra_bits + q;       \ +        if (__sum > 8)                              \ +        {                                           \ +            advance_vmpa(&(a)->base, __sum / 8);    \ +            (a)->consumed_extra_bits = __sum % 8;   \ +        }                                           \ +        else                                        \ +            (a)->consumed_extra_bits = __sum;       \ +    }                                               \ +    while (0) + +#define align_evmpa_on_byte(a)              \ +    do                                      \ +    {                                       \ +        if ((a)->consumed_extra_bits > 0)   \ +        {                                   \ +            advance_vmpa(&(a)->base, 1);    \ +            (a)->consumed_extra_bits = 0;   \ +        }                                   \ +    }                                       \ +    while (0); + +  /* ------------------------ AIDES FONCTIONNELLES AUXILIAIRES ------------------------ */  | 
