diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/instruction.c | 143 | ||||
-rw-r--r-- | src/arch/instruction.h | 7 | ||||
-rw-r--r-- | src/arch/operand-int.h | 9 | ||||
-rw-r--r-- | src/arch/operand.c | 62 | ||||
-rw-r--r-- | src/arch/operand.h | 6 |
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 *); |