summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-01-13 23:44:21 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-01-13 23:44:21 (GMT)
commit2a6d92e2d55c0a7826137b2cc2e3148bb298abb9 (patch)
tree55714d85528a4cbe15e802b8a7bc2cdbf861c744
parent2ed3c9274c8dafb660bc25743a1aac7c72c12965 (diff)
Provided uncached code block links.
-rw-r--r--plugins/pychrysalide/analysis/block.c25
-rw-r--r--src/analysis/block-int.h12
-rw-r--r--src/analysis/block.c320
-rw-r--r--src/analysis/block.h33
-rw-r--r--src/analysis/disass/block.c114
-rw-r--r--src/analysis/disass/rank.c13
-rw-r--r--src/gtkext/graph/cluster.c25
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 <malloc.h>
#include <pygobject.h>
@@ -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 <assert.h>
+#include <malloc.h>
#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));