summaryrefslogtreecommitdiff
path: root/plugins/arm/v7/operands
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-08-22 17:57:19 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-08-22 17:59:06 (GMT)
commitf94210f2617968774277078a8db9097c56029039 (patch)
treeb65eb802595a4496e931fe124010ad6f7b995272 /plugins/arm/v7/operands
parent1e4bc888ff02d21b8fe4a45c70298624f35e758a (diff)
Defined paths to access to the instruction operands.
Diffstat (limited to 'plugins/arm/v7/operands')
-rw-r--r--plugins/arm/v7/operands/maccess.c154
-rw-r--r--plugins/arm/v7/operands/offset.c83
-rw-r--r--plugins/arm/v7/operands/rotation.c106
-rw-r--r--plugins/arm/v7/operands/shift.c83
4 files changed, 422 insertions, 4 deletions
diff --git a/plugins/arm/v7/operands/maccess.c b/plugins/arm/v7/operands/maccess.c
index be3f0c9..aa0e9cf 100644
--- a/plugins/arm/v7/operands/maccess.c
+++ b/plugins/arm/v7/operands/maccess.c
@@ -24,8 +24,15 @@
#include "maccess.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
#include <arch/operand-int.h>
+#include <common/cpp.h>
#include <common/sort.h>
+#include <core/logs.h>
#include <gtkext/gtkblockdisplay.h>
@@ -67,6 +74,12 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *);
/* Compare un opérande avec un autre. */
static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *, const GArmV7MAccessOperand *);
+/* Détermine le chemin conduisant à un opérande interne. */
+static char *g_armv7_maccess_operand_find_inner_operand_path(const GArmV7MAccessOperand *, const GArchOperand *);
+
+/* Obtient l'opérande correspondant à un chemin donné. */
+static GArchOperand *g_armv7_maccess_operand_get_inner_operand_from_path(const GArmV7MAccessOperand *, const char *);
+
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *, GBufferLine *);
@@ -105,12 +118,16 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass)
GArchOperandClass *operand; /* Version de classe parente */
object = G_OBJECT_CLASS(klass);
- operand = G_ARCH_OPERAND_CLASS(klass);
object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_maccess_operand_dispose;
object->finalize = (GObjectFinalizeFunc)g_armv7_maccess_operand_finalize;
+ operand = G_ARCH_OPERAND_CLASS(klass);
+
operand->compare = (operand_compare_fc)g_armv7_maccess_operand_compare;
+ operand->find_inner = (find_inner_operand_fc)g_armv7_maccess_operand_find_inner_operand_path;
+ operand->get_inner = (get_inner_operand_fc)g_armv7_maccess_operand_get_inner_operand_from_path;
+
operand->print = (operand_print_fc)g_armv7_maccess_operand_print;
operand->unserialize = (unserialize_operand_fc)g_armv7_maccess_operand_unserialize;
@@ -227,6 +244,141 @@ static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *a, const
/******************************************************************************
* *
+* Paramètres : operand = opérande à consulter. *
+* target = instruction à venir retrouver. *
+* *
+* Description : Détermine le chemin conduisant à un opérande interne. *
+* *
+* Retour : Chemin d'accès à l'opérande ou NULL en cas d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_armv7_maccess_operand_find_inner_operand_path(const GArmV7MAccessOperand *operand, const GArchOperand *target)
+{
+ char *result; /* Chemin à retourner */
+ size_t count; /* Nombre d'opérandes en place */
+ size_t i; /* Boucle de parcours */
+ int ret; /* Bilan d'une construction */
+ char *sub_path; /* Sous-chemin emprunté */
+
+ GArchOperand *candidates[] = { operand->base, operand->offset, operand->shift };
+
+ result = NULL;
+
+ count = ARRAY_SIZE(candidates);
+
+ /* Première passe : accès direct */
+
+ for (i = 0; i < count && result == NULL; i++)
+ {
+ if (candidates[i] == NULL)
+ continue;
+
+ if (candidates[i] == target)
+ {
+ ret = asprintf(&result, "%zu", i);
+ if (ret == -1)
+ {
+ LOG_ERROR_N("asprintf");
+ result = NULL;
+ }
+ }
+
+ }
+
+ /* Seconde passe : accès profond */
+
+ for (i = 0; i < count && result == NULL; i++)
+ {
+ if (candidates[i] == NULL)
+ continue;
+
+ sub_path = g_arch_operand_find_inner_operand_path(candidates[i], target);
+
+ if (sub_path != NULL)
+ {
+ ret = asprintf(&result, "%zu:%s", i, sub_path);
+ if (ret == -1)
+ {
+ LOG_ERROR_N("asprintf");
+ result = NULL;
+ }
+
+ free(sub_path);
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* path = chemin d'accès à un opérande à retrouver. *
+* *
+* Description : Obtient l'opérande correspondant à un chemin donné. *
+* *
+* Retour : Opérande trouvé ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchOperand *g_armv7_maccess_operand_get_inner_operand_from_path(const GArmV7MAccessOperand *operand, const char *path)
+{
+ GArchOperand *result; /* Opérande trouvée à renvoyer */
+ size_t index; /* Indice de l'opérande visé */
+ char *end; /* Poursuite du parcours ? */
+ GArchOperand *found; /* Opérande trouvé */
+
+ GArchOperand *candidates[] = { operand->base, operand->offset, operand->shift };
+
+ result = NULL;
+
+ /* Recherche au premier niveau */
+
+ index = strtoul(path, &end, 10);
+
+ if ((index == ULONG_MAX && errno == ERANGE) || (index == 0 && errno == EINVAL))
+ {
+ LOG_ERROR_N("strtoul");
+ goto done;
+ }
+
+ if (index >= ARRAY_SIZE(candidates))
+ goto done;
+
+ found = candidates[index];
+ if (found == NULL) goto done;
+
+ if (*end == '\0')
+ {
+ result = found;
+ g_object_ref(G_OBJECT(result));
+ goto done;
+ }
+
+ /* Recherche en profondeur */
+
+ assert(*end == ':');
+
+ result = g_arch_operand_get_inner_operand_from_path(found, end + 1);
+
+ done:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = opérande à traiter. *
* line = ligne tampon où imprimer l'opérande donné. *
* *
diff --git a/plugins/arm/v7/operands/offset.c b/plugins/arm/v7/operands/offset.c
index 6bcacaf..967b296 100644
--- a/plugins/arm/v7/operands/offset.c
+++ b/plugins/arm/v7/operands/offset.c
@@ -24,6 +24,10 @@
#include "offset.h"
+#include <stdio.h>
+#include <string.h>
+
+
#include <arch/operand-int.h>
#include <common/sort.h>
#include <gtkext/gtkblockdisplay.h>
@@ -64,6 +68,12 @@ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *);
/* Compare un opérande avec un autre. */
static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *, const GArmV7OffsetOperand *);
+/* Détermine le chemin conduisant à un opérande interne. */
+static char *g_armv7_offset_operand_find_inner_operand_path(const GArmV7OffsetOperand *, const GArchOperand *);
+
+/* Obtient l'opérande correspondant à un chemin donné. */
+static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GArmV7OffsetOperand *, const char *);
+
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *, GBufferLine *);
@@ -102,12 +112,16 @@ static void g_armv7_offset_operand_class_init(GArmV7OffsetOperandClass *klass)
GArchOperandClass *operand; /* Version de classe parente */
object = G_OBJECT_CLASS(klass);
- operand = G_ARCH_OPERAND_CLASS(klass);
object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_offset_operand_dispose;
object->finalize = (GObjectFinalizeFunc)g_armv7_offset_operand_finalize;
+ operand = G_ARCH_OPERAND_CLASS(klass);
+
operand->compare = (operand_compare_fc)g_armv7_offset_operand_compare;
+ operand->find_inner = (find_inner_operand_fc)g_armv7_offset_operand_find_inner_operand_path;
+ operand->get_inner = (get_inner_operand_fc)g_armv7_offset_operand_get_inner_operand_from_path;
+
operand->print = (operand_print_fc)g_armv7_offset_operand_print;
operand->unserialize = (unserialize_operand_fc)g_armv7_offset_operand_unserialize;
@@ -207,6 +221,73 @@ static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *a, const GA
/******************************************************************************
* *
+* Paramètres : operand = opérande à consulter. *
+* target = instruction à venir retrouver. *
+* *
+* Description : Détermine le chemin conduisant à un opérande interne. *
+* *
+* Retour : Chemin d'accès à l'opérande ou NULL en cas d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_armv7_offset_operand_find_inner_operand_path(const GArmV7OffsetOperand *operand, const GArchOperand *target)
+{
+ char *result; /* Chemin à retourner */
+
+ if (target == operand->value)
+ result = strdup("0");
+ else
+ result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* path = chemin d'accès à un opérande à retrouver. *
+* *
+* Description : Obtient l'opérande correspondant à un chemin donné. *
+* *
+* Retour : Opérande trouvé ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GArmV7OffsetOperand *operand, const char *path)
+{
+ GArchOperand *result; /* Opérande trouvée à renvoyer */
+
+ if (strncmp(path, "0", 1) == 0)
+ switch (path[1])
+ {
+ case '\0':
+ result = operand->value;
+ g_object_ref(G_OBJECT(result));
+ break;
+
+ case ':':
+ result = g_arch_operand_get_inner_operand_from_path(operand->value, path + 1);
+ break;
+
+ default:
+ result = NULL;
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = opérande à traiter. *
* line = ligne tampon où imprimer l'opérande donné. *
* *
diff --git a/plugins/arm/v7/operands/rotation.c b/plugins/arm/v7/operands/rotation.c
index b6fe1cf..5db1d27 100644
--- a/plugins/arm/v7/operands/rotation.c
+++ b/plugins/arm/v7/operands/rotation.c
@@ -24,7 +24,12 @@
#include "rotation.h"
+#include <stdio.h>
+#include <string.h>
+
+
#include <arch/operand-int.h>
+#include <core/logs.h>
#include <gtkext/gtkblockdisplay.h>
@@ -62,6 +67,12 @@ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *);
/* Compare un opérande avec un autre. */
static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *, const GArmV7RotationOperand *);
+/* Détermine le chemin conduisant à un opérande interne. */
+static char *g_armv7_rotation_operand_find_inner_operand_path(const GArmV7RotationOperand *, const GArchOperand *);
+
+/* Obtient l'opérande correspondant à un chemin donné. */
+static GArchOperand *g_armv7_rotation_operand_get_inner_operand_from_path(const GArmV7RotationOperand *, const char *);
+
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *, GBufferLine *);
@@ -100,12 +111,16 @@ static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klas
GArchOperandClass *operand; /* Version de classe parente */
object = G_OBJECT_CLASS(klass);
- operand = G_ARCH_OPERAND_CLASS(klass);
object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_rotation_operand_dispose;
object->finalize = (GObjectFinalizeFunc)g_armv7_rotation_operand_finalize;
+ operand = G_ARCH_OPERAND_CLASS(klass);
+
operand->compare = (operand_compare_fc)g_armv7_rotation_operand_compare;
+ operand->find_inner = (find_inner_operand_fc)g_armv7_rotation_operand_find_inner_operand_path;
+ operand->get_inner = (get_inner_operand_fc)g_armv7_rotation_operand_get_inner_operand_from_path;
+
operand->print = (operand_print_fc)g_armv7_rotation_operand_print;
operand->unserialize = (unserialize_operand_fc)g_armv7_rotation_operand_unserialize;
@@ -200,6 +215,95 @@ static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *a, cons
/******************************************************************************
* *
+* Paramètres : operand = opérande à consulter. *
+* target = instruction à venir retrouver. *
+* *
+* Description : Détermine le chemin conduisant à un opérande interne. *
+* *
+* Retour : Chemin d'accès à l'opérande ou NULL en cas d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_armv7_rotation_operand_find_inner_operand_path(const GArmV7RotationOperand *operand, const GArchOperand *target)
+{
+ char *result; /* Chemin à retourner */
+ char *sub_path; /* Sous-chemin emprunté */
+ int ret; /* Bilan d'une construction */
+
+ if (target == operand->value)
+ result = strdup("0");
+
+ else
+ {
+ sub_path = g_arch_operand_find_inner_operand_path(operand->value, target);
+
+ if (sub_path != NULL)
+ {
+ ret = asprintf(&result, "0:%s", sub_path);
+ if (ret == -1)
+ {
+ LOG_ERROR_N("asprintf");
+ result = NULL;
+ }
+
+ free(sub_path);
+
+ }
+
+ else
+ result = NULL;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* path = chemin d'accès à un opérande à retrouver. *
+* *
+* Description : Obtient l'opérande correspondant à un chemin donné. *
+* *
+* Retour : Opérande trouvé ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchOperand *g_armv7_rotation_operand_get_inner_operand_from_path(const GArmV7RotationOperand *operand, const char *path)
+{
+ GArchOperand *result; /* Opérande trouvée à renvoyer */
+
+ if (strncmp(path, "0", 1) == 0)
+ switch (path[1])
+ {
+ case '\0':
+ result = operand->value;
+ g_object_ref(G_OBJECT(result));
+ break;
+
+ case ':':
+ result = g_arch_operand_get_inner_operand_from_path(operand->value, path + 1);
+ break;
+
+ default:
+ result = NULL;
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = opérande à traiter. *
* line = ligne tampon où imprimer l'opérande donné. *
* *
diff --git a/plugins/arm/v7/operands/shift.c b/plugins/arm/v7/operands/shift.c
index a0c345a..8da666e 100644
--- a/plugins/arm/v7/operands/shift.c
+++ b/plugins/arm/v7/operands/shift.c
@@ -24,6 +24,10 @@
#include "shift.h"
+#include <stdio.h>
+#include <string.h>
+
+
#include <arch/operand-int.h>
#include <common/sort.h>
#include <gtkext/gtkblockdisplay.h>
@@ -64,6 +68,12 @@ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *);
/* Compare un opérande avec un autre. */
static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *, const GArmV7ShiftOperand *);
+/* Détermine le chemin conduisant à un opérande interne. */
+static char *g_armv7_shift_operand_find_inner_operand_path(const GArmV7ShiftOperand *, const GArchOperand *);
+
+/* Obtient l'opérande correspondant à un chemin donné. */
+static GArchOperand *g_armv7_shift_operand_get_inner_operand_from_path(const GArmV7ShiftOperand *, const char *);
+
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *, GBufferLine *);
@@ -102,12 +112,16 @@ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *klass)
GArchOperandClass *operand; /* Version de classe parente */
object = G_OBJECT_CLASS(klass);
- operand = G_ARCH_OPERAND_CLASS(klass);
object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_shift_operand_dispose;
object->finalize = (GObjectFinalizeFunc)g_armv7_shift_operand_finalize;
+ operand = G_ARCH_OPERAND_CLASS(klass);
+
operand->compare = (operand_compare_fc)g_armv7_shift_operand_compare;
+ operand->find_inner = (find_inner_operand_fc)g_armv7_shift_operand_find_inner_operand_path;
+ operand->get_inner = (get_inner_operand_fc)g_armv7_shift_operand_get_inner_operand_from_path;
+
operand->print = (operand_print_fc)g_armv7_shift_operand_print;
operand->unserialize = (unserialize_operand_fc)g_armv7_shift_operand_unserialize;
@@ -207,6 +221,73 @@ static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *a, const GArm
/******************************************************************************
* *
+* Paramètres : operand = opérande à consulter. *
+* target = instruction à venir retrouver. *
+* *
+* Description : Détermine le chemin conduisant à un opérande interne. *
+* *
+* Retour : Chemin d'accès à l'opérande ou NULL en cas d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_armv7_shift_operand_find_inner_operand_path(const GArmV7ShiftOperand *operand, const GArchOperand *target)
+{
+ char *result; /* Chemin à retourner */
+
+ if (target == operand->shift_value)
+ result = strdup("0");
+ else
+ result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* path = chemin d'accès à un opérande à retrouver. *
+* *
+* Description : Obtient l'opérande correspondant à un chemin donné. *
+* *
+* Retour : Opérande trouvé ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchOperand *g_armv7_shift_operand_get_inner_operand_from_path(const GArmV7ShiftOperand *operand, const char *path)
+{
+ GArchOperand *result; /* Opérande trouvée à renvoyer */
+
+ if (strncmp(path, "0", 1) == 0)
+ switch (path[1])
+ {
+ case '\0':
+ result = operand->shift_value;
+ g_object_ref(G_OBJECT(result));
+ break;
+
+ case ':':
+ result = g_arch_operand_get_inner_operand_from_path(operand->shift_value, path + 1);
+ break;
+
+ default:
+ result = NULL;
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = opérande à traiter. *
* line = ligne tampon où imprimer l'opérande donné. *
* *