summaryrefslogtreecommitdiff
path: root/src/arch/operands/register.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/operands/register.c')
-rw-r--r--src/arch/operands/register.c371
1 files changed, 277 insertions, 94 deletions
diff --git a/src/arch/operands/register.c b/src/arch/operands/register.c
index 4615a99..07e35c4 100644
--- a/src/arch/operands/register.c
+++ b/src/arch/operands/register.c
@@ -28,7 +28,10 @@
#include "register-int.h"
-#include "../storage.h"
+#include "../../glibext/comparable-int.h"
+#include "../../glibext/hashable-int.h"
+#include "../../glibext/serialize-int.h"
+#include "../../glibext/strbuilder-int.h"
@@ -38,34 +41,61 @@
/* Initialise la classe des opérandes de registre. */
static void g_register_operand_class_init(GRegisterOperandClass *);
+/* Procède à l'initialisation de l'interface de comparaison. */
+static void g_register_operand_comparable_object_iface_init(GComparableObjectInterface *);
+
+/* Procède à l'initialisation de l'interface de détermination. */
+static void g_register_operand_hashable_object_iface_init(GHashableObjectInterface *);
+
+/* Procède à l'initialisation de l'interface de sérialisation. */
+static void g_register_operand_serializable_iface_init(GSerializableObjectInterface *);
+
+/* Procède à l'initialisation de l'interface d'exportation. */
+static void g_register_operand_string_builder_iface_init(GStringBuilderInterface *);
+
/* Initialise une instance d'opérande de registre. */
static void g_register_operand_init(GRegisterOperand *);
/* Supprime toutes les références externes. */
-static void g_register_operand_dispose(GRegisterOperand *);
+static void g_register_operand_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void g_register_operand_finalize(GRegisterOperand *);
+static void g_register_operand_finalize(GObject *);
+
+
+
+/* ---------------------- COMPARAISON DETAILLEE DE DEUX OBJETS ---------------------- */
+
+
+/* Réalise une comparaison étendue entre objets. */
+static int g_register_operand_compare(const GComparableObject *, const GComparableObject *);
+
+/* ---------------------- CALCUL D'UNE EMPREINTE DE L'INSTANCE ---------------------- */
-/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+/* Calcule l'empreinte sur 32 bits d'un objet. */
+static guint g_register_operand_hash(const GHashableObject *);
-/* Compare un opérande avec un autre. */
-static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *, bool);
-/* Traduit un opérande en version humainement lisible. */
-static void g_register_operand_print(const GRegisterOperand *, GBufferLine *);
-/* Fournit l'empreinte d'un candidat à une centralisation. */
-static guint g_register_operand_hash(const GRegisterOperand *, bool);
+/* ------------------- MECANISMES DE CONSERVATION ET RESTAURATION ------------------- */
-/* Charge un contenu depuis une mémoire tampon. */
-static bool g_register_operand_load(GRegisterOperand *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un contenu dans une mémoire tampon. */
-static bool g_register_operand_store(GRegisterOperand *, GObjectStorage *, packed_buffer_t *);
+/* Charge un objet depuis un flux de données. */
+static bool g_register_operand_load(GSerializableObject *, GObjectStorage *, int);
+
+/* Sauvegarde un objet dans un flux de données. */
+static bool g_register_operand_store(const GSerializableObject *, GObjectStorage *, int);
+
+
+
+/* ----------------- EXPORTATION SOUS FORME DE CHAINE DE CARACTERES ----------------- */
+
+
+/* Exporte une chaîne de caractères à partir d'un objet. */
+static bool g_register_operand_to_string(const GStringBuilder *, unsigned int, sized_binary_t *);
@@ -75,7 +105,12 @@ static bool g_register_operand_store(GRegisterOperand *, GObjectStorage *, packe
/* Indique le type défini par la GLib pour un opérande de registre Dalvik. */
-G_DEFINE_TYPE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE_WITH_CODE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND,
+ G_IMPLEMENT_INTERFACE(G_TYPE_COMPARABLE_OBJECT, g_register_operand_comparable_object_iface_init)
+ G_IMPLEMENT_INTERFACE(G_TYPE_HASHABLE_OBJECT, g_register_operand_hashable_object_iface_init)
+ G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_register_operand_serializable_iface_init)
+ G_IMPLEMENT_INTERFACE(G_TYPE_STRING_BUILDER, g_register_operand_string_builder_iface_init)
+ G_IMPLEMENT_INTERFACE_IF_SYM(g_arch_operand_ui_get_type, g_register_operand_ui_arch_operand_ui_iface_init));
/******************************************************************************
@@ -93,23 +128,88 @@ G_DEFINE_TYPE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND);
static void g_register_operand_class_init(GRegisterOperandClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
- GArchOperandClass *operand; /* Version de classe parente */
object = G_OBJECT_CLASS(klass);
- operand = G_ARCH_OPERAND_CLASS(klass);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_register_operand_dispose;
- object->finalize = (GObjectFinalizeFunc)g_register_operand_finalize;
+ object->dispose = g_register_operand_dispose;
+ object->finalize = g_register_operand_finalize;
- operand = G_ARCH_OPERAND_CLASS(klass);
+}
- operand->compare = (operand_compare_fc)g_register_operand_compare;
- operand->print = (operand_print_fc)g_register_operand_print;
- operand->hash = (operand_hash_fc)g_register_operand_hash;
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de comparaison. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- operand->load = (load_operand_fc)g_register_operand_load;
- operand->store = (store_operand_fc)g_register_operand_store;
+static void g_register_operand_comparable_object_iface_init(GComparableObjectInterface *iface)
+{
+ iface->compare = g_register_operand_compare;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de détermination. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_register_operand_hashable_object_iface_init(GHashableObjectInterface *iface)
+{
+ iface->hash = g_register_operand_hash;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de sérialisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_register_operand_serializable_iface_init(GSerializableObjectInterface *iface)
+{
+ iface->load = g_register_operand_load;
+ iface->store = g_register_operand_store;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface d'exportation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_register_operand_string_builder_iface_init(GStringBuilderInterface *iface)
+{
+ iface->to_string = g_register_operand_to_string;
}
@@ -135,7 +235,7 @@ static void g_register_operand_init(GRegisterOperand *operand)
/******************************************************************************
* *
-* Paramètres : binary = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -145,18 +245,22 @@ static void g_register_operand_init(GRegisterOperand *operand)
* *
******************************************************************************/
-static void g_register_operand_dispose(GRegisterOperand *operand)
+static void g_register_operand_dispose(GObject *object)
{
+ GRegisterOperand *operand; /* Version spécialisée */
+
+ operand = G_REGISTER_OPERAND(object);
+
g_clear_object(&operand->reg);
- G_OBJECT_CLASS(g_register_operand_parent_class)->dispose(G_OBJECT(operand));
+ G_OBJECT_CLASS(g_register_operand_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : binary = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -166,9 +270,36 @@ static void g_register_operand_dispose(GRegisterOperand *operand)
* *
******************************************************************************/
-static void g_register_operand_finalize(GRegisterOperand *operand)
+static void g_register_operand_finalize(GObject *object)
+{
+ G_OBJECT_CLASS(g_register_operand_parent_class)->finalize(object);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance à initialiser pleinement. *
+* reg = registre matériel à représenter. *
+* *
+* Description : Met en place un opérande réprésentant une valeur numérique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_register_operand_create(GRegisterOperand *operand, GArchRegister *reg)
{
- G_OBJECT_CLASS(g_register_operand_parent_class)->finalize(G_OBJECT(operand));
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ operand->reg = reg;
+ ref_object(reg);
+
+ return result;
}
@@ -190,8 +321,7 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)
GArchRegister *result; /* Instance à retourner */
result = operand->reg;
-
- g_object_ref(G_OBJECT(result));
+ ref_object(result);
return result;
@@ -200,17 +330,16 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)
/* ---------------------------------------------------------------------------------- */
-/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* COMPARAISON DETAILLEE DE DEUX OBJETS */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : a = premier opérande à consulter. *
-* b = second opérande à consulter. *
-* lock = précise le besoin en verrouillage. *
+* Paramètres : object = premier objet à consulter pour une comparaison. *
+* other = second objet à consulter pour une comparaison. *
* *
-* Description : Compare un opérande avec un autre. *
+* Description : Réalise une comparaison étendue entre objets. *
* *
* Retour : Bilan de la comparaison. *
* *
@@ -218,17 +347,25 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)
* *
******************************************************************************/
-static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b, bool lock)
+static int g_register_operand_compare(const GComparableObject *object, const GComparableObject *other)
{
int result; /* Bilan à retourner */
- GArchOperandClass *class; /* Classe parente normalisée */
+ GComparableObjectInterface *iface; /* Interface utilisée */
+ GComparableObjectInterface *parent_iface; /* Interface parente */
+ GRegisterOperand *operand; /* Version spécialisée */
+
+ iface = G_COMPARABLE_OBJECT_GET_IFACE(object);
- result = g_arch_register_compare(a->reg, b->reg);
+ parent_iface = g_type_interface_peek_parent(iface);
+
+ result = parent_iface->compare(object, other);
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);
+ operand = G_REGISTER_OPERAND(object);
+
+ result = g_comparable_object_compare(G_COMPARABLE_OBJECT(operand->reg), other);
+
}
return result;
@@ -236,53 +373,96 @@ static int g_register_operand_compare(const GRegisterOperand *a, const GRegister
}
+
+/* ---------------------------------------------------------------------------------- */
+/* CALCUL D'UNE EMPREINTE DE L'INSTANCE */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : operand = opérande à traiter. *
-* line = ligne tampon où imprimer l'opérande donné. *
+* Paramètres : object = objet dont l'instance est à consulter. *
* *
-* Description : Traduit un opérande en version humainement lisible. *
+* Description : Calcule l'empreinte sur 32 bits d'un objet. *
* *
-* Retour : - *
+* Retour : Valeur de représentation, unique pour l'objet ou non. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line)
+static guint g_register_operand_hash(const GHashableObject *object)
{
- g_arch_register_print(operand->reg, line);
+ guint result; /* Valeur à retourner */
+ GHashableObjectInterface *iface; /* Interface utilisée */
+ GHashableObjectInterface *parent_iface; /* Interface parente */
+ GRegisterOperand *operand; /* Version spécialisée */
+
+ iface = G_HASHABLE_OBJECT_GET_IFACE(object);
+
+ parent_iface = g_type_interface_peek_parent(iface);
+
+ result = parent_iface->hash(object);
+
+ operand = G_REGISTER_OPERAND(object);
+
+ result ^= g_hashable_object_hash(G_HASHABLE_OBJECT(operand->reg));
+
+ return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* MECANISMES DE CONSERVATION ET RESTAURATION */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : operand = objet dont l'instance se veut unique. *
-* lock = précise le besoin en verrouillage. *
+* Paramètres : object = élément GLib à constuire. *
+* storage = conservateur de données à manipuler. *
+* fd = flux ouvert en lecture. *
* *
-* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* Description : Charge un objet depuis un flux de données. *
* *
-* Retour : Empreinte de l'élément représenté. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)
+static bool g_register_operand_load(GSerializableObject *object, GObjectStorage *storage, int fd)
{
- guint result; /* Valeur à retourner */
- GArchOperandClass *class; /* Classe parente normalisée */
- GArchRegister *reg; /* Registre visé par l'opérande*/
+ bool result; /* Bilan à retourner */
+ GSerializableObjectInterface *iface; /* Interface utilisée */
+ GSerializableObjectInterface *parent_iface; /* Interface parente */
+ GSerializableObject *reg; /* Registre récupéré */
+ GRegisterOperand *operand; /* Version spécialisée */
+
+ iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object);
+
+ parent_iface = g_type_interface_peek_parent(iface);
+
+ result = parent_iface->load(object, storage, fd);
+
+ if (result)
+ {
+ reg = g_object_storage_unpack_object(storage, fd, "registers");
- class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
- result = class->hash(G_ARCH_OPERAND(operand), false);
+ if (reg == NULL)
+ result = false;
- reg = g_register_operand_get_register(operand);
+ else
+ {
+ operand = G_REGISTER_OPERAND(object);
- result ^= g_arch_register_hash(reg);
+ operand->reg = G_ARCH_REGISTER(reg);
+
+ }
- g_object_unref(G_OBJECT(reg));
+ }
return result;
@@ -291,11 +471,11 @@ static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)
/******************************************************************************
* *
-* Paramètres : operand = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
+* Paramètres : object = élément GLib à consulter. *
+* storage = conservateur de données à manipuler. *
+* fd = flux ouvert en écriture. *
* *
-* Description : Charge un contenu depuis une mémoire tampon. *
+* Description : Sauvegarde un objet dans un flux de données. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -303,61 +483,64 @@ static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)
* *
******************************************************************************/
-static bool g_register_operand_load(GRegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+static bool g_register_operand_store(const GSerializableObject *object, GObjectStorage *storage, int fd)
{
bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GSerializableObject *reg; /* Registre manipulé */
+ GRegisterOperand *operand; /* Version spécialisée */
+ off64_t reg_pos; /* Position renvoyant au reg. */
+ GSerializableObjectInterface *iface; /* Interface utilisée */
+ GSerializableObjectInterface *parent_iface; /* Interface parente */
- parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
+ operand = G_REGISTER_OPERAND(object);
- result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
+ result = g_object_storage_store_object(storage, "registers", G_SERIALIZABLE_OBJECT(operand->reg), &reg_pos);
+ if (!result) goto exit;
- if (result)
- {
- reg = g_object_storage_unpack_object(storage, "registers", pbuf);
+ iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object);
- result = (reg != NULL);
+ parent_iface = g_type_interface_peek_parent(iface);
- if (result)
- operand->reg = G_ARCH_REGISTER(reg);
+ result = parent_iface->store(object, storage, fd);
+ if (!result) goto exit;
- }
+ result = store_uleb128((uleb128_t []) { reg_pos }, fd);
+
+ exit:
return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* EXPORTATION SOUS FORME DE CHAINE DE CARACTERES */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : operand = élément GLib à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : builder = objet dont l'instance est exportable. *
+* flags = éventuelles indications pour l'opération. *
+* out = chaîne de caractères mise en place. [OUT] *
* *
-* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* Description : Exporte une chaîne de caractères à partir d'un objet. *
* *
* Retour : Bilan de l'opération. *
* *
-* Remarques : - *
+* Remarques : La sortie out est à nettoyer avec exit_sized_binary() après *
+* usage. *
* *
******************************************************************************/
-static bool g_register_operand_store(GRegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+static bool g_register_operand_to_string(const GStringBuilder *builder, unsigned int flags, sized_binary_t *out)
{
bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GSerializableObject *reg; /* Registre manipulé */
+ const GRegisterOperand *operand; /* Version spécialisée */
- parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class);
+ operand = G_REGISTER_OPERAND(builder);
- result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- reg = G_SERIALIZABLE_OBJECT(operand->reg);
- result = g_object_storage_pack_object(storage, "registers", reg, pbuf);
- }
+ result = g_string_builder_to_string(G_STRING_BUILDER(operand->reg), flags, out);
return result;