diff options
Diffstat (limited to 'src/arch/operands/register.c')
-rw-r--r-- | src/arch/operands/register.c | 371 |
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), ®_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; |