diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2021-08-14 19:54:31 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2021-08-14 19:54:31 (GMT) | 
| commit | a6c0351774988094a51c9502f2a8e07633956263 (patch) | |
| tree | dcaad9d00b6ce130d9af012286899ab877cc82cb /src/arch/operands | |
| parent | 0daed1fa6212eb83b65ccd10c9f2c80bf12c6d27 (diff) | |
Improve the object padding exploitation for operands.
Diffstat (limited to 'src/arch/operands')
| -rw-r--r-- | src/arch/operands/immediate.c | 507 | ||||
| -rw-r--r-- | src/arch/operands/immediate.h | 21 | ||||
| -rw-r--r-- | src/arch/operands/proxy.c | 75 | ||||
| -rw-r--r-- | src/arch/operands/register-int.h | 45 | ||||
| -rw-r--r-- | src/arch/operands/register.c | 92 | ||||
| -rw-r--r-- | src/arch/operands/register.h | 14 | ||||
| -rw-r--r-- | src/arch/operands/target-int.h | 26 | ||||
| -rw-r--r-- | src/arch/operands/target.c | 162 | ||||
| -rw-r--r-- | src/arch/operands/target.h | 8 | 
9 files changed, 463 insertions, 487 deletions
| diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c index ec81cfe..cb4e457 100644 --- a/src/arch/operands/immediate.c +++ b/src/arch/operands/immediate.c @@ -42,9 +42,9 @@  #include "../operand-int.h"  #include "../../common/asm.h"  #include "../../common/extstr.h" +#include "../../common/sort.h"  #include "../../core/logs.h"  #include "../../format/format.h" -#include "../../glibext/objhole.h"  #include "../../gtkext/gtkblockdisplay.h" @@ -52,30 +52,24 @@  /* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */ -/* Etats particuliers d'un opérande de valeur immédiate */ -typedef enum _ImmOpFlag +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _immop_extra_data_t  { -    IOF_ZERO_PADDING_BY_DEFAULT,            /* Bourrage avec 0 par défaut ?*/ -    IOF_ZERO_PADDING,                       /* Bourrage avec 0 ?           */ +    operand_extra_data_t parent;            /* A laisser en premier        */ -} ImmOpFlag; +    MemoryDataSize size;                    /* Taille de l'opérande        */ -/* 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       */ +    /** +     * 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  */ -    gint lock;                              /* Gestion d'accès aux fanions */ +} immop_extra_data_t; -} immop_obj_extra;  /* Définition d'un opérande de valeur numérique (instance) */  struct _GImmOperand @@ -84,46 +78,30 @@ struct _GImmOperand      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 +/* 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 __SIZEOF_INT__ == __SIZEOF_LONG__ -#   define INIT_IMM_OP_EXTRA(op) op->extra.lock = 0 - -#   define GET_IMM_OP_EXTRA(op) &op->extra +#   define GET_IMM_OP_EXTRA(op) (immop_extra_data_t *)&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) +#   define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_extra_data_t)  #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 *); @@ -144,7 +122,7 @@ static void g_imm_operand_dispose(GImmOperand *);  static void g_imm_operand_finalize(GImmOperand *);  /* Compare un opérande avec un autre. */ -static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *); +static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *, bool);  /* 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]); @@ -156,7 +134,7 @@ static void g_imm_operand_print(const GImmOperand *, GBufferLine *);  static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *);  /* Fournit l'empreinte d'un candidat à une centralisation. */ -static guint g_imm_operand_hash(const GImmOperand *); +static guint g_imm_operand_hash(const GImmOperand *, bool);  /* Charge un opérande depuis une mémoire tampon. */  static bool g_imm_operand_unserialize(GImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); @@ -208,11 +186,14 @@ static void g_known_imm_operand_dispose(GKnownImmOperand *);  static void g_known_imm_operand_finalize(GKnownImmOperand *);  /* Compare un opérande avec un autre. */ -static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *); +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 opérande depuis une mémoire tampon. */  static bool g_known_imm_operand_unserialize(GKnownImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); @@ -284,13 +265,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; +  } @@ -389,7 +370,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          */ @@ -500,7 +481,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; @@ -524,8 +505,9 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)  /******************************************************************************  *                                                                             * -*  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.                           *  *                                                                             * @@ -535,80 +517,45 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)  *                                                                             *  ******************************************************************************/ -static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b) +static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b, bool lock)  {      int result;                             /* Bilan à retourner           */ -    immop_obj_extra *ea;                    /* Données insérées à modifier */ -    immop_obj_extra *eb;                    /* Données insérées à modifier */ +    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   */      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) +    if (lock)      { -        result = 1; -        goto done; +        LOCK_GOBJECT_EXTRA(ea); +        LOCK_GOBJECT_EXTRA(eb);      } -    if (a->raw < b->raw) -    { -        result = -1; -        goto done; -    } -    else if (a->raw > b->raw) -    { -        result = 1; -        goto done; -    } +    result = sort_unsigned_long(ea->size, eb->size); -    if (ea->def_display < eb->def_display) -    { -        result = -1; -        goto done;  -   } -    else if (ea->def_display > eb->def_display) -    { -        result = 1; -        goto done; -    } +    if (result == 0) +        sort_uint64_t(a->raw, b->raw); -    if (ea->display < eb->display) -    { -        result = -1; -        goto done; -    } -    else if (ea->display > eb->display) -    { -        result = 1; -        goto done; -    } +    if (result == 0) +        result = sort_unsigned_long(ea->def_display, eb->def_display); -    if (ea->flags < eb->flags) +    if (result == 0) +        result = sort_unsigned_long(ea->display, eb->display); + +    if (result == 0)      { -        result = -1; -        goto done; +        class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); +        result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);      } -    else if (ea->flags > eb->flags) + +    if (lock)      { -        result = 1; -        goto done; +        UNLOCK_GOBJECT_EXTRA(eb); +        UNLOCK_GOBJECT_EXTRA(ea);      } -    result = 0; - - done: - -    g_bit_unlock(&eb->lock, HOLE_LOCK_BIT); -    g_bit_unlock(&ea->lock, HOLE_LOCK_BIT); -      return result;  } @@ -629,15 +576,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; @@ -661,7 +608,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          */ @@ -676,7 +623,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; @@ -731,7 +678,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; @@ -773,141 +720,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);  } @@ -927,15 +752,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);  } @@ -955,15 +780,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; @@ -985,15 +810,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);  } @@ -1013,18 +838,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; @@ -1046,11 +871,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)      { @@ -1070,7 +895,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; @@ -1113,7 +938,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           */ @@ -1137,7 +962,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); @@ -1178,7 +1003,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)      { @@ -1302,7 +1127,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); @@ -1468,18 +1293,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; @@ -1502,18 +1327,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; @@ -1535,15 +1360,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);  } @@ -1563,15 +1388,15 @@ 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);  } @@ -1579,6 +1404,7 @@ void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val)  /******************************************************************************  *                                                                             *  *  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.      *  *                                                                             * @@ -1588,13 +1414,26 @@ void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val)  *                                                                             *  ******************************************************************************/ -static guint g_imm_operand_hash(const GImmOperand *operand) +static guint g_imm_operand_hash(const GImmOperand *operand, bool lock)  {      guint result;                           /* Valeur à retourner          */ +    immop_extra_data_t *extra;              /* Données insérées à modifier */ +    GArchOperandClass *class;               /* Classe parente normalisée   */ + +    extra = GET_IMM_OP_EXTRA(operand); + +    if (lock) +        LOCK_GOBJECT_EXTRA(extra); -    result = (operand->raw & 0xffffffff); +    class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); +    result = class->hash(G_ARCH_OPERAND(operand), false); + +    result ^= (operand->raw & 0xffffffff);      result ^= (operand->raw >> 32); +    if (lock) +        UNLOCK_GOBJECT_EXTRA(extra); +      return result;  } @@ -1619,7 +1458,8 @@ static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage  {      bool result;                            /* Bilan à retourner           */      GArchOperandClass *parent;              /* Classe parente à consulter  */ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ +    immop_extra_data_t *extra;              /* Données insérées à modifier */ +    uint8_t val;                            /* Champ de bits manipulé      */      parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); @@ -1632,20 +1472,23 @@ static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage      {          extra = GET_IMM_OP_EXTRA(operand); -        g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +        LOCK_GOBJECT_EXTRA(extra);          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); +        { +            result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); +            extra->def_display = val; +        }          if (result) -            result = extract_packed_buffer(pbuf, &extra->flags, sizeof(uint8_t), false); +        { +            result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); +            extra->display = val; +        } -        g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +        UNLOCK_GOBJECT_EXTRA(extra);      } @@ -1672,7 +1515,7 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto  {      bool result;                            /* Bilan à retourner           */      GArchOperandClass *parent;              /* Classe parente à consulter  */ -    immop_obj_extra *extra;                 /* Données insérées à modifier */ +    immop_extra_data_t *extra;              /* Données insérées à modifier */      parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); @@ -1685,20 +1528,17 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto      {          extra = GET_IMM_OP_EXTRA(operand); -        g_bit_lock(&extra->lock, HOLE_LOCK_BIT); +        LOCK_GOBJECT_EXTRA(extra);          result = extend_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true);          if (result) -            result = extend_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true); - -        if (result) -            result = extend_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true); +            result = extend_packed_buffer(pbuf, (uint8_t []) { extra->def_display }, sizeof(uint8_t), false);          if (result) -            result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ImmOpFlag), true); +            result = extend_packed_buffer(pbuf, (uint8_t []) { extra->display }, sizeof(uint8_t), false); -        g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); +        UNLOCK_GOBJECT_EXTRA(extra);      } @@ -1799,6 +1639,8 @@ static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass)      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->unserialize = (unserialize_operand_fc)g_known_imm_operand_unserialize;      operand->serialize = (serialize_operand_fc)g_known_imm_operand_serialize; @@ -1900,8 +1742,8 @@ static void g_known_imm_operand_finalize(GKnownImmOperand *operand)  GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)  {      GKnownImmOperand *result;               /* Remplacement à retourner    */ -    immop_obj_extra *src;                   /* Données insérées à consulter*/ -    immop_obj_extra *dest;                  /* Données insérées à modifier */ +    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); @@ -1910,11 +1752,16 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)      src = GET_IMM_OP_EXTRA(old);      dest = GET_IMM_OP_EXTRA(&result->parent); -    g_bit_lock(&src->lock, HOLE_LOCK_BIT); +    LOCK_GOBJECT_EXTRA(src); + +    *(&dest->parent) = *(&src->parent); -    *dest = *src; +    dest->size = src->size; -    g_bit_unlock(&src->lock, HOLE_LOCK_BIT); +    dest->def_display = src->def_display; +    dest->display = src->display; + +    UNLOCK_GOBJECT_EXTRA(src);      result->alt_text = strdup(alt); @@ -1925,8 +1772,9 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)  /******************************************************************************  *                                                                             * -*  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.                           *  *                                                                             * @@ -1936,17 +1784,35 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)  *                                                                             *  ******************************************************************************/ -static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b) +static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b, bool lock)  {      int result;                             /* Bilan à retourner           */ -    GArchOperandClass *class;               /* Classe parente à consulter  */ +    lockable_obj_extra_t *ea;               /* Données insérées à consulter*/ +    lockable_obj_extra_t *eb;               /* Données insérées à consulter*/ +    GArchOperandClass *class;               /* Classe parente normalisée   */ -    class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); +    ea = GET_GOBJECT_EXTRA(G_OBJECT(a), lockable_obj_extra_t); +    eb = GET_GOBJECT_EXTRA(G_OBJECT(b), lockable_obj_extra_t); + +    if (lock) +    { +        LOCK_GOBJECT_EXTRA(ea); +        LOCK_GOBJECT_EXTRA(eb); +    } -    result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b)); +    result = strcmp(a->alt_text, b->alt_text);      if (result == 0) -        result = strcmp(a->alt_text, b->alt_text); +    { +        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; @@ -1979,6 +1845,43 @@ static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLi  /******************************************************************************  *                                                                             * +*  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          */ +    lockable_obj_extra_t *extra;            /* Données insérées à consulter*/ +    GArchOperandClass *class;               /* Classe parente normalisée   */ + +    extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t); + +    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 = opérande d'assemblage à constituer.                *  *                storage = mécanisme de sauvegarde à manipuler.               *  *                format  = format binaire chargé associé à l'architecture.    * diff --git a/src/arch/operands/immediate.h b/src/arch/operands/immediate.h index e6fab96..1291962 100644 --- a/src/arch/operands/immediate.h +++ b/src/arch/operands/immediate.h @@ -39,6 +39,14 @@  /* ------------------------- 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 +60,6 @@ typedef enum _ImmOperandDisplay  } ImmOperandDisplay; -  #define IOD_LAST_VALID IOD_CHAR @@ -95,18 +102,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); diff --git a/src/arch/operands/proxy.c b/src/arch/operands/proxy.c index bf26a4f..992c481 100644 --- a/src/arch/operands/proxy.c +++ b/src/arch/operands/proxy.c @@ -44,11 +44,14 @@ static void g_proxy_operand_dispose(GProxyOperand *);  static void g_proxy_operand_finalize(GProxyOperand *);  /* Compare un opérande avec un autre. */ -static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *); +static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *, bool);  /* 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); +  /* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ @@ -98,6 +101,8 @@ 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->hash = (operand_hash_fc)g_proxy_operand_hash; +      operand->unserialize = (unserialize_operand_fc)g_proxy_operand_unserialize;      operand->serialize = (serialize_operand_fc)g_proxy_operand_serialize; @@ -190,8 +195,9 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder)  /******************************************************************************  *                                                                             * -*  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.                           *  *                                                                             * @@ -201,12 +207,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           */ +    lockable_obj_extra_t *ea;               /* Données insérées à consulter*/ +    lockable_obj_extra_t *eb;               /* Données insérées à consulter*/ +    GArchOperandClass *class;               /* Classe parente normalisée   */ + +    ea = GET_GOBJECT_EXTRA(G_OBJECT(a), lockable_obj_extra_t); +    eb = GET_GOBJECT_EXTRA(G_OBJECT(b), lockable_obj_extra_t); + +    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,6 +264,43 @@ static void g_proxy_operand_print(const GProxyOperand *operand, GBufferLine *lin  /******************************************************************************  *                                                                             * +*  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_proxy_operand_hash(const GProxyOperand *operand, bool lock) +{ +    guint result;                           /* Valeur à retourner          */ +    lockable_obj_extra_t *extra;            /* Données insérées à consulter*/ +    GArchOperandClass *class;               /* Classe parente normalisée   */ + +    extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t); + +    if (lock) +        LOCK_GOBJECT_EXTRA(extra); + +    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; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : operand = opérande à consulter.                              *  *                                                                             *  *  Description : Fournit le fournisseur représenté par l'opérande.            * 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 e457158..9c0a337 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" @@ -45,7 +48,7 @@ static void g_register_operand_dispose(GRegisterOperand *);  static void g_register_operand_finalize(GRegisterOperand *);  /* Compare un opérande avec un autre. */ -static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *); +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 *); @@ -56,7 +59,7 @@ 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 *); +static guint g_register_operand_hash(const GRegisterOperand *, bool); @@ -132,8 +135,6 @@ static void g_register_operand_init(GRegisterOperand *operand)  {      operand->reg = NULL; -    INIT_REG_OP_EXTRA(operand); -  } @@ -179,8 +180,9 @@ static void g_register_operand_finalize(GRegisterOperand *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.                           *  *                                                                             * @@ -190,12 +192,19 @@ static void g_register_operand_finalize(GRegisterOperand *operand)  *                                                                             *  ******************************************************************************/ -static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b) +static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b, bool lock)  {      int result;                             /* Bilan à retourner           */ +    GArchOperandClass *class;               /* Classe parente normalisée   */      result = g_arch_register_compare(a->reg, b->reg); +    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;  } @@ -246,63 +255,6 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande représentant un registre à mettre à jour. * -*                                                                             * -*  Description : Marque l'opérande comme étant écrit plutôt que consulté.     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_register_operand_mark_as_written(GRegisterOperand *operand) -{ -    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); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande représentant un registre à consulter.     * -*                                                                             * -*  Description : Indique le type d'accès réalisé sur l'opérande.              * -*                                                                             * -*  Retour      : Type d'accès : true en cas d'écriture, false sinon.          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool g_register_operand_is_written(const GRegisterOperand *operand) -{ -    bool result;                            /* Statut à retourner          */ -    regop_obj_extra *extra;                 /* Données insérées à modifier */ - -    extra = GET_REG_OP_EXTRA(operand); - -    g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - -    result = extra->is_written; - -    g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); - -    return result; - -} - -  /* ---------------------------------------------------------------------------------- */  /*                          CONTROLE DU VOLUME DES INSTANCES                          */ @@ -312,6 +264,7 @@ bool g_register_operand_is_written(const GRegisterOperand *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.      *  *                                                                             * @@ -321,20 +274,21 @@ bool g_register_operand_is_written(const GRegisterOperand *operand)  *                                                                             *  ******************************************************************************/ -static guint g_register_operand_hash(const GRegisterOperand *operand) +static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)  {      guint result;                           /* Valeur à retourner          */ +    GArchOperandClass *class;               /* Classe parente normalisée   */      GArchRegister *reg;                     /* Registre visé par l'opérande*/ +    class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); +    result = class->hash(G_ARCH_OPERAND(operand), false); +      reg = g_register_operand_get_register(operand); -    result = g_arch_register_hash(reg); +    result ^= g_arch_register_hash(reg);      g_object_unref(G_OBJECT(reg)); -    if (g_register_operand_is_written(operand)) -        result ^= 1; -      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..ac4cdcd 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 __SIZEOF_INT__ == __SIZEOF_LONG__ + +#   define GET_TARGET_OP_EXTRA(op) (tarop_extra_data_t *)&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..6450834 100644 --- a/src/arch/operands/target.c +++ b/src/arch/operands/target.c @@ -37,6 +37,7 @@  #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" @@ -60,7 +61,7 @@ static void g_target_operand_dispose(GTargetOperand *);  static void g_target_operand_finalize(GTargetOperand *);  /* 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 *); @@ -68,6 +69,9 @@ static void g_target_operand_print(const GTargetOperand *, GBufferLine *);  /* Construit un petit résumé concis de l'opérande. */  static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_target_operand_hash(const GTargetOperand *, bool); +  /* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ @@ -122,6 +126,8 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)      operand->print = (operand_print_fc)g_target_operand_print;      operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip; +    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; @@ -142,10 +148,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 +217,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 +229,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 +303,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 +330,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 +365,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); @@ -457,7 +468,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 +507,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,6 +594,48 @@ 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   : -                                                            * +*                                                                             * +******************************************************************************/ + +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; + +} + +  /* ---------------------------------------------------------------------------------- */  /*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */ @@ -632,6 +699,7 @@ 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)  {      bool result;                            /* Bilan à retourner           */ +    MemoryDataSize size;                    /* Taille retenue              */      GArchOperand *original;                 /* Opérande d'origine          */      /** @@ -639,10 +707,12 @@ 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); 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)) | 
