diff options
Diffstat (limited to 'tests/analysis/disass')
-rw-r--r-- | tests/analysis/disass/Makefile | 5 | ||||
-rw-r--r-- | tests/analysis/disass/block.py | 38 | ||||
-rw-r--r-- | tests/analysis/disass/irreducible.c | 37 |
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; + +} |