diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-08-08 19:59:34 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-08-08 19:59:34 (GMT) |
commit | b3b515ba37ef58751e5407bfcdff2dd67932b99a (patch) | |
tree | 88dabcde3d63e87e7ac0c7509629346dde066429 /src/analysis/block.c | |
parent | 0442cf03782e65bd680449cc213ace9a21bb081b (diff) |
Defined a new kind of code blocks.
Diffstat (limited to 'src/analysis/block.c')
-rw-r--r-- | src/analysis/block.c | 837 |
1 files changed, 777 insertions, 60 deletions
diff --git a/src/analysis/block.c b/src/analysis/block.c index cd3ef94..14b2c0e 100644 --- a/src/analysis/block.c +++ b/src/analysis/block.c @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * block.c - encadrement des instructions par blocs + * block.h - encadrement des blocs de code * * Copyright (C) 2012-2017 Cyrille Bagard * @@ -24,33 +24,86 @@ #include "block.h" +#include <assert.h> +#include <malloc.h> + + #include "block-int.h" -/* Initialise la classe des blocs d'instructions. */ -static void g_instr_block_class_init(GInstrBlockClass *); +/* ----------------------------- BLOC DE CODE GENERIQUE ----------------------------- */ + + +/* Initialise la classe des blocs de code. */ +static void g_code_block_class_init(GCodeBlockClass *); -/* Initialise un bloc d'instructions. */ -static void g_instr_block_init(GInstrBlock *); +/* Initialise un bloc de code. */ +static void g_code_block_init(GCodeBlock *); /* Supprime toutes les références externes. */ -static void g_instr_block_dispose(GInstrBlock *); +static void g_code_block_dispose(GCodeBlock *); /* Procède à la libération totale de la mémoire. */ -static void g_instr_block_finalize(GInstrBlock *); +static void g_code_block_finalize(GCodeBlock *); + +/* Indique l'indice d'intégration du bloc dans une liste. */ +static void g_code_block_set_index(GCodeBlock *, size_t); + +/* Etablit les liens entre un bloc de code et ses voisins. */ +static void g_code_block_resolve_links(GCodeBlock *, const GBlockList *); + +/* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */ + + +/* Description d'une liste de blocs de code (instance) */ +struct _GBlockList +{ + GObject parent; /* A laisser en premier */ + + GCodeBlock **blocks; /* Blocs de code rassemblés */ + size_t count; /* Quantité de ces blocs */ + +}; + +/* Description d'une liste de blocs de code (classe) */ +struct _GBlockListClass +{ + GObjectClass parent; /* A laisser en premier */ -/* Indique le type défini pour un bloc d'instructions. */ -G_DEFINE_TYPE(GInstrBlock, g_instr_block, G_TYPE_OBJECT); +}; + + +/* Initialise la classe des listes de blocs de code. */ +static void g_block_list_class_init(GBlockListClass *); + +/* Initialise une liste de blocs de code. */ +static void g_block_list_init(GBlockList *); + +/* Supprime toutes les références externes. */ +static void g_block_list_dispose(GBlockList *); + +/* Procède à la libération totale de la mémoire. */ +static void g_block_list_finalize(GBlockList *); + + + +/* ---------------------------------------------------------------------------------- */ +/* BLOC DE CODE GENERIQUE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un bloc de code. */ +G_DEFINE_TYPE(GCodeBlock, g_code_block, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : class = classe à initialiser. * * * -* Description : Initialise la classe des blocs d'instructions. * +* Description : Initialise la classe des blocs de code. * * * * Retour : - * * * @@ -58,14 +111,14 @@ G_DEFINE_TYPE(GInstrBlock, g_instr_block, G_TYPE_OBJECT); * * ******************************************************************************/ -static void g_instr_block_class_init(GInstrBlockClass *class) +static void g_code_block_class_init(GCodeBlockClass *class) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(class); - object->dispose = (GObjectFinalizeFunc/* ! */)g_instr_block_dispose; - object->finalize = (GObjectFinalizeFunc)g_instr_block_finalize; + object->dispose = (GObjectFinalizeFunc/* ! */)g_code_block_dispose; + object->finalize = (GObjectFinalizeFunc)g_code_block_finalize; } @@ -74,7 +127,7 @@ static void g_instr_block_class_init(GInstrBlockClass *class) * * * Paramètres : block = instance à initialiser. * * * -* Description : Initialise un bloc d'instructions. * +* Description : Initialise un bloc de code. * * * * Retour : - * * * @@ -82,8 +135,15 @@ static void g_instr_block_class_init(GInstrBlockClass *class) * * ******************************************************************************/ -static void g_instr_block_init(GInstrBlock *block) +static void g_code_block_init(GCodeBlock *block) { + block->index = (size_t)-1; + block->rank = (size_t)-1; + + block->from = NULL; + block->to = NULL; + + block->view = NULL; } @@ -100,12 +160,24 @@ static void g_instr_block_init(GInstrBlock *block) * * ******************************************************************************/ -static void g_instr_block_dispose(GInstrBlock *block) +static void g_code_block_dispose(GCodeBlock *block) { - if (block->links_block != NULL) - g_object_unref(G_OBJECT(block->links_block)); +#ifndef NDEBUG + g_code_block_lock_src(block); + assert(count_flat_array_items(block->from) == 0); + g_code_block_unlock_src(block); +#endif + +#ifndef NDEBUG + g_code_block_lock_dest(block); + assert(count_flat_array_items(block->to) == 0); + g_code_block_unlock_dest(block); +#endif - G_OBJECT_CLASS(g_instr_block_parent_class)->dispose(G_OBJECT(block)); + if (block->view != NULL) + g_object_unref(G_OBJECT(block->view)); + + G_OBJECT_CLASS(g_code_block_parent_class)->dispose(G_OBJECT(block)); } @@ -122,62 +194,512 @@ static void g_instr_block_dispose(GInstrBlock *block) * * ******************************************************************************/ -static void g_instr_block_finalize(GInstrBlock *block) +static void g_code_block_finalize(GCodeBlock *block) +{ + delete_bit_field(block->domination); + + G_OBJECT_CLASS(g_code_block_parent_class)->finalize(G_OBJECT(block)); + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc de code à consulter. * +* * +* Description : Indique la liste des blocs de code dominés. * +* * +* Retour : Champ de bits représentant des blocs. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const bitfield_t *g_code_block_get_domination(const GCodeBlock *block) +{ + return block->domination; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc à mettre à jour. * +* index = indice valide dans la liste d'appartenance. * +* * +* Description : Indique l'indice d'intégration du bloc dans une liste. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_code_block_set_index(GCodeBlock *block, size_t index) +{ + assert(block->index == (size_t)-1); + + block->index = index; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc à consulter. * +* * +* Description : Indique l'indice d'intégration du bloc dans une liste. * +* * +* Retour : Indice valide dans une liste. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_code_block_get_index(const GCodeBlock *block) +{ + size_t result; /* Indice à retourner */ + + assert(block->index != (size_t)-1); + + result = block->index; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc de code à consulter. * +* addr = localisation à comparer. * +* * +* Description : Détermine si un bloc de code débute à une adresse donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_code_block_is_starting_with(const GCodeBlock *block, const vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + GCodeBlockClass *class; /* Classe des blocs de code */ + + class = G_CODE_BLOCK_GET_CLASS(block); + + result = class->is_starting(block, addr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc de code à mettre à jour. * +* list = ensemble des blocs de code à disposition. * +* * +* Description : Etablit les liens entre un bloc de code et ses voisins. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_code_block_resolve_links(GCodeBlock *block, const GBlockList *list) +{ + GCodeBlockClass *class; /* Classe des blocs de code */ + + class = G_CODE_BLOCK_GET_CLASS(block); + + class->link(block, list); + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc de code à consulter. * +* * +* Description : Fournit le rang du bloc de code dans le flot d'exécution. * +* * +* Retour : Indice supérieur ou égal à zéro. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_code_block_get_rank(const GCodeBlock *block) +{ + size_t result; /* Rang à retourner */ + + result = block->rank; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc de code à mettre à jour. * +* rank = indice supérieur à zéro à prendre en compte. * +* * +* Description : Définit le rang du bloc de code dans le flot d'exécution. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_code_block_set_rank(GCodeBlock *block, size_t rank) +{ + block->rank = rank; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc de code à manipuler. * +* highlighted = gestionnaire de surbrillance pour segments. * +* * +* Description : Fournit la représentation graphique d'un bloc de code. * +* * +* Retour : Vue d'un cache de lignes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBufferView *g_code_block_get_view(GCodeBlock *block, segcnt_list *highlighted) +{ + GBufferView *result; /* Instance à retourner */ + GCodeBlockClass *class; /* Classe des blocs de code */ + + if (block->view == NULL) + { + class = G_CODE_BLOCK_GET_CLASS(block); + + block->view = class->build(block, highlighted); + + } + + result = block->view; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DE LIAISONS ENTRE BLOCS DE CODE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : block = bloc de code à mettre à jour. * +* src = sélection de l'extrémité à traiter. * +* lock = indique le sens du verrouillage à mener. * +* * +* Description : Met à disposition un encadrement des accès aux liens. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_code_block_lock_unlock_links(GCodeBlock *block, bool src, bool lock) +{ + flat_array_t **array; /* Choix du tableau ciblé */ + + array = (src ? &block->from : &block->to); + + if (lock) + lock_flat_array(array); + else + unlock_flat_array(array); + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc dont les informations sont à consulter. * +* dest = bloc de code visé par la liaison (côté destination). * +* type = type de lien à construire. * +* * +* Description : Etablit un lien entre deux blocs de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_code_block_link_with(GCodeBlock *block, GCodeBlock *dest, InstructionLinkType type) +{ + block_link_t new_src; /* Nouveau lien à définir #1 */ + block_link_t new_dst; /* Nouveau lien à définir #2 */ + + /* Côté destination */ + + new_src.linked = block; + new_src.type = type; + + ref_block_link((&new_src)); + + /* Côté point de départ */ + + new_dst.linked = dest; + new_dst.type = type; + + ref_block_link((&new_dst)); + + /* Ajout dans le respect d'une cohérence globale */ + + g_code_block_lock_src(dest); + g_code_block_lock_dest(block); + + add_item_to_flat_array(&dest->from, &new_src, sizeof(block_link_t)); + + add_item_to_flat_array(&block->to, &new_dst, sizeof(block_link_t)); + + g_code_block_unlock_dest(block); + g_code_block_unlock_src(dest); + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc de code dont les informations sont à traiter. * +* * +* Description : Supprime tous les liens établis avec d'autres blocs de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_code_block_delete_all_links(GCodeBlock *block) { - G_OBJECT_CLASS(g_instr_block_parent_class)->finalize(G_OBJECT(block)); + block_link_t *link_src; /* Lien à supprimer #2 */ + GCodeBlock *other; /* Bloc de l'autre bout */ + size_t count; /* Quantié de liens présents */ + size_t i; /* Boucle de parcours */ + block_link_t *link_dst; /* Lien à supprimer #1 */ + + /* Coté sources */ + + g_code_block_lock_src(block); + + while (count_flat_array_items(block->from) > 0) + { + link_src = get_flat_array_item(block->from, 0, sizeof(block_link_t)); + + other = link_src->linked; + + g_code_block_lock_dest(other); + + count = count_flat_array_items(other->to); + + for (i = 0; i < count; i++) + { + link_dst = get_flat_array_item(other->to, i, sizeof(block_link_t)); + + if (link_dst->linked == block && link_dst->type == link_src->type) + { + unref_block_link(link_dst); + + rem_item_from_flat_array(&other->to, i, sizeof(block_link_t)); + + break; + + } + + } + + assert(i < count); + + g_code_block_unlock_dest(other); + + unref_block_link(link_src); + + rem_item_from_flat_array(&block->from, 0, sizeof(block_link_t)); + + } + + g_code_block_unlock_src(block); + + /* Coté destinations */ + + g_code_block_lock_dest(block); + + while (count_flat_array_items(block->to) > 0) + { + link_dst = get_flat_array_item(block->to, 0, sizeof(block_link_t)); + + other = link_dst->linked; + + g_code_block_lock_src(other); + + count = count_flat_array_items(other->from); + + for (i = 0; i < count; i++) + { + link_src = get_flat_array_item(other->from, i, sizeof(block_link_t)); + + if (link_src->linked == block && link_src->type == link_dst->type) + { + unref_block_link(link_src); + + rem_item_from_flat_array(&other->from, i, sizeof(block_link_t)); + + break; + + } + + } + + assert(i < count); + + g_code_block_unlock_src(other); + + unref_block_link(link_dst); + + rem_item_from_flat_array(&block->to, 0, sizeof(block_link_t)); + + } + + g_code_block_unlock_dest(block); } /****************************************************************************** * * -* Paramètres : block = bloc de départ des recherches. * -* addr = ensemble de blocs à parcourir. * -* final = indique si la cible ou le conteneur est renvoyée. * +* Paramètres : block = bloc dont les informations sont à consulter. * * * -* Description : Recherche le bloc contenant une adresse donnée. * +* Description : Fournit la quantité de blocs de code pointant vers un autre. * * * -* Retour : bloc basique trouvé ou NULL en cas d'échec. * +* Retour : Nombre de ces origines. * * * * Remarques : - * * * ******************************************************************************/ -GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *block, const vmpa2t *addr, bool final) +size_t g_code_block_count_sources(const GCodeBlock *block) { - return G_INSTR_BLOCK_GET_CLASS(block)->find_by_addr(block, addr, final); + size_t result; /* Nombre de liens à renvoyer */ + + result = count_flat_array_items(block->from); + + return result; } /****************************************************************************** * * -* Paramètres : block = bloc d'instructions démarrant la visite. * -* callback = ensemble de blocs à parcourir. * -* data = donnée utilisateur à associer au parcours. * +* Paramètres : block = bloc dont les informations sont à consulter. * +* index = indice de l'élément à retrouver. * * * -* Description : Parcourt tous les blocs d'instructions dans un ordre donné. * +* Description : Fournit les détails d'une origine d'un bloc de code donné. * * * -* Retour : true si le parcours a été jusqu'à son terme, false sinon. * +* Retour : Lien déterminé vers un bloc de code d'origine. * * * * Remarques : - * * * ******************************************************************************/ -bool g_instr_block_visit(GInstrBlock *block, instr_block_visitor_cb callback, void *data) +const block_link_t *g_code_block_get_source(GCodeBlock *block, size_t index) { - return G_INSTR_BLOCK_GET_CLASS(block)->visit_blocks(block, callback, data); + block_link_t *result; /* Détails présents à renvoyer */ + + result = get_flat_array_item(block->from, index, sizeof(block_link_t)); + + ref_block_link(result); + + return result; } /****************************************************************************** * * -* Paramètres : block = bloc d'instructions à consulter. * -* list = ensemble de blocs à compléter. [OUT] * -* count = nombre de blocs au total. [OUT] * +* Paramètres : block = bloc dont les informations sont à consulter. * +* * +* Description : Donne le nombre de blocs de code suivants dans le flot. * * * -* Description : Etablit la liste de tous les blocs présents. * +* Retour : Nombre de ces destinations. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_code_block_count_destinations(const GCodeBlock *block) +{ + size_t result; /* Nombre de liens à renvoyer */ + + result = count_flat_array_items(block->to); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc dont les informations sont à consulter. * +* index = indice de l'élément à retrouver. * +* * +* Description : Fournit les détails d'une destination de bloc de code. * +* * +* Retour : Lien déterminé vers un bloc de code de destination. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const block_link_t *g_code_block_get_destination(GCodeBlock *block, size_t index) +{ + block_link_t *result; /* Détails présents à renvoyer */ + + result = get_flat_array_item(block->to, index, sizeof(block_link_t)); + + ref_block_link(result); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* REGROUPEMENT EN LISTE DE BLOCS */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une liste de blocs de code. */ +G_DEFINE_TYPE(GBlockList, g_block_list, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : class = classe à initialiser. * +* * +* Description : Initialise la classe des listes de blocs de code. * * * * Retour : - * * * @@ -185,20 +707,23 @@ bool g_instr_block_visit(GInstrBlock *block, instr_block_visitor_cb callback, vo * * ******************************************************************************/ -void g_instr_block_list_all_blocks(const GInstrBlock *block, GInstrBlock ***list, size_t *count) +static void g_block_list_class_init(GBlockListClass *class) { - G_INSTR_BLOCK_GET_CLASS(block)->list_blocks(block, list, count); + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_block_list_dispose; + object->finalize = (GObjectFinalizeFunc)g_block_list_finalize; } /****************************************************************************** * * -* Paramètres : block = bloc d'instructions à consulter. * -* list = ensemble de blocs à compléter. [OUT] * -* count = nombre de blocs au total. [OUT] * +* Paramètres : block = instance à initialiser. * * * -* Description : Etablit la liste de tous les blocs terminaux. * +* Description : Initialise une liste de blocs de code. * * * * Retour : - * * * @@ -206,19 +731,19 @@ void g_instr_block_list_all_blocks(const GInstrBlock *block, GInstrBlock ***list * * ******************************************************************************/ -void g_instr_block_list_leafs_blocks(const GInstrBlock *block, GInstrBlock ***list, size_t *count) +static void g_block_list_init(GBlockList *list) { - G_INSTR_BLOCK_GET_CLASS(block)->list_leafs(block, list, count); + list->blocks = NULL; + list->count = 0; } /****************************************************************************** * * -* Paramètres : block = bloc d'instructions à mettre à jour. * -* links = bloc contenant les blocs liés au bloc. * +* Paramètres : block = instance d'objet GLib à traiter. * * * -* Description : Définit l'ensemble contenant les blocs liés. * +* Description : Supprime toutes les références externes. * * * * Retour : - * * * @@ -226,31 +751,223 @@ void g_instr_block_list_leafs_blocks(const GInstrBlock *block, GInstrBlock ***li * * ******************************************************************************/ -void g_instr_block_set_links_block(GInstrBlock *block, GInstrBlock *links) +static void g_block_list_dispose(GBlockList *list) { - if (block->links_block != NULL) - g_object_unref(G_OBJECT(block->links_block)); + size_t i; /* Boucle de parcours */ + + for (i = 0; i < list->count; i++) + if (list->blocks[i] != NULL) + { + g_code_block_delete_all_links(list->blocks[i]); + g_object_unref(G_OBJECT(list->blocks[i])); + } - g_object_ref(G_OBJECT(links)); - block->links_block = links; + G_OBJECT_CLASS(g_block_list_parent_class)->dispose(G_OBJECT(list)); } /****************************************************************************** * * -* Paramètres : block = bloc d'instructions à mettre à jour. * +* Paramètres : block = instance d'objet GLib à traiter. * * * -* Description : Fournit l'ensemble contenant les blocs liés. * +* Description : Procède à la libération totale de la mémoire. * * * -* Retour : Bloc contenant les blocs liés au bloc. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GInstrBlock *g_instr_block_get_links_block(const GInstrBlock *block) +static void g_block_list_finalize(GBlockList *list) { - return block->links_block; + if (list->blocks != NULL) + free(list->blocks); + + G_OBJECT_CLASS(g_block_list_parent_class)->finalize(G_OBJECT(list)); + +} + + +/****************************************************************************** +* * +* Paramètres : count = quantité finale de blocs présentie. * +* * +* Description : Crée une liste de blocs de code. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBlockList *g_block_list_new(size_t count) +{ + GBlockList *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_BLOCK_LIST, NULL); + + result->blocks = (GCodeBlock **)calloc(count, sizeof(GCodeBlock *)); + + result->count = count; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de blocs de code à consulter. * +* * +* Description : Compte le nombre de blocs de code représentés. * +* * +* Retour : Quantité de blocs de code rassemblés. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_block_list_count_blocks(const GBlockList *list) +{ + size_t result; /* Quantité à retourner */ + + result = list->count; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de blocs de code à compléter. * +* block = bloc de code à intégrer. * +* index = indice de la position d'insertion du bloc. * +* * +* Description : Ajoute un bloc de code à une liste définie. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_block_list_add_block(GBlockList *list, GCodeBlock *block, size_t index) +{ + assert(index < list->count); + assert(list->blocks[index] == NULL); + + list->blocks[index] = block; + + g_code_block_set_index(block, index); + +} + + + +/****************************************************************************** +* * +* Paramètres : list = ensemble des blocs de code à traiter. * +* * +* Description : Etablit les liens entre les blocs de code et leurs voisins. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_block_list_resolve_links(const GBlockList *list) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < list->count; i++) + g_code_block_resolve_links(list->blocks[i], list); + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de blocs de code à consulter. * +* index = indice de la position du bloc recherché. * +* * +* Description : Fournit le bloc de code correspondant à un indice de liste. * +* * +* Retour : Bloc de code trouvé, ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCodeBlock *g_block_list_get_block(const GBlockList *list, size_t index) +{ + GCodeBlock *result; /* Bloc de code à retourner */ + + assert(index < list->count); + + if (index < list->count) + result = list->blocks[index]; + else + result = NULL; + + /** + * La liste peut être dimensionnée sans avoir été remplie... + * Donc on fait attention avec le compteur de références. + */ + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de blocs de code à consulter. * +* addr = localisation à comparer. * +* * +* Description : Recherche un bloc de code débutant à une adresse donnée. * +* * +* Retour : Bloc de code trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCodeBlock *g_block_list_find_by_starting_instr(const GBlockList *list, const vmpa2t *addr) +{ + GCodeBlock *result; /* Trouvaille à retourner */ + size_t i; /* Boucle de parcours */ + GCodeBlock *block; /* Bloc basique analysé */ + + result = NULL; + + for (i = 0; i < list->count && result == NULL; i++) + { + block = list->blocks[i]; + + /** + * La liste peut être dimensionnée sans avoir été remplie... + * Donc on fait attention. + */ + + assert(block != NULL); + + if (block == NULL) + continue; + + if (g_code_block_is_starting_with(block, addr)) + { + result = block; + g_object_ref(G_OBJECT(result)); + } + + } + + return result; } |