summaryrefslogtreecommitdiff
path: root/src/analysis/disass
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-01-15 22:00:38 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-01-15 22:00:38 (GMT)
commit831f90f15a145636177c387fdd73d777a9e6d84f (patch)
tree2144026093c2b35b49660343961af12b0847c1d0 /src/analysis/disass
parent487e574f590d20ce40545030e7a4c80d95308788 (diff)
Improved complex loop detection.
Diffstat (limited to 'src/analysis/disass')
-rw-r--r--src/analysis/disass/loop.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c
index b82d58e..4a499fd 100644
--- a/src/analysis/disass/loop.c
+++ b/src/analysis/disass/loop.c
@@ -77,6 +77,9 @@ static void tag_loop_head(bblock_info_t *, bblock_info_t *);
/* Parcourt une arborescence de blocs à la recherche de boucles. */
static bblock_info_t *traverse_basic_blocks_dfs(bblock_info_t *, GBlockList *, bblock_info_t *, unsigned int);
+/* Indique si une boucle doit être définie. */
+static bool should_be_natural_loop_link(bblock_info_t *, bblock_info_t *);
+
/* Définit les boucles entre un ensemble de blocs basiques. */
static void define_basic_blocks_loops(GBlockList *list, bblock_info_t *);
@@ -342,6 +345,33 @@ static bblock_info_t *traverse_basic_blocks_dfs(bblock_info_t *root, GBlockList
/******************************************************************************
* *
+* Paramètres : dest = informations du bloc de destination. *
+* header = informations de l'entête de boucle. *
+* *
+* Description : Indique si une boucle doit être définie. *
+* *
+* Retour : true si une boucle naturelle est bien présente. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool should_be_natural_loop_link(bblock_info_t *dest, bblock_info_t *header)
+{
+ bool result; /* Conclusion à retourner */
+
+ result = (dest == header);
+
+ if (!result && header != NULL)
+ result = should_be_natural_loop_link(dest, header->iloop_header);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : list = liste de blocs de code à consulter. *
* info = informations complémentaires quant aux blocs. *
* *
@@ -408,7 +438,7 @@ static void define_basic_blocks_loops(GBlockList *list, bblock_info_t *info)
links = get_block_successors(block, info, &count);
for (k = 0; k < count; k++)
- if (links[k].info == iter->iloop_header
+ if (should_be_natural_loop_link(links[k].info, iter->iloop_header)
/**
* Il se peut qu'un bloc fasse référence à lui même !
*