diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2020-08-22 17:57:19 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2020-08-22 17:59:06 (GMT) |
commit | f94210f2617968774277078a8db9097c56029039 (patch) | |
tree | b65eb802595a4496e931fe124010ad6f7b995272 /plugins/arm/v7/operands | |
parent | 1e4bc888ff02d21b8fe4a45c70298624f35e758a (diff) |
Defined paths to access to the instruction operands.
Diffstat (limited to 'plugins/arm/v7/operands')
-rw-r--r-- | plugins/arm/v7/operands/maccess.c | 154 | ||||
-rw-r--r-- | plugins/arm/v7/operands/offset.c | 83 | ||||
-rw-r--r-- | plugins/arm/v7/operands/rotation.c | 106 | ||||
-rw-r--r-- | plugins/arm/v7/operands/shift.c | 83 |
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é. * * * |