From 0fbc34f028e9eb7705e1f4ee1591ecd6d05160e8 Mon Sep 17 00:00:00 2001 From: Daniel Palmer Date: Thu, 2 Jul 2026 17:50:59 +0900 Subject: [PATCH 1/8] tools/nolibc: unistd: Add getcwd() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add getcwd() for getting the current working directory. The behaviour matches what musl is doing except for one important difference: If the passed buf is NULL musl (and glibc) uses a big buffer on the stack and that is then strdup()'d and returned. According to the man page for getcwd() this is a glibc extension and I don't think we need it in nolibc. Signed-off-by: Daniel Palmer Acked-by: Willy Tarreau Link: https://patch.msgid.link/20260702085101.3304547-2-daniel@thingy.jp Signed-off-by: Thomas Weißschuh --- tools/include/nolibc/unistd.h | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h index 79599ceef45d..2e0edbc26315 100644 --- a/tools/include/nolibc/unistd.h +++ b/tools/include/nolibc/unistd.h @@ -73,6 +73,48 @@ int ftruncate(int fd, off_t length) return __sysret(_sys_ftruncate(fd, length)); } +/* + * char *getcwd(char *buf, size_t size); + */ + +static __attribute__((unused)) +int _sys_getcwd(char *buf, size_t size) +{ + return __nolibc_syscall2(__NR_getcwd, buf, size); +} + +static __attribute__((unused)) +char *getcwd(char *buf, size_t size) +{ + int ret; + + /* Unlike other libc's we don't handle passing NULL for buf */ + if (!buf || !size) { + SET_ERRNO(EINVAL); + return NULL; + } + + ret = __sysret(_sys_getcwd(buf, size)); + + /* On error return NULL, __sysret() above will have set errno */ + if (ret < 0) + return NULL; + + /* Handle no path being written or the kernel putting + * "(unreachable)" into the buffer instead of a path. + * This matches what musl is doing. + */ + if (ret == 0 || buf[0] != '/') { + SET_ERRNO(ENOENT); + return NULL; + } + + /* ret must be the number of bytes written at this point, + * so return the pointer to buf. + */ + return buf; +} + static __attribute__((unused)) int msleep(unsigned int msecs) { From 94518b77e194d71b1d76a2dd75f4891954edc296 Mon Sep 17 00:00:00 2001 From: Daniel Palmer Date: Thu, 2 Jul 2026 17:51:00 +0900 Subject: [PATCH 2/8] tools/nolibc: unistd: Add readlink() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add readlink(). This is needed to test getcwd(). Signed-off-by: Daniel Palmer Acked-by: Willy Tarreau Link: https://patch.msgid.link/20260702085101.3304547-3-daniel@thingy.jp Signed-off-by: Thomas Weißschuh --- tools/include/nolibc/unistd.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h index 2e0edbc26315..a264a20da13d 100644 --- a/tools/include/nolibc/unistd.h +++ b/tools/include/nolibc/unistd.h @@ -128,6 +128,22 @@ int msleep(unsigned int msecs) return 0; } +/* + * ssize_t readlink(const char *path, char *buf, size_t bufsiz); + */ + +static __attribute__((unused)) +ssize_t _sys_readlink(const char *path, char *buf, size_t bufsiz) +{ + return __nolibc_syscall4(__NR_readlinkat, AT_FDCWD, path, buf, bufsiz); +} + +static __attribute__((unused)) +ssize_t readlink(const char *path, char *buf, size_t bufsiz) +{ + return __sysret(_sys_readlink(path, buf, bufsiz)); +} + static __attribute__((unused)) unsigned int sleep(unsigned int seconds) { From 4f5777cfbd98c10e71c7fbfe4615dd499fada7b7 Mon Sep 17 00:00:00 2001 From: Daniel Palmer Date: Thu, 2 Jul 2026 17:51:01 +0900 Subject: [PATCH 3/8] selftests/nolibc: Add test for getcwd() and readlink() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a test that uses both getcwd() and readlink() so that both are exercised. First the happy path is tested by fetching what should be the same string via getcwd() and readlink() and checking they match. Then a few different combinations of bad parameters are passed to getcwd() to make sure it returns NULL and sets errno in those cases. Signed-off-by: Daniel Palmer Link: https://patch.msgid.link/20260702085101.3304547-4-daniel@thingy.jp Signed-off-by: Thomas Weißschuh --- tools/testing/selftests/nolibc/nolibc-test.c | 53 ++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index c1c1ce43a047..996e8d13508e 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -854,6 +854,58 @@ static int test_dirent(void) return 0; } +int test_getcwd(void) +{ + char cwd_syscall[PATH_MAX]; + char cwd_proc[PATH_MAX]; + ssize_t len; + + /* Read where the link /proc/self/cwd points */ + len = readlink("/proc/self/cwd", cwd_proc, sizeof(cwd_proc) - 1); + if (len <= 0) + return __LINE__; + + /* Terminate the string from readlink() */ + cwd_proc[len] = '\0'; + + /* Get the cwd via syscall */ + if (getcwd(cwd_syscall, sizeof(cwd_syscall)) == NULL) + return __LINE__; + + /* Fail if they aren't the same */ + if (strcmp(cwd_proc, cwd_syscall) != 0) + return __LINE__; + + /* Try getcwd() with NULL for the buffer, + * should return NULL and an error in errno. + * Other libc's allow this by allocating a buffer + * internally. + */ + if (is_nolibc) { + errno = 0; + if (getcwd(NULL, 0) != NULL || !errno) + return __LINE__; + } + + /* Try getcwd() with a buffer but make the size 0, + * should return NULL and an error in errno. + */ + errno = 0; + if (getcwd(cwd_syscall, 0) != NULL || !errno) + return __LINE__; + + /* Try getcwd() with a buffer but make the size 1, + * should return NULL and an error in errno because + * the string written to the buffer is terminated + * so you need at least 2 bytes even for "/". + */ + errno = 0; + if (getcwd(cwd_syscall, 1) != NULL || !errno) + return __LINE__; + + return 0; +} + int test_getrandom(void) { uint64_t rng = 0; @@ -1555,6 +1607,7 @@ int run_syscall(int min, int max) CASE_TEST(clock_getres); EXPECT_SYSZR(1, clock_getres(CLOCK_MONOTONIC, &ts)); break; CASE_TEST(clock_gettime); EXPECT_SYSZR(1, clock_gettime(CLOCK_MONOTONIC, &ts)); break; CASE_TEST(clock_settime); EXPECT_SYSER(1, clock_settime(CLOCK_MONOTONIC, &ts), -1, EINVAL); break; + CASE_TEST(getcwd); EXPECT_SYSZR(proc, test_getcwd()); break; CASE_TEST(getpid); EXPECT_SYSNE(1, getpid(), -1); break; CASE_TEST(getppid); EXPECT_SYSNE(1, getppid(), -1); break; CASE_TEST(gettid); EXPECT_SYSNE(has_gettid, gettid(), -1); break; From a3b2181459a2c74c03ddbad585f884eefc8ff8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Fri, 3 Jul 2026 19:30:16 +0200 Subject: [PATCH 4/8] tools/nolibc: mark arg1 operand in __nolibc_syscall0() as write-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit __nolibc_syscall0() does not set the arg1 variable before passing it to the asm block. This uninitialized variable read is undefined behavior. Clang can miscompile this. Mark the asm operand as write-only to fix this. Fixes: 8e1930296f92 ("tools/nolibc: Add support for SPARC") Signed-off-by: Thomas Weißschuh Acked-by: Willy Tarreau Link: https://patch.msgid.link/20260703-nolibc-sparc-asm-v1-1-c7fe73e2e777@weissschuh.net --- tools/include/nolibc/arch-sparc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/include/nolibc/arch-sparc.h b/tools/include/nolibc/arch-sparc.h index ddae9bc10dfe..23fab40accfa 100644 --- a/tools/include/nolibc/arch-sparc.h +++ b/tools/include/nolibc/arch-sparc.h @@ -45,7 +45,7 @@ \ __asm__ volatile ( \ _NOLIBC_SYSCALL \ - : "+r"(_arg1) \ + : "=r"(_arg1) \ : "r"(_num) \ : "memory", "cc" \ ); \ From 070cf03f5ec454eec9c42827ee9f3c0b3fad09f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 7 Jul 2026 18:42:30 +0200 Subject: [PATCH 5/8] selftests/nolibc: add debug information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When working on nolibc, debug information is very valuable. I find myself adding this flag in many patchsets. Enable debug information unconditionally, as there is no downside to it. Signed-off-by: Thomas Weißschuh Acked-by: Willy Tarreau Link: https://patch.msgid.link/20260707-nolibc-debug-v1-1-31619ec94bbd@weissschuh.net --- tools/testing/selftests/nolibc/Makefile.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/nolibc/Makefile.include b/tools/testing/selftests/nolibc/Makefile.include index c30ca3a9ef14..ea520eac64a6 100644 --- a/tools/testing/selftests/nolibc/Makefile.include +++ b/tools/testing/selftests/nolibc/Makefile.include @@ -5,7 +5,7 @@ _CFLAGS_STACKPROTECTOR ?= $(call try-run, \ echo 'void foo(void) {}' | $(CC) -x c - -o - -S $(CLANG_CROSS_FLAGS) $(__CFLAGS_STACKPROTECTOR) | grep -q __stack_chk_guard, \ $(__CFLAGS_STACKPROTECTOR)) _CFLAGS_SANITIZER ?= $(call cc-option,-fsanitize=undefined -fsanitize-trap=all) -CFLAGS_NOLIBC_TEST ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \ +CFLAGS_NOLIBC_TEST ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 -ggdb \ -W -Wall -Wextra -Wundef -Wwrite-strings \ $(call cc-option,-fno-stack-protector) $(call cc-option,-Wmissing-prototypes) \ $(_CFLAGS_STACKPROTECTOR) $(_CFLAGS_SANITIZER) From 01d8fa031ac2d84ba5254caeb1fa5c11159797b5 Mon Sep 17 00:00:00 2001 From: Ammar Faizi Date: Sun, 26 Jul 2026 17:13:05 +0700 Subject: [PATCH 6/8] tools/nolibc: remove dead __ARCH_WANT_SYS_OLD_SELECT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The macro lost its last user when select() was reimplemented on top of pselect6 for every architecture; sys/select.h no longer looks at it, and nothing else in the tree does either. See commit 668e43737279 ("tools/nolibc/select: drop non-pselect based implementations"). The comment that goes with it is stale for the same reason, as neither architecture can end up calling old_select any more. Drop both from arch-x86.h and arch-arm.h. Cc: Alviro Iskandar Setiawan Signed-off-by: Ammar Faizi Signed-off-by: Thomas Weißschuh --- tools/include/nolibc/arch-arm.h | 3 --- tools/include/nolibc/arch-x86.h | 3 --- 2 files changed, 6 deletions(-) diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h index 8681922e05ca..b88686fb19c4 100644 --- a/tools/include/nolibc/arch-arm.h +++ b/tools/include/nolibc/arch-arm.h @@ -33,10 +33,7 @@ * with r7 before calling svc, and r6 is marked as clobbered. * We're just using any regular register which we assign to r7 after saving * it. - * - * Also, ARM supports the old_select syscall if newselect is not available */ -#define __ARCH_WANT_SYS_OLD_SELECT #if (defined(__THUMBEB__) || defined(__THUMBEL__)) && \ !defined(NOLIBC_OMIT_FRAME_POINTER) diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h index fe152ac2650b..577e9b682eb3 100644 --- a/tools/include/nolibc/arch-x86.h +++ b/tools/include/nolibc/arch-x86.h @@ -25,10 +25,7 @@ * don't have to experience issues with register constraints. * - the syscall number is always specified last in order to allow to force * some registers before (gcc refuses a %-register at the last position). - * - * Also, i386 supports the old_select syscall if newselect is not available */ -#define __ARCH_WANT_SYS_OLD_SELECT #define __nolibc_syscall0(num) \ ({ \ From b9fc5a1742b0c8fb7edf066cc17fa0b18b7be623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Mon, 27 Jul 2026 17:02:48 +0200 Subject: [PATCH 7/8] tools/nolibc/powerpc: mark ctr and xer as clobbered by system call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The system call can clobber the ctr and xer registers. Make sure the compiler takes this into account. The missing clobbers only seem to be an issue with newer compilers. Fixes: 0cb0675ec37e ("tools/nolibc: add support for powerpc") Signed-off-by: Thomas Weißschuh Link: https://patch.msgid.link/20260727-nolibc-powerpc-clobber-v1-1-e0911cc99ce1@linutronix.de Signed-off-by: Thomas Weißschuh --- tools/include/nolibc/arch-powerpc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/include/nolibc/arch-powerpc.h b/tools/include/nolibc/arch-powerpc.h index a1ab91d55384..dbe2e5205aaa 100644 --- a/tools/include/nolibc/arch-powerpc.h +++ b/tools/include/nolibc/arch-powerpc.h @@ -26,7 +26,7 @@ */ #define _NOLIBC_SYSCALL_CLOBBERLIST \ - "memory", "cr0", "r12", "r11", "r10", "r9" + "memory", "cr0", "ctr", "xer", "r12", "r11", "r10", "r9" #define __nolibc_syscall0(num) \ ({ \ From b58afc8d1cf85688601b8d7e271125fff666f661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Wed, 22 Jul 2026 00:07:05 +0200 Subject: [PATCH 8/8] tools/nolibc: add support for Alpha MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A straightforward new architecture. Signed-off-by: Thomas Weißschuh Acked-by: Willy Tarreau Tested-by: Michael Cree Link: https://patch.msgid.link/20260722-nolibc-alpha-v2-1-4970e48eb7bf@weissschuh.net --- tools/include/nolibc/Makefile | 2 +- tools/include/nolibc/arch-alpha.h | 159 ++++++++++++++++++ tools/include/nolibc/arch.h | 2 + .../testing/selftests/nolibc/Makefile.nolibc | 2 + tools/testing/selftests/nolibc/nolibc-test.c | 4 + tools/testing/selftests/nolibc/run-tests.sh | 3 +- 6 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 tools/include/nolibc/arch-alpha.h diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile index 00fd2e566d75..6d213d372bf8 100644 --- a/tools/include/nolibc/Makefile +++ b/tools/include/nolibc/Makefile @@ -17,7 +17,7 @@ endif # it defaults to this nolibc directory. OUTPUT ?= $(CURDIR)/ -architectures := arm arm64 loongarch m68k mips openrisc parisc powerpc riscv s390 sh sparc x86 +architectures := alpha arm arm64 loongarch m68k mips openrisc parisc powerpc riscv s390 sh sparc x86 arch_files := arch.h $(addsuffix .h, $(addprefix arch-, $(architectures))) all_files := \ alloca.h \ diff --git a/tools/include/nolibc/arch-alpha.h b/tools/include/nolibc/arch-alpha.h new file mode 100644 index 000000000000..04ff8a95c52c --- /dev/null +++ b/tools/include/nolibc/arch-alpha.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * Alpha specific definitions for NOLIBC + * Copyright (C) 2025 Thomas Weißschuh + */ + +#ifndef _NOLIBC_ARCH_ALPHA_H +#define _NOLIBC_ARCH_ALPHA_H + +#include "compiler.h" +#include "crt.h" + +/* + * Syscalls for Alpha: + * - registers are 64-bit + * - syscall number is passed in $0/v0 + * - the system call is performed by calling callsys + * - syscall return comes in $0/v0, error flag in $19/a3 + * - arguments are passed in $16/a0 to $21/a5 + * - GCC does not support symbol register names + */ + +#define _NOLIBC_SYSCALL_CLOBBERLIST \ + "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \ + "$22", "$23", "$24", "$25", "$27", "$28", "memory", "cc" + +#define __nolibc_syscall0(num) \ +({ \ + register long _num __asm__ ("$0") = (num); \ + register long _err __asm__ ("$19"); \ + \ + __asm__ volatile ( \ + "callsys" \ + : "+r"(_num), "=r"(_err) \ + : \ + : _NOLIBC_SYSCALL_CLOBBERLIST, \ + "$16", "$17", "$18", "$20", "$21" \ + ); \ + _err ? -_num : _num; \ +}) + +#define __nolibc_syscall1(num, arg1) \ +({ \ + register long _num __asm__ ("$0") = (num); \ + register long _err __asm__ ("$19"); \ + register long _arg1 __asm__ ("$16") = (long)(arg1); \ + \ + __asm__ volatile ( \ + "callsys" \ + : "+r"(_num), "=r"(_err) \ + : "r"(_arg1) \ + : _NOLIBC_SYSCALL_CLOBBERLIST, "$17", "$18", "$20", "$21" \ + ); \ + _err ? -_num : _num; \ +}) + +#define __nolibc_syscall2(num, arg1, arg2) \ +({ \ + register long _num __asm__ ("$0") = (num); \ + register long _err __asm__ ("$19"); \ + register long _arg1 __asm__ ("$16") = (long)(arg1); \ + register long _arg2 __asm__ ("$17") = (long)(arg2); \ + \ + __asm__ volatile ( \ + "callsys" \ + : "+r"(_num), "=r"(_err) \ + : "r"(_arg1), "r"(_arg2) \ + : _NOLIBC_SYSCALL_CLOBBERLIST, "$18", "$20", "$21" \ + ); \ + _err ? -_num : _num; \ +}) + +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ +({ \ + register long _num __asm__ ("$0") = (num); \ + register long _err __asm__ ("$19"); \ + register long _arg1 __asm__ ("$16") = (long)(arg1); \ + register long _arg2 __asm__ ("$17") = (long)(arg2); \ + register long _arg3 __asm__ ("$18") = (long)(arg3); \ + \ + __asm__ volatile ( \ + "callsys" \ + : "+r"(_num), "=r"(_err) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3) \ + : _NOLIBC_SYSCALL_CLOBBERLIST, "$20", "$21" \ + ); \ + _err ? -_num : _num; \ +}) + +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ +({ \ + register long _num __asm__ ("$0") = (num); \ + register long _arg1 __asm__ ("$16") = (long)(arg1); \ + register long _arg2 __asm__ ("$17") = (long)(arg2); \ + register long _arg3 __asm__ ("$18") = (long)(arg3); \ + register long _arg4 __asm__ ("$19") = (long)(arg4); \ + \ + __asm__ volatile ( \ + "callsys" \ + : "+r"(_num), "+r"(_arg4) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3) \ + : _NOLIBC_SYSCALL_CLOBBERLIST, "$20", "$21" \ + ); \ + _arg4 ? -_num : _num; \ +}) + +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +({ \ + register long _num __asm__ ("$0") = (num); \ + register long _arg1 __asm__ ("$16") = (long)(arg1); \ + register long _arg2 __asm__ ("$17") = (long)(arg2); \ + register long _arg3 __asm__ ("$18") = (long)(arg3); \ + register long _arg4 __asm__ ("$19") = (long)(arg4); \ + register long _arg5 __asm__ ("$20") = (long)(arg5); \ + \ + __asm__ volatile ( \ + "callsys" \ + : "+r"(_num), "+r"(_arg4) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg5) \ + : _NOLIBC_SYSCALL_CLOBBERLIST, "$21" \ + ); \ + _arg4 ? -_num : _num; \ +}) + +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +({ \ + register long _num __asm__ ("$0") = (num); \ + register long _arg1 __asm__ ("$16") = (long)(arg1); \ + register long _arg2 __asm__ ("$17") = (long)(arg2); \ + register long _arg3 __asm__ ("$18") = (long)(arg3); \ + register long _arg4 __asm__ ("$19") = (long)(arg4); \ + register long _arg5 __asm__ ("$20") = (long)(arg5); \ + register long _arg6 __asm__ ("$21") = (long)(arg6); \ + \ + __asm__ volatile ( \ + "callsys" \ + : "+r"(_num), "+r"(_arg4) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg5), \ + "r"(_arg6) \ + : _NOLIBC_SYSCALL_CLOBBERLIST \ + ); \ + _arg4 ? -_num : _num; \ +}) + +/* startup code */ +void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector +_start(void) +{ + __asm__ volatile ( + "br $gp, 0f\n" /* setup $gp, so that 'lda' works */ + "0: ldgp $gp, 0($gp)\n" + "lda $27, _start_c\n" /* setup current function address for _start_c */ + "mov $sp, $16\n" /* save argc pointer to $16, as arg1 of _start_c */ + "br _start_c\n" /* transfer to c runtime */ + ); + __nolibc_entrypoint_epilogue(); +} + +#endif /* _NOLIBC_ARCH_ALPHA_H */ diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h index b69d9c5ec5c6..06cc2dbe7a33 100644 --- a/tools/include/nolibc/arch.h +++ b/tools/include/nolibc/arch.h @@ -32,6 +32,8 @@ #include "arch-openrisc.h" #elif defined(__hppa__) #include "arch-parisc.h" +#elif defined(__alpha__) +#include "arch-alpha.h" #else #error Unsupported Architecture #endif diff --git a/tools/testing/selftests/nolibc/Makefile.nolibc b/tools/testing/selftests/nolibc/Makefile.nolibc index 06f881e2e90c..f70c8dfca018 100644 --- a/tools/testing/selftests/nolibc/Makefile.nolibc +++ b/tools/testing/selftests/nolibc/Makefile.nolibc @@ -112,6 +112,7 @@ EXTRACONFIG_armthumb = -e CONFIG_NAMESPACES EXTRACONFIG_sparc32 = -e CONFIG_TMPFS EXTRACONFIG_m68k = -e CONFIG_BLK_DEV_INITRD EXTRACONFIG_sh4 = -e CONFIG_BLK_DEV_INITRD -e CONFIG_CMDLINE_FROM_BOOTLOADER +EXTRACONFIG_alpha = -e CONFIG_BLK_DEV_INITRD EXTRACONFIG = $(EXTRACONFIG_$(XARCH)) # optional tests to run (default = all) @@ -174,6 +175,7 @@ QEMU_ARGS_m68k = -M virt -append "console=ttyGF0,115200 panic=-1 $(TEST:%= QEMU_ARGS_sh4 = -M r2d -serial file:/dev/stdout -append "console=ttySC1,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_openrisc = -M virt -m 512M -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_parisc32 = -M B160L -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" +QEMU_ARGS_alpha = -M clipper -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS = -m 1G $(QEMU_ARGS_$(XARCH)) $(QEMU_ARGS_BIOS) $(QEMU_ARGS_EXTRA) # OUTPUT is only set when run from the main makefile, otherwise diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index 996e8d13508e..ed860b0a15a1 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -756,6 +756,10 @@ int run_startup(int min, int max) /* checking NULL for argv/argv0, environ and _auxv is not enough, let's compare with sbrk(0) or &end */ extern char end; char *brk = sbrk(0) != (void *)-1 ? sbrk(0) : &end; +#if defined(__alpha__) + /* the ordering above does not work on an alpha kernel due to STACK_TOP != TASK_SIZE */ + brk = NULL; +#endif /* differ from nolibc, both glibc and musl have no global _auxv */ const unsigned long *test_auxv = (void *)-1; #ifdef NOLIBC diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh index 6460e25001de..dc0b1649c641 100755 --- a/tools/testing/selftests/nolibc/run-tests.sh +++ b/tools/testing/selftests/nolibc/run-tests.sh @@ -30,6 +30,7 @@ all_archs=( m68k sh4 parisc32 + alpha ) archs="${all_archs[@]}" @@ -193,7 +194,7 @@ test_arch() { exit 1 esac printf '%-15s' "$arch:" - if [ "$arch" = "m68k" -o "$arch" = "sh4" -o "$arch" = "openrisc" -o "$arch" = "parisc32" ] && [ "$llvm" = "1" ]; then + if [ "$arch" = "m68k" -o "$arch" = "sh4" -o "$arch" = "openrisc" -o "$arch" = "parisc32" -o "$arch" = "alpha" ] && [ "$llvm" = "1" ]; then echo "Unsupported configuration" return fi