summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2021-08-14 19:54:31 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2021-08-14 19:54:31 (GMT)
commita6c0351774988094a51c9502f2a8e07633956263 (patch)
treedcaad9d00b6ce130d9af012286899ab877cc82cb /src
parent0daed1fa6212eb83b65ccd10c9f2c80bf12c6d27 (diff)
Improve the object padding exploitation for operands.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/type-int.h66
-rw-r--r--src/analysis/type.c78
-rw-r--r--src/analysis/type.h2
-rw-r--r--src/analysis/types/proto.c6
-rw-r--r--src/arch/instruction-int.h80
-rw-r--r--src/arch/instruction.c74
-rw-r--r--src/arch/instruction.h2
-rw-r--r--src/arch/instructions/raw.c62
-rw-r--r--src/arch/instructions/undefined-int.h56
-rw-r--r--src/arch/instructions/undefined.c30
-rw-r--r--src/arch/operand-int.h50
-rw-r--r--src/arch/operand.c232
-rw-r--r--src/arch/operand.h29
-rw-r--r--src/arch/operands/immediate.c507
-rw-r--r--src/arch/operands/immediate.h21
-rw-r--r--src/arch/operands/proxy.c75
-rw-r--r--src/arch/operands/register-int.h45
-rw-r--r--src/arch/operands/register.c92
-rw-r--r--src/arch/operands/register.h14
-rw-r--r--src/arch/operands/target-int.h26
-rw-r--r--src/arch/operands/target.c162
-rw-r--r--src/arch/operands/target.h8
-rw-r--r--src/format/format-int.h75
-rw-r--r--src/format/format.c30
-rw-r--r--src/format/symbol-int.h60
-rw-r--r--src/format/symbol.c66
-rw-r--r--src/glibext/objhole.h49
27 files changed, 1159 insertions, 838 deletions
diff --git a/src/analysis/type-int.h b/src/analysis/type-int.h
index 6c77954..8999b19 100644
--- a/src/analysis/type-int.h
+++ b/src/analysis/type-int.h
@@ -60,27 +60,34 @@ typedef bool (* type_is_reference_fc) (const GDataType *);
/* Informations glissées dans la structure GObject de GBinSymbol */
-typedef union _type_obj_extra
+typedef struct _type_extra_data_t
{
- struct
- {
- TypeQualifier qualifiers; /* Eventuels qualificatifs */
- char ns_sep[2]; /* Séparateur d'éléments */
- TypeFlag flags; /* Propriétés du type */
+ char ns_sep[2]; /* Séparateur d'éléments */
+ TypeFlag flags; /* Propriétés du type */
- };
+ /**
+ * Afin de ne pas dépasser une taille de 31 bits, le champ de type
+ * TypeQualifier suivant est ramené à un champs de bits.
+ */
+
+ unsigned int qualifiers : 2; /* Eventuels qualificatifs */
+
+} type_extra_data_t;
+
+/* Encapsulation avec un verrou d'accès */
+typedef union _type_obj_extra_t
+{
+ type_extra_data_t data; /* Données embarquées */
+ lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */
- gint lock; /* Gestion d'accès aux fanions */
+} type_obj_extra_t;
-} type_obj_extra;
/* Description de type quelconque (instance) */
struct _GDataType
{
GObject parent; /* A laisser en premier */
- GDataType *namespace; /* Espace de noms / classe */
-
#if __SIZEOF_INT__ == __SIZEOF_LONG__
/**
@@ -90,29 +97,13 @@ struct _GDataType
* ce dernier.
*/
- type_obj_extra extra; /* Externalisation embarquée */
+ type_obj_extra_t extra; /* Externalisation embarquée */
#endif
-};
-
-/**
- * Accès aux informations éventuellement déportées.
- */
-
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
-# define INIT_DATA_TYPE_EXTRA(tp) tp->extra.lock = 0
-
-# define GET_DATA_TYPE_EXTRA(tp) &tp->extra
-
-#else
-
-# define INIT_DATA_TYPE_EXTRA(tp) INIT_GOBJECT_EXTRA(G_OBJECT(tp))
-
-# define GET_DATA_TYPE_EXTRA(tp) GET_GOBJECT_EXTRA(G_OBJECT(tp), type_obj_extra)
+ GDataType *namespace; /* Espace de noms / classe */
-#endif
+};
/* Description de type quelconque (classe) */
struct _GDataTypeClass
@@ -133,5 +124,20 @@ struct _GDataTypeClass
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_DATA_TYPE_EXTRA(tp) (type_extra_data_t *)&tp->extra
+
+#else
+
+# define GET_DATA_TYPE_EXTRA(tp) GET_GOBJECT_EXTRA(G_OBJECT(tp), type_extra_data_t)
+
+#endif
+
+
#endif /* _ANALYSIS_TYPE_INT_H */
diff --git a/src/analysis/type.c b/src/analysis/type.c
index ca14fdc..f05b9a8 100644
--- a/src/analysis/type.c
+++ b/src/analysis/type.c
@@ -111,7 +111,11 @@ static void g_data_type_class_init(GDataTypeClass *klass)
static void g_data_type_init(GDataType *type)
{
- INIT_DATA_TYPE_EXTRA(type);
+ type_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_DATA_TYPE_EXTRA(type);
+
+ INIT_GOBJECT_EXTRA_LOCK(extra);
g_data_type_set_qualifiers(type, TQF_NONE);
@@ -280,7 +284,7 @@ static bool g_data_type_load(GDataType *type, GObjectStorage *storage, packed_bu
static bool _g_data_type_store(const GDataType *type, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
result = pack_uleb128((uleb128_t []){ g_data_type_get_qualifiers(type) }, pbuf);
if (!result) goto exit;
@@ -290,7 +294,7 @@ static bool _g_data_type_store(const GDataType *type, GObjectStorage *storage, p
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extend_packed_buffer(pbuf, extra->ns_sep, 2 * sizeof(char), false);
if (!result) goto unlocking_exit;
@@ -306,7 +310,7 @@ static bool _g_data_type_store(const GDataType *type, GObjectStorage *storage, p
unlocking_exit:
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
exit:
@@ -390,7 +394,7 @@ GDataType *g_data_type_dup(const GDataType *type)
{
GDataType *result; /* Copie à retourner */
GDataTypeClass *class; /* Classe du type */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
GDataType *ns; /* Eventuel espace de noms */
bool status; /* Bilan d'un rattachement */
@@ -404,7 +408,7 @@ GDataType *g_data_type_dup(const GDataType *type)
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (extra->ns_sep[0] != '\0')
{
@@ -422,7 +426,7 @@ GDataType *g_data_type_dup(const GDataType *type)
}
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -446,7 +450,7 @@ char *g_data_type_to_string(const GDataType *type, bool include)
{
char *result; /* Chaîne à retourner */
GDataTypeClass *class; /* Classe du type */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
char *namespace; /* Groupe d'appartenance */
TypeQualifier qualifiers; /* Qualificatifs du type */
@@ -461,7 +465,7 @@ char *g_data_type_to_string(const GDataType *type, bool include)
{
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (type->namespace != NULL && g_data_type_handle_namespaces(type))
{
@@ -474,7 +478,7 @@ char *g_data_type_to_string(const GDataType *type, bool include)
}
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -509,15 +513,15 @@ char *g_data_type_to_string(const GDataType *type, bool include)
void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers)
{
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->qualifiers = qualifiers;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -537,15 +541,15 @@ void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers)
void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier)
{
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->qualifiers |= qualifier;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -565,15 +569,15 @@ void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier)
TypeQualifier g_data_type_get_qualifiers(const GDataType *type)
{
TypeQualifier result; /* Qualificatifs à renvoyer */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->qualifiers;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -597,7 +601,7 @@ TypeQualifier g_data_type_get_qualifiers(const GDataType *type)
bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char *sep)
{
bool result; /* Bilan à retourner */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
result = ((namespace == NULL && sep == NULL) || (namespace != NULL && sep != NULL && sep[0] != '\0'));
@@ -605,7 +609,7 @@ bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char
{
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (sep == NULL)
{
@@ -625,7 +629,7 @@ bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char
g_object_ref(G_OBJECT(namespace));
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -649,18 +653,18 @@ bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char
GDataType *g_data_type_get_namespace(const GDataType *type)
{
GDataType *result; /* Espace à renvoyer */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = type->namespace;
if (result != NULL)
g_object_ref(G_OBJECT(result));
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -682,11 +686,11 @@ GDataType *g_data_type_get_namespace(const GDataType *type)
char *g_data_type_get_namespace_separator(const GDataType *type)
{
char *result; /* Séparateur à retourner */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (extra->ns_sep[0] == '\0')
result = NULL;
@@ -697,7 +701,7 @@ char *g_data_type_get_namespace_separator(const GDataType *type)
else
result = strndup(extra->ns_sep, 2);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -748,15 +752,15 @@ bool g_data_type_handle_namespaces(const GDataType *type)
void g_data_type_set_flags(GDataType *type, TypeFlag flags)
{
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->flags = flags;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -776,15 +780,15 @@ void g_data_type_set_flags(GDataType *type, TypeFlag flags)
void g_data_type_add_flag(GDataType *type, TypeFlag flag)
{
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->flags |= flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -804,15 +808,15 @@ void g_data_type_add_flag(GDataType *type, TypeFlag flag)
TypeFlag g_data_type_get_flags(const GDataType *type)
{
TypeFlag result; /* Propriétés à renvoyer */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_DATA_TYPE_EXTRA(type);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->flags;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
diff --git a/src/analysis/type.h b/src/analysis/type.h
index 819af38..f5cc242 100644
--- a/src/analysis/type.h
+++ b/src/analysis/type.h
@@ -65,7 +65,7 @@ typedef enum _TypeFlag
TFL_SINGLETON = (1 << 1), /* Singleton effectif */
TFL_USER_LOW_BIT = (1 << 2), /* Premier bit libre */
- TFL_USER_HIGH_BIT = (1 << 6) /* Dernier bit libre */
+ TFL_USER_HIGH_BIT = (1 << 7) /* Dernier bit libre */
} TypeFlag;
diff --git a/src/analysis/types/proto.c b/src/analysis/types/proto.c
index aad073a..3cb074a 100644
--- a/src/analysis/types/proto.c
+++ b/src/analysis/types/proto.c
@@ -400,7 +400,7 @@ static char *g_proto_type_to_string(const GProtoType *type, bool include)
{
char *result; /* Valeur à renvoyer */
GDataType *base; /* Version d'instance parente */
- type_obj_extra *extra; /* Données insérées à modifier */
+ type_extra_data_t *extra; /* Données insérées à modifier */
char *namespace; /* Groupe d'appartenance */
size_t i; /* Boucle de parcours */
char *arg; /* Argument à décrire */
@@ -424,7 +424,7 @@ static char *g_proto_type_to_string(const GProtoType *type, bool include)
{
extra = GET_DATA_TYPE_EXTRA(base);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (base->namespace != NULL)
{
@@ -438,7 +438,7 @@ static char *g_proto_type_to_string(const GProtoType *type, bool include)
}
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 6a3ccea..9a23bf2 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -59,26 +59,42 @@ typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBuffe
typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *);
-/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _instr_obj_extra
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _instr_extra_data_t
{
- struct
- {
- itid_t uid; /* Identifiant unique du type */
+ itid_t uid; /* Identifiant unique du type */
+
+ ArchInstrFlag flags; /* Informations complémentaires*/
- ArchInstrFlag flags; /* Informations complémentaires*/
+} instr_extra_data_t;
- };
+/* Informations glissées dans la structure GObject de GArchInstruction */
+typedef union _instr_obj_extra_t
+{
+ instr_extra_data_t data; /* Données embarquées */
+ lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */
- gint lock; /* Gestion d'accès aux fanions */
+} instr_obj_extra_t;
-} instr_obj_extra;
/* Définition générique d'une instruction d'architecture (instance) */
struct _GArchInstruction
{
GObject parent; /* A laisser en premier */
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+ /**
+ * L'inclusion des informations suivantes dépend de l'architecture.
+ *
+ * Si la structure GObject possède un trou, on remplit de préférence
+ * ce dernier.
+ */
+
+ instr_obj_extra_t extra; /* Externalisation embarquée */
+
+#endif
+
mrange_t range; /* Emplacement en mémoire */
flat_array_t *operands; /* Liste des opérandes */
@@ -108,39 +124,8 @@ struct _GArchInstruction
flat_array_t *from; /* Origines des références */
flat_array_t *to; /* Instructions visées */
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
- /**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
- */
-
- instr_obj_extra extra; /* Externalisation embarquée */
-
-#endif
-
};
-/**
- * Accès aux informations éventuellement déportées.
- */
-
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
-# define INIT_ARCH_INSTR_EXTRA(ins) ins->extra.lock = 0
-
-# define GET_ARCH_INSTR_EXTRA(ins) &ins->extra
-
-#else
-
-# define INIT_ARCH_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins))
-
-# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_obj_extra)
-
-#endif
-
/* Définition générique d'une instruction d'architecture (classe) */
struct _GArchInstructionClass
{
@@ -163,6 +148,21 @@ struct _GArchInstructionClass
/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARCH_INSTR_EXTRA(ins) (instr_extra_data_t *)&ins->extra
+
+#else
+
+# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_extra_data_t)
+
+#endif
+
+
+/**
* Fournit une marge pour toutes les instructions particulières communes
* à l'ensemble des architectures (GRawInstruction, GUndefInstruction).
*/
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index cd9ccff..e0d1091 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -144,7 +144,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
static void g_arch_instruction_init(GArchInstruction *instr)
{
- INIT_ARCH_INSTR_EXTRA(instr);
+ instr_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ INIT_GOBJECT_EXTRA_LOCK(extra);
instr->operands = NULL;
@@ -286,19 +290,19 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr)
bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
- extra->flags |= flag;
+ result = !(extra->flags & flag);
- result = true;
+ extra->flags |= flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -321,19 +325,19 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
- extra->flags &= ~flag;
+ result = (extra->flags & flag);
- result = true;
+ extra->flags &= ~flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -356,17 +360,17 @@ bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & flag);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -388,27 +392,15 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl
ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
{
ArchInstrFlag result; /* Fanions à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->flags;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- /**
- * La pose du verrou a entraîné la mise à 1 du bit de poids fort de la zone
- * couverte par le champ "extra".
- *
- * Même si les fanions ne couvrent pas cet emplacement, leur stockage s'étend
- * sur 16 bits, et contient donc le fameux bit de verrouillage.
- *
- * On efface ce marqueur après-coup ici.
- */
-
- result &= ((AIF_HIGH_USER << 1) - 1);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -430,15 +422,15 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
{
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->uid = uid;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -458,15 +450,15 @@ void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
itid_t g_arch_instruction_get_unique_id(const GArchInstruction *instr)
{
itid_t result; /* Numéro à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->uid;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1681,7 +1673,7 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage
GArchOperand *op; /* Opérande à traiter */
instr_link_t link; /* Lien vers une instruction */
packed_buffer_t ins_pbuf; /* Tampon des données à écrire */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à consulter*/
result = unpack_mrange(&instr->range, pbuf);
@@ -1765,14 +1757,14 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage
{
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extract_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
if (result)
result = extract_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -1843,7 +1835,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
off64_t pos; /* Position dans le flux */
size_t kept; /* Nombre de liens conservés */
const instr_link_t *link; /* Lien vers une instruction */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à consulter*/
result = pack_mrange(&instr->range, pbuf);
@@ -1947,14 +1939,14 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
{
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extend_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
if (result)
result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 80c500b..a9d66be 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -66,7 +66,7 @@ typedef enum _ArchInstrFlag
AIF_CALL = (1 << 3), /* Instruction d'appel */
AIF_LOW_USER = (1 << AIF_USER_BIT), /* Premier bit disponible */
- AIF_HIGH_USER = (1 << 14), /* Dernier bit disponible */
+ AIF_HIGH_USER = (1 << 7), /* Dernier bit disponible */
} ArchInstrFlag;
diff --git a/src/arch/instructions/raw.c b/src/arch/instructions/raw.c
index 481dd1c..6340e46 100644
--- a/src/arch/instructions/raw.c
+++ b/src/arch/instructions/raw.c
@@ -213,17 +213,17 @@ static void g_raw_instruction_finalize(GRawInstruction *instr)
GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value)
{
GArchInstruction *result; /* Instruction à retourner */
- GImmOperand *operand; /* Octet non décodé à afficher */
+ GArchOperand *operand; /* Octet non décodé à afficher */
mrange_t range; /* Couverture de l'instruction */
result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL);
- operand = G_IMM_OPERAND(g_imm_operand_new_from_value(size, value));
- if (operand == NULL) goto grinfv_error;
+ operand = g_imm_operand_new_from_value(size, value);
+ if (operand == NULL) goto error;
- g_imm_operand_pad(operand, true);
+ g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
+ g_arch_instruction_attach_extra_operand(result, operand);
switch (size)
{
@@ -249,7 +249,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat
default:
assert(false);
- goto grinfv_error;
+ goto error;
break;
}
@@ -258,7 +258,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat
return result;
- grinfv_error:
+ error:
g_object_unref(G_OBJECT(result));
@@ -287,13 +287,15 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa
uleb128_t value; /* Valeur uleb128 à représenter*/
phys_t diff; /* Couverture de la lecture */
MemoryDataSize leb_size; /* Taille de la valeur */
- GImmOperand *operand; /* Octet non décodé à afficher */
+ GArchOperand *operand; /* Octet non décodé à afficher */
mrange_t range; /* Couverture de l'instruction */
+ result = NULL;
+
copy_vmpa(&start, addr);
if (!g_binary_content_read_uleb128(content, addr, &value))
- goto grinu_error;
+ goto error;
diff = compute_vmpa_diff(&start, addr);
@@ -305,16 +307,18 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa
init_mrange(&range, &start, diff);
g_arch_instruction_set_range(result, &range);
- operand = G_IMM_OPERAND(g_imm_operand_new_from_value(leb_size, (uint64_t)value));
- if (operand == NULL) goto grinu_error;
+ operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value);
+ if (operand == NULL) goto error;
- g_imm_operand_pad(operand, true);
+ g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
+ g_arch_instruction_attach_extra_operand(result, operand);
return result;
- grinu_error:
+ error:
+
+ g_clear_object(&result);
return NULL;
@@ -341,13 +345,15 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa
uleb128_t value; /* Valeur uleb128 à représenter*/
phys_t diff; /* Couverture de la lecture */
MemoryDataSize leb_size; /* Taille de la valeur */
- GImmOperand *operand; /* Octet non décodé à afficher */
+ GArchOperand *operand; /* Octet non décodé à afficher */
mrange_t range; /* Couverture de l'instruction */
+ result = NULL;
+
copy_vmpa(&start, addr);
if (!g_binary_content_read_uleb128(content, addr, &value))
- goto grins_error;
+ goto error;
diff = compute_vmpa_diff(&start, addr);
@@ -359,16 +365,18 @@ GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa
init_mrange(&range, &start, diff);
g_arch_instruction_set_range(result, &range);
- operand = G_IMM_OPERAND(g_imm_operand_new_from_value(leb_size, (uint64_t)value));
- if (operand == NULL) goto grins_error;
+ operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value);
+ if (operand == NULL) goto error;
- g_imm_operand_pad(operand, true);
+ g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
+ g_arch_instruction_attach_extra_operand(result, operand);
return result;
- grins_error:
+ error:
+
+ g_clear_object(&result);
return NULL;
@@ -396,7 +404,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory
GArchInstruction *result; /* Instruction à retourner */
vmpa2t old; /* Sauvegarde de la position */
size_t i; /* Boucle de parcours */
- GImmOperand *operand; /* Octet non décodé à afficher */
+ GArchOperand *operand; /* Octet non décodé à afficher */
mrange_t range; /* Couverture de l'instruction */
/* Par soucis de cohérence */
@@ -408,12 +416,12 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory
for (i = 0; i < count; i++)
{
- operand = G_IMM_OPERAND(g_imm_operand_new_from_data(size, content, addr, endian));
- if (operand == NULL) goto grina_error;
+ operand = g_imm_operand_new_from_data(size, content, addr, endian);
+ if (operand == NULL) goto error;
- g_imm_operand_pad(operand, true);
+ g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, G_ARCH_OPERAND(operand));
+ g_arch_instruction_attach_extra_operand(result, operand);
}
@@ -423,7 +431,7 @@ GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, Memory
return result;
- grina_error:
+ error:
g_object_unref(G_OBJECT(result));
diff --git a/src/arch/instructions/undefined-int.h b/src/arch/instructions/undefined-int.h
index 8a648cf..491ec31 100644
--- a/src/arch/instructions/undefined-int.h
+++ b/src/arch/instructions/undefined-int.h
@@ -32,63 +32,57 @@
/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _undef_obj_extra
+typedef struct _undef_extra_data_t
{
- struct
- {
- InstrExpectedBehavior behavior; /* Conséquences réelles */
+ /**
+ * Le champ uid de la structure parente attendue conduit à une taille
+ * alignée sur 2 octets, donc à une taille totale de 4 octets ce qui
+ * représente la limite maximale de taille supportée.
+ *
+ * Pour 3 octets à la base, qui devraient laisser 8 - 1 octets disponbibles
+ * en incluant le bit de verrouillage.
+ *
+ * On reproduit donc la structure instr_extra_data_t ici, en basculant
+ * l'énumération InstrExpectedBehavior en champ de bits.
+ */
- };
+ itid_t uid; /* Identifiant unique du type */
+ ArchInstrFlag flags; /* Informations complémentaires*/
- gint lock; /* Gestion d'accès aux fanions */
+ unsigned int behavior : 2; /* Conséquences réelles */
+
+} undef_extra_data_t;
-} undef_obj_extra;
/* Définition générique d'une instruction au comportement non défini (instance) */
struct _GUndefInstruction
{
GArchInstruction parent; /* A laisser en premier */
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
- /**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
- */
-
- undef_obj_extra extra; /* Externalisation embarquée */
+};
-#endif
+/* Définition générique d'une instruction au comportement non défini (classe) */
+struct _GUndefInstructionClass
+{
+ GArchInstructionClass parent; /* A laisser en premier */
};
+
/**
* Accès aux informations éventuellement déportées.
*/
#if __SIZEOF_INT__ == __SIZEOF_LONG__
-# define INIT_UNDEF_INSTR_EXTRA(ins) ins->extra.lock = 0
-
-# define GET_UNDEF_INSTR_EXTRA(ins) &ins->extra
+# define GET_UNDEF_INSTR_EXTRA(ins) (undef_extra_data_t *)&ins->extra
#else
-# define INIT_UNDEF_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins))
-
-# define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_obj_extra)
+# define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_extra_data_t)
#endif
-/* Définition générique d'une instruction au comportement non défini (classe) */
-struct _GUndefInstructionClass
-{
- GArchInstructionClass parent; /* A laisser en premier */
-
-};
-
#endif /* _ARCH_INSTRUCTIONS_UNDEFINED_INT_H */
diff --git a/src/arch/instructions/undefined.c b/src/arch/instructions/undefined.c
index 880e338..663a9eb 100644
--- a/src/arch/instructions/undefined.c
+++ b/src/arch/instructions/undefined.c
@@ -132,7 +132,7 @@ static void g_undef_instruction_class_init(GUndefInstructionClass *klass)
static void g_undef_instruction_init(GUndefInstruction *instr)
{
- INIT_ARCH_INSTR_EXTRA(instr);
+ GET_UNDEF_INSTR_EXTRA(instr)->behavior = IEB_UNDEFINED;
}
@@ -190,7 +190,7 @@ static void g_undef_instruction_finalize(GUndefInstruction *instr)
GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior behavior)
{
GArchInstruction *result; /* Instruction à retourner */
- undef_obj_extra *extra; /* Données insérées à modifier */
+ undef_extra_data_t *extra; /* Données insérées à modifier */
result = g_object_new(G_TYPE_UNDEF_INSTRUCTION, NULL);
@@ -241,7 +241,7 @@ static const char *g_undef_instruction_get_encoding(const GUndefInstruction *ins
const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr)
{
const char *result; /* Désignation à retourner */
- undef_obj_extra *extra; /* Données insérées à consulter*/
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_UNDEF_INSTR_EXTRA(instr);
@@ -300,7 +300,8 @@ static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorag
{
bool result; /* Bilan à retourner */
GArchInstructionClass *parent; /* Classe parente à consulter */
- undef_obj_extra *extra; /* Données insérées à modifier */
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
+ uint8_t val; /* Champ de bits manipulé */
parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
@@ -310,7 +311,12 @@ static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorag
{
extra = GET_UNDEF_INSTR_EXTRA(instr);
- result = extract_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true);
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
+ extra->behavior = val;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -337,7 +343,7 @@ static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage
{
bool result; /* Bilan à retourner */
GArchInstructionClass *parent; /* Classe parente à consulter */
- undef_obj_extra *extra; /* Données insérées à consulter*/
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
@@ -347,7 +353,11 @@ static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage
{
extra = GET_UNDEF_INSTR_EXTRA(instr);
- result = extend_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true);
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extend_packed_buffer(pbuf, (uint8_t []){ extra->behavior }, sizeof(uint8_t), false);
+
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -417,12 +427,16 @@ static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *lin
InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *instr)
{
InstrExpectedBehavior result; /* Comportement à retourner */
- undef_obj_extra *extra; /* Données insérées à consulter*/
+ undef_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_UNDEF_INSTR_EXTRA(instr);
+ LOCK_GOBJECT_EXTRA(extra);
+
result = extra->behavior;
+ UNLOCK_GOBJECT_EXTRA(extra);
+
return result;
}
diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h
index ca5204c..c348654 100644
--- a/src/arch/operand-int.h
+++ b/src/arch/operand-int.h
@@ -26,11 +26,12 @@
#include "operand.h"
+#include "../glibext/objhole.h"
/* Compare un opérande avec un autre. */
-typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *);
+typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *, bool);
/* Détermine le chemin conduisant à un opérande interne. */
typedef char * (* find_inner_operand_fc) (const GArchOperand *, const GArchOperand *);
@@ -51,7 +52,7 @@ typedef GArchOperand ** (* operand_list_inners_fc) (const GArchOperand *, size_t
typedef void (* operand_update_inners_fc) (GArchOperand *, GArchOperand **, size_t);
/* Fournit l'empreinte d'un candidat à une centralisation. */
-typedef guint (* operand_hash_fc) (const GArchOperand *);
+typedef guint (* operand_hash_fc) (const GArchOperand *, bool);
/* Charge un opérande depuis une mémoire tampon. */
typedef bool (* unserialize_operand_fc) (GArchOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
@@ -60,15 +61,41 @@ typedef bool (* unserialize_operand_fc) (GArchOperand *, GAsmStorage *, GBinForm
typedef bool (* serialize_operand_fc) (const GArchOperand *, GAsmStorage *, packed_buffer_t *);
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _operand_extra_data_t
+{
+ ArchOperandFlag flags; /* Informations diverses */
+
+} operand_extra_data_t;
+
+/* Encapsulation avec un verrou d'accès */
+typedef union _operand_obj_extra_t
+{
+ operand_extra_data_t data; /* Données embarquées */
+ lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */
+
+} operand_obj_extra_t;
+
+
/* Définition générique d'un opérande d'architecture (instance) */
struct _GArchOperand
{
GObject parent; /* A laisser en premier */
- bool read_only; /* Verrouillage du contenu */
+#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.
+ */
+ operand_obj_extra_t extra; /* Externalisation embarquée */
+
+#endif
+
+};
/* Définition générique d'un opérande d'architecture (classe) */
struct _GArchOperandClass
@@ -92,5 +119,20 @@ struct _GArchOperandClass
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARCH_OP_EXTRA(op) (operand_extra_data_t *)&op->extra
+
+#else
+
+# define GET_ARCH_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), operand_extra_data_t)
+
+#endif
+
+
#endif /* _ARCH_OPERAND_INT_H */
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;
diff --git a/src/arch/operand.h b/src/arch/operand.h
index 9e1b5a8..f8d2536 100644
--- a/src/arch/operand.h
+++ b/src/arch/operand.h
@@ -41,6 +41,23 @@
typedef struct _GLoadedBinary GLoadedBinary;
+/* Indications supplémentaires liées aux opérandes */
+
+#define AOF_USER_BIT 1
+
+typedef enum _ArchOperandFlag
+{
+ AOF_NONE = (0 << 0), /* Aucune propriété */
+ AOF_READ_ONLY = (1 << 0), /* Indication de nature */
+
+ AOF_LOW_USER = (1 << AOF_USER_BIT), /* Premier bit disponible */
+ AOF_HIGH_USER = (1 << 7), /* Dernier bit disponible */
+
+} ArchOperandFlag;
+
+#define AOF_USER_FLAG(n) (1 << (AOF_USER_BIT + n))
+
+
#define G_TYPE_ARCH_OPERAND g_arch_operand_get_type()
#define G_ARCH_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARCH_OPERAND, GArchOperand))
#define G_IS_ARCH_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARCH_OPERAND))
@@ -74,6 +91,18 @@ void g_arch_operand_print(const GArchOperand *, GBufferLine *);
/* Construit un petit résumé concis de l'opérande. */
char *g_arch_operand_build_tooltip(const GArchOperand *, const GLoadedBinary *);
+/* Ajoute une information complémentaire à un opérande. */
+bool g_arch_operand_set_flag(GArchOperand *, ArchOperandFlag);
+
+/* Retire une information complémentaire à un opérande. */
+bool g_arch_operand_unset_flag(GArchOperand *, ArchOperandFlag);
+
+/* Détermine si un opérande possède un fanion particulier. */
+bool g_arch_operand_has_flag(const GArchOperand *, ArchOperandFlag);
+
+/* Fournit les particularités de l'opérande. */
+ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *);
+
/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c
index ec81cfe..cb4e457 100644
--- a/src/arch/operands/immediate.c
+++ b/src/arch/operands/immediate.c
@@ -42,9 +42,9 @@
#include "../operand-int.h"
#include "../../common/asm.h"
#include "../../common/extstr.h"
+#include "../../common/sort.h"
#include "../../core/logs.h"
#include "../../format/format.h"
-#include "../../glibext/objhole.h"
#include "../../gtkext/gtkblockdisplay.h"
@@ -52,30 +52,24 @@
/* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */
-/* Etats particuliers d'un opérande de valeur immédiate */
-typedef enum _ImmOpFlag
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _immop_extra_data_t
{
- IOF_ZERO_PADDING_BY_DEFAULT, /* Bourrage avec 0 par défaut ?*/
- IOF_ZERO_PADDING, /* Bourrage avec 0 ? */
+ operand_extra_data_t parent; /* A laisser en premier */
-} ImmOpFlag;
+ MemoryDataSize size; /* Taille de l'opérande */
-/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _immop_obj_extra
-{
- struct
- {
- MemoryDataSize size; /* Taille de l'opérande */
-
- ImmOperandDisplay def_display; /* Type par défaut d'affichage */
- ImmOperandDisplay display; /* Format général d'affichage */
- ImmOpFlag flags; /* Informations diverses */
+ /**
+ * Les deux éléments suivants sont de type ImmOperandDisplay ;
+ * leur espace de conservation est réduit au maximum afin d'éviter
+ * un recouvrement .
+ */
- };
+ unsigned int def_display : 3; /* Type par défaut d'affichage */
+ unsigned int display : 3; /* Format général d'affichage */
- gint lock; /* Gestion d'accès aux fanions */
+} immop_extra_data_t;
-} immop_obj_extra;
/* Définition d'un opérande de valeur numérique (instance) */
struct _GImmOperand
@@ -84,46 +78,30 @@ struct _GImmOperand
uint64_t raw; /* Valeur transtypée */
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
- /**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
- */
-
- immop_obj_extra extra; /* Externalisation embarquée */
+};
-#endif
+/* Définition d'un opérande de valeur numérique (classe) */
+struct _GImmOperandClass
+{
+ GArchOperandClass parent; /* Classe parente */
};
+
/**
* Accès aux informations éventuellement déportées.
*/
#if __SIZEOF_INT__ == __SIZEOF_LONG__
-# define INIT_IMM_OP_EXTRA(op) op->extra.lock = 0
-
-# define GET_IMM_OP_EXTRA(op) &op->extra
+# define GET_IMM_OP_EXTRA(op) (immop_extra_data_t *)&op->extra
#else
-# define INIT_IMM_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op))
-
-# define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_obj_extra)
+# define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_extra_data_t)
#endif
-/* Définition d'un opérande de valeur numérique (classe) */
-struct _GImmOperandClass
-{
- GArchOperandClass parent; /* Classe parente */
-
-};
-
/* Initialise la classe des opérandes de valeur immédiate. */
static void g_imm_operand_class_init(GImmOperandClass *);
@@ -144,7 +122,7 @@ static void g_imm_operand_dispose(GImmOperand *);
static void g_imm_operand_finalize(GImmOperand *);
/* Compare un opérande avec un autre. */
-static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *);
+static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *, bool);
/* Construit la chaîne de caractères correspondant à l'opérande. */
static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]);
@@ -156,7 +134,7 @@ static void g_imm_operand_print(const GImmOperand *, GBufferLine *);
static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *);
/* Fournit l'empreinte d'un candidat à une centralisation. */
-static guint g_imm_operand_hash(const GImmOperand *);
+static guint g_imm_operand_hash(const GImmOperand *, bool);
/* Charge un opérande depuis une mémoire tampon. */
static bool g_imm_operand_unserialize(GImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
@@ -208,11 +186,14 @@ static void g_known_imm_operand_dispose(GKnownImmOperand *);
static void g_known_imm_operand_finalize(GKnownImmOperand *);
/* Compare un opérande avec un autre. */
-static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *);
+static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_known_imm_operand_print(const GKnownImmOperand *, GBufferLine *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_known_imm_operand_hash(const GKnownImmOperand *, bool);
+
/* Charge un opérande depuis une mémoire tampon. */
static bool g_known_imm_operand_unserialize(GKnownImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
@@ -284,13 +265,13 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)
static void g_imm_operand_init(GImmOperand *operand)
{
- operand->raw = 0;
-
- INIT_IMM_OP_EXTRA(operand);
+ GET_IMM_OP_EXTRA(operand)->size = MDS_UNDEFINED;
GET_IMM_OP_EXTRA(operand)->def_display = IOD_HEX;
GET_IMM_OP_EXTRA(operand)->display = IOD_COUNT;
+ operand->raw = 0;
+
}
@@ -389,7 +370,7 @@ static void g_imm_operand_finalize(GImmOperand *operand)
GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian)
{
GImmOperand *result; /* Opérande à retourner */
- immop_obj_extra *extra; /* Données insérées à modifier */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
uint8_t uval8; /* Valeur sur 8 bits */
uint16_t uval16; /* Valeur sur 16 bits */
uint32_t uval32; /* Valeur sur 32 bits */
@@ -500,7 +481,7 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten
GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
{
GImmOperand *result; /* Opérande à retourner */
- immop_obj_extra *extra; /* Données insérées à modifier */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
if (size == MDS_UNDEFINED)
result = NULL;
@@ -524,8 +505,9 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Compare un opérande avec un autre. *
* *
@@ -535,80 +517,45 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
* *
******************************************************************************/
-static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b)
+static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b, bool lock)
{
int result; /* Bilan à retourner */
- immop_obj_extra *ea; /* Données insérées à modifier */
- immop_obj_extra *eb; /* Données insérées à modifier */
+ immop_extra_data_t *ea; /* Données insérées à modifier */
+ immop_extra_data_t *eb; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
ea = GET_IMM_OP_EXTRA(a);
eb = GET_IMM_OP_EXTRA(b);
- g_bit_lock(&ea->lock, HOLE_LOCK_BIT);
- g_bit_lock(&eb->lock, HOLE_LOCK_BIT);
-
- if (ea->size < eb->size)
- {
- result = -1;
- goto done;
- }
- else if (ea->size > eb->size)
+ if (lock)
{
- result = 1;
- goto done;
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
}
- if (a->raw < b->raw)
- {
- result = -1;
- goto done;
- }
- else if (a->raw > b->raw)
- {
- result = 1;
- goto done;
- }
+ result = sort_unsigned_long(ea->size, eb->size);
- if (ea->def_display < eb->def_display)
- {
- result = -1;
- goto done;
- }
- else if (ea->def_display > eb->def_display)
- {
- result = 1;
- goto done;
- }
+ if (result == 0)
+ sort_uint64_t(a->raw, b->raw);
- if (ea->display < eb->display)
- {
- result = -1;
- goto done;
- }
- else if (ea->display > eb->display)
- {
- result = 1;
- goto done;
- }
+ if (result == 0)
+ result = sort_unsigned_long(ea->def_display, eb->def_display);
- if (ea->flags < eb->flags)
+ if (result == 0)
+ result = sort_unsigned_long(ea->display, eb->display);
+
+ if (result == 0)
{
- result = -1;
- goto done;
+ class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
}
- else if (ea->flags > eb->flags)
+
+ if (lock)
{
- result = 1;
- goto done;
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
}
- result = 0;
-
- done:
-
- g_bit_unlock(&eb->lock, HOLE_LOCK_BIT);
- g_bit_unlock(&ea->lock, HOLE_LOCK_BIT);
-
return result;
}
@@ -629,15 +576,15 @@ static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b)
MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
{
MemoryDataSize result; /* Taille à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->size;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -661,7 +608,7 @@ MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...)
{
bool result; /* Bilan à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
va_list ap; /* Liste des compléments */
uint8_t *uval8; /* Valeur sur 8 bits */
uint16_t *uval16; /* Valeur sur 16 bits */
@@ -676,7 +623,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (extra->size != size)
goto exit;
@@ -731,7 +678,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..
exit:
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -773,141 +720,19 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand)
void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
assert(size != MDS_UNDEFINED);
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->size = size;
operand->raw = value;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = structure dont le contenu est à consulter. *
-* *
-* Description : Indique si une valeur est complétée par des zéros par défaut.*
-* *
-* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_imm_operand_get_default_padding(const GImmOperand *operand)
-{
- bool result; /* Statut à retourner */
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = (extra->flags & IOF_ZERO_PADDING_BY_DEFAULT);
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] *
-* state = true si des zéro sont à ajouter, false sinon. *
-* *
-* Description : Précise si des zéro doivent compléter l'affichage ou non. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_imm_operand_set_default_padding(GImmOperand *operand, bool state)
-{
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- if (state)
- extra->flags |= IOF_ZERO_PADDING_BY_DEFAULT;
- else
- extra->flags &= ~IOF_ZERO_PADDING_BY_DEFAULT;
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] *
-* state = true si des zéro sont à ajouter, false sinon. *
-* *
-* Description : Précise si des zéro doivent compléter l'affichage ou non. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_imm_operand_pad(GImmOperand *operand, bool state)
-{
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- if (state)
- extra->flags |= (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- else
- extra->flags &= ~(IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = structure dont le contenu est à consulter. *
-* *
-* Description : Indique si une valeur est complétée par des zéros. *
-* *
-* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_imm_operand_does_padding(const GImmOperand *operand)
-{
- bool result; /* Statut à retourner */
- immop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_IMM_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING));
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- return result;
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -927,15 +752,15 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)
void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->def_display = display;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -955,15 +780,15 @@ void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay d
ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
{
ImmOperandDisplay result; /* Affichage à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->def_display;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -985,15 +810,15 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)
void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->display = display;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -1013,18 +838,18 @@ void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)
ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)
{
ImmOperandDisplay result; /* Affichage à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
if (extra->display != IOD_COUNT)
result = extra->display;
else
result = extra->def_display;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1046,11 +871,11 @@ ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand)
bool g_imm_operand_is_negative(const GImmOperand *operand)
{
bool result; /* Bilan à renvoyer */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
switch (extra->size)
{
@@ -1070,7 +895,7 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
break;
}
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1113,7 +938,7 @@ bool g_imm_operand_is_null(const GImmOperand *operand)
static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE])
{
size_t result; /* Longueur à retourner */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
unsigned int range; /* Catégorie de la taille */
const char *prefix; /* Entrée en matière */
const char *suffix; /* Sortie de matière */
@@ -1137,7 +962,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ //LOCK_GOBJECT_EXTRA(extra);
range = MDS_RANGE(extra->size);
@@ -1178,7 +1003,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
/* Drapeau de remplissage ? */
- do_padding = (extra->flags & (IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING));
+ do_padding = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
if (do_padding)
{
@@ -1302,7 +1127,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis
}
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ //UNLOCK_GOBJECT_EXTRA(extra);
assert(result > 0);
@@ -1468,18 +1293,18 @@ static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoad
bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos)
{
bool result; /* Bilan à renvoyer */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = !MDS_IS_SIGNED(extra->size);
if (result)
*pos = operand->raw;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1502,18 +1327,18 @@ bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos)
bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr)
{
bool result; /* Bilan à renvoyer */
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = !MDS_IS_SIGNED(extra->size);
if (result)
*addr = operand->raw;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -1535,15 +1360,15 @@ bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr)
void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
*val = operand->raw;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -1563,15 +1388,15 @@ void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val)
void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val)
{
- immop_obj_extra *extra; /* Données insérées à consulter*/
+ immop_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
*val = operand->raw;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -1579,6 +1404,7 @@ void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val)
/******************************************************************************
* *
* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
@@ -1588,13 +1414,26 @@ void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val)
* *
******************************************************************************/
-static guint g_imm_operand_hash(const GImmOperand *operand)
+static guint g_imm_operand_hash(const GImmOperand *operand, bool lock)
{
guint result; /* Valeur à retourner */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_IMM_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
- result = (operand->raw & 0xffffffff);
+ class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= (operand->raw & 0xffffffff);
result ^= (operand->raw >> 32);
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
return result;
}
@@ -1619,7 +1458,8 @@ static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
- immop_obj_extra *extra; /* Données insérées à modifier */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
+ uint8_t val; /* Champ de bits manipulé */
parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
@@ -1632,20 +1472,23 @@ static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage
{
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extract_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true);
if (result)
- result = extract_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true);
-
- if (result)
- result = extract_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true);
+ {
+ result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
+ extra->def_display = val;
+ }
if (result)
- result = extract_packed_buffer(pbuf, &extra->flags, sizeof(uint8_t), false);
+ {
+ result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
+ extra->display = val;
+ }
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -1672,7 +1515,7 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
- immop_obj_extra *extra; /* Données insérées à modifier */
+ immop_extra_data_t *extra; /* Données insérées à modifier */
parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class);
@@ -1685,20 +1528,17 @@ static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *sto
{
extra = GET_IMM_OP_EXTRA(operand);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extend_packed_buffer(pbuf, &extra->size, sizeof(MemoryDataSize), true);
if (result)
- result = extend_packed_buffer(pbuf, &extra->def_display, sizeof(ImmOperandDisplay), true);
-
- if (result)
- result = extend_packed_buffer(pbuf, &extra->display, sizeof(ImmOperandDisplay), true);
+ result = extend_packed_buffer(pbuf, (uint8_t []) { extra->def_display }, sizeof(uint8_t), false);
if (result)
- result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ImmOpFlag), true);
+ result = extend_packed_buffer(pbuf, (uint8_t []) { extra->display }, sizeof(uint8_t), false);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -1799,6 +1639,8 @@ static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass)
operand->compare = (operand_compare_fc)g_known_imm_operand_compare;
operand->print = (operand_print_fc)g_known_imm_operand_print;
+ operand->hash = (operand_hash_fc)g_known_imm_operand_hash;
+
operand->unserialize = (unserialize_operand_fc)g_known_imm_operand_unserialize;
operand->serialize = (serialize_operand_fc)g_known_imm_operand_serialize;
@@ -1900,8 +1742,8 @@ static void g_known_imm_operand_finalize(GKnownImmOperand *operand)
GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)
{
GKnownImmOperand *result; /* Remplacement à retourner */
- immop_obj_extra *src; /* Données insérées à consulter*/
- immop_obj_extra *dest; /* Données insérées à modifier */
+ immop_extra_data_t *src; /* Données insérées à consulter*/
+ immop_extra_data_t *dest; /* Données insérées à modifier */
result = g_object_new(G_TYPE_KNOWN_IMM_OPERAND, NULL);
@@ -1910,11 +1752,16 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)
src = GET_IMM_OP_EXTRA(old);
dest = GET_IMM_OP_EXTRA(&result->parent);
- g_bit_lock(&src->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(src);
+
+ *(&dest->parent) = *(&src->parent);
- *dest = *src;
+ dest->size = src->size;
- g_bit_unlock(&src->lock, HOLE_LOCK_BIT);
+ dest->def_display = src->def_display;
+ dest->display = src->display;
+
+ UNLOCK_GOBJECT_EXTRA(src);
result->alt_text = strdup(alt);
@@ -1925,8 +1772,9 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Compare un opérande avec un autre. *
* *
@@ -1936,17 +1784,35 @@ GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt)
* *
******************************************************************************/
-static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b)
+static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b, bool lock)
{
int result; /* Bilan à retourner */
- GArchOperandClass *class; /* Classe parente à consulter */
+ lockable_obj_extra_t *ea; /* Données insérées à consulter*/
+ lockable_obj_extra_t *eb; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
- class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+ ea = GET_GOBJECT_EXTRA(G_OBJECT(a), lockable_obj_extra_t);
+ eb = GET_GOBJECT_EXTRA(G_OBJECT(b), lockable_obj_extra_t);
+
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
- result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b));
+ result = strcmp(a->alt_text, b->alt_text);
if (result == 0)
- result = strcmp(a->alt_text, b->alt_text);
+ {
+ class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
+
+ if (lock)
+ {
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
+ }
return result;
@@ -1979,6 +1845,43 @@ static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLi
/******************************************************************************
* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint g_known_imm_operand_hash(const GKnownImmOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ lockable_obj_extra_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= g_str_hash(operand->alt_text);
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = opérande d'assemblage à constituer. *
* storage = mécanisme de sauvegarde à manipuler. *
* format = format binaire chargé associé à l'architecture. *
diff --git a/src/arch/operands/immediate.h b/src/arch/operands/immediate.h
index e6fab96..1291962 100644
--- a/src/arch/operands/immediate.h
+++ b/src/arch/operands/immediate.h
@@ -39,6 +39,14 @@
/* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _ImmOpFlag
+{
+ IOF_ZERO_PADDING_BY_DEFAULT = AOF_USER_FLAG(0), /* Bourrage avec 0 par défaut ?*/
+ IOF_ZERO_PADDING = AOF_USER_FLAG(1), /* Bourrage avec 0 ? */
+
+} ImmOpFlag;
+
/* Grande ligne d'un format d'affichage */
typedef enum _ImmOperandDisplay
{
@@ -52,7 +60,6 @@ typedef enum _ImmOperandDisplay
} ImmOperandDisplay;
-
#define IOD_LAST_VALID IOD_CHAR
@@ -95,18 +102,6 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *);
/* Définit la nouvelle valeur de l'opérande à une valeur. */
void g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t);
-/* Indique si une valeur est complétée par des zéros par défaut. */
-bool g_imm_operand_get_default_padding(const GImmOperand *);
-
-/* Précise si des zéro doivent compléter l'affichage ou non. */
-void g_imm_operand_set_default_padding(GImmOperand *, bool);
-
-/* Précise si des zéro doivent compléter l'affichage ou non. */
-void g_imm_operand_pad(GImmOperand *, bool);
-
-/* Indique si une valeur est complétée par des zéros. */
-bool g_imm_operand_does_padding(const GImmOperand *);
-
/* Définit le format textuel par défaut de la valeur. */
void g_imm_operand_set_default_display(GImmOperand *, ImmOperandDisplay);
diff --git a/src/arch/operands/proxy.c b/src/arch/operands/proxy.c
index bf26a4f..992c481 100644
--- a/src/arch/operands/proxy.c
+++ b/src/arch/operands/proxy.c
@@ -44,11 +44,14 @@ static void g_proxy_operand_dispose(GProxyOperand *);
static void g_proxy_operand_finalize(GProxyOperand *);
/* Compare un opérande avec un autre. */
-static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *);
+static int g_proxy_operand_compare(const GProxyOperand *, const GProxyOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_proxy_operand_print(const GProxyOperand *, GBufferLine *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_proxy_operand_hash(const GProxyOperand *, bool);
+
/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
@@ -98,6 +101,8 @@ static void g_proxy_operand_class_init(GProxyOperandClass *klass)
operand->compare = (operand_compare_fc)g_proxy_operand_compare;
operand->print = (operand_print_fc)g_proxy_operand_print;
+ operand->hash = (operand_hash_fc)g_proxy_operand_hash;
+
operand->unserialize = (unserialize_operand_fc)g_proxy_operand_unserialize;
operand->serialize = (serialize_operand_fc)g_proxy_operand_serialize;
@@ -190,8 +195,9 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Compare un opérande avec un autre. *
* *
@@ -201,12 +207,36 @@ GArchOperand *g_proxy_operand_new(GProxyFeeder *feeder)
* *
******************************************************************************/
-static int g_proxy_operand_compare(const GProxyOperand *a, const GProxyOperand *b)
+static int g_proxy_operand_compare(const GProxyOperand *a, const GProxyOperand *b, bool lock)
{
int result; /* Bilan à retourner */
+ lockable_obj_extra_t *ea; /* Données insérées à consulter*/
+ lockable_obj_extra_t *eb; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ ea = GET_GOBJECT_EXTRA(G_OBJECT(a), lockable_obj_extra_t);
+ eb = GET_GOBJECT_EXTRA(G_OBJECT(b), lockable_obj_extra_t);
+
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
result = g_proxy_feeder_compare(a->feeder, b->feeder);
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
+
+ if (lock)
+ {
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
+ }
+
return result;
}
@@ -234,6 +264,43 @@ static void g_proxy_operand_print(const GProxyOperand *operand, GBufferLine *lin
/******************************************************************************
* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint g_proxy_operand_hash(const GProxyOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ lockable_obj_extra_t *extra; /* Données insérées à consulter*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_GOBJECT_EXTRA(G_OBJECT(operand), lockable_obj_extra_t);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_proxy_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= g_direct_hash(operand->feeder);
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = opérande à consulter. *
* *
* Description : Fournit le fournisseur représenté par l'opérande. *
diff --git a/src/arch/operands/register-int.h b/src/arch/operands/register-int.h
index bf3e9d4..a887567 100644
--- a/src/arch/operands/register-int.h
+++ b/src/arch/operands/register-int.h
@@ -29,23 +29,9 @@
#include "../operand-int.h"
-#include "../../glibext/objhole.h"
-/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _regop_obj_extra
-{
- struct
- {
- bool is_written; /* Changement de contenu */
-
- };
-
- gint lock; /* Gestion d'accès aux fanions */
-
-} regop_obj_extra;
-
/* Définition d'un opérande visant un registre (instance) */
struct _GRegisterOperand
{
@@ -53,39 +39,8 @@ struct _GRegisterOperand
GArchRegister *reg; /* Registre représenté */
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
- /**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
- */
-
- regop_obj_extra extra; /* Externalisation embarquée */
-
-#endif
-
};
-/**
- * Accès aux informations éventuellement déportées.
- */
-
-#if __SIZEOF_INT__ == __SIZEOF_LONG__
-
-# define INIT_REG_OP_EXTRA(op) op->extra.lock = 0
-
-# define GET_REG_OP_EXTRA(op) &op->extra
-
-#else
-
-# define INIT_REG_OP_EXTRA(op) INIT_GOBJECT_EXTRA(G_OBJECT(op))
-
-# define GET_REG_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), regop_obj_extra)
-
-#endif
-
/* Définition d'un opérande visant un registre (classe) */
struct _GRegisterOperandClass
{
diff --git a/src/arch/operands/register.c b/src/arch/operands/register.c
index e457158..9c0a337 100644
--- a/src/arch/operands/register.c
+++ b/src/arch/operands/register.c
@@ -24,6 +24,9 @@
#include "register.h"
+#include <assert.h>
+
+
#include "register-int.h"
#include "../storage.h"
@@ -45,7 +48,7 @@ static void g_register_operand_dispose(GRegisterOperand *);
static void g_register_operand_finalize(GRegisterOperand *);
/* Compare un opérande avec un autre. */
-static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *);
+static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_register_operand_print(const GRegisterOperand *, GBufferLine *);
@@ -56,7 +59,7 @@ static void g_register_operand_print(const GRegisterOperand *, GBufferLine *);
/* Fournit l'empreinte d'un candidat à une centralisation. */
-static guint g_register_operand_hash(const GRegisterOperand *);
+static guint g_register_operand_hash(const GRegisterOperand *, bool);
@@ -132,8 +135,6 @@ static void g_register_operand_init(GRegisterOperand *operand)
{
operand->reg = NULL;
- INIT_REG_OP_EXTRA(operand);
-
}
@@ -179,8 +180,9 @@ static void g_register_operand_finalize(GRegisterOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Compare un opérande avec un autre. *
* *
@@ -190,12 +192,19 @@ static void g_register_operand_finalize(GRegisterOperand *operand)
* *
******************************************************************************/
-static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b)
+static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b, bool lock)
{
int result; /* Bilan à retourner */
+ GArchOperandClass *class; /* Classe parente normalisée */
result = g_arch_register_compare(a->reg, b->reg);
+ if (result == 0)
+ {
+ class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
+ }
+
return result;
}
@@ -246,63 +255,6 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)
}
-/******************************************************************************
-* *
-* Paramètres : operand = opérande représentant un registre à mettre à jour. *
-* *
-* Description : Marque l'opérande comme étant écrit plutôt que consulté. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_register_operand_mark_as_written(GRegisterOperand *operand)
-{
- regop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_REG_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- extra->is_written = true;
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = opérande représentant un registre à consulter. *
-* *
-* Description : Indique le type d'accès réalisé sur l'opérande. *
-* *
-* Retour : Type d'accès : true en cas d'écriture, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_register_operand_is_written(const GRegisterOperand *operand)
-{
- bool result; /* Statut à retourner */
- regop_obj_extra *extra; /* Données insérées à modifier */
-
- extra = GET_REG_OP_EXTRA(operand);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = extra->is_written;
-
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- return result;
-
-}
-
-
/* ---------------------------------------------------------------------------------- */
/* CONTROLE DU VOLUME DES INSTANCES */
@@ -312,6 +264,7 @@ bool g_register_operand_is_written(const GRegisterOperand *operand)
/******************************************************************************
* *
* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Fournit l'empreinte d'un candidat à une centralisation. *
* *
@@ -321,20 +274,21 @@ bool g_register_operand_is_written(const GRegisterOperand *operand)
* *
******************************************************************************/
-static guint g_register_operand_hash(const GRegisterOperand *operand)
+static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)
{
guint result; /* Valeur à retourner */
+ GArchOperandClass *class; /* Classe parente normalisée */
GArchRegister *reg; /* Registre visé par l'opérande*/
+ class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
reg = g_register_operand_get_register(operand);
- result = g_arch_register_hash(reg);
+ result ^= g_arch_register_hash(reg);
g_object_unref(G_OBJECT(reg));
- if (g_register_operand_is_written(operand))
- result ^= 1;
-
return result;
}
diff --git a/src/arch/operands/register.h b/src/arch/operands/register.h
index 7f746b6..e2f2c46 100644
--- a/src/arch/operands/register.h
+++ b/src/arch/operands/register.h
@@ -37,6 +37,14 @@
/* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */
+/* Etats particuliers d'un opérande de registre */
+typedef enum _RegOpFlag
+{
+ ROF_IS_WRITTEN = AOF_USER_FLAG(0), /* Opération d'écriture ? */
+
+} RegOpFlag;
+
+
#define G_TYPE_REGISTER_OPERAND g_register_operand_get_type()
#define G_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_REGISTER_OPERAND, GRegisterOperand))
#define G_IS_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_REGISTER_OPERAND))
@@ -58,12 +66,6 @@ GType g_register_operand_get_type(void);
/* Fournit le registre associé à l'opérande. */
GArchRegister *g_register_operand_get_register(const GRegisterOperand *);
-/* Marque l'opérande comme étant écrit plutôt que consulté. */
-void g_register_operand_mark_as_written(GRegisterOperand *);
-
-/* Indique le type d'accès réalisé sur l'opérande. */
-bool g_register_operand_is_written(const GRegisterOperand *);
-
#endif /* _ARCH_OPERANDS_REGISTER_H */
diff --git a/src/arch/operands/target-int.h b/src/arch/operands/target-int.h
index f3ed447..ac4cdcd 100644
--- a/src/arch/operands/target-int.h
+++ b/src/arch/operands/target-int.h
@@ -30,15 +30,22 @@
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _tarop_extra_data_t
+{
+ operand_extra_data_t parent; /* A laisser en premier */
+
+ MemoryDataSize size; /* Taille de l'opérande */
+
+} tarop_extra_data_t;
+
/* Définition d'un opérande ciblant idéalement un symbole connu (instance) */
struct _GTargetOperand
{
GArchOperand parent; /* Instance parente */
- MemoryDataSize size; /* Taille de l'opérande */
vmpa2t addr; /* Adresse de l'élément visé */
- bool strict; /* Résolution stricte */
/* Référence circulaire */
GBinSymbol *symbol; /* Eventuel symbole associé */
phys_t diff; /* Position dans le symbole */
@@ -54,5 +61,20 @@ struct _GTargetOperandClass
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_TARGET_OP_EXTRA(op) (tarop_extra_data_t *)&op->extra
+
+#else
+
+# define GET_TARGET_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), tarop_extra_data_t)
+
+#endif
+
+
#endif /* _ARCH_OPERANDS_TARGET_INT_H */
diff --git a/src/arch/operands/target.c b/src/arch/operands/target.c
index 5edc805..6450834 100644
--- a/src/arch/operands/target.c
+++ b/src/arch/operands/target.c
@@ -37,6 +37,7 @@
#include "targetable-int.h"
#include "../../analysis/routine.h"
#include "../../common/extstr.h"
+#include "../../common/sort.h"
#include "../../format/format.h"
#include "../../format/strsym.h"
#include "../../glibext/gbinarycursor.h"
@@ -60,7 +61,7 @@ static void g_target_operand_dispose(GTargetOperand *);
static void g_target_operand_finalize(GTargetOperand *);
/* Compare un opérande avec un autre. */
-static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *);
+static int g_target_operand_compare(const GTargetOperand *, const GTargetOperand *, bool);
/* Traduit un opérande en version humainement lisible. */
static void g_target_operand_print(const GTargetOperand *, GBufferLine *);
@@ -68,6 +69,9 @@ static void g_target_operand_print(const GTargetOperand *, GBufferLine *);
/* Construit un petit résumé concis de l'opérande. */
static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_target_operand_hash(const GTargetOperand *, bool);
+
/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
@@ -122,6 +126,8 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)
operand->print = (operand_print_fc)g_target_operand_print;
operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip;
+ operand->hash = (operand_hash_fc)g_target_operand_hash;
+
operand->unserialize = (unserialize_operand_fc)g_target_operand_unserialize;
operand->serialize = (serialize_operand_fc)g_target_operand_serialize;
@@ -142,10 +148,10 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)
static void g_target_operand_init(GTargetOperand *operand)
{
- operand->size = MDS_UNDEFINED;
+ GET_TARGET_OP_EXTRA(operand)->size = MDS_UNDEFINED;
+
init_vmpa(&operand->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
- operand->strict = true;
operand->symbol = NULL;
operand->diff = 0;
@@ -211,8 +217,9 @@ static void g_target_operand_finalize(GTargetOperand *operand)
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
+* Paramètres : a = premier opérande à consulter. *
+* b = second opérande à consulter. *
+* lock = précise le besoin en verrouillage. *
* *
* Description : Compare un opérande avec un autre. *
* *
@@ -222,56 +229,56 @@ static void g_target_operand_finalize(GTargetOperand *operand)
* *
******************************************************************************/
-static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b)
+static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperand *b, bool lock)
{
int result; /* Bilan à retourner */
+ tarop_extra_data_t *ea; /* Données insérées à modifier */
+ tarop_extra_data_t *eb; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
- result = cmp_vmpa(&a->addr, &b->addr);
- if (result != 0) goto gtoc_done;
+ ea = GET_TARGET_OP_EXTRA(a);
+ eb = GET_TARGET_OP_EXTRA(b);
- if (a->size < b->size)
+ if (lock)
{
- result = -1;
- goto gtoc_done;
- }
- else if (a->size > b->size)
- {
- result = 1;
- goto gtoc_done;
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
}
- if (a->symbol == NULL && b->symbol != NULL)
- {
- result = -1;
- goto gtoc_done;
- }
- else if (a->symbol != NULL && b->symbol == NULL)
- {
- result = 1;
- goto gtoc_done;
- }
- else if (a->symbol != NULL && b->symbol != NULL)
+ result = sort_unsigned_long(ea->size, eb->size);
+
+ if (result == 0)
+ result = cmp_vmpa(&a->addr, &b->addr);
+
+ if (result == 0)
{
- result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol },
- (const GBinSymbol *[]) { b->symbol });
- if (result != 0) goto gtoc_done;
+ if (a->symbol == NULL && b->symbol != NULL)
+ result = -1;
+
+ else if (a->symbol != NULL && b->symbol == NULL)
+ result = 1;
+
+ else if (a->symbol != NULL && b->symbol != NULL)
+ result = g_binary_symbol_cmp((const GBinSymbol *[]) { a->symbol },
+ (const GBinSymbol *[]) { b->symbol });
+
}
- if (a->diff < b->diff)
+ if (result == 0)
+ result = sort_uint64_t(a->diff, b->diff);
+
+ if (result == 0)
{
- result = -1;
- goto gtoc_done;
+ class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class);
+ result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
}
- else if (a->diff > b->diff)
+
+ if (lock)
{
- result = 1;
- goto gtoc_done;
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
}
- result = 0;
-
- gtoc_done:
-
return result;
}
@@ -296,6 +303,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
vmpa2t tmp; /* Coquille vide pour argument */
VMPA_BUFFER(value); /* Adresse brute à imprimer */
size_t len; /* Taille de l'élément inséré */
+ MemoryDataSize size; /* Taille retenue */
label = g_binary_symbol_get_label(operand->symbol);
@@ -322,7 +330,9 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
}
else
{
- vmpa2_to_string(&operand->addr, operand->size, value, &len);
+ size = g_target_operand_get_size(operand);
+
+ vmpa2_to_string(&operand->addr, size, value, &len);
g_buffer_line_append_text(line, DLC_ASSEMBLY, value, len, RTT_LABEL, G_OBJECT(operand));
@@ -355,7 +365,8 @@ GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)
assert(size != MDS_UNDEFINED);
- result->size = size;
+ GET_TARGET_OP_EXTRA(result)->size = size;
+
copy_vmpa(&result->addr, addr);
return G_ARCH_OPERAND(result);
@@ -457,7 +468,18 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const
MemoryDataSize g_target_operand_get_size(const GTargetOperand *operand)
{
- return operand->size;
+ MemoryDataSize result; /* Taille à retourner */
+ tarop_extra_data_t *extra; /* Données insérées à consulter*/
+
+ extra = GET_TARGET_OP_EXTRA(operand);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = extra->size;
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
}
@@ -485,7 +507,10 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool
const mrange_t *range; /* Couverture du symbole */
#endif
- operand->strict = strict;
+ if (strict)
+ g_arch_operand_set_flag(G_ARCH_OPERAND(operand), TOF_STRICT);
+ else
+ g_arch_operand_unset_flag(G_ARCH_OPERAND(operand), TOF_STRICT);
result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff);
@@ -569,6 +594,48 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d
}
+/******************************************************************************
+* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint g_target_operand_hash(const GTargetOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ tarop_extra_data_t *extra; /* Données insérées à modifier */
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_TARGET_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_target_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= extra->size;
+
+ result ^= g_direct_hash(operand->symbol);
+
+ result ^= (operand->diff & 0xffffffff);
+ result ^= (operand->diff >> 32);
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* TRANSPOSITIONS VIA CACHE DES OPERANDES */
@@ -632,6 +699,7 @@ static bool g_target_operand_unserialize(GTargetOperand *operand, GAsmStorage *s
static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
+ MemoryDataSize size; /* Taille retenue */
GArchOperand *original; /* Opérande d'origine */
/**
@@ -639,10 +707,12 @@ static bool g_target_operand_serialize(const GTargetOperand *operand, GAsmStorag
* par la position physique.
*/
+ size = g_target_operand_get_size(operand);
+
if (has_virt_addr(&operand->addr))
- original = g_imm_operand_new_from_value(operand->size, get_virt_addr(&operand->addr));
+ original = g_imm_operand_new_from_value(size, get_virt_addr(&operand->addr));
else
- original = g_imm_operand_new_from_value(operand->size, get_phy_addr(&operand->addr));
+ original = g_imm_operand_new_from_value(size, get_phy_addr(&operand->addr));
result = g_arch_operand_store(original, storage, pbuf);
diff --git a/src/arch/operands/target.h b/src/arch/operands/target.h
index 8810efa..40db610 100644
--- a/src/arch/operands/target.h
+++ b/src/arch/operands/target.h
@@ -35,6 +35,14 @@
+/* Etats particuliers d'un opérande de valeur immédiate */
+typedef enum _TargetOpFlag
+{
+ TOF_STRICT = AOF_USER_FLAG(0), /* Résolution stricte */
+
+} TargetOpFlag;
+
+
#define G_TYPE_TARGET_OPERAND g_target_operand_get_type()
#define G_TARGET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TARGET_OPERAND, GTargetOperand))
#define G_IS_TARGET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TARGET_OPERAND))
diff --git a/src/format/format-int.h b/src/format/format-int.h
index de29751..11505d0 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -45,18 +45,22 @@ typedef SourceEndian (* format_get_endian_fc) (const GBinFormat *);
/* Rythme des allocations pour les entrées de code */
#define EXTRA_POINT_BLOCK 20
-/* Informations glissées dans la structure GObject de GBinFormat */
-typedef union _fmt_obj_extra
+
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _fmt_extra_data_t
{
- struct
- {
- FormatFlag flags; /* Informations complémentaires*/
+ FormatFlag flags; /* Informations complémentaires*/
+
+} fmt_extra_data_t;
- };
+/* Encapsulation avec un verrou d'accès */
+typedef union _fmt_obj_extra_t
+{
+ fmt_extra_data_t data; /* Données embarquées */
+ lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */
- gint lock; /* Gestion d'accès aux fanions */
+} fmt_obj_extra_t;
-} fmt_obj_extra;
/* Description d'une erreur */
typedef struct _fmt_error
@@ -73,6 +77,19 @@ struct _GBinFormat
{
GKnownFormat parent; /* A laisser en premier */
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+ /**
+ * L'inclusion des informations suivantes dépend de l'architecture.
+ *
+ * Si la structure GObject possède un trou, on remplit de préférence
+ * ce dernier.
+ */
+
+ fmt_obj_extra_t extra; /* Externalisation embarquée */
+
+#endif
+
virt_t *start_points[DPL_COUNT]; /* Départ de désassemblage */
size_t pt_allocated[DPL_COUNT]; /* Taille d'inscription allouée*/
size_t pt_count[DPL_COUNT]; /* Nombre de points enregistrés*/
@@ -97,53 +114,37 @@ struct _GBinFormat
gint error_locked; /* Statut d'accès à la liste */
#endif
-#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.
- */
+/* Format binaire générique (classe) */
+struct _GBinFormatClass
+{
+ GKnownFormatClass parent; /* A laisser en premier */
- fmt_obj_extra extra; /* Externalisation embarquée */
+ format_get_endian_fc get_endian; /* Boutisme employé */
-#endif
+ /* Signaux */
+
+ void (* symbol_added) (GBinFormat *, GBinSymbol *);
+ void (* symbol_removed) (GBinFormat *, GBinSymbol *);
};
+
/**
* Accès aux informations éventuellement déportées.
*/
#if __SIZEOF_INT__ == __SIZEOF_LONG__
-# define INIT_BIN_FORMAT_EXTRA(fmt) fmt->extra.lock = 0
-
-# define GET_BIN_FORMAT_EXTRA(fmt) &fmt->extra
+# define GET_BIN_FORMAT_EXTRA(fmt) (fmt_extra_data_t *)&fmt->extra
#else
-# define INIT_BIN_FORMAT_EXTRA(fmt) INIT_GOBJECT_EXTRA(G_OBJECT(fmt))
-
-# define GET_BIN_FORMAT_EXTRA(fmt) GET_GOBJECT_EXTRA(G_OBJECT(fmt), fmt_obj_extra)
+# define GET_BIN_FORMAT_EXTRA(fmt) GET_GOBJECT_EXTRA(G_OBJECT(fmt), fmt_extra_data_t)
#endif
-/* Format binaire générique (classe) */
-struct _GBinFormatClass
-{
- GKnownFormatClass parent; /* A laisser en premier */
-
- format_get_endian_fc get_endian; /* Boutisme employé */
-
- /* Signaux */
-
- void (* symbol_added) (GBinFormat *, GBinSymbol *);
- void (* symbol_removed) (GBinFormat *, GBinSymbol *);
-
-};
-
/* ------------------------------ DECODAGE DE SYMBOLES ------------------------------ */
diff --git a/src/format/format.c b/src/format/format.c
index 045bc92..f8fe13a 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -123,7 +123,11 @@ static void g_binary_format_class_init(GBinFormatClass *klass)
static void g_binary_format_init(GBinFormat *format)
{
- INIT_BIN_FORMAT_EXTRA(format);
+ fmt_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_BIN_FORMAT_EXTRA(format);
+
+ INIT_GOBJECT_EXTRA_LOCK(extra);
g_rw_lock_init(&format->pt_lock);
@@ -235,17 +239,17 @@ static void g_binary_format_finalize(GBinFormat *format)
bool g_binary_format_set_flag(GBinFormat *format, FormatFlag flag)
{
bool result; /* Bilan à retourner */
- fmt_obj_extra *extra; /* Données insérées à modifier */
+ fmt_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_FORMAT_EXTRA(format);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = !(extra->flags & flag);
extra->flags |= flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -268,17 +272,17 @@ bool g_binary_format_set_flag(GBinFormat *format, FormatFlag flag)
bool g_binary_format_unset_flag(GBinFormat *format, FormatFlag flag)
{
bool result; /* Bilan à retourner */
- fmt_obj_extra *extra; /* Données insérées à modifier */
+ fmt_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_FORMAT_EXTRA(format);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & flag);
extra->flags &= ~flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -301,15 +305,15 @@ bool g_binary_format_unset_flag(GBinFormat *format, FormatFlag flag)
bool g_binary_format_has_flag(const GBinFormat *format, FormatFlag flag)
{
bool result; /* Bilan à retourner */
- fmt_obj_extra *extra; /* Données insérées à modifier */
+ fmt_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_FORMAT_EXTRA(format);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & flag);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -331,15 +335,15 @@ bool g_binary_format_has_flag(const GBinFormat *format, FormatFlag flag)
FormatFlag g_binary_format_get_flags(const GBinFormat *format)
{
FormatFlag result; /* Fanions à retourner */
- fmt_obj_extra *extra; /* Données insérées à modifier */
+ fmt_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_FORMAT_EXTRA(format);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & FFL_MASK);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
diff --git a/src/format/symbol-int.h b/src/format/symbol-int.h
index 99cee88..7f5807c 100644
--- a/src/format/symbol-int.h
+++ b/src/format/symbol-int.h
@@ -35,32 +35,31 @@ typedef char * (* get_symbol_label_fc) (const GBinSymbol *);
/* Informations glissées dans la structure GObject de GBinSymbol */
-typedef union _sym_obj_extra
+typedef struct _sym_extra_data_t
{
- struct
- {
- SymbolType stype; /* Type du symbole */
- SymbolStatus status; /* Visibilité du symbole */
+ SymbolType stype; /* Type du symbole */
+ SymbolStatus status; /* Visibilité du symbole */
- char nm_prefix; /* Eventuel préfixe "nm" */
+ char nm_prefix; /* Eventuel préfixe "nm" */
- SymbolFlag flags; /* Informations complémentaires*/
+ SymbolFlag flags; /* Informations complémentaires*/
- };
+} sym_extra_data_t;
- gint lock; /* Gestion d'accès aux fanions */
+/* Encapsulation avec un verrou d'accès */
+typedef union _symbol_obj_extra_t
+{
+ sym_extra_data_t data; /* Données embarquées */
+ lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */
+
+} symbol_obj_extra_t;
-} sym_obj_extra;
/* Symbole d'exécutable (instance) */
struct _GBinSymbol
{
GObject parent; /* A laisser en premier */
- mrange_t range; /* Couverture mémoire */
-
- char *alt; /* Nom alternatif */
-
#if __SIZEOF_INT__ == __SIZEOF_LONG__
/**
@@ -70,39 +69,40 @@ struct _GBinSymbol
* ce dernier.
*/
- sym_obj_extra extra; /* Externalisation embarquée */
+ symbol_obj_extra_t extra; /* Externalisation embarquée */
#endif
+ mrange_t range; /* Couverture mémoire */
+
+ char *alt; /* Nom alternatif */
+
};
+/* Symbole d'exécutable (classe) */
+struct _GBinSymbolClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+ get_symbol_label_fc get_label; /* Obtention d'une étiquette */
+
+};
+
+
/**
* Accès aux informations éventuellement déportées.
*/
#if __SIZEOF_INT__ == __SIZEOF_LONG__
-# define INIT_BIN_SYMBOL_EXTRA(sym) sym->extra.lock = 0
-
-# define GET_BIN_SYMBOL_EXTRA(sym) &sym->extra
+# define GET_BIN_SYMBOL_EXTRA(sym) (sym_extra_data_t *)&sym->extra
#else
-# define INIT_BIN_SYMBOL_EXTRA(sym) INIT_GOBJECT_EXTRA(G_OBJECT(sym))
-
-# define GET_BIN_SYMBOL_EXTRA(sym) GET_GOBJECT_EXTRA(G_OBJECT(sym), sym_obj_extra)
+# define GET_BIN_SYMBOL_EXTRA(sym) GET_GOBJECT_EXTRA(G_OBJECT(sym), sym_extra_data_t)
#endif
-/* Symbole d'exécutable (classe) */
-struct _GBinSymbolClass
-{
- GObjectClass parent; /* A laisser en premier */
-
- get_symbol_label_fc get_label; /* Obtention d'une étiquette */
-
-};
-
#endif /* _FORMAT_SYMBOL_INT_H */
diff --git a/src/format/symbol.c b/src/format/symbol.c
index eb61db8..d3d5285 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -124,7 +124,11 @@ static void g_binary_symbol_class_init(GBinSymbolClass *klass)
static void g_binary_symbol_init(GBinSymbol *symbol)
{
- INIT_BIN_SYMBOL_EXTRA(symbol);
+ sym_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_BIN_SYMBOL_EXTRA(symbol);
+
+ INIT_GOBJECT_EXTRA_LOCK(extra);
g_binary_symbol_set_stype(symbol, STP_COUNT);
@@ -331,15 +335,15 @@ const mrange_t *g_binary_symbol_get_range(const GBinSymbol *symbol)
void g_binary_symbol_set_stype(GBinSymbol *symbol, SymbolType type)
{
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->stype = type;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -359,15 +363,15 @@ void g_binary_symbol_set_stype(GBinSymbol *symbol, SymbolType type)
SymbolType g_binary_symbol_get_stype(const GBinSymbol *symbol)
{
SymbolType result; /* Type à retourner */
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->stype;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -389,15 +393,15 @@ SymbolType g_binary_symbol_get_stype(const GBinSymbol *symbol)
void g_binary_symbol_set_status(GBinSymbol *symbol, SymbolStatus status)
{
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->status = status;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -417,15 +421,15 @@ void g_binary_symbol_set_status(GBinSymbol *symbol, SymbolStatus status)
SymbolStatus g_binary_symbol_get_status(const GBinSymbol *symbol)
{
SymbolStatus result; /* Visibilité à retourner */
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->status;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -448,17 +452,17 @@ SymbolStatus g_binary_symbol_get_status(const GBinSymbol *symbol)
bool g_binary_symbol_set_flag(GBinSymbol *symbol, SymbolFlag flag)
{
bool result; /* Bilan à retourner */
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = !(extra->flags & flag);
extra->flags |= flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -481,17 +485,17 @@ bool g_binary_symbol_set_flag(GBinSymbol *symbol, SymbolFlag flag)
bool g_binary_symbol_unset_flag(GBinSymbol *symbol, SymbolFlag flag)
{
bool result; /* Bilan à retourner */
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & flag);
extra->flags &= ~flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -514,15 +518,15 @@ bool g_binary_symbol_unset_flag(GBinSymbol *symbol, SymbolFlag flag)
bool g_binary_symbol_has_flag(const GBinSymbol *symbol, SymbolFlag flag)
{
bool result; /* Bilan à retourner */
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & flag);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -544,15 +548,15 @@ bool g_binary_symbol_has_flag(const GBinSymbol *symbol, SymbolFlag flag)
SymbolFlag g_binary_symbol_get_flags(const GBinSymbol *symbol)
{
SymbolFlag result; /* Fanions à retourner */
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->flags;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -575,18 +579,18 @@ SymbolFlag g_binary_symbol_get_flags(const GBinSymbol *symbol)
bool g_binary_symbol_get_nm_prefix(const GBinSymbol *symbol, char *prefix)
{
bool result; /* Validité à retourner */
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & SFL_HAS_NM_PREFIX);
if (result)
*prefix = extra->nm_prefix;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -607,16 +611,16 @@ bool g_binary_symbol_get_nm_prefix(const GBinSymbol *symbol, char *prefix)
void g_binary_symbol_set_nm_prefix(const GBinSymbol *symbol, char prefix)
{
- sym_obj_extra *extra; /* Données insérées à modifier */
+ sym_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_BIN_SYMBOL_EXTRA(symbol);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->nm_prefix = prefix;
extra->flags |= SFL_HAS_NM_PREFIX;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
diff --git a/src/glibext/objhole.h b/src/glibext/objhole.h
index cf9fc28..c256cfb 100644
--- a/src/glibext/objhole.h
+++ b/src/glibext/objhole.h
@@ -25,6 +25,7 @@
#define _GLIBEXT_OBJHOLE_H
+#include <glib.h>
#include <glib-object.h>
@@ -46,17 +47,6 @@
*/
-#define INIT_GOBJECT_EXTRA(obj) \
- do \
- { \
- guint *___space; \
- ___space = (((guint *)&obj->ref_count) + 1); \
- BUILD_BUG_ON((___space + 1) == (guint *)&obj->qdata); \
- *___space = 0; \
- } \
- while (0)
-
-
#define GET_GOBJECT_EXTRA(obj, tp) \
({ \
BUILD_BUG_ON(sizeof(tp) > sizeof(guint)); \
@@ -67,7 +57,6 @@
})
-
/**
* Choix du bit de verrou pour le champ "lock".
*
@@ -90,5 +79,41 @@
#endif
+/* Verrou d'accès pour une encapsulation */
+typedef struct _lockable_obj_extra_t
+{
+ gint lock; /* Gestion d'accès aux fanions */
+
+} lockable_obj_extra_t;
+
+
+#define INIT_GOBJECT_EXTRA_LOCK(xtr) \
+ do \
+ { \
+ lockable_obj_extra_t *__lockable; \
+ __lockable = (lockable_obj_extra_t *)xtr; \
+ __lockable->lock = 0; \
+ } \
+ while (0)
+
+#define LOCK_GOBJECT_EXTRA(xtr) \
+ do \
+ { \
+ lockable_obj_extra_t *__lockable; \
+ __lockable = (lockable_obj_extra_t *)xtr; \
+ g_bit_lock(&__lockable->lock, HOLE_LOCK_BIT); \
+ } \
+ while (0)
+
+#define UNLOCK_GOBJECT_EXTRA(xtr) \
+ do \
+ { \
+ lockable_obj_extra_t *__lockable; \
+ __lockable = (lockable_obj_extra_t *)xtr; \
+ g_bit_unlock(&__lockable->lock, HOLE_LOCK_BIT); \
+ } \
+ while (0)
+
+
#endif /* _GLIBEXT_OBJHOLE_H */