diff --git a/README.adoc b/README.adoc index 28ad687..828d1f0 100644 --- a/README.adoc +++ b/README.adoc @@ -14012,7 +14012,14 @@ lkmc_exit_status_(\d+) and then exit with the given regular expression, e.g.: .... -./run --arch aarch64 baremetal +./run --arch aarch64 baremetal/return2.c +echo $? +.... + +should output: + +.... +2 .... This magic output string is notably generated by: @@ -14028,6 +14035,7 @@ So setup this `on_exit` automatically from all our <>, so + The following examples end up testing that our setup is working: + +* link:baremetal/assert_fail.c[] * link:baremetal/lkmc_assert_fail.c[] * link:baremetal/return1.c[] * link:baremetal/return2.c[] @@ -14038,6 +14046,30 @@ The following examples end up testing that our setup is working: Beware that on Linux kernel simulations, you cannot even echo that string from userland, since userland stdout shows up on the serial. +====== baremetal assert + +TODO: implement enough syscalls for it, so we can get the error line: + +.... +cd baremetal +ln -s ../lkmc/assert_fail.c +cd .. +./build --arch aarch64 +.... + +fails with: + +.... +/path/to/linux-kernel-module-cheat/out/crosstool-ng/build/default/install/aarch64/lib/gcc/aarch64-unknown-elf/8.1.0/../../../../aarch64-unknown-elf/lib/libg.a(lib_a-signalr.o): In function `_kill_r': +/path/to/linux-kernel-module-cheat/out/crosstool-ng/build/default/build/aarch64-unknown-elf/src/newlib/newlib/libc/reent/signalr.c:53: undefined reference to `_kill' +/path/to/linux-kernel-module-cheat/out/crosstool-ng/build/default/build/aarch64-unknown-elf/src/newlib/newlib/libc/reent/signalr.c:53:(.text+0x20): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_kill' +/path/to/linux-kernel-module-cheat/out/crosstool-ng/build/default/install/aarch64/lib/gcc/aarch64-unknown-elf/8.1.0/../../../../aarch64-unknown-elf/lib/libg.a(lib_a-signalr.o): In function `_getpid_r': +/path/to/linux-kernel-module-cheat/out/crosstool-ng/build/default/build/aarch64-unknown-elf/src/newlib/newlib/libc/reent/signalr.c:83: undefined reference to `_getpid' +/path/to/linux-kernel-module-cheat/out/crosstool-ng/build/default/build/aarch64-unknown-elf/src/newlib/newlib/libc/reent/signalr.c:83:(.text+0x44): relocation truncated to fit: R_AARCH64_JUMP26 against undefined symbol `_getpid' +.... + +at 406ee82cf33a6e3df0067b219b0414c59d7018b3 + 1. + ==== Non-automated tests ===== Test GDB Linux kernel diff --git a/baremetal/assert_fail.c b/baremetal/assert_fail.c new file mode 120000 index 0000000..0263f59 --- /dev/null +++ b/baremetal/assert_fail.c @@ -0,0 +1 @@ +../lkmc/assert_fail.c \ No newline at end of file diff --git a/baremetal/lib/syscalls.c b/baremetal/lib/syscalls.c index 626176d..da42a7b 100644 --- a/baremetal/lib/syscalls.c +++ b/baremetal/lib/syscalls.c @@ -13,13 +13,55 @@ enum { int _close(int file) { return -1; } +void _exit(int status) { +#if defined(GEM5) + LKMC_M5OPS_EXIT; +#else +#if defined(__arm__) + __asm__ __volatile__ ( + "mov r0, #0x18\n" + "ldr r1, =#0x20026\n" + "svc 0x00123456\n" + : + : + : "r0", "r1" + ); +#elif defined(__aarch64__) + /* TODO actually use the exit value here, just for fun. */ + __asm__ __volatile__ ( + "mov x1, #0x26\n" \ + "movk x1, #2, lsl #16\n" \ + "str x1, [sp,#0]\n" \ + "mov x0, #0\n" \ + "str x0, [sp,#8]\n" \ + "mov x1, sp\n" \ + "mov w0, #0x18\n" \ + "hlt 0xf000\n" + : + : + : "x0", "x1" + ); +#endif +#endif +} + int _fstat(int file, struct stat *st) { st->st_mode = S_IFCHR; return 0; } +/* Required by assert. */ +int _getpid(void) { return 0; } + +/* Required by assert. */ +int _kill(pid_t pid, int sig) { + exit(128 + sig); +} + int _isatty(int file) { return 1; } + int _lseek(int file, int ptr, int dir) { return 0; } + int _open(const char *name, int flags, int mode) { return -1; } int _read(int file, char *ptr, int len) { @@ -61,35 +103,3 @@ int _write(int file, char *ptr, int len) { } return len; } - -void _exit(int status) { -#if defined(GEM5) - LKMC_M5OPS_EXIT; -#else -#if defined(__arm__) - __asm__ __volatile__ ( - "mov r0, #0x18\n" - "ldr r1, =#0x20026\n" - "svc 0x00123456\n" - : - : - : "r0", "r1" - ); -#elif defined(__aarch64__) - /* TODO actually use the exit value here, just for fun. */ - __asm__ __volatile__ ( - "mov x1, #0x26\n" \ - "movk x1, #2, lsl #16\n" \ - "str x1, [sp,#0]\n" \ - "mov x0, #0\n" \ - "str x0, [sp,#8]\n" \ - "mov x1, sp\n" \ - "mov w0, #0x18\n" \ - "hlt 0xf000\n" - : - : - : "x0", "x1" - ); -#endif -#endif -} diff --git a/baremetal/lkmc_assert_fail.c b/baremetal/lkmc_assert_fail.c index 0263f59..c612c70 120000 --- a/baremetal/lkmc_assert_fail.c +++ b/baremetal/lkmc_assert_fail.c @@ -1 +1 @@ -../lkmc/assert_fail.c \ No newline at end of file +../lkmc/lkmc_assert_fail.c \ No newline at end of file diff --git a/lkmc/assert_fail.c b/lkmc/assert_fail.c index 68fbefa..cc881b6 100644 --- a/lkmc/assert_fail.c +++ b/lkmc/assert_fail.c @@ -1,5 +1,18 @@ -#include +/* Let's see what happens when an assert fails. + * + * Outcome on Ubuntu 19.04 shows the failure line: + * + * assert_fail.out: /path/to/linux-kernel-module-cheat/userland/c/assert_fail.c:15: main: Assertion `0' failed. + * + * and exit status 134 == 128 + 6, which corresponds to SIGABORT (6). + */ + +#include +#include +#include int main(void) { - lkmc_assert_fail(); + assert(0); + puts("here"); + return EXIT_SUCCESS; } diff --git a/lkmc/lkmc_assert_fail.c b/lkmc/lkmc_assert_fail.c new file mode 100644 index 0000000..68fbefa --- /dev/null +++ b/lkmc/lkmc_assert_fail.c @@ -0,0 +1,5 @@ +#include + +int main(void) { + lkmc_assert_fail(); +} diff --git a/path_properties.py b/path_properties.py index 449155c..d87d593 100644 --- a/path_properties.py +++ b/path_properties.py @@ -242,6 +242,7 @@ path_properties_tuples = ( ) } ), + 'assert_fail.c': {'exit_status': 134}, 'lkmc_assert_fail.c': {'exit_status': 1}, 'exit1.c': {'exit_status': 1}, 'infinite_loop.c': {'more_than_1s': True}, @@ -344,6 +345,7 @@ path_properties_tuples = ( 'c': ( {}, { + 'assert_fail.c': {'receives_signal': True}, 'false.c': {'exit_status': 1}, 'getchar.c': {'interactive': True}, 'infinite_loop.c': {'more_than_1s': True}, diff --git a/userland/c/assert_fail.c b/userland/c/assert_fail.c new file mode 120000 index 0000000..c1c99d6 --- /dev/null +++ b/userland/c/assert_fail.c @@ -0,0 +1 @@ +../../lkmc/assert_fail.c \ No newline at end of file diff --git a/userland/lkmc/assert_fail.c b/userland/lkmc/assert_fail.c index c1c99d6..73df102 120000 --- a/userland/lkmc/assert_fail.c +++ b/userland/lkmc/assert_fail.c @@ -1 +1 @@ -../../lkmc/assert_fail.c \ No newline at end of file +../../lkmc/lkmc_assert_fail.c \ No newline at end of file