/* Chrysalide - Outil d'analyse de fichiers binaires * instruction.c - gestion générique des instructions * * Copyright (C) 2008-2014 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "instruction.h" #include #include #include #include "instruction-int.h" /* Initialise la classe générique des instructions. */ static void g_arch_instruction_class_init(GArchInstructionClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_arch_instruction_init(GArchInstruction *); /* Supprime toutes les références externes. */ static void g_arch_instruction_dispose(GArchInstruction *); /* Procède à la libération totale de la mémoire. */ static void g_arch_instruction_finalize(GArchInstruction *); /* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */ /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ static GBufferLine *_g_arch_instruction_print(GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax); /* Indique le type défini pour une instruction d'architecture. */ G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe générique des instructions. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_instruction_class_init(GArchInstructionClass *klass) { GObjectClass *object; /* Autre version de la classe */ GArchInstructionClass *instr; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_instruction_dispose; object->finalize = (GObjectFinalizeFunc)g_arch_instruction_finalize; instr = G_ARCH_INSTRUCTION_CLASS(klass); instr->print = (print_instruction_fc)_g_arch_instruction_print; } /****************************************************************************** * * * Paramètres : instr = instance à initialiser. * * * * Description : Initialise une instance d'instruction d'architecture. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_instruction_init(GArchInstruction *instr) { DL_LIST_ITEM_INIT(&instr->flow); instr->max_displayed_len = VMPA_NO_PHYSICAL; g_rw_lock_init(&instr->link_access); #ifndef NDEBUG g_atomic_int_set(&instr->hold_link_access, 0); #endif } /****************************************************************************** * * * Paramètres : instr = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_instruction_dispose(GArchInstruction *instr) { G_OBJECT_CLASS(g_arch_instruction_parent_class)->dispose(G_OBJECT(instr)); } /****************************************************************************** * * * Paramètres : instr = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_instruction_finalize(GArchInstruction *instr) { g_rw_lock_clear(&instr->link_access); G_OBJECT_CLASS(g_arch_instruction_parent_class)->finalize(G_OBJECT(instr)); } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à consulter. * * * * Description : Indique l'encodage d'une instruction de façon détaillée. * * * * Retour : Description humaine de l'encodage utilisé. * * * * Remarques : - * * * ******************************************************************************/ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr) { return G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_encoding(instr); } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à modifier. * * flag = drapeau d'information complémentaire à planter. * * * * Description : Ajoute une information complémentaire à une instruction. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag) { instr->flags |= flag; return true; } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à modifier. * * * * Description : Fournit les informations complémentaires d'une instruction. * * * * Retour : Eventuels drapeaux d'information complémentaire à plantés. * * * * Remarques : - * * * ******************************************************************************/ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr) { return instr->flags; } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à modifier. * * type = type de procédure à mémoriser. * * hook = fonction à appeler sur commande. * * * * Description : Définit un traitement complémentare au désassemblage. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_set_hooks(GArchInstruction *instr, const instr_hook_fc hooks[IPH_COUNT]) { instr->hooks = hooks; } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à traiter. * * type = type de procédure à utiliser. * * proc = représentation de l'architecture utilisée. * * context = contexte associé à la phase de désassemblage. * * format = accès aux données du binaire d'origine. * * * * Description : Complète un désassemblage accompli pour une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GArchProcessor *proc, GProcContext *context, GExeFormat *format) { assert(type < IPH_COUNT); if (instr->hooks != NULL && instr->hooks[type] != NULL) instr->hooks[type](instr, proc, context, format); } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à modifier. * * address = adresse virtuelle et/ou position physique. * * length = taille de l'instruction. * * * * Description : Définit la localisation d'une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_set_range(GArchInstruction *instr, const mrange_t *range) { copy_mrange(&instr->range, range); } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à consulter. * * * * Description : Fournit la place mémoire d'une instruction. * * * * Retour : Zone mémoire couverte par l'instruction. * * * * Remarques : - * * * ******************************************************************************/ const mrange_t *g_arch_instruction_get_range(const GArchInstruction *instr) { return &instr->range; } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à consulter. * * offset = position physique dans le code binaire/NULL. [OUT] * * length = taille de l'instruction ou NULL. [OUT] * * address = adresse virtuelle ou position physique/NULL. [OUT] * * * * Description : Fournit la localisation d'une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_get_location(const GArchInstruction *instr, off_t *offset, off_t *length, vmpa_t *address) { //if (offset != NULL) *offset = instr->offset; //if (length != NULL) *length = instr->length; //if (address != NULL) *address = instr->address; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * opererand = instruction à venir associer. * * * * Description : Attache un opérande supplémentaire à une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand) { instr->operands_count++; instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *)); instr->operands[instr->operands_count - 1] = operand; } /****************************************************************************** * * * Paramètres : instr = instance à consulter. * * * * Description : Indique la quantité d'opérandes présents dans l'instruction. * * * * Retour : Nombre d'opérandes attachés. * * * * Remarques : - * * * ******************************************************************************/ size_t g_arch_instruction_count_operands(const GArchInstruction *instr) { return instr->operands_count; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * index = indice de l'opérande concernée. * * * * Description : Fournit un opérande donné d'une instruction. * * * * Retour : Opérande trouvée ou NULL si aucune. * * * * Remarques : - * * * ******************************************************************************/ GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index) { GArchOperand *result; /* Opérande à retourner */ if (index >= instr->operands_count) result = NULL; else result = instr->operands[index]; /* TODO : incrémenter la référence ! */ return result; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * new = nouvelle opérande à attacher. * * old = ancienne opérande à détacher. * * * * Description : Remplace un opérande d'une instruction par un autre. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old) { size_t i; /* Boucle de parcours */ for (i = 0; i < instr->operands_count; i++) if (instr->operands[i] == old) break; if (i < instr->operands_count) { g_object_unref(G_OBJECT(instr->operands[i])); instr->operands[i] = new; } } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * opererand = instruction à venir dissocier. * * * * Description : Détache un opérande liée d'une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand) { size_t i; /* Boucle de parcours */ for (i = 0; i < instr->operands_count; i++) if (instr->operands[i] == operand) break; if ((i + 1) < instr->operands_count) memmove(&instr->operands[i], &instr->operands[i + 1], (instr->operands_count - i - 1) * sizeof(GArchOperand *)); instr->operands_count--; instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *)); } /****************************************************************************** * * * Paramètres : instr = instruction à consulter. * * rregs = liste des rgistres lus. [OUT] * * rcount = nombre de registres lus. [OUT] * * wregs = liste des rgistres écrits. [OUT] * * wcount = nombre de registres écrits. [OUT] * * * * Description : Liste les registres lus et écrits par l'instruction. * * * * Retour : - * * * * Remarques : Les compteurs de références sont à décrémenter après usage ! * * * ******************************************************************************/ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount) { #if 0 size_t i; /* Boucle de parcours */ *rregs = NULL; *rcount = 0; *wregs = NULL; *wcount = 0; instr->get_rw_regs(instr, rregs, rcount, wregs, wcount); for (i = 0; i < *rcount; i++) g_object_ref(G_OBJECT((*rregs)[i])); for (i = 0; i < *wcount; i++) g_object_ref(G_OBJECT((*wregs)[i])); #endif } /* ---------------------------------------------------------------------------------- */ /* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : instr = instruction à mettre à jour. * * write = précise le type d'accès prévu (lecture/écriture). * * lock = indique le sens du verrouillage à mener. * * * * Description : Met à disposition un encadrement des accès aux liens. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_lock_unlock_links(GArchInstruction *instr, bool write, bool lock) { #ifndef NDEBUG if (!lock) g_atomic_int_dec_and_test(&instr->hold_link_access); #endif if (write) { if (lock) g_rw_lock_writer_lock(&instr->link_access); else g_rw_lock_writer_unlock(&instr->link_access); } else { if (lock) g_rw_lock_reader_lock(&instr->link_access); else g_rw_lock_reader_unlock(&instr->link_access); } #ifndef NDEBUG if (lock) g_atomic_int_inc(&instr->hold_link_access); #endif } /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * * dest = ligne visée par la liaison (côté destination). * * type = type de lien à construire. * * ... = éventuelles informations complémentaires. * * * * Description : Etablit un lien entre deux instructions. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType type) { size_t count; /* Raccourci pour la lecture */ instr_link_t *new; /* Nouveau lien à définir */ /* Côté destination */ g_arch_instruction_wlock_src(dest); count = ++dest->from_count; dest->from = (instr_link_t *)realloc(dest->from, count * sizeof(instr_link_t)); new = &dest->from[count - 1]; new->linked = instr; new->type = type; g_arch_instruction_wunlock_src(dest); /* Côté point de départ */ g_arch_instruction_wlock_dest(instr); count = ++instr->to_count; instr->to = (instr_link_t *)realloc(instr->to, count * sizeof(instr_link_t)); new = &instr->to[count - 1]; new->linked = dest; new->type = type; g_arch_instruction_wunlock_dest(instr); } /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * * dest = ligne visée par la liaison (côté destination). * * old = ancien type de lien construit. * * new = nouveau type de lien à construire. * * * * Description : Change la nature d'un lien entre deux instructions. * * * * Retour : true pour une mise à jour réussie, false sinon. * * * * Remarques : Le verrou doit être posé sur les destination de 'instr'. * * * ******************************************************************************/ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType old, InstructionLinkType new) { bool result; /* Bilan à retourner */ size_t count; /* Raccourci pour la lecture */ size_t i; /* Boucle de parcours */ size_t from_idx; /* Indice côté destination */ size_t to_idx; /* Indice côté source */ result = false; assert(g_atomic_int_get(&instr->hold_link_access) > 0); g_arch_instruction_wlock_src(dest); /* Côté destination */ count = dest->from_count; for (i = 0; i < count; i++) if (dest->from[i].linked == instr && dest->from[i].type == old) break; if (i == count) goto gaicl_exit; else from_idx = i; /* Côté point de départ */ count = instr->to_count; for (i = 0; i < count; i++) if (instr->to[i].linked == dest && instr->to[i].type == old) break; if (i == count) goto gaicl_exit; else to_idx = i; /* Si les deux extrémités sont raccord... */ dest->from[from_idx].type = new; instr->to[to_idx].type = new; result = true; gaicl_exit: g_arch_instruction_wunlock_src(dest); return result; } /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * * * * Description : Indique si l'instruction a une ou plusieurs origines. * * * * Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ bool g_arch_instruction_has_sources(const GArchInstruction *instr) { assert(g_atomic_int_get(&instr->hold_link_access) > 0); return (instr->from_count > 0); } /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter.* * sources = liste des liens aux instructions d'origine. [OUT] * * * * Description : Fournit les origines d'une instruction donnée. * * * * Retour : Nombre de ces origines. * * * * Remarques : - * * * ******************************************************************************/ size_t g_arch_instruction_get_sources(const GArchInstruction *instr, instr_link_t **sources) { assert(g_atomic_int_get(&instr->hold_link_access) > 0); if (sources != NULL) *sources = instr->from; return instr->from_count; } /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * * * * Description : Indique si l'instruction a une suite autre que la suivante. * * * * Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ bool g_arch_instruction_has_destinations(const GArchInstruction *instr) { assert(g_atomic_int_get(&instr->hold_link_access) > 0); return (instr->to_count > 0); } /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * * dests = liste de liens aux instructions de destination. [OUT]* * * * Description : Fournit les destinations d'une instruction donnée. * * * * Retour : Nombre de ces destinations. * * * * Remarques : - * * * ******************************************************************************/ size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, instr_link_t **dests) { assert(g_atomic_int_get(&instr->hold_link_access) > 0); if (dests != NULL) *dests = instr->to; return instr->to_count; } /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * * type = type de lien recherché. * * * * Description : Fournit la destination d'une instruction et d'un type donné. * * * * Retour : Instruction de destination trouvée ou NULL. * * * * Remarques : - * * * ******************************************************************************/ GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstruction *instr, InstructionLinkType type) { GArchInstruction *result; /* Résultat à remonter */ size_t i; /* Boucle de parcours */ result = NULL; assert(g_atomic_int_get(&instr->hold_link_access) > 0); for (i = 0; i < instr->to_count && result == NULL; i++) if (instr->to[i].type == type) result = instr->to[i].linked; return result; } /****************************************************************************** * * * Paramètres : iter = membre du groupe donné en référence. * * list = liste des instructions à analyser. * * count = taille de cette liste. * * * * Description : Indique la position dans les instructions identiques. * * * * Retour : Indice dans les instructions identiques du groupe. * * * * Remarques : - * * * ******************************************************************************/ size_t g_arch_instruction_compute_group_index(GArchInstruction **iter, GArchInstruction **list, size_t count) { size_t result; /* Valeur à retourner */ size_t i; /* Boucle de parcours */ result = 0; for (i = 0; i < count; i++) { if ((list + i) == iter) break; if (list[i] == *iter) result++; } return result; } /* ---------------------------------------------------------------------------------- */ /* CONVERSIONS DU FORMAT DES INSTRUCTIONS */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : instr = instruction d'assemblage à consulter. * * syntax = type de représentation demandée. * * * * Description : Fournit le nom humain de l'instruction manipulée. * * * * Retour : Mot clef de bas niveau. * * * * Remarques : - * * * ******************************************************************************/ const char *g_arch_instruction_get_keyword(GArchInstruction *instr, AsmSyntax syntax) { const char *result; /* Désignation à retourner */ result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_keyword(instr, syntax); return result; } /****************************************************************************** * * * Paramètres : instr = instruction d'assemblage à consulter. * * * * Description : Indique si elle existe la quantité maximale de code affiché. * * * * Retour : Quantité de code affichée au plus ou VMPA_NO_PHYSICAL. * * * * Remarques : - * * * ******************************************************************************/ phys_t g_arch_instruction_get_displayed_max_length(const GArchInstruction *instr) { return instr->max_displayed_len; } /****************************************************************************** * * * Paramètres : instr = instruction d'assemblage à consulter. * * max = quantité affichée au plus ou VMPA_NO_PHYSICAL. * * * * Description : Définit la quantité maximale de code affiché. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_set_displayed_max_length(GArchInstruction *instr, phys_t max) { instr->max_displayed_len = max; } /****************************************************************************** * * * 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); } /****************************************************************************** * * * Paramètres : instr = instruction d'origine à convertir. * * ctx = contexte de la phase de décompilation. * * * * Description : Décompile une instruction de façon générique. * * * * Retour : Instruction mise en place ou NULL. * * * * Remarques : - * * * ******************************************************************************/ GDecInstruction *g_arch_instruction_decompile(const GArchInstruction *instr, GDecContext *ctx) { #if 0 GDecInstruction *result; /* Instruction à retourner */ GDecInstruction *list; /* Instructions décompilées */ if (instr->decomp != NULL) { result = instr->decomp(instr, ctx); if (result != NULL) { list = g_dec_context_get_decomp_instrs(ctx); if (list == NULL) list = result; else g_dec_instruction_add_to_list(&list, result); g_dec_context_set_decomp_instrs(ctx, list); } } else result = NULL; return result; #endif return NULL; } /* ---------------------------------------------------------------------------------- */ /* TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : list = liste d'instructions à consulter. * * * * Description : Renvoie vers la dernière instruction d'une série. * * * * Retour : Dernière instruction trouvée (ou NULL ?!). * * * * Remarques : - * * * ******************************************************************************/ GArchInstruction *g_arch_instruction_find_last(const GArchInstruction *list) { return ainstr_list_last(list); } /****************************************************************************** * * * Paramètres : list = liste d'instructions à compléter, ou NULL. * * instr = nouvelle instruction à intégrer à l'ensemble. * * * * Description : Ajoute une instruction à un ensemble existant. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_add_to_list(GArchInstruction **list, GArchInstruction *instr) { ainstr_list_add_tail(instr, list); } /****************************************************************************** * * * Paramètres : list1 = première liste à traiter. * * list2 = seconde liste à traiter. * * * * Description : Fusionne deux listes d'instructions. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_merge_lists(GArchInstruction **list1, GArchInstruction **list2) { ainstr_list_merge(list1, list2); } /****************************************************************************** * * * Paramètres : list = liste d'instructions à consulter. * * : iter = position actuelle dans la liste. * * * * Description : Fournit l'élement suivant un autre pour un parcours. * * * * Retour : Elément suivant ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ GArchInstruction *g_arch_instruction_get_prev_iter(const GArchInstruction *list, const GArchInstruction *iter) { GArchInstruction *result; /* Elément suivant à renvoyer */ result = ainstr_list_prev_iter(iter, list); return result; } /****************************************************************************** * * * Paramètres : list = liste d'instructions à consulter. * * : iter = position actuelle dans la liste. * * max = adresse marquant la limite (exclue) du parcours. * * * * Description : Fournit l'élement suivant un autre pour un parcours. * * * * Retour : Elément suivant ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ GArchInstruction *g_arch_instruction_get_next_iter(const GArchInstruction *list, const GArchInstruction *iter, vmpa_t max) { GArchInstruction *result; /* Elément suivant à renvoyer */ result = ainstr_list_next_iter(iter, list); /* FIXME : utiliser les nouvelles adresses ! if (result != NULL && result->address >= max) result = NULL; */ return result; } /****************************************************************************** * * * Paramètres : list = liste de lignes à parcourir. * * range = emplacement mémoire à comparer. * * * * Description : Recherche une instruction d'après son emplacement mémoire. * * * * Retour : Instruction trouvée à l'adresse donnée, NULL si aucune. * * * * Remarques : - * * * ******************************************************************************/ GArchInstruction *g_arch_instruction_find_by_range(GArchInstruction *list, const mrange_t *range) { GArchInstruction *result; /* Trouvaille à retourner */ ainstr_list_for_each(result, list) { if (cmp_mrange(&result->range, range) == 0) break; } return result; } /****************************************************************************** * * * Paramètres : list = liste de lignes à parcourir. * * addr = position en mémoire ou physique à chercher. * * strict = définit la considération à porter à l'adresse. * * * * Description : Recherche une instruction d'après son adresse. * * * * Retour : Instruction trouvée à l'adresse donnée, NULL si aucune. * * * * Remarques : - * * * ******************************************************************************/ GArchInstruction *g_arch_instruction_find_by_address(GArchInstruction *list, const vmpa2t *addr, bool strict) { GArchInstruction *result; /* Trouvaille à retourner */ bool found; /* Bilan de comparaisons */ ainstr_list_for_each(result, list) { if (strict) found = (cmp_vmpa(get_mrange_addr(&result->range), addr) == 0); else found = mrange_contains_addr(&result->range, addr); if (found) break; } return result; }