diff options
Diffstat (limited to 'src/arch/instruction.c')
-rw-r--r-- | src/arch/instruction.c | 293 |
1 files changed, 212 insertions, 81 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 5f35db4..fc474ea 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -30,6 +30,7 @@ #include "instruction-int.h" +#include "../glibext/linegen-int.h" @@ -39,6 +40,9 @@ static void g_arch_instruction_class_init(GArchInstructionClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_arch_instruction_init(GArchInstruction *); +/* Procède à l'initialisation de l'interface de génération. */ +static void g_arch_instruction_interface_init(GLineGeneratorInterface *); + /* Supprime toutes les références externes. */ static void g_arch_instruction_dispose(GArchInstruction *); @@ -47,16 +51,32 @@ static void g_arch_instruction_finalize(GArchInstruction *); -/* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */ +/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */ + + +/* Indique le nombre de ligne prêtes à être générées. */ +static size_t g_arch_instruction_count_lines(const GArchInstruction *); + +/* Retrouve l'emplacement correspondant à une position donnée. */ +static void g_arch_instruction_compute_addr(const GArchInstruction *, gint, vmpa2t *, size_t, size_t); +/* Détermine si le conteneur s'inscrit dans une plage donnée. */ +static int g_arch_instruction_contains_addr(const GArchInstruction *, const vmpa2t *, size_t, size_t); + +/* Renseigne sur les propriétés liées à un générateur. */ +static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *, size_t, size_t); /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -static GBufferLine *_g_arch_instruction_print(GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax); +static void _g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t); + +/* Imprime dans une ligne de rendu le contenu représenté. */ +static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t); /* Indique le type défini pour une instruction d'architecture. */ -G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_interface_init)); /****************************************************************************** @@ -116,6 +136,29 @@ static void g_arch_instruction_init(GArchInstruction *instr) /****************************************************************************** * * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de génération. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_interface_init(GLineGeneratorInterface *iface) +{ + iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines; + iface->compute = (linegen_compute_fc)g_arch_instruction_compute_addr; + iface->contains = (linegen_contains_fc)g_arch_instruction_contains_addr; + iface->get_flags = (linegen_get_flags_fc)g_arch_instruction_get_flags2; + iface->print = (linegen_print_fc)g_arch_instruction_print; + +} + + +/****************************************************************************** +* * * Paramètres : instr = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * @@ -897,84 +940,6 @@ void g_arch_instruction_set_displayed_max_length(GArchInstruction *instr, phys_t } -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à représenter. * -* buffer = espace où placer ledit contenu. * -* msize = taille idéale des positions et adresses; * -* content = contenu binaire global à venir lire. * -* syntax = type de représentation demandée. * -* * -* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GBufferLine *_g_arch_instruction_print(GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax) -{ - GBufferLine *result; /* Ligne de destination */ - const char *key; /* Mot clef principal */ - size_t klen; /* Taille de ce mot clef */ - size_t i; /* Boucle de parcours */ - - result = g_code_buffer_prepare_new_line(buffer, &instr->range); - - g_buffer_line_add_flag(result, BLF_HAS_CODE); - - g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, instr->max_displayed_len); - - /* Instruction proprement dite */ - - key = g_arch_instruction_get_keyword(instr, syntax); - klen = strlen(key); - - g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); - - if (instr->operands_count > 0) - { - g_arch_operand_print(instr->operands[0], result, syntax); - - for (i = 1; i < instr->operands_count; i++) - { - g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); - g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); - - g_arch_operand_print(instr->operands[i], result, syntax); - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à représenter. * -* buffer = espace où placer ledit contenu. * -* msize = taille idéale des positions et adresses; * -* content = contenu binaire global à venir lire. * -* syntax = type de représentation demandée. * -* * -* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBufferLine *g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax) -{ - return G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, buffer, msize, content, syntax); - -} - /* ---------------------------------------------------------------------------------- */ /* TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE */ @@ -1110,3 +1075,169 @@ GArchInstruction *g_arch_instruction_find_by_address(GArchInstruction *list, con return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* OFFRE DE CAPACITES DE GENERATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à consulter. * +* * +* Description : Indique le nombre de ligne prêtes à être générées. * +* * +* Retour : Nombre de lignes devant apparaître au final. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t g_arch_instruction_count_lines(const GArchInstruction *instr) +{ + return 1; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à consulter. * +* x = position géographique sur la ligne concernée. * +* addr = position en mémoire à analyser. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Retrouve l'emplacement correspondant à une position donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_compute_addr(const GArchInstruction *instr, gint x, vmpa2t *addr, size_t index, size_t repeat) +{ + copy_vmpa(addr, get_mrange_addr(&instr->range)); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à consulter. * +* addr = position en mémoire à analyser. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Détermine si le conteneur s'inscrit dans une plage donnée. * +* * +* Retour : Bilan de la détermination, utilisable en comparaisons. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int g_arch_instruction_contains_addr(const GArchInstruction *instr, const vmpa2t *addr, size_t index, size_t repeat) +{ + int result; /* Conclusion à retourner */ + + result = cmp_mrange_with_vmpa(&instr->range, addr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à consulter. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Renseigne sur les propriétés liées à un générateur. * +* * +* Retour : Propriétés particulières associées. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *instr, size_t index, size_t repeat) +{ + return BLF_HAS_CODE; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à représenter. * +* buffer = espace où placer ledit contenu. * +* msize = taille idéale des positions et adresses; * +* content = contenu binaire global à venir lire. * +* syntax = type de représentation demandée. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat) +{ + const char *key; /* Mot clef principal */ + size_t klen; /* Taille de ce mot clef */ + size_t i; /* Boucle de parcours */ + + g_buffer_line_fill_vmpa(line, get_mrange_addr(&instr->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); + + /* Instruction proprement dite */ + + key = g_arch_instruction_get_keyword(instr, 0/*, syntax*/); + klen = strlen(key); + + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); + + if (instr->operands_count > 0) + { + g_arch_operand_print(instr->operands[0], line, 0/*syntax*/); + + for (i = 1; i < instr->operands_count; i++) + { + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); + + g_arch_operand_print(instr->operands[i], line, 0/*syntax*/); + + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à utiliser pour l'impression. * +* line = ligne de rendu à compléter. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Imprime dans une ligne de rendu le contenu représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat) +{ + G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, line, index, repeat); + +} |