diff options
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r-- | src/arch/operand.c | 200 |
1 files changed, 197 insertions, 3 deletions
diff --git a/src/arch/operand.c b/src/arch/operand.c index 930a588..1d4b468 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -30,7 +30,9 @@ #include "operand-int.h" +#include "storage.h" #include "../common/sort.h" +#include "../core/logs.h" @@ -48,6 +50,17 @@ static void g_arch_operand_finalize(GArchOperand *); +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_arch_operand_unserialize(GArchOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_arch_operand_serialize(const GArchOperand *, GAsmStorage *, packed_buffer *); + + + /* Indique le type défini pour un opérande d'architecture. */ G_DEFINE_TYPE(GArchOperand, g_arch_operand, G_TYPE_OBJECT); @@ -68,12 +81,18 @@ G_DEFINE_TYPE(GArchOperand, g_arch_operand, G_TYPE_OBJECT); static void g_arch_operand_class_init(GArchOperandClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GArchOperandClass *operand; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_arch_operand_finalize; + operand = G_ARCH_OPERAND_CLASS(klass); + + operand->unserialize = (unserialize_operand_fc)g_arch_operand_unserialize; + operand->serialize = (serialize_operand_fc)g_arch_operand_serialize; + } @@ -197,10 +216,17 @@ void g_arch_operand_set_alt_text(GArchOperand *operand, const char *text, Render { alt_len = strlen(text); - operand->alt_info = (alt_rendering *)malloc(sizeof(RenderingTagType) + alt_len + 1); + if (alt_len == 0) + operand->alt_info = NULL; + + else + { + operand->alt_info = (alt_rendering *)malloc(sizeof(RenderingTagType) + alt_len + 1); + + operand->alt_info->tag = tag; + strcpy(operand->alt_info->text, text); - operand->alt_info->tag = tag; - strcpy(operand->alt_info->text, text); + } } @@ -270,3 +296,171 @@ char *g_arch_operand_build_tooltip(const GArchOperand *operand, const GLoadedBin return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : operand = opérande d'assemblage à constituer. * +* storage = mécanisme de sauvegarde à manipuler. * +* format = format binaire chargé associé à l'architecture. * +* pbuf = zone tampon à remplir. * +* * +* Description : Charge un opérande depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arch_operand_unserialize(GArchOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + unsigned char len; /* Taille du contenu alternatif*/ + char *text; /* Texte alternatif */ + RenderingTagType tag; /* Type de rendu */ + + result = extract_packed_buffer(pbuf, &len, sizeof(unsigned char), false); + + if (result && len > 0) + { + text = (char *)malloc(len); + + if (result) + result = extract_packed_buffer(pbuf, text, len, false); + + if (result) + result = extract_packed_buffer(pbuf, &tag, sizeof(RenderingTagType), true); + + if (result) + g_arch_operand_set_alt_text(operand, text, tag); + + free(text); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : storage = mécanisme de sauvegarde à manipuler. * +* format = format binaire chargé associé à l'architecture. * +* pbuf = zone tampon à remplir. * +* * +* Description : Charge un opérande depuis une mémoire tampon. * +* * +* Retour : Opérande d'assemblage constitué ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_arch_operand_load(GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + GArchOperand *result; /* Instance à retourner */ + bool status; /* Bilan du chargement */ + + result = G_ARCH_OPERAND(g_asm_storage_create_object(storage, pbuf)); + + if (result != NULL) + { + status = G_ARCH_OPERAND_GET_CLASS(result)->unserialize(result, storage, format, pbuf); + + if (!status) + { + g_object_unref(G_OBJECT(result)); + result = NULL; + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un opérande dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_arch_operand_serialize(const GArchOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + size_t len; /* Taille du contenu alternatif*/ + + if (operand->alt_info == NULL) + result = extend_packed_buffer(pbuf, (unsigned char []) { 0 }, sizeof(unsigned char), false); + + else + { + len = strlen(operand->alt_info->text) + 1; + assert(len > 1); + + if (len > (2 << (sizeof(unsigned char) * 8 - 1))) + { + log_variadic_message(LMT_ERROR, "Alternative text too long: '%s' (%zu bytes)", + operand->alt_info->text, len); + result = false; + } + + else + result = extend_packed_buffer(pbuf, (unsigned char []) { len }, sizeof(unsigned char), false); + + if (result) + result = extend_packed_buffer(pbuf, operand->alt_info->text, len, false); + + if (result) + result = extend_packed_buffer(pbuf, &operand->alt_info->tag, sizeof(RenderingTagType), true); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instruction d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un opérande dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_operand_store(const GArchOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + + result = g_asm_storage_store_object_gtype(storage, G_OBJECT(operand), pbuf); + + if (result) + result = G_ARCH_OPERAND_GET_CLASS(operand)->serialize(operand, storage, pbuf); + + return result; + +} |