summaryrefslogtreecommitdiff
path: root/src/arch/operand.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-05-14 19:40:07 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-05-14 19:40:07 (GMT)
commit0286b53bad21abf91cbe17c4772ca9cde6a89cbc (patch)
tree3bec9dc7e118c00ce9c748576b01606a71880ad7 /src/arch/operand.c
parent267b1ae8608ed4bf52de743798e8647c903ee1b4 (diff)
Created an instruction database for Chrysalide.
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r--src/arch/operand.c200
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;
+
+}