summaryrefslogtreecommitdiff
path: root/tests/analysis/disass
diff options
context:
space:
mode:
Diffstat (limited to 'tests/analysis/disass')
-rw-r--r--tests/analysis/disass/Makefile5
-rw-r--r--tests/analysis/disass/block.py38
-rw-r--r--tests/analysis/disass/irreducible.c37
3 files changed, 79 insertions, 1 deletions
diff --git a/tests/analysis/disass/Makefile b/tests/analysis/disass/Makefile
index 8155642..030e868 100644
--- a/tests/analysis/disass/Makefile
+++ b/tests/analysis/disass/Makefile
@@ -1,5 +1,5 @@
-EXECUTABLES=hello endofname
+EXECUTABLES=hello endofname irreducible
all: $(EXECUTABLES)
@@ -9,5 +9,8 @@ hello: hello.c
endofname: endofname.c
$(ARM_CROSS)gcc $< -o $@
+irreducible: irreducible.c
+ $(ARM_CROSS)gcc $< -o $@
+
clean:
rm -f $(EXECUTABLES)
diff --git a/tests/analysis/disass/block.py b/tests/analysis/disass/block.py
index 1663150..84fa4c3 100644
--- a/tests/analysis/disass/block.py
+++ b/tests/analysis/disass/block.py
@@ -8,6 +8,7 @@
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
@@ -28,6 +29,8 @@ class TestBasicBlocks(ChrysalideTestCase):
os.system('make -C %s hello > /dev/null 2>&1' % dirpath)
+ os.system('make -C %s irreducible > /dev/null 2>&1' % dirpath)
+
@classmethod
def tearDownClass(cls):
@@ -72,3 +75,38 @@ class TestBasicBlocks(ChrysalideTestCase):
self.assertEqual(found.index, 0)
self.assertEqual(found.rank, 0)
+
+
+ def testIrreducible(self):
+ """Validate support for irreducible loops."""
+
+ fullname = sys.modules[self.__class__.__module__].__file__
+ filename = os.path.basename(fullname)
+
+ baselen = len(fullname) - len(filename)
+
+ cnt = FileContent(fullname[:baselen] + 'irreducible')
+ 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('argstr')
+ self.assertIsNotNone(sym)
+
+ found = sym.basic_blocks.find_by_starting_addr(sym.range.addr)
+ self.assertIsNotNone(found)
+
+ 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)
diff --git a/tests/analysis/disass/irreducible.c b/tests/analysis/disass/irreducible.c
new file mode 100644
index 0000000..8edd592
--- /dev/null
+++ b/tests/analysis/disass/irreducible.c
@@ -0,0 +1,37 @@
+
+static void argstr(char *p, int flags)
+{
+ if (flags)
+ {
+ tilde:
+ p++;
+ }
+
+ for (;;)
+ {
+ switch (*p)
+ {
+ case '\0':
+ goto breakloop;
+
+ case ':':
+ if (*--p == '~')
+ goto tilde;
+ continue;
+ }
+
+ }
+
+ breakloop:
+
+ ;
+
+}
+
+int main(int argc, char **argv)
+{
+ argstr(argv[0], 0);
+
+ return 0;
+
+}