summaryrefslogtreecommitdiff
path: root/plugins/arm/v7/operands/maccess.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/arm/v7/operands/maccess.c')
-rw-r--r--plugins/arm/v7/operands/maccess.c199
1 files changed, 198 insertions, 1 deletions
diff --git a/plugins/arm/v7/operands/maccess.c b/plugins/arm/v7/operands/maccess.c
index a21921f..5359527 100644
--- a/plugins/arm/v7/operands/maccess.c
+++ b/plugins/arm/v7/operands/maccess.c
@@ -71,6 +71,17 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *, GBufferL
+/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */
+
+
+/* Charge un opérande depuis une mémoire tampon. */
+static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *, GAsmStorage *, GBinFormat *, packed_buffer *);
+
+/* Sauvegarde un opérande dans une mémoire tampon. */
+static bool g_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *, GAsmStorage *, packed_buffer *);
+
+
+
/* Indique le type défini par la GLib pour un accès à la mémoire depuis une base. */
G_DEFINE_TYPE(GArmV7MAccessOperand, g_armv7_maccess_operand, G_TYPE_ARCH_OPERAND);
@@ -101,6 +112,9 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass)
operand->compare = (operand_compare_fc)g_armv7_maccess_operand_compare;
operand->print = (operand_print_fc)g_armv7_maccess_operand_print;
+ operand->unserialize = (unserialize_operand_fc)g_armv7_maccess_operand_unserialize;
+ operand->serialize = (serialize_operand_fc)g_armv7_maccess_operand_serialize;
+
}
@@ -118,6 +132,9 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass)
static void g_armv7_maccess_operand_init(GArmV7MAccessOperand *operand)
{
+ operand->base = NULL;
+ operand->offset = NULL;
+ operand->shift = NULL;
}
@@ -136,7 +153,8 @@ static void g_armv7_maccess_operand_init(GArmV7MAccessOperand *operand)
static void g_armv7_maccess_operand_dispose(GArmV7MAccessOperand *operand)
{
- g_object_unref(G_OBJECT(operand->base));
+ if (operand->base != NULL)
+ g_object_unref(G_OBJECT(operand->base));
if (operand->offset != NULL)
g_object_unref(G_OBJECT(operand->offset));
@@ -383,3 +401,182 @@ bool g_armv7_maccess_operand_has_to_write_back(const GArmV7MAccessOperand *opera
return operand->write_back;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* 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_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ GArchOperand *subop; /* Sous-opérande à intégrer */
+ uint8_t boolean; /* Valeur booléenne */
+
+ parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class);
+
+ result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf);
+
+ if (result)
+ {
+ subop = g_arch_operand_load(storage, format, pbuf);
+
+ if (subop == NULL)
+ result = false;
+
+ else
+ operand->base = subop;
+
+ }
+
+ if (result)
+ {
+ result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
+
+ if (result && boolean == 1)
+ {
+ subop = g_arch_operand_load(storage, format, pbuf);
+
+ if (subop == NULL)
+ result = false;
+
+ else
+ operand->offset = subop;
+
+ }
+
+ }
+
+ if (result)
+ {
+ result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
+
+ if (result && boolean == 1)
+ {
+ subop = g_arch_operand_load(storage, format, pbuf);
+
+ if (subop == NULL)
+ result = false;
+
+ else
+ operand->shift = subop;
+
+ }
+
+ }
+
+ if (result)
+ {
+ result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
+
+ if (result)
+ operand->post_indexed = (boolean == 1 ? true : false);
+
+ }
+
+ if (result)
+ {
+ result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
+
+ if (result)
+ operand->write_back = (boolean == 1 ? true : false);
+
+ }
+
+ 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_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *operand, GAsmStorage *storage, packed_buffer *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ uint8_t boolean; /* Valeur booléenne */
+
+ parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class);
+
+ result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = g_arch_operand_store(operand->base, storage, pbuf);
+
+ if (result)
+ {
+ if (operand->offset == NULL)
+ result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false);
+
+ else
+ {
+ result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false);
+
+ if (result)
+ result = g_arch_operand_store(operand->offset, storage, pbuf);
+
+ }
+
+ }
+
+ if (result)
+ {
+ if (operand->shift == NULL)
+ result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false);
+
+ else
+ {
+ result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false);
+
+ if (result)
+ result = g_arch_operand_store(operand->shift, storage, pbuf);
+
+ }
+
+ }
+
+ if (result)
+ {
+ boolean = (operand->post_indexed ? 1 : 0);
+ result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
+ }
+
+ if (result)
+ {
+ boolean = (operand->write_back ? 1 : 0);
+ result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
+ }
+
+ return result;
+
+}