Skip to content

Commit 1da02f5

Browse files
wtarreaupaulmckrcu
authored andcommitted
selftests/nolibc: support glibc as well
Adding support for glibc can be useful to distinguish between bugs in nolibc and bugs in the kernel when a syscall reports an unusual value. It's not that much work and should not affect the long term maintainability of the tests. The necessary changes can essentially be summed up like this: - set _GNU_SOURCE a the top to access some definitions - many includes added when we know we don't come from nolibc (missing the stdio include guard) - disable gettid() which is not exposed by glibc - disable gettimeofday's support of bad pointers since these crash in glibc - add a simple itoa() for errorname(); strerror() is too verbose (no way to get short messages). strerrorname_np() was added in modern glibc (2.32) to do exactly this but that 's too recent to be usable as the default fallback. - use the standard ioperm() definition. May be we need to implement ioperm() in nolibc if that's useful. Signed-off-by: Willy Tarreau <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 7172f1c commit 1da02f5

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

tools/testing/selftests/nolibc/nolibc-test.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,41 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
#define _GNU_SOURCE
4+
35
/* platform-specific include files coming from the compiler */
46
#include <limits.h>
57

68
/* libc-specific include files
7-
* The program may be built in 2 ways:
9+
* The program may be built in 3 ways:
810
* $(CC) -nostdlib -include /path/to/nolibc.h => NOLIBC already defined
9-
* $(CC) -nostdlib -I/path/to/nolibc/sysroot
11+
* $(CC) -nostdlib -I/path/to/nolibc/sysroot => _NOLIBC_* guards are present
12+
* $(CC) with default libc => NOLIBC* never defined
1013
*/
1114
#ifndef NOLIBC
1215
#include <stdio.h>
1316
#include <stdlib.h>
1417
#include <string.h>
18+
#ifndef _NOLIBC_STDIO_H
19+
/* standard libcs need more includes */
20+
#include <linux/reboot.h>
21+
#include <sys/io.h>
22+
#include <sys/ioctl.h>
23+
#include <sys/mount.h>
24+
#include <sys/reboot.h>
25+
#include <sys/stat.h>
26+
#include <sys/syscall.h>
27+
#include <sys/sysmacros.h>
28+
#include <sys/time.h>
29+
#include <sys/wait.h>
30+
#include <dirent.h>
31+
#include <errno.h>
32+
#include <fcntl.h>
33+
#include <poll.h>
34+
#include <sched.h>
35+
#include <signal.h>
36+
#include <stdarg.h>
37+
#include <unistd.h>
38+
#endif
1539
#endif
1640

1741
/* will be used by nolibc by getenv() */
@@ -23,6 +47,17 @@ struct test {
2347
int (*func)(int min, int max); // handler
2448
};
2549

50+
#ifndef _NOLIBC_STDLIB_H
51+
char *itoa(int i)
52+
{
53+
static char buf[12];
54+
int ret;
55+
56+
ret = snprintf(buf, sizeof(buf), "%d", i);
57+
return (ret >= 0 && ret < sizeof(buf)) ? buf : "#err";
58+
}
59+
#endif
60+
2661
#define CASE_ERR(err) \
2762
case err: return #err
2863

@@ -431,7 +466,9 @@ int run_syscall(int min, int max)
431466
switch (test + __LINE__ + 1) {
432467
CASE_TEST(getpid); EXPECT_SYSNE(1, getpid(), -1); break;
433468
CASE_TEST(getppid); EXPECT_SYSNE(1, getppid(), -1); break;
469+
#ifdef NOLIBC
434470
CASE_TEST(gettid); EXPECT_SYSNE(1, gettid(), -1); break;
471+
#endif
435472
CASE_TEST(getpgid_self); EXPECT_SYSNE(1, getpgid(0), -1); break;
436473
CASE_TEST(getpgid_bad); EXPECT_SYSER(1, getpgid(-1), -1, ESRCH); break;
437474
CASE_TEST(kill_0); EXPECT_SYSZR(1, kill(getpid(), 0)); break;
@@ -460,9 +497,11 @@ int run_syscall(int min, int max)
460497
CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
461498
CASE_TEST(getdents64_null); EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;
462499
CASE_TEST(gettimeofday_null); EXPECT_SYSZR(1, gettimeofday(NULL, NULL)); break;
500+
#ifdef NOLIBC
463501
CASE_TEST(gettimeofday_bad1); EXPECT_SYSER(1, gettimeofday((void *)1, NULL), -1, EFAULT); break;
464502
CASE_TEST(gettimeofday_bad2); EXPECT_SYSER(1, gettimeofday(NULL, (void *)1), -1, EFAULT); break;
465503
CASE_TEST(gettimeofday_bad2); EXPECT_SYSER(1, gettimeofday(NULL, (void *)1), -1, EFAULT); break;
504+
#endif
466505
CASE_TEST(ioctl_tiocinq); EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;
467506
CASE_TEST(ioctl_tiocinq); EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;
468507
CASE_TEST(link_root1); EXPECT_SYSER(1, link("/", "/"), -1, EEXIST); break;
@@ -703,7 +742,11 @@ int main(int argc, char **argv, char **envp)
703742
* exit with status code 2N+1 when N is written to 0x501. We
704743
* hard-code the syscall here as it's arch-dependent.
705744
*/
745+
#if defined(_NOLIBC_SYS_H)
706746
else if (my_syscall3(__NR_ioperm, 0x501, 1, 1) == 0)
747+
#else
748+
else if (ioperm(0x501, 1, 1) == 0)
749+
#endif
707750
asm volatile ("outb %%al, %%dx" :: "d"(0x501), "a"(0));
708751
/* if it does nothing, fall back to the regular panic */
709752
#endif

0 commit comments

Comments
 (0)