diff options
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r-- | src/arch/operand.c | 232 |
1 files changed, 227 insertions, 5 deletions
diff --git a/src/arch/operand.c b/src/arch/operand.c index 66af6d2..944c34e 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -31,6 +31,7 @@ #include "operand-int.h" #include "storage.h" +#include "../common/fnv1a.h" #include "../common/sort.h" #include "../core/logs.h" #include "../glibext/singleton-int.h" @@ -55,6 +56,9 @@ static void g_arch_operand_dispose(GArchOperand *); /* Procède à la libération totale de la mémoire. */ static void g_arch_operand_finalize(GArchOperand *); +/* Compare un opérande avec un autre. */ +static int _g_arch_operand_compare(const GArchOperand *, const GArchOperand *, bool); + /* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */ @@ -67,6 +71,9 @@ static GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, static void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t); /* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint _g_arch_operand_hash(const GArchOperand *, bool); + +/* Fournit l'empreinte d'un candidat à une centralisation. */ static guint g_arch_operand_hash(const GArchOperand *); /* Détermine si deux candidats à l'unicité sont identiques. */ @@ -91,12 +98,16 @@ static bool g_arch_operand_serialize(const GArchOperand *, GAsmStorage *, packed +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'OPERANDE QUELCONQUE */ +/* ---------------------------------------------------------------------------------- */ + + /* Indique le type défini pour un opérande d'architecture. */ G_DEFINE_TYPE_WITH_CODE(GArchOperand, g_arch_operand, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_SINGLETON_CANDIDATE, g_arch_operand_singleton_interface_init)); - /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * @@ -121,6 +132,10 @@ static void g_arch_operand_class_init(GArchOperandClass *klass) operand = G_ARCH_OPERAND_CLASS(klass); + operand->compare = (operand_compare_fc)_g_arch_operand_compare; + + operand->hash = _g_arch_operand_hash; + operand->unserialize = (unserialize_operand_fc)g_arch_operand_unserialize; operand->serialize = (serialize_operand_fc)g_arch_operand_serialize; @@ -141,6 +156,11 @@ static void g_arch_operand_class_init(GArchOperandClass *klass) static void g_arch_operand_init(GArchOperand *operand) { + operand_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_ARCH_OP_EXTRA(operand); + + INIT_GOBJECT_EXTRA_LOCK(extra); } @@ -211,6 +231,38 @@ static void g_arch_operand_finalize(GArchOperand *operand) /****************************************************************************** * * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int _g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b, bool lock) +{ + int result; /* Bilan à faire remonter */ + operand_extra_data_t *ea; /* Données insérées à consulter*/ + operand_extra_data_t *eb; /* Données insérées à consulter*/ + + assert(!lock); + + ea = GET_ARCH_OP_EXTRA(a); + eb = GET_ARCH_OP_EXTRA(b); + + result = sort_unsigned_long(ea->flags, eb->flags); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : a = premier opérande à consulter. * * b = second opérande à consulter. * * * @@ -236,7 +288,7 @@ int g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b) result = sort_unsigned_long(type_a, type_b); if (result == 0) - result = G_ARCH_OPERAND_GET_CLASS(a)->compare(a, b); + result = G_ARCH_OPERAND_GET_CLASS(a)->compare(a, b, true); return result; @@ -355,6 +407,139 @@ char *g_arch_operand_build_tooltip(const GArchOperand *operand, const GLoadedBin } +/****************************************************************************** +* * +* Paramètres : operand = opérande à venir modifier. * +* flag = drapeau d'information complémentaire à planter. * +* * +* Description : Ajoute une information complémentaire à un opérande. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_operand_set_flag(GArchOperand *operand, ArchOperandFlag flag) +{ + bool result; /* Bilan à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + assert(flag <= AOF_HIGH_USER); + + extra = GET_ARCH_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = !(extra->flags & flag); + + extra->flags |= flag; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à venir modifier. * +* flag = drapeau d'information complémentaire à planter. * +* * +* Description : Retire une information complémentaire à un opérande. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_operand_unset_flag(GArchOperand *operand, ArchOperandFlag flag) +{ + bool result; /* Bilan à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + assert(flag <= AOF_HIGH_USER); + + extra = GET_ARCH_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = (extra->flags & flag); + + extra->flags &= ~flag; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à venir consulter. * +* flag = drapeau d'information à rechercher. * +* * +* Description : Détermine si un opérande possède un fanion particulier. * +* * +* Retour : Bilan de la détection. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_operand_has_flag(const GArchOperand *operand, ArchOperandFlag flag) +{ + bool result; /* Bilan à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + assert(flag <= AOF_HIGH_USER); + + extra = GET_ARCH_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = (extra->flags & flag); + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à venir consulter. * +* * +* Description : Fournit les particularités de l'opérande. * +* * +* Retour : Somme de tous les fanions associés à l'opérande. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *operand) +{ + ArchOperandFlag result; /* Fanions à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_ARCH_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = extra->flags; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* CONTROLE DU VOLUME DES INSTANCES */ @@ -430,6 +615,43 @@ static void g_arch_operand_update_inner_instances(GArchOperand *operand, GArchOp /****************************************************************************** * * * Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * +* * +* Retour : Empreinte de l'élément représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint _g_arch_operand_hash(const GArchOperand *operand, bool lock) +{ + guint result; /* Valeur à retourner */ + const char *name; /* Désignation du type d'object*/ + fnv64_t name_hash; /* Empreinte du nom */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + + assert(!lock); + + name = G_OBJECT_TYPE_NAME(G_OBJECT(operand)); + name_hash = fnv_64a_hash(name); + + result = (name_hash & 0xffffffff); + result ^= (name_hash >> 32); + + extra = GET_ARCH_OP_EXTRA(operand); + + result ^= extra->flags; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = objet dont l'instance se veut unique. * * * * Description : Fournit l'empreinte d'un candidat à une centralisation. * * * @@ -446,7 +668,7 @@ static guint g_arch_operand_hash(const GArchOperand *operand) class = G_ARCH_OPERAND_GET_CLASS(operand); - result = class->hash(operand); + result = class->hash(operand, true); return result; @@ -494,7 +716,7 @@ static gboolean g_arch_operand_is_equal(const GArchOperand *operand, const GArch static void g_arch_operand_set_read_only(GArchOperand *operand) { - operand->read_only = true; + g_arch_operand_set_flag(operand, AOF_READ_ONLY); } @@ -515,7 +737,7 @@ static bool g_arch_operand_is_read_only(GArchOperand *operand) { bool result; /* Etat à retourner */ - result = operand->read_only; + result = g_arch_operand_has_flag(operand, AOF_READ_ONLY); return result; |