From d6bf56e4a75be0fe0946189a42dd7baecb399903 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 21 Feb 2019 21:33:20 +0100
Subject: Fixed a little mistake introduced in 7fc86b40.

---
 src/analysis/disass/loop.c     |  2 +-
 tests/analysis/disass/Makefile |  5 ++-
 tests/analysis/disass/block.py |  4 +--
 tests/analysis/disass/h2.c     | 36 ++++++++++++++++++++
 tests/analysis/disass/links.py | 11 ++++---
 tests/analysis/disass/loop.py  | 75 ++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 125 insertions(+), 8 deletions(-)
 create mode 100644 tests/analysis/disass/h2.c
 create mode 100644 tests/analysis/disass/loop.py

diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c
index c35bab7..984b355 100644
--- a/src/analysis/disass/loop.c
+++ b/src/analysis/disass/loop.c
@@ -366,7 +366,7 @@ static bool _should_be_natural_loop_link(bblock_info_t *dest, bblock_info_t *hea
     result = (dest == header);
 
     if (!result && header != NULL)
-        result = should_be_natural_loop_link(dest, header->iloop_header);
+        result = _should_be_natural_loop_link(dest, header->iloop_header);
 
     return result;
 
diff --git a/tests/analysis/disass/Makefile b/tests/analysis/disass/Makefile
index 8359b5c..4fd0338 100644
--- a/tests/analysis/disass/Makefile
+++ b/tests/analysis/disass/Makefile
@@ -1,5 +1,5 @@
 
-EXECUTABLES=hello endofname irreducible selfloop evalcommand h1b
+EXECUTABLES=hello endofname irreducible selfloop evalcommand h1b h2
 
 all: $(EXECUTABLES)
 
@@ -21,5 +21,8 @@ evalcommand: evalcommand.c
 h1b: h1b.c
 	$(ARM_CROSS)gcc $< -o $@
 
+h2: h2.c
+	$(ARM_CROSS)gcc $< -o $@
+
 clean:
 	rm -f $(EXECUTABLES)
diff --git a/tests/analysis/disass/block.py b/tests/analysis/disass/block.py
index 0907542..b9f34cd 100644
--- a/tests/analysis/disass/block.py
+++ b/tests/analysis/disass/block.py
@@ -280,7 +280,7 @@ class TestBasicBlocks(ChrysalideTestCase):
                 if dt == ArchInstruction.ILT_LOOP:
                     loop_count += 1
 
-        self.assertEqual(loop_count, 8)
+        self.assertEqual(loop_count, 7)
 
         loop_count = 0
 
@@ -289,4 +289,4 @@ class TestBasicBlocks(ChrysalideTestCase):
                 if dt == ArchInstruction.ILT_LOOP:
                     loop_count += 1
 
-        self.assertEqual(loop_count, 8)
+        self.assertEqual(loop_count, 7)
diff --git a/tests/analysis/disass/h2.c b/tests/analysis/disass/h2.c
new file mode 100644
index 0000000..fe77341
--- /dev/null
+++ b/tests/analysis/disass/h2.c
@@ -0,0 +1,36 @@
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    int i;
+    int j;
+
+    for (i = 0; i < argc; i++)
+    {
+        printf("arg[%d]: %s\n", i, argv[i]);
+
+        for (j = 0; j < i; j++)
+        {
+            printf(".");
+
+#if 1
+            if (argc > 2)
+                printf("!");
+            else
+                printf("#");
+
+            printf(".");
+#endif
+
+        }
+
+        printf("\n");
+
+    }
+
+    printf("Hello\n");
+
+    return 0;
+
+}
diff --git a/tests/analysis/disass/links.py b/tests/analysis/disass/links.py
index e0c9ec9..e4c9946 100644
--- a/tests/analysis/disass/links.py
+++ b/tests/analysis/disass/links.py
@@ -62,11 +62,14 @@ class TestDisassLinks(ChrysalideTestCase):
 
         binary.analyze_and_wait()
 
+        sym = fmt.find_symbol_by_label('main')
+        self.assertIsNotNone(sym)
+
         nat_count = 0
 
-        for ins in binary.processor.instrs:
-            for _, dt in ins.destinations:
-                if dt == ArchInstruction.ILT_EXEC_FLOW:
+        for blk in sym.basic_blocks:
+            for _, dt in blk.destinations:
+                if dt == ArchInstruction.ILT_LOOP:
                     nat_count += 1
 
-        self.assertEqual(nat_count, 3)
+        self.assertEqual(nat_count, 1)
diff --git a/tests/analysis/disass/loop.py b/tests/analysis/disass/loop.py
new file mode 100644
index 0000000..6f7f405
--- /dev/null
+++ b/tests/analysis/disass/loop.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+
+# S'assure du bon fonctionnement des blocs basiques
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.analysis.contents import FileContent
+from pychrysalide.analysis import LoadedBinary
+from pychrysalide.arch import ArchInstruction
+from pychrysalide.format.elf import ElfFormat
+import os
+import sys
+
+
+class TestDisassLoop(ChrysalideTestCase):
+    """TestCase for loop detection."""
+
+    @classmethod
+    def setUpClass(cls):
+
+        super(TestDisassLoop, cls).setUpClass()
+
+        cls.log('Compile binary "h2" if needed...')
+
+        fullname = sys.modules[cls.__module__].__file__
+        dirpath = os.path.dirname(fullname)
+
+        os.system('make -C %s h2 > /dev/null 2>&1' % dirpath)
+
+
+    @classmethod
+    def tearDownClass(cls):
+
+        super(TestDisassLoop, cls).tearDownClass()
+
+        cls.log('Delete built binaries...')
+
+        fullname = sys.modules[cls.__module__].__file__
+        dirpath = os.path.dirname(fullname)
+
+        os.system('make -C %s clean > /dev/null 2>&1' % dirpath)
+
+
+    def testLoopOverflow(self):
+        """Ensure loop number does't not get overestimated."""
+
+        fullname = sys.modules[self.__class__.__module__].__file__
+        filename = os.path.basename(fullname)
+
+        baselen = len(fullname) - len(filename)
+
+        cnt = FileContent(fullname[:baselen] + 'h2')
+        self.assertIsNotNone(cnt)
+
+        fmt = ElfFormat(cnt)
+        self.assertIsNotNone(fmt)
+
+        binary = LoadedBinary(fmt)
+        self.assertIsNotNone(binary)
+
+        binary.analyze_and_wait()
+
+        sym = fmt.find_symbol_by_label('main')
+        self.assertIsNotNone(sym)
+
+        loop_count = 0
+
+        for blk in sym.basic_blocks:
+            for _, dt in blk.destinations:
+                if dt == ArchInstruction.ILT_LOOP:
+                    loop_count += 1
+
+        self.assertEqual(loop_count, 2)
-- 
cgit v0.11.2-87-g4458