diff options
Diffstat (limited to 'src/arch/operands')
-rw-r--r-- | src/arch/operands/Makefile.am | 14 | ||||
-rw-r--r-- | src/arch/operands/feeder-int.h | 14 | ||||
-rw-r--r-- | src/arch/operands/feeder.c | 76 | ||||
-rw-r--r-- | src/arch/operands/feeder.h | 9 | ||||
-rw-r--r-- | src/arch/operands/immediate-int.h | 85 | ||||
-rw-r--r-- | src/arch/operands/immediate.c | 1052 | ||||
-rw-r--r-- | src/arch/operands/immediate.h | 46 | ||||
-rw-r--r-- | src/arch/operands/known.c | 499 | ||||
-rw-r--r-- | src/arch/operands/known.h | 59 | ||||
-rw-r--r-- | src/arch/operands/proxy.c | 161 | ||||
-rw-r--r-- | src/arch/operands/register-int.h | 45 | ||||
-rw-r--r-- | src/arch/operands/register.c | 198 | ||||
-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 | 223 | ||||
-rw-r--r-- | src/arch/operands/target.h | 8 |
16 files changed, 1338 insertions, 1191 deletions
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)) |