summaryrefslogtreecommitdiff
path: root/src/arch/operand.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r--src/arch/operand.c232
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;