summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/instruction.c143
-rw-r--r--src/arch/instruction.h7
-rw-r--r--src/arch/operand-int.h9
-rw-r--r--src/arch/operand.c62
-rw-r--r--src/arch/operand.h6
5 files changed, 227 insertions, 0 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index ea19dab..52c3aa0 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -27,11 +27,14 @@
#include <assert.h>
#include <malloc.h>
#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "instruction-int.h"
#include "storage.h"
+#include "../core/logs.h"
#include "../glibext/gbinarycursor.h"
#include "../glibext/linegen-int.h"
#include "../gtkext/gtkblockdisplay.h"
@@ -819,6 +822,146 @@ bool _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *t
}
+/******************************************************************************
+* *
+* Paramètres : instr = instance à consulter. *
+* target = instruction à venir retrouver. *
+* *
+* Description : Détermine le chemin conduisant à un opérande. *
+* *
+* Retour : Chemin d'accès à l'opérande ou NULL en cas d'absence. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *g_arch_instruction_find_operand_path(GArchInstruction *instr, const GArchOperand *target)
+{
+ char *result; /* Chemin à retourner */
+ size_t count; /* Nombre d'opérandes en place */
+ size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à manipuler */
+ int ret; /* Bilan d'une construction */
+ char *sub_path; /* Sous-chemin emprunté */
+
+ result = NULL;
+
+ g_arch_instruction_lock_operands(instr);
+
+ count = _g_arch_instruction_count_operands(instr);
+
+ /* Première passe : accès direct */
+
+ for (i = 0; i < count && result == NULL; i++)
+ {
+ op = _g_arch_instruction_get_operand(instr, i);
+
+ if (op == target)
+ {
+ ret = asprintf(&result, "%zu", i);
+ if (ret == -1)
+ {
+ LOG_ERROR_N("asprintf");
+ result = NULL;
+ }
+ }
+
+ g_object_unref(G_OBJECT(op));
+
+ }
+
+ /* Seconde passe : accès profond */
+
+ for (i = 0; i < count && result == NULL; i++)
+ {
+ op = _g_arch_instruction_get_operand(instr, i);
+
+ sub_path = g_arch_operand_find_inner_operand_path(op, 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);
+
+ }
+
+ g_object_unref(G_OBJECT(op));
+
+ }
+
+ g_arch_instruction_unlock_operands(instr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instance à 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 : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_arch_instruction_get_operand_from_path(GArchInstruction *instr, 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é */
+
+ result = NULL;
+
+ g_arch_instruction_lock_operands(instr);
+
+ /* 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;
+ }
+
+ found = _g_arch_instruction_get_operand(instr, index);
+ if (found == NULL) goto done;
+
+ if (*end == '\0')
+ {
+ result = found;
+ goto done;
+ }
+
+ /* Recherche en profondeur */
+
+ assert(*end == ':');
+
+ result = g_arch_operand_get_inner_operand_from_path(found, end + 1);
+
+ g_object_unref(G_OBJECT(found));
+
+ done:
+
+ g_arch_instruction_unlock_operands(instr);
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index e8ba4bd..0401853 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -208,6 +208,13 @@ bool _g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
})
+/* Détermine le chemin conduisant à un opérande. */
+char *g_arch_instruction_find_operand_path(GArchInstruction *, const GArchOperand *);
+
+/* Obtient l'opérande correspondant à un chemin donné. */
+GArchOperand *g_arch_instruction_get_operand_from_path(GArchInstruction *, const char *);
+
+
/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */
diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h
index 4cc676e..b019ac1 100644
--- a/src/arch/operand-int.h
+++ b/src/arch/operand-int.h
@@ -32,6 +32,12 @@
/* Compare un opérande avec un autre. */
typedef int (* operand_compare_fc) (const GArchOperand *, const GArchOperand *);
+/* Détermine le chemin conduisant à un opérande interne. */
+typedef char * (* find_inner_operand_fc) (const GArchOperand *, const GArchOperand *);
+
+/* Obtient l'opérande correspondant à un chemin donné. */
+typedef GArchOperand * (* get_inner_operand_fc) (const GArchOperand *, const char *);
+
/* Traduit un opérande en version humainement lisible. */
typedef void (* operand_print_fc) (const GArchOperand *, GBufferLine *);
@@ -59,6 +65,9 @@ struct _GArchOperandClass
GObjectClass parent; /* A laisser en premier */
operand_compare_fc compare; /* Comparaison d'opérandes */
+ find_inner_operand_fc find_inner; /* Définition d'un chemin */
+ get_inner_operand_fc get_inner; /* Récupération d'un opérande */
+
operand_print_fc print; /* Texte humain équivalent */
operand_build_tooltip_fc build_tooltip; /* Construction de description */
diff --git a/src/arch/operand.c b/src/arch/operand.c
index 237cc76..92fb1d6 100644
--- a/src/arch/operand.c
+++ b/src/arch/operand.c
@@ -193,6 +193,68 @@ int g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b)
/******************************************************************************
* *
+* 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 : - *
+* *
+******************************************************************************/
+
+char *g_arch_operand_find_inner_operand_path(const GArchOperand *operand, const GArchOperand *target)
+{
+ char *result; /* Chemin à retourner */
+ GArchOperandClass *class; /* Classe associée à l'objet */
+
+ class = G_ARCH_OPERAND_GET_CLASS(operand);
+
+ if (class->find_inner != NULL)
+ result = class->find_inner(operand, target);
+
+ 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 : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_arch_operand_get_inner_operand_from_path(const GArchOperand *operand, const char *path)
+{
+ GArchOperand *result; /* Opérande trouvée à renvoyer */
+ GArchOperandClass *class; /* Classe associée à l'objet */
+
+ class = G_ARCH_OPERAND_GET_CLASS(operand);
+
+ if (class->get_inner != NULL)
+ result = class->get_inner(operand, path);
+
+ else
+ result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = opérande à traiter. *
* line = ligne tampon où imprimer l'opérande donné. *
* *
diff --git a/src/arch/operand.h b/src/arch/operand.h
index faeab49..4d3a80a 100644
--- a/src/arch/operand.h
+++ b/src/arch/operand.h
@@ -62,6 +62,12 @@ GType g_arch_operand_get_type(void);
/* Compare un opérande avec un autre. */
int g_arch_operand_compare(const GArchOperand *, const GArchOperand *);
+/* Détermine le chemin conduisant à un opérande interne. */
+char *g_arch_operand_find_inner_operand_path(const GArchOperand *, const GArchOperand *);
+
+/* Obtient l'opérande correspondant à un chemin donné. */
+GArchOperand *g_arch_operand_get_inner_operand_from_path(const GArchOperand *, const char *);
+
/* Traduit un opérande en version humainement lisible. */
void g_arch_operand_print(const GArchOperand *, GBufferLine *);