summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2021-12-30 18:28:18 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2021-12-30 18:44:35 (GMT)
commit945e0c9ecce02155555387aad672e272f5646362 (patch)
tree3d35bdb25012a9ef710a13c9e733b5a80f6641b1
parent98570719ff25a4dcde917056e55490bf2a6b1453 (diff)
Create generic functions to load and store operands.
-rw-r--r--plugins/arm/v7/operands/limitation.c8
-rw-r--r--plugins/arm/v7/operands/maccess.c127
-rw-r--r--plugins/arm/v7/operands/offset.c76
-rw-r--r--plugins/arm/v7/operands/rotation.c89
-rw-r--r--plugins/arm/v7/operands/shift.c29
-rw-r--r--plugins/dalvik/operands/args.c109
-rw-r--r--src/analysis/storage/storage.c75
-rw-r--r--src/analysis/storage/storage.h3
-rw-r--r--src/arch/Makefile.am2
-rw-r--r--src/arch/operand-int.c308
-rw-r--r--src/arch/operand-int.h42
-rw-r--r--src/arch/operand.c8
12 files changed, 483 insertions, 393 deletions
diff --git a/plugins/arm/v7/operands/limitation.c b/plugins/arm/v7/operands/limitation.c
index b3c6d07..f2e8373 100644
--- a/plugins/arm/v7/operands/limitation.c
+++ b/plugins/arm/v7/operands/limitation.c
@@ -456,15 +456,11 @@ static bool g_armv7_limitation_operand_load(GArmV7LimitationOperand *operand, GO
{
extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand);
- LOCK_GOBJECT_EXTRA(extra);
-
result = unpack_uleb128(&value, pbuf);
if (result)
extra->type = value;
- UNLOCK_GOBJECT_EXTRA(extra);
-
}
return result;
@@ -500,12 +496,8 @@ static bool g_armv7_limitation_operand_store(GArmV7LimitationOperand *operand, G
{
extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand);
- LOCK_GOBJECT_EXTRA(extra);
-
result = pack_uleb128((uleb128_t []){ extra->type }, pbuf);
- UNLOCK_GOBJECT_EXTRA(extra);
-
}
return result;
diff --git a/plugins/arm/v7/operands/maccess.c b/plugins/arm/v7/operands/maccess.c
index 3eb3116..d503b12 100644
--- a/plugins/arm/v7/operands/maccess.c
+++ b/plugins/arm/v7/operands/maccess.c
@@ -99,12 +99,6 @@ static void g_armv7_maccess_operand_update_inner_instances(GArmV7MAccessOperand
/* Fournit l'empreinte d'un candidat à une centralisation. */
static guint g_armv7_maccess_operand_hash(const GArmV7MAccessOperand *, bool);
-/* Charge un contenu depuis une mémoire tampon. */
-static bool g_armv7_maccess_operand_load(GArmV7MAccessOperand *, GObjectStorage *, packed_buffer_t *);
-
-/* Sauvegarde un contenu dans une mémoire tampon. */
-static bool g_armv7_maccess_operand_store(GArmV7MAccessOperand *, GObjectStorage *, packed_buffer_t *);
-
/* ---------------------------------------------------------------------------------- */
@@ -150,8 +144,8 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass)
operand->update_inner = (operand_update_inners_fc)g_armv7_maccess_operand_update_inner_instances;
operand->hash = (operand_hash_fc)g_armv7_maccess_operand_hash;
- operand->load = (load_operand_fc)g_armv7_maccess_operand_load;
- operand->store = (store_operand_fc)g_armv7_maccess_operand_store;
+ operand->load = g_arch_operand_load_generic_fixed_3;
+ operand->store = g_arch_operand_store_generic_fixed;
}
@@ -638,28 +632,28 @@ static void g_armv7_maccess_operand_update_inner_instances(GArmV7MAccessOperand
switch (i)
{
case 0:
- g_object_unref(G_OBJECT(operand->base));
+ g_clear_object(&operand->base);
operand->base = instances[i];
break;
case 1:
if (operand->offset != NULL)
{
- g_object_unref(G_OBJECT(operand->offset));
+ g_clear_object(&operand->offset);
operand->offset = instances[i];
}
else
{
assert(count == 2);
- g_object_unref(G_OBJECT(operand->shift));
+ g_clear_object(&operand->shift);
operand->shift = instances[i];
}
break;
case 2:
- g_object_unref(G_OBJECT(operand->shift));
+ g_clear_object(&operand->shift);
operand->shift = instances[i];
break;
@@ -716,112 +710,3 @@ static guint g_armv7_maccess_operand_hash(const GArmV7MAccessOperand *operand, b
return result;
}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
-* *
-* Description : Charge un contenu depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_armv7_maccess_operand_load(GArmV7MAccessOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GSerializableObject *obj; /* Instance à manipuler */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class);
-
- result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- obj = g_object_storage_unpack_object(storage, "operands", pbuf);
-
- result = (obj != NULL);
-
- if (result)
- operand->base = G_ARCH_OPERAND(obj);
-
- }
-
- if (result)
- {
- obj = g_object_storage_unpack_object(storage, "operands", pbuf);
-
- result = (obj != NULL);
-
- if (result)
- operand->offset = G_ARCH_OPERAND(obj);
-
- }
-
- if (result)
- {
- obj = g_object_storage_unpack_object(storage, "operands", pbuf);
-
- result = (obj != NULL);
-
- if (result)
- operand->shift = G_ARCH_OPERAND(obj);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = élément GLib à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Sauvegarde un contenu dans une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_armv7_maccess_operand_store(GArmV7MAccessOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GSerializableObject *obj; /* Instance à manipuler */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class);
-
- result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- obj = G_SERIALIZABLE_OBJECT(operand->base);
- result = g_object_storage_pack_object(storage, "operands", obj, pbuf);
- }
-
- if (result)
- {
- obj = G_SERIALIZABLE_OBJECT(operand->offset);
- result = g_object_storage_pack_object(storage, "operands", obj, pbuf);
- }
-
- if (result)
- {
- obj = G_SERIALIZABLE_OBJECT(operand->shift);
- result = g_object_storage_pack_object(storage, "operands", obj, pbuf);
- }
-
- return result;
-
-}
diff --git a/plugins/arm/v7/operands/offset.c b/plugins/arm/v7/operands/offset.c
index 1634230..79c5cf9 100644
--- a/plugins/arm/v7/operands/offset.c
+++ b/plugins/arm/v7/operands/offset.c
@@ -24,6 +24,7 @@
#include "offset.h"
+#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -85,11 +86,11 @@ static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GA
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *, GBufferLine *);
-/* Charge un contenu depuis une mémoire tampon. */
-static bool g_armv7_offset_operand_load(GArmV7OffsetOperand *, GObjectStorage *, packed_buffer_t *);
+/* Fournit une liste de candidats embarqués par un candidat. */
+static GArchOperand **g_armv7_offset_operand_list_inner_instances(const GArmV7OffsetOperand *, size_t *);
-/* Sauvegarde un contenu dans une mémoire tampon. */
-static bool g_armv7_offset_operand_store(GArmV7OffsetOperand *, GObjectStorage *, packed_buffer_t *);
+/* Met à jour une liste de candidats embarqués par un candidat. */
+static void g_armv7_offset_operand_update_inner_instances(GArmV7OffsetOperand *, GArchOperand **, size_t);
@@ -132,8 +133,11 @@ static void g_armv7_offset_operand_class_init(GArmV7OffsetOperandClass *klass)
operand->print = (operand_print_fc)g_armv7_offset_operand_print;
- operand->load = (load_operand_fc)g_armv7_offset_operand_load;
- operand->store = (store_operand_fc)g_armv7_offset_operand_store;
+ operand->list_inner = (operand_list_inners_fc)g_armv7_offset_operand_list_inner_instances;
+ operand->update_inner = (operand_update_inners_fc)g_armv7_offset_operand_update_inner_instances;
+
+ operand->load = g_arch_operand_load_generic_fixed_1;
+ operand->store = g_arch_operand_store_generic_fixed;
}
@@ -379,38 +383,27 @@ static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *operand, GBu
/******************************************************************************
* *
-* Paramètres : operand = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* count = quantité d'instances à l'unicité internes. *
* *
-* Description : Charge un contenu depuis une mémoire tampon. *
+* Description : Fournit une liste de candidats embarqués par un candidat. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Liste de candidats internes ou NULL si aucun. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_offset_operand_load(GArmV7OffsetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+static GArchOperand **g_armv7_offset_operand_list_inner_instances(const GArmV7OffsetOperand *operand, size_t *count)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GSerializableObject *value; /* Valeur du décalage */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class);
+ GArchOperand **result; /* Instances à retourner */
- result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- value = g_object_storage_unpack_object(storage, "operands", pbuf);
+ *count = 1;
- result = (value != NULL);
+ result = malloc(*count * sizeof(GArchOperand *));
- if (result)
- operand->value = G_ARCH_OPERAND(value);
-
- }
+ result[0] = operand->value;
+ g_object_ref(G_OBJECT(result[0]));
return result;
@@ -419,34 +412,25 @@ static bool g_armv7_offset_operand_load(GArmV7OffsetOperand *operand, GObjectSto
/******************************************************************************
* *
-* Paramètres : operand = élément GLib à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* instances = liste de candidats internes devenus singletons. *
+* count = quantité d'instances à l'unicité internes. *
* *
-* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* Description : Met à jour une liste de candidats embarqués par un candidat. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_armv7_offset_operand_store(GArmV7OffsetOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+static void g_armv7_offset_operand_update_inner_instances(GArmV7OffsetOperand *operand, GArchOperand **instances, size_t count)
{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GSerializableObject *value; /* Valeur du décalage */
+ assert(count == 1);
- parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class);
-
- result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- value = G_SERIALIZABLE_OBJECT(operand->value);
- result = g_object_storage_pack_object(storage, "operands", value, pbuf);
- }
+ g_clear_object(&operand->value);
- return result;
+ operand->value = instances[0];
+ g_object_ref(G_OBJECT(instances[0]));
}
diff --git a/plugins/arm/v7/operands/rotation.c b/plugins/arm/v7/operands/rotation.c
index f90c76b..8136401 100644
--- a/plugins/arm/v7/operands/rotation.c
+++ b/plugins/arm/v7/operands/rotation.c
@@ -93,12 +93,6 @@ static GArchOperand **g_armv7_rotation_operand_list_inner_instances(const GArmV7
/* Met à jour une liste de candidats embarqués par un candidat. */
static void g_armv7_rotation_operand_update_inner_instances(GArmV7RotationOperand *, GArchOperand **, size_t);
-/* Charge un contenu depuis une mémoire tampon. */
-static bool g_armv7_rotation_operand_load(GArmV7RotationOperand *, GObjectStorage *, packed_buffer_t *);
-
-/* Sauvegarde un contenu dans une mémoire tampon. */
-static bool g_armv7_rotation_operand_store(GArmV7RotationOperand *, GObjectStorage *, packed_buffer_t *);
-
/* ---------------------------------------------------------------------------------- */
@@ -143,8 +137,8 @@ static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klas
operand->list_inner = (operand_list_inners_fc)g_armv7_rotation_operand_list_inner_instances;
operand->update_inner = (operand_update_inners_fc)g_armv7_rotation_operand_update_inner_instances;
- operand->load = (load_operand_fc)g_armv7_rotation_operand_load;
- operand->store = (store_operand_fc)g_armv7_rotation_operand_store;
+ operand->load = g_arch_operand_load_generic_fixed_1;
+ operand->store = g_arch_operand_store_generic_fixed;
}
@@ -454,82 +448,9 @@ static void g_armv7_rotation_operand_update_inner_instances(GArmV7RotationOperan
{
assert(count == 1);
- g_object_unref(G_OBJECT(operand->value));
- operand->value = instances[0];
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
-* *
-* Description : Charge un contenu depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_armv7_rotation_operand_load(GArmV7RotationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GSerializableObject *value; /* Valeur de la rotation */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class);
-
- result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- value = g_object_storage_unpack_object(storage, "operands", pbuf);
-
- result = (value != NULL);
-
- if (result)
- operand->value = G_ARCH_OPERAND(value);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = élément GLib à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Sauvegarde un contenu dans une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_armv7_rotation_operand_store(GArmV7RotationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- GSerializableObject *value; /* Valeur de la rotation */
-
- parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class);
-
- result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- {
- value = G_SERIALIZABLE_OBJECT(operand->value);
- result = g_object_storage_pack_object(storage, "operands", value, pbuf);
- }
+ g_clear_object(&operand->value);
- return result;
+ operand->value = instances[0];
+ g_object_ref(G_OBJECT(instances[0]));
}
diff --git a/plugins/arm/v7/operands/shift.c b/plugins/arm/v7/operands/shift.c
index 55f2a22..ccdfe5c 100644
--- a/plugins/arm/v7/operands/shift.c
+++ b/plugins/arm/v7/operands/shift.c
@@ -537,8 +537,10 @@ static void g_armv7_shift_operand_update_inner_instances(GArmV7ShiftOperand *ope
{
assert(count == 1);
- g_object_unref(G_OBJECT(operand->shift_value));
+ g_clear_object(&operand->shift_value);
+
operand->shift_value = instances[0];
+ g_object_ref(G_OBJECT(instances[0]));
}
@@ -603,7 +605,6 @@ static bool g_armv7_shift_operand_load(GArmV7ShiftOperand *operand, GObjectStora
GArchOperandClass *parent; /* Classe parente à consulter */
a7shiftop_extra_data_t *extra; /* Données insérées à modifier */
uleb128_t value; /* Valeur ULEB128 à charger */
- GSerializableObject *shift_value; /* Valeur du décalage */
parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class);
@@ -613,27 +614,15 @@ static bool g_armv7_shift_operand_load(GArmV7ShiftOperand *operand, GObjectStora
{
extra = GET_ARMV7_SHIFT_OP_EXTRA(operand);
- LOCK_GOBJECT_EXTRA(extra);
-
result = unpack_uleb128(&value, pbuf);
if (result)
extra->shift_type = value;
- UNLOCK_GOBJECT_EXTRA(extra);
-
}
if (result)
- {
- shift_value = g_object_storage_unpack_object(storage, "operands", pbuf);
-
- result = (shift_value != NULL);
-
- if (result)
- operand->shift_value = G_ARCH_OPERAND(shift_value);
-
- }
+ result = _g_arch_operand_load_inner_instances(G_ARCH_OPERAND(operand), storage, pbuf, 1);
return result;
@@ -659,7 +648,6 @@ static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *operand, GObjectStor
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
a7shiftop_extra_data_t *extra; /* Données insérées à modifier */
- GSerializableObject *shift_value; /* Valeur du décalage */
parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class);
@@ -669,19 +657,12 @@ static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *operand, GObjectStor
{
extra = GET_ARMV7_SHIFT_OP_EXTRA(operand);
- LOCK_GOBJECT_EXTRA(extra);
-
result = pack_uleb128((uleb128_t []){ extra->shift_type }, pbuf);
- UNLOCK_GOBJECT_EXTRA(extra);
-
}
if (result)
- {
- shift_value = G_SERIALIZABLE_OBJECT(operand->shift_value);
- result = g_object_storage_pack_object(storage, "operands", shift_value, pbuf);
- }
+ result = _g_arch_operand_store_inner_instances(G_ARCH_OPERAND(operand), storage, pbuf, true);
return result;
diff --git a/plugins/dalvik/operands/args.c b/plugins/dalvik/operands/args.c
index 7eec5d7..b1aa59f 100644
--- a/plugins/dalvik/operands/args.c
+++ b/plugins/dalvik/operands/args.c
@@ -97,12 +97,6 @@ static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *, G
/* Fournit l'empreinte d'un candidat à une centralisation. */
static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *, bool);
-/* Charge un contenu depuis une mémoire tampon. */
-static bool g_dalvik_args_operand_load(GDalvikArgsOperand *, GObjectStorage *, packed_buffer_t *);
-
-/* Sauvegarde un contenu dans une mémoire tampon. */
-static bool g_dalvik_args_operand_store(GDalvikArgsOperand *, GObjectStorage *, packed_buffer_t *);
-
/* ---------------------------------------------------------------------------------- */
@@ -148,8 +142,8 @@ static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass)
operand->update_inner = (operand_update_inners_fc)g_dalvik_args_operand_update_inner_instances;
operand->hash = (operand_hash_fc)g_dalvik_args_operand_hash;
- operand->load = (load_operand_fc)g_dalvik_args_operand_load;
- operand->store = (store_operand_fc)g_dalvik_args_operand_store;
+ operand->load = g_arch_operand_load_generic_variadic;
+ operand->store = g_arch_operand_store_generic_variadic;
}
@@ -586,15 +580,16 @@ static void g_dalvik_args_operand_update_inner_instances(GDalvikArgsOperand *ope
{
size_t i; /* Boucle de parcours */
- assert(count == operand->count);
-
for (i = 0; i < count; i++)
- {
g_object_unref(G_OBJECT(operand->args[i]));
+ operand->count = count;
+ operand->args = realloc(operand->args, operand->count * sizeof(GArchOperand *));
+
+ for (i = 0; i < count; i++)
+ {
operand->args[i] = instances[i];
g_object_ref(G_OBJECT(instances[i]));
-
}
}
@@ -635,93 +630,3 @@ static guint g_dalvik_args_operand_hash(const GDalvikArgsOperand *operand, bool
return result;
}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
-* *
-* Description : Charge un contenu depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_dalvik_args_operand_load(GDalvikArgsOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- uleb128_t value; /* Valeur ULEB128 à charger */
- size_t i; /* Boucle de parcours */
- GSerializableObject *arg; /* Nouvel argument à intégrer */
-
- parent = G_ARCH_OPERAND_CLASS(g_dalvik_args_operand_parent_class);
-
- result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- result = unpack_uleb128(&value, pbuf);
-
- if (result)
- {
- operand->count = value;
- operand->args = calloc(operand->count, sizeof(GArchOperand *));
- }
-
- for (i = 0; i < operand->count && result; i++)
- {
- arg = g_object_storage_unpack_object(storage, "operands", pbuf);
- if (arg == NULL) break;
-
- operand->args[operand->count - 1] = G_ARCH_OPERAND(arg);
-
- }
-
- result = (i == operand->count);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : operand = élément GLib à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Sauvegarde un contenu dans une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_dalvik_args_operand_store(GDalvikArgsOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchOperandClass *parent; /* Classe parente à consulter */
- size_t i; /* Boucle de parcours */
- GSerializableObject *arg; /* Nouvel argument à intégrer */
-
- parent = G_ARCH_OPERAND_CLASS(g_dalvik_args_operand_parent_class);
-
- result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
-
- if (result)
- result = pack_uleb128((uleb128_t []){ operand->count }, pbuf);
-
- for (i = 0; i < operand->count && result; i++)
- {
- arg = G_SERIALIZABLE_OBJECT(operand->args[i]);
- result = g_object_storage_pack_object(storage, "operands", arg, pbuf);
- }
-
- return result;
-
-}
diff --git a/src/analysis/storage/storage.c b/src/analysis/storage/storage.c
index e286641..c641a52 100644
--- a/src/analysis/storage/storage.c
+++ b/src/analysis/storage/storage.c
@@ -28,6 +28,7 @@
#include <malloc.h>
#include <string.h>
#include <unistd.h>
+#include <stdarg.h>
#include "storage-int.h"
@@ -702,6 +703,67 @@ GSerializableObject *g_object_storage_unpack_object(GObjectStorage *storage, con
/******************************************************************************
* *
+* Paramètres : storage = gestionnaire à manipuler. *
+* name = désignation d'un nouveau groupe d'objets. *
+* pbuf = zone tampon à parcourir. *
+* expected = type d'objet attendu. *
+* ... = élément restauré ou NULL en cas d'échec. [OUT] *
+* *
+* Description : Charge un objet interne à partir de données rassemblées. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_object_storage_unpack_object_2(GObjectStorage *storage, const char *name, packed_buffer_t *pbuf, GType expected, ...)
+{
+ bool result; /* Bilan d'une opération */
+ uint64_t pos; /* Localisation des données */
+ GSerializableObject *instance; /* Objet rechargé à valider */
+ va_list ap; /* Liste d'arguments variables */
+ void **object; /* Lieu d'enregistrement final */
+
+ result = extract_packed_buffer(pbuf, &pos, sizeof(uint64_t), true);
+
+ if (result)
+ {
+ if (pos == 0)
+ *object = NULL;
+
+ else
+ {
+ instance = g_object_storage_load_object(storage, name, pos);
+
+ result = G_TYPE_CHECK_INSTANCE_TYPE(instance, expected);
+
+ if (result)
+ {
+ va_start(ap, expected);
+
+ object = va_arg(ap, void **);
+
+ *object = instance;
+
+ va_end(ap);
+
+ }
+
+ else
+ g_clear_object(&instance);
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : storage = gestionnaire à manipuler. *
* name = désignation d'un nouveau groupe d'objets. *
* object = objet sérialisable à traiter. *
@@ -787,10 +849,17 @@ bool g_object_storage_pack_object(GObjectStorage *storage, const char *name, con
bool result; /* Bilan à retourner */
off64_t pos; /* Localisation des données */
- result = g_object_storage_store_object(storage, name, object, &pos);
+ if (object == NULL)
+ result = extend_packed_buffer(pbuf, (uint64_t []){ 0 }, sizeof(uint64_t), true);
- if (result)
- result = extend_packed_buffer(pbuf, (uint64_t []){ pos }, sizeof(uint64_t), true);
+ else
+ {
+ result = g_object_storage_store_object(storage, name, object, &pos);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, (uint64_t []){ pos }, sizeof(uint64_t), true);
+
+ }
return result;
diff --git a/src/analysis/storage/storage.h b/src/analysis/storage/storage.h
index 0d35d78..cc0caad 100644
--- a/src/analysis/storage/storage.h
+++ b/src/analysis/storage/storage.h
@@ -78,6 +78,9 @@ GSerializableObject *g_object_storage_unpack_object(GObjectStorage *, const char
/* Sauvegarde un object sous forme de données rassemblées. */
bool g_object_storage_store_object(GObjectStorage *, const char *, const GSerializableObject *, off64_t *);
+/* Charge un objet interne à partir de données rassemblées. */
+bool g_object_storage_unpack_object_2(GObjectStorage *, const char *, packed_buffer_t *, GType, ...);
+
/* Sauvegarde un object interne sous forme de données. */
bool g_object_storage_pack_object(GObjectStorage *, const char *, const GSerializableObject *, packed_buffer_t *);
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index 3ea5713..8a2eea3 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -9,7 +9,7 @@ libarch_la_SOURCES = \
instruction-int.h \
instruction.h instruction.c \
link.h link.c \
- operand-int.h \
+ operand-int.h operand-int.c \
operand.h operand.c \
post.h post.c \
processor-int.h \
diff --git a/src/arch/operand-int.c b/src/arch/operand-int.c
new file mode 100644
index 0000000..51e8d44
--- /dev/null
+++ b/src/arch/operand-int.c
@@ -0,0 +1,308 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * operand-int.c - définition générique interne des opérandes
+ *
+ * Copyright (C) 2021 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "operand-int.h"
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONSERVATION ET RECHARGEMENT DES DONNEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à consulter. *
+* count = quantité d'opérandes à extraire du tampon. *
+* *
+* Description : Charge une série d'opérandes internes depuis un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _g_arch_operand_load_inner_instances(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf, size_t count)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperand **instances; /* Liste d'opérandes à charger */
+ size_t i; /* Boucle de parcours */
+
+ result = true;
+
+ instances = calloc(count, sizeof(GArchOperand *));
+
+ for (i = 0; i < count && result; i++)
+ result = g_object_storage_unpack_object_2(storage, "operands", pbuf, G_TYPE_ARCH_OPERAND, &instances[i]);
+
+ if (result)
+ g_arch_operand_update_inner_instances(operand, instances, count);
+
+ for (i = 0; i < count; i++)
+ g_clear_object(&instances[i]);
+
+ free(instances);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à consulter. *
+* *
+* Description : Charge une série d'opérandes internes depuis un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_load_generic_fixed_1(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, 1);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à consulter. *
+* *
+* Description : Charge une série d'opérandes internes depuis un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_load_generic_fixed_3(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, 3);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à consulter. *
+* *
+* Description : Charge une série d'opérandes internes depuis un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_load_generic_variadic(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+ uleb128_t value; /* Valeur ULEB128 à charger */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ result = _g_arch_operand_load_inner_instances(operand, storage, pbuf, value);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* fixed = précise si le nombre d'opérande est fixe ou non. *
+* *
+* Description : Sauvegarde une série d'opérandes internes dans un tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _g_arch_operand_store_inner_instances(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf, bool fixed)
+{
+ bool result; /* Bilan à retourner */
+ size_t count; /* Nombre d'opérandes listées */
+ GArchOperand **instances; /* Liste d'opérandes à traiter */
+ size_t i; /* Boucle de parcours */
+ GSerializableObject *obj; /* Objet à conserver */
+
+ result = true;
+
+ instances = g_arch_operand_list_inner_instances(operand, &count);
+
+ if (!fixed)
+ result = pack_uleb128((uleb128_t []){ count }, pbuf);
+
+ if (instances != NULL)
+ {
+ for (i = 0; i < count && result; i++)
+ {
+ if (instances[i] == NULL)
+ result = g_object_storage_pack_object(storage, "operands", NULL, pbuf);
+
+ else
+ {
+ obj = G_SERIALIZABLE_OBJECT(instances[i]);
+
+ result = g_object_storage_pack_object(storage, "operands", obj, pbuf);
+
+ g_object_unref(G_OBJECT(instances[i]));
+
+ }
+
+ }
+
+ for (; i < count && result; i++)
+ g_clear_object(&instances[i]);
+
+ free(instances);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* fixed = précise si le nombre d'opérande est fixe ou non. *
+* *
+* Description : Sauvegarde un opérande dans un tampon de façon générique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_store_generic_fixed(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = _g_arch_operand_store_inner_instances(operand, storage, pbuf, true);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = élément GLib à consulter. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à remplir. *
+* fixed = précise si le nombre d'opérande est fixe ou non. *
+* *
+* Description : Sauvegarde un opérande dans un tampon de façon générique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_operand_store_generic_variadic(GArchOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GType type; /* Type d'opérande manipulé */
+ GArchOperandClass *parent; /* Classe parente à consulter */
+
+ type = G_TYPE_FROM_INSTANCE(operand);
+
+ parent = g_type_class_peek_parent(g_type_class_peek(type));
+
+ result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
+
+ if (result)
+ result = _g_arch_operand_store_inner_instances(operand, storage, pbuf, false);
+
+ return result;
+
+}
diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h
index dc505b6..d424e94 100644
--- a/src/arch/operand-int.h
+++ b/src/arch/operand-int.h
@@ -26,6 +26,11 @@
#include "operand.h"
+
+
+#include <stdbool.h>
+
+
#include "../analysis/storage/storage.h"
#include "../glibext/objhole.h"
@@ -143,4 +148,41 @@ bool _g_arch_operand_unset_flag(GArchOperand *, ArchOperandFlag, bool);
+/* ------------------------ CONTROLE DU VOLUME DES INSTANCES ------------------------ */
+
+
+/* Fournit une liste de candidats embarqués par un candidat. */
+GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, size_t *);
+
+/* Met à jour une liste de candidats embarqués par un candidat. */
+void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t);
+
+
+
+/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+
+
+/* Charge une série d'opérandes internes depuis un tampon. */
+bool _g_arch_operand_load_inner_instances(GArchOperand *, GObjectStorage *, packed_buffer_t *, size_t);
+
+/* Charge une série d'opérandes internes depuis un tampon. */
+bool g_arch_operand_load_generic_fixed_1(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Charge une série d'opérandes internes depuis un tampon. */
+bool g_arch_operand_load_generic_fixed_3(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Charge une série d'opérandes internes depuis un tampon. */
+bool g_arch_operand_load_generic_variadic(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde une série d'opérandes internes dans un tampon. */
+bool _g_arch_operand_store_inner_instances(GArchOperand *, GObjectStorage *, packed_buffer_t *, bool);
+
+/* Sauvegarde un opérande dans un tampon de façon générique. */
+bool g_arch_operand_store_generic_fixed(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un opérande dans un tampon de façon générique. */
+bool g_arch_operand_store_generic_variadic(GArchOperand *, GObjectStorage *, packed_buffer_t *);
+
+
+
#endif /* _ARCH_OPERAND_INT_H */
diff --git a/src/arch/operand.c b/src/arch/operand.c
index 81aa633..f262373 100644
--- a/src/arch/operand.c
+++ b/src/arch/operand.c
@@ -69,10 +69,10 @@ static int _g_arch_operand_compare(const GArchOperand *, const GArchOperand *, b
/* Fournit une liste de candidats embarqués par un candidat. */
-static GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, size_t *);
+GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *, size_t *);
/* Met à jour une liste de candidats embarqués par un candidat. */
-static void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t);
+void g_arch_operand_update_inner_instances(GArchOperand *, GArchOperand **, size_t);
/* Fournit l'empreinte d'un candidat à une centralisation. */
static guint _g_arch_operand_hash(const GArchOperand *, bool);
@@ -642,7 +642,7 @@ ArchOperandFlag g_arch_operand_get_flags(const GArchOperand *operand)
* *
******************************************************************************/
-static GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *operand, size_t *count)
+GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *operand, size_t *count)
{
GArchOperand **result; /* Instances à retourner */
GArchOperandClass *class; /* Classe associée à l'objet */
@@ -677,7 +677,7 @@ static GArchOperand **g_arch_operand_list_inner_instances(const GArchOperand *op
* *
******************************************************************************/
-static void g_arch_operand_update_inner_instances(GArchOperand *operand, GArchOperand **instances, size_t count)
+void g_arch_operand_update_inner_instances(GArchOperand *operand, GArchOperand **instances, size_t count)
{
GArchOperandClass *class; /* Classe associée à l'objet */