diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..f890506 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,5 @@ +all: + ./testall.sh +clean: + rm -f output.o output.o.inventory reference.inventory test.inventory + diff --git a/test/test01.c b/test/test01.c new file mode 100644 index 0000000..b45be2f --- /dev/null +++ b/test/test01.c @@ -0,0 +1,16 @@ +#include + +void test_func() { + printf("this is before\n"); +} + +/* + * This test case ensures that deep inspection for rela entries + * that reference strings is taking place. The text and rela sections + * for test_func() are the same between the original and patched + * versions. However, the tool should detect that the string referenced + * by the printf has changed. + * + * Verification points: test_func bundle and the rodata.str1.8 section + * are included. + */ diff --git a/test/test01.inventory b/test/test01.inventory new file mode 100644 index 0000000..5fa4a73 --- /dev/null +++ b/test/test01.inventory @@ -0,0 +1,11 @@ +section .rodata.str1.1 +section .text.test_func +section .rela.text.test_func +section .shstrtab +section .symtab +section .strtab +symbol test01.c 4 0 +symbol .rodata.str1.1 3 0 +symbol .text.test_func 3 0 +symbol test_func 2 1 +symbol puts 0 1 diff --git a/test/test01.patch b/test/test01.patch new file mode 100644 index 0000000..cdec9ac --- /dev/null +++ b/test/test01.patch @@ -0,0 +1,11 @@ +--- test01.c.orig 2014-03-10 14:34:02.547250917 -0500 ++++ test01.c 2014-03-10 14:34:02.549250971 -0500 +@@ -1,7 +1,7 @@ + #include + + void test_func() { +- printf("this is before\n"); ++ printf("this is after\n"); + } + + /* diff --git a/test/test02.c b/test/test02.c new file mode 100644 index 0000000..e3ea0d0 --- /dev/null +++ b/test/test02.c @@ -0,0 +1,22 @@ +#include + +static int a = 1; + +void test_func() { + printf("%d\n",a); +} + +/* this is to ensure that a isn't optimized out by the compiler */ +void test_func2() { + a = 2; +} + +/* + * This test case ensures that static data structures, normally referenced + * by section in rela entries that reference them, are being converted to + * symbol references, so they can later be linked to the location of the + * data structure in the running kernel + * + * Verification points: test_func() bundle and 'a' symbol should be included. + * 'a' should have GLOBAL bind and NOTYPE type. + */ diff --git a/test/test02.inventory b/test/test02.inventory new file mode 100644 index 0000000..10d8641 --- /dev/null +++ b/test/test02.inventory @@ -0,0 +1,13 @@ +section .rodata.str1.1 +section .text.test_func +section .rela.text.test_func +section .shstrtab +section .symtab +section .strtab +symbol test02.c 4 0 +symbol .rodata.str1.1 3 0 +symbol .text.test_func 3 0 +symbol a 0 1 +symbol test_func 2 1 +symbol printf 0 1 +symbol puts 0 1 diff --git a/test/test02.patch b/test/test02.patch new file mode 100644 index 0000000..b7d5e08 --- /dev/null +++ b/test/test02.patch @@ -0,0 +1,10 @@ +--- test02.c.orig 2014-03-10 14:34:02.556251118 -0500 ++++ test02.c 2014-03-10 14:34:02.558251160 -0500 +@@ -4,6 +4,7 @@ + + void test_func() { + printf("%d\n",a); ++ printf("this is after\n"); + } + + /* this is to ensure that a isn't optimized out by the compiler */ diff --git a/test/test03.c b/test/test03.c new file mode 100644 index 0000000..118aee3 --- /dev/null +++ b/test/test03.c @@ -0,0 +1,13 @@ +#include + +void test_func() { + printf("this is before\n"); +} + +/* + * This test case introduces a new function called by an existing function + * and ensure that the bundle for that function is included. + * + * Verification points: bundles for test_func() and test_func2() should be + * included. + */ diff --git a/test/test03.inventory b/test/test03.inventory new file mode 100644 index 0000000..ef9d1d4 --- /dev/null +++ b/test/test03.inventory @@ -0,0 +1,15 @@ +section .rodata.str1.1 +section .text.test_func2 +section .rela.text.test_func2 +section .text.test_func +section .rela.text.test_func +section .shstrtab +section .symtab +section .strtab +symbol test03.c 4 0 +symbol .rodata.str1.1 3 0 +symbol .text.test_func2 3 0 +symbol test_func2 2 0 +symbol .text.test_func 3 0 +symbol puts 0 1 +symbol test_func 2 1 diff --git a/test/test03.patch b/test/test03.patch new file mode 100644 index 0000000..90359f1 --- /dev/null +++ b/test/test03.patch @@ -0,0 +1,15 @@ +--- test03.c.orig 2014-03-10 14:34:02.564251278 -0500 ++++ test03.c 2014-03-10 14:34:02.566251318 -0500 +@@ -1,7 +1,12 @@ + #include + ++static void test_func2() { ++ printf("this is after\n"); ++} ++ + void test_func() { + printf("this is before\n"); ++ test_func2(); + } + + /* diff --git a/test/testall.sh b/test/testall.sh new file mode 100755 index 0000000..0059cf0 --- /dev/null +++ b/test/testall.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +for i in *.c +do + TESTCASE=${i%.*} + ./testone.sh $TESTCASE +done diff --git a/test/testone.sh b/test/testone.sh new file mode 100755 index 0000000..8f9387f --- /dev/null +++ b/test/testone.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +if [[ $# -ne 1 ]] +then + echo "test.sh testcase" + exit 1 +fi + +TESTCASE=$1 +FLAGS="-fno-strict-aliasing -fno-common -fno-delete-null-pointer-checks -O2 -m64 -mpreferred-stack-boundary=4 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fno-asynchronous-unwind-tables -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-overflow -fconserve-stack -ffunction-sections -fdata-sections -fno-inline" +CFLAGS="$FLAGS" make $TESTCASE.o > /dev/null 2>&1 || exit 1 +mv -f $TESTCASE.o $TESTCASE.o.orig +patch $TESTCASE.c $TESTCASE.patch > /dev/null 2>&1 || exit 1 +CFLAGS="$FLAGS" make $TESTCASE.o > /dev/null 2>&1 || exit 1 +if [[ ! -e ../kpatch-build/create-diff-object ]] +then + make -C ../kpatch-build create-diff-object || exit 1 +fi +../kpatch-build/create-diff-object -i $TESTCASE.o.orig $TESTCASE.o output.o > /dev/null 2>&1 || exit 1 +rm -f $TESTCASE.o $TESTCASE.o.orig > /dev/null 2>&1 +patch -R $TESTCASE.c $TESTCASE.patch > /dev/null 2>&1 || echo "warning: unable to unpatch file $TESTCASE.c" + +sort $TESTCASE.inventory > reference.inventory +sort output.o.inventory > test.inventory +rm -f output.o.inventory > /dev/null 2>&1 +diff reference.inventory test.inventory +if [[ $? -ne 0 ]] +then + echo "$TESTCASE failed" && exit 1 +else + echo "$TESTCASE passed" +fi +rm -f reference.inventory test.inventory output.o