summaryrefslogtreecommitdiff
path: root/tests/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'tests/analysis')
-rw-r--r--tests/analysis/disass/Makefile5
-rw-r--r--tests/analysis/disass/block.py37
-rwxr-xr-xtests/analysis/disass/selfloop.c64
3 files changed, 105 insertions, 1 deletions
diff --git a/tests/analysis/disass/Makefile b/tests/analysis/disass/Makefile
index 030e868..ef70dec 100644
--- a/tests/analysis/disass/Makefile
+++ b/tests/analysis/disass/Makefile
@@ -1,5 +1,5 @@
-EXECUTABLES=hello endofname irreducible
+EXECUTABLES=hello endofname irreducible selfloop
all: $(EXECUTABLES)
@@ -12,5 +12,8 @@ endofname: endofname.c
irreducible: irreducible.c
$(ARM_CROSS)gcc $< -o $@
+selfloop: selfloop.c
+ $(ARM_CROSS)gcc $< -o $@
+
clean:
rm -f $(EXECUTABLES)
diff --git a/tests/analysis/disass/block.py b/tests/analysis/disass/block.py
index 84fa4c3..10a2c80 100644
--- a/tests/analysis/disass/block.py
+++ b/tests/analysis/disass/block.py
@@ -31,6 +31,8 @@ class TestBasicBlocks(ChrysalideTestCase):
os.system('make -C %s irreducible > /dev/null 2>&1' % dirpath)
+ os.system('make -C %s selfloop > /dev/null 2>&1' % dirpath)
+
@classmethod
def tearDownClass(cls):
@@ -110,3 +112,38 @@ class TestBasicBlocks(ChrysalideTestCase):
loop_count += 1
self.assertEqual(loop_count, 2)
+
+
+ def testSelfLoopBlock(self):
+ """Validate support for self loop blocks."""
+
+ fullname = sys.modules[self.__class__.__module__].__file__
+ filename = os.path.basename(fullname)
+
+ baselen = len(fullname) - len(filename)
+
+ cnt = FileContent(fullname[:baselen] + 'selfloop')
+ 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('string_array_len')
+ 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, 1)
diff --git a/tests/analysis/disass/selfloop.c b/tests/analysis/disass/selfloop.c
new file mode 100755
index 0000000..fe9cf21
--- /dev/null
+++ b/tests/analysis/disass/selfloop.c
@@ -0,0 +1,64 @@
+
+#include <stdio.h>
+
+
+/**
+ * On reproduit un code similaire à celui d'un fichier de Busybox (busybox-1.30.0/libbb/appletlib.c).
+ *
+ * La commande de compilation est :
+ *
+ * arm-linux-gnueabi-gcc -Wp,-MD,libbb/.appletlib.o.d -std=gnu99 -Iinclude -Ilibbb -include include/autoconf.h -D_GNU_SOURCE -DNDEBUG -D"BB_VER=KBUILD_STR(1.30.0)" -Wall -Wshadow -Wwrite-strings -Wundef -Wstrict-prototypes -Wunused -Wunused-parameter -Wunused-function -Wunused-value -Wmissing-prototypes -Wmissing-declarations -Wno-format-security -Wdeclaration-after-statement -Wold-style-definition -fno-builtin-strlen -finline-limit=0 -fomit-frame-pointer -ffunction-sections -fdata-sections -fno-guess-branch-probability -funsigned-char -static-libgcc -falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1 -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-builtin-printf -Os -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(appletlib)" -D"KBUILD_MODNAME=KBUILD_STR(appletlib)" -c -o libbb/appletlib.o libbb/appletlib.c
+ *
+ */
+
+
+/*
+unsigned FAST_FUNC string_array_len(char **argv)
+{
+ char **start = argv;
+
+ while (*argv)
+ argv++;
+
+ return argv - start;
+}
+*/
+
+unsigned __attribute__ ((naked)) string_array_len(char **argv)
+{
+ /*
+ 0x00009a0c <+0>: mov r2, r0
+ 0x00009a10 <+4>: mov r3, r2
+ 0x00009a14 <+8>: ldr r1, [r3]
+ 0x00009a18 <+12>: add r2, r2, #4
+ 0x00009a1c <+16>: cmp r1, #0
+ 0x00009a20 <+20>: bne 0x9a10 <string_array_len+4>
+ 0x00009a24 <+24>: rsb r0, r0, r3
+ 0x00009a28 <+28>: asr r0, r0, #2
+ 0x00009a2c <+32>: bx lr
+ */
+
+asm (
+
+ "mov r2, r0" "\n"
+
+ ".Lbl_9a10%=:" "\n"
+
+ "mov r3, r2" "\n"
+ "ldr r1, [r3]" "\n"
+ "add r2, r2, #4" "\n"
+ "cmp r1, #0" "\n"
+ "bne .Lbl_9a10%=" "\n"
+ "rsb r0, r0, r3" "\n"
+ "asr r0, r0, #2" "\n"
+ "bx lr" "\n"
+
+ ::"r" (argv));
+
+}
+
+int main(int argc, char **argv)
+{
+ return string_array_len(argv);
+
+}