From 2a6d92e2d55c0a7826137b2cc2e3148bb298abb9 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 14 Jan 2019 00:44:21 +0100 Subject: Provided uncached code block links. --- plugins/pychrysalide/analysis/block.c | 25 +-- src/analysis/block-int.h | 12 +- src/analysis/block.c | 320 ++++------------------------------ src/analysis/block.h | 33 +--- src/analysis/disass/block.c | 114 +++++++++++- src/analysis/disass/rank.c | 13 +- src/gtkext/graph/cluster.c | 25 ++- 7 files changed, 185 insertions(+), 357 deletions(-) diff --git a/plugins/pychrysalide/analysis/block.c b/plugins/pychrysalide/analysis/block.c index 1456e15..c484ba6 100644 --- a/plugins/pychrysalide/analysis/block.c +++ b/plugins/pychrysalide/analysis/block.c @@ -25,6 +25,7 @@ #include "block.h" +#include #include @@ -151,21 +152,20 @@ static PyObject *py_code_block_get_sources(PyObject *self, void *closure) PyObject *result; /* Trouvailles à retourner */ GCodeBlock *block; /* Bloc de code à consulter */ size_t count; /* Quantité de blocs liés */ + block_link_t *links; /* Liens à traiter */ size_t i; /* Boucle de parcours */ - const block_link_t *link; /* Informations conservées */ + block_link_t *link; /* Informations conservées */ PyObject *info; /* Informations à transmettre */ block = G_CODE_BLOCK(pygobject_get(self)); - g_code_block_lock_src(block); - - count = g_code_block_count_sources(block); + links = g_code_block_get_sources(block, &count); result = PyTuple_New(count); for (i = 0; i < count; i++) { - link = g_code_block_get_source(block, i); + link = &links[i]; info = PyTuple_New(2); @@ -178,7 +178,8 @@ static PyObject *py_code_block_get_sources(PyObject *self, void *closure) } - g_code_block_unlock_src(block); + if (links != NULL) + free(links); return result; @@ -203,21 +204,20 @@ static PyObject *py_code_block_get_destinations(PyObject *self, void *closure) PyObject *result; /* Trouvailles à retourner */ GCodeBlock *block; /* Bloc de code à consulter */ size_t count; /* Quantité de blocs liés */ + block_link_t *links; /* Liens à traiter */ size_t i; /* Boucle de parcours */ - const block_link_t *link; /* Informations conservées */ + block_link_t *link; /* Informations conservées */ PyObject *info; /* Informations à transmettre */ block = G_CODE_BLOCK(pygobject_get(self)); - g_code_block_lock_dest(block); - - count = g_code_block_count_destinations(block); + links = g_code_block_get_destinations(block, &count); result = PyTuple_New(count); for (i = 0; i < count; i++) { - link = g_code_block_get_destination(block, i); + link = &links[i]; info = PyTuple_New(2); @@ -230,7 +230,8 @@ static PyObject *py_code_block_get_destinations(PyObject *self, void *closure) } - g_code_block_unlock_dest(block); + if (links != NULL) + free(links); return result; diff --git a/src/analysis/block-int.h b/src/analysis/block-int.h index b9b90f0..ca38703 100644 --- a/src/analysis/block-int.h +++ b/src/analysis/block-int.h @@ -38,8 +38,8 @@ /* Détermine si un bloc de code débute à une adresse donnée. */ typedef bool (* block_is_starting_fc) (const GCodeBlock *, const vmpa2t *); -/* Etablit les liens entre un bloc de code et ses voisins. */ -typedef void (* block_resolve_links_fc) (GCodeBlock *, const GBlockList *); +/* Fournit les détails des origines d'un bloc de code donné. */ +typedef block_link_t * (* block_get_links_fc) (const GCodeBlock *, const GBlockList *, size_t *); /* Fournit la représentation graphique d'un bloc de code. */ typedef GBufferView * (* block_build_view_fc) (const GCodeBlock *, segcnt_list *); @@ -50,14 +50,13 @@ struct _GCodeBlock { GObject parent; /* A laisser en premier */ + GBlockList *list; /* Lien vers l'ensemble */ + bitfield_t *domination; /* Blocs dominés de l'ensemble */ size_t index; /* Indice dans une liste */ size_t rank; /* Rang dans l'exécution */ - flat_array_t *from; /* Origines des références */ - flat_array_t *to; /* Instructions visées */ - GBufferView *view; /* Représentation construite */ }; @@ -68,7 +67,8 @@ struct _GCodeBlockClass GObjectClass parent; /* A laisser en premier */ block_is_starting_fc is_starting; /* Analyse d'adresse initiale */ - block_resolve_links_fc link; /* Etablissement des liens */ + block_get_links_fc get_src; /* Obtention des origines */ + block_get_links_fc get_dest; /* Obtention des destinations */ block_build_view_fc build; /* Construction d'une vue */ }; diff --git a/src/analysis/block.c b/src/analysis/block.c index a23634c..7003ccd 100644 --- a/src/analysis/block.c +++ b/src/analysis/block.c @@ -50,9 +50,6 @@ 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 ------------------------- */ @@ -137,12 +134,11 @@ static void g_code_block_class_init(GCodeBlockClass *class) static void g_code_block_init(GCodeBlock *block) { + block->list = NULL; + block->index = (size_t)-1; block->rank = (size_t)-1; - block->from = NULL; - block->to = NULL; - block->view = NULL; } @@ -162,17 +158,7 @@ static void g_code_block_init(GCodeBlock *block) static void g_code_block_dispose(GCodeBlock *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_clear_object(&block->list); g_clear_object(&block->view); @@ -297,30 +283,6 @@ bool g_code_block_is_starting_with(const GCodeBlock *block, const vmpa2t *addr) /****************************************************************************** * * -* 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. * @@ -405,205 +367,36 @@ GBufferView *g_code_block_get_view(GCodeBlock *block, segcnt_list *highlighted) /****************************************************************************** * * -* 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. * +* count = nombre de ces origines. [OUT] * * * -* Description : Etablit un lien entre deux blocs de code. * +* Description : Fournit les détails des origines d'un bloc de code donné. * * * -* Retour : - * +* Retour : Liens déterminés vers des blocs de code d'origine. * * * * Remarques : - * * * ******************************************************************************/ -void g_code_block_link_with(GCodeBlock *block, GCodeBlock *dest, InstructionLinkType type) +block_link_t *g_code_block_get_sources(const GCodeBlock *block, size_t *count) { - 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) -{ - 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); + block_link_t *result; /* Détails présents à renvoyer */ + GCodeBlockClass *class; /* Classe des blocs de code */ - while (count_flat_array_items(block->from) > 0) + if (block->list == NULL) { - 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)); - + result = NULL; + *count = 0; } - g_code_block_unlock_src(block); - - /* Coté destinations */ - - g_code_block_lock_dest(block); - - while (count_flat_array_items(block->to) > 0) + else { - 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); + class = G_CODE_BLOCK_GET_CLASS(block); - rem_item_from_flat_array(&block->to, 0, sizeof(block_link_t)); + result = class->get_src(block, block->list, count); } - g_code_block_unlock_dest(block); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc dont les informations sont à consulter. * -* * -* Description : Fournit la quantité de blocs de code pointant vers un autre. * -* * -* Retour : Nombre de ces origines. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_code_block_count_sources(const GCodeBlock *block) -{ - size_t result; /* Nombre de liens à renvoyer */ - - result = count_flat_array_items(block->from); - return result; } @@ -612,72 +405,34 @@ size_t g_code_block_count_sources(const GCodeBlock *block) /****************************************************************************** * * * Paramètres : block = bloc dont les informations sont à consulter. * -* index = indice de l'élément à retrouver. * +* count = nombre de ces destinations. [OUT] * * * -* Description : Fournit les détails d'une origine d'un bloc de code donné. * +* Description : Fournit les détails des destinations de bloc de code. * * * -* Retour : Lien déterminé vers un bloc de code d'origine. * +* Retour : Liens déterminés vers des blocs de code de destination. * * * * Remarques : - * * * ******************************************************************************/ -const block_link_t *g_code_block_get_source(GCodeBlock *block, size_t index) +block_link_t *g_code_block_get_destinations(const GCodeBlock *block, size_t *count) { block_link_t *result; /* Détails présents à renvoyer */ + GCodeBlockClass *class; /* Classe des blocs de code */ - result = get_flat_array_item(block->from, index, sizeof(block_link_t)); - - ref_block_link(result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc dont les informations sont à consulter. * -* * -* Description : Donne le nombre de blocs de code suivants dans le flot. * -* * -* 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 : - * -* * -******************************************************************************/ + if (block->list == NULL) + { + result = NULL; + *count = 0; + } -const block_link_t *g_code_block_get_destination(GCodeBlock *block, size_t index) -{ - block_link_t *result; /* Détails présents à renvoyer */ + else + { + class = G_CODE_BLOCK_GET_CLASS(block); - result = get_flat_array_item(block->to, index, sizeof(block_link_t)); + result = class->get_dest(block, block->list, count); - ref_block_link(result); + } return result; @@ -755,11 +510,7 @@ static void g_block_list_dispose(GBlockList *list) 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_clear_object(&list->blocks[i]); - } + g_clear_object(&list->blocks[i]); G_OBJECT_CLASS(g_block_list_parent_class)->dispose(G_OBJECT(list)); @@ -806,7 +557,7 @@ GBlockList *g_block_list_new(size_t count) result = g_object_new(G_TYPE_BLOCK_LIST, NULL); - result->blocks = (GCodeBlock **)calloc(count, sizeof(GCodeBlock *)); + result->blocks = calloc(count, sizeof(GCodeBlock *)); result->count = count; @@ -859,6 +610,9 @@ void g_block_list_add_block(GBlockList *list, GCodeBlock *block, size_t index) list->blocks[index] = block; + block->list = list; + g_object_ref(G_OBJECT(list)); + g_code_block_set_index(block, index); } @@ -879,10 +633,6 @@ void g_block_list_add_block(GBlockList *list, GCodeBlock *block, size_t index) 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); } diff --git a/src/analysis/block.h b/src/analysis/block.h index 21eaaa5..23637d7 100644 --- a/src/analysis/block.h +++ b/src/analysis/block.h @@ -88,36 +88,15 @@ typedef struct _block_link_t } block_link_t; -#define ref_block_link(l) g_object_ref(G_OBJECT(l->linked)); -#define unref_block_link(l) g_object_unref(G_OBJECT(l->linked)); +#define ref_block_link(l) g_object_ref(G_OBJECT((l)->linked)); +#define unref_block_link(l) g_object_unref(G_OBJECT((l)->linked)); -/* Met à disposition un encadrement des accès aux liens. */ -void g_code_block_lock_unlock_links(GCodeBlock *, bool, bool); +/* Fournit les détails des origines d'un bloc de code donné. */ +block_link_t *g_code_block_get_sources(const GCodeBlock *, size_t *); -/* Etablit un lien entre deux blocs de code. */ -void g_code_block_link_with(GCodeBlock *, GCodeBlock *, InstructionLinkType); - -/* Supprime tous les liens établis avec d'autres blocs de code. */ -void g_code_block_delete_all_links(GCodeBlock *block); - -#define g_code_block_lock_src(blk) g_code_block_lock_unlock_links(blk, true, true) -#define g_code_block_unlock_src(blk) g_code_block_lock_unlock_links(blk, true, false) - -/* Fournit la quantité de blocs de code pointant vers un autre. */ -size_t g_code_block_count_sources(const GCodeBlock *); - -/* Fournit les détails d'une origine d'un bloc de code donné. */ -const block_link_t *g_code_block_get_source(GCodeBlock *, size_t); - -#define g_code_block_lock_dest(blk) g_code_block_lock_unlock_links(blk, false, true) -#define g_code_block_unlock_dest(blk) g_code_block_lock_unlock_links(blk, false, false) - -/* Donne le nombre de blocs de code suivants dans le flot. */ -size_t g_code_block_count_destinations(const GCodeBlock *); - -/* Fournit les détails d'une destination de bloc de code. */ -const block_link_t *g_code_block_get_destination(GCodeBlock *, size_t); +/* Fournit les détails des destinations de bloc de code. */ +block_link_t *g_code_block_get_destinations(const GCodeBlock *, size_t *); diff --git a/src/analysis/disass/block.c b/src/analysis/disass/block.c index 6cf7c17..23393f6 100644 --- a/src/analysis/disass/block.c +++ b/src/analysis/disass/block.c @@ -25,6 +25,7 @@ #include +#include #include "../block-int.h" @@ -70,8 +71,11 @@ static void g_basic_block_finalize(GBasicBlock *); /* Détermine si un bloc de code débute à une adresse donnée. */ static bool g_basic_block_is_starting_with(const GBasicBlock *, const vmpa2t *); -/* Etablit les liens entre un bloc de code et ses voisins. */ -static void g_basic_block_resolve_links(GBasicBlock *, const GBlockList *); +/* Fournit les détails des origines d'un bloc de code donné. */ +static block_link_t *g_basic_block_get_sources(const GBasicBlock *, const GBlockList *, size_t *); + +/* Fournit les détails des destinations de bloc de code. */ +static block_link_t *g_basic_block_get_destinations(const GBasicBlock *, const GBlockList *, size_t *); /* Fournit la représentation graphique d'un bloc de code. */ static GBufferView *g_basic_block_build_view(const GBasicBlock *, segcnt_list *); @@ -112,7 +116,8 @@ static void g_basic_block_class_init(GBasicBlockClass *class) block = G_CODE_BLOCK_CLASS(class); block->is_starting = (block_is_starting_fc)g_basic_block_is_starting_with; - block->link = (block_resolve_links_fc)g_basic_block_resolve_links; + block->get_src = (block_get_links_fc)g_basic_block_get_sources; + block->get_dest = (block_get_links_fc)g_basic_block_get_destinations; block->build = (block_build_view_fc)g_basic_block_build_view; } @@ -248,24 +253,102 @@ static bool g_basic_block_is_starting_with(const GBasicBlock *block, const vmpa2 /****************************************************************************** * * -* Paramètres : block = bloc de code à mettre à jour. * +* Paramètres : block = bloc dont les informations sont à consulter. * * list = ensemble des blocs de code à disposition. * +* count = nombre de ces origines. [OUT] * * * -* Description : Etablit les liens entre un bloc de code et ses voisins. * +* Description : Fournit les détails des origines d'un bloc de code donné. * * * -* Retour : - * +* Retour : Liens déterminés vers des blocs de code d'origine. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static block_link_t *g_basic_block_get_sources(const GBasicBlock *block, const GBlockList *list, size_t *count) +{ + block_link_t *result; /* Détails présents à renvoyer */ + size_t scount; /* Nombre de liens d'origine */ + size_t i; /* Boucle de parcours */ + const instr_link_t *src; /* Instr. visée par une autre */ + const mrange_t *range; /* Couverture d'instruction */ + GCodeBlock *target; /* Bloc ciblé par un lien */ + block_link_t *new; /* Nouvelle entrée à définir */ + + result = NULL; + *count = 0; + + g_arch_instruction_lock_src(block->first); + scount = g_arch_instruction_count_sources(block->first); + + for (i = 0; i < scount; i++) + { + src = g_arch_instruction_get_source(block->first, i); + + range = g_arch_instruction_get_range(src->linked); + + target = g_block_list_find_by_starting_addr(list, get_mrange_addr(range)); + + /** + * Les liens ne sont pas toujours internes ! + */ + + if (target != NULL) + { + result = realloc(result, ++(*count) * sizeof(block_link_t)); + + new = &result[*count - 1]; + + new->linked = target; + new->type = src->type; + + /** + * On pourrait par optimisation retirer les deux lignes suivantes... + */ + + ref_block_link(new); + + g_object_unref(G_OBJECT(target)); + + } + + unref_instr_link(src); + + } + + g_arch_instruction_unlock_src(block->first); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc dont les informations sont à consulter. * +* list = ensemble des blocs de code à disposition. * +* count = nombre de ces destinations. [OUT] * +* * +* Description : Fournit les détails des destinations de bloc de code. * +* * +* Retour : Liens déterminés vers des blocs de code de destination. * * * * Remarques : - * * * ******************************************************************************/ -static void g_basic_block_resolve_links(GBasicBlock *block, const GBlockList *list) +static block_link_t *g_basic_block_get_destinations(const GBasicBlock *block, const GBlockList *list, size_t *count) { + block_link_t *result; /* Détails présents à renvoyer */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ const instr_link_t *dest; /* Instr. visée par une autre */ const mrange_t *range; /* Couverture d'instruction */ GCodeBlock *target; /* Bloc ciblé par un lien */ + block_link_t *new; /* Nouvelle entrée à définir */ + + result = NULL; + *count = 0; g_arch_instruction_lock_dest(block->last); dcount = g_arch_instruction_count_destinations(block->last); @@ -291,8 +374,21 @@ static void g_basic_block_resolve_links(GBasicBlock *block, const GBlockList *li if (target != NULL) { - g_code_block_link_with(G_CODE_BLOCK(block), target, dest->type); + result = realloc(result, ++(*count) * sizeof(block_link_t)); + + new = &result[*count - 1]; + + new->linked = target; + new->type = dest->type; + + /** + * On pourrait par optimisation retirer les deux lignes suivantes... + */ + + ref_block_link(new); + g_object_unref(G_OBJECT(target)); + } unref_instr_link(dest); @@ -301,6 +397,8 @@ static void g_basic_block_resolve_links(GBasicBlock *block, const GBlockList *li g_arch_instruction_unlock_dest(block->last); + return result; + } diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index b6eb4c5..d703aee 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -50,19 +50,19 @@ void rank_routine_block(const GBlockList *list, GCodeBlock *block) { size_t next; /* Rang suivant obtenu */ size_t dcount; /* Nombre de liens de dest. */ + block_link_t *links; /* Liens associés au bloc */ size_t i; /* Boucle de parcours */ - const block_link_t *dest; /* Instr. visée par une autre */ + block_link_t *dest; /* Bloc visé par un autre */ InstructionLinkType type; /* Raccourci pour confort */ unsigned int rank; /* Rang à constituer */ next = g_code_block_get_rank(block) + 1; - g_code_block_lock_dest(block); - dcount = g_code_block_count_destinations(block); + links = g_code_block_get_destinations(block, &dcount); for (i = 0; i < dcount; i++) { - dest = g_code_block_get_destination(block, i); + dest = &links[i]; type = dest->type; @@ -93,11 +93,12 @@ void rank_routine_block(const GBlockList *list, GCodeBlock *block) next_dest: - unref_instr_link(dest); + unref_block_link(dest); } - g_code_block_unlock_dest(block); + if (links != NULL) + free(links); } diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c index 70d58fa..bc8f9dd 100644 --- a/src/gtkext/graph/cluster.c +++ b/src/gtkext/graph/cluster.c @@ -1712,8 +1712,9 @@ static void g_graph_cluster_add_sub(GGraphCluster *cluster, GGraphCluster *sub) static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all) { size_t dcount; /* Nombre de liens de dest. */ + block_link_t *links; /* Liens associés au bloc */ size_t i; /* Boucle de parcours #1 */ - const block_link_t *dest; /* Bloc visé par une autre */ + block_link_t *dest; /* Bloc visé par un autre */ GGraphCluster *target; /* Bloc ciblé par un lien */ leaving_link_t *leaving; /* Point de départ d'un lien */ incoming_link_t *incoming; /* Définitions d'arrivée */ @@ -1722,12 +1723,11 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all /* Au niveau du bloc courant */ - g_code_block_lock_dest(cluster->block); - dcount = g_code_block_count_destinations(cluster->block); + links = g_code_block_get_destinations(cluster->block, &dcount); for (i = 0; i < dcount; i++) { - dest = g_code_block_get_destination(cluster->block, i); + dest = &links[i]; switch (dest->type) { @@ -1783,7 +1783,6 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all /* Point d'arrivée */ midpts = malloc(2 * sizeof(GdkPoint)); - midpts = calloc(2, sizeof(GdkPoint));//////////////// REMME incoming = create_incoming_loop_link(target, midpts, leaving); @@ -1813,9 +1812,8 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all } - g_code_block_unlock_dest(cluster->block); - - + if (links != NULL) + free(links); /* Doit-on forcer un lien strictement vertical ? */ @@ -2634,8 +2632,9 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi gboolean new; /* Bloc déjà traité ? */ #endif size_t dcount; /* Nombre de liens de dest. */ + block_link_t *links; /* Liens associés au bloc */ size_t i; /* Boucle de parcours #1 */ - const block_link_t *dest; /* Bloc visé par une autre */ + block_link_t *dest; /* Bloc visé par un autre */ size_t j; /* Boucle de parcours #2 */ bool changed; /* Un ajout a été effectué ? */ const bitfield_t *dominators; /* Blocs dominant ce même bloc */ @@ -2655,12 +2654,11 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi /* Détermination des blocs suivants */ - g_code_block_lock_dest(block); - dcount = g_code_block_count_destinations(block); + links = g_code_block_get_destinations(block, &dcount); for (i = 0; i < dcount; i++) { - dest = g_code_block_get_destination(block, i); + dest = &links[i]; switch (dest->type) { @@ -2718,7 +2716,8 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi } - g_code_block_unlock_dest(block); + if (links != NULL) + free(links); g_object_unref(G_OBJECT(block)); -- cgit v0.11.2-87-g4458