GNU/Weeb Mailing List <[email protected]>
 help / color / mirror / Atom feed
* [PATCH nolibc 01/19] tools/nolibc: i386: Fix a stack misalign bug on _start
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 02/19] MAINTAINERS: nolibc: update tree location Paul E. McKenney
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: gwml, kernel-team, w, Ammar Faizi, Zhangjin Wu,
	Nicholas Rosenberg, Thomas Weißschuh,
	Alviro Iskandar Setiawan, Willy Tarreau

From: Ammar Faizi <[email protected]>

The ABI mandates that the %esp register must be a multiple of 16 when
executing a 'call' instruction.

Commit 2ab446336b17 ("tools/nolibc: i386: shrink _start with _start_c")
simplified the _start function, but it didn't take care of the %esp
alignment, causing SIGSEGV on SSE and AVX programs that use aligned move
instruction (e.g., movdqa, movaps, and vmovdqa).

The 'and $-16, %esp' aligns the %esp at a multiple of 16. Then 'push
%eax' will subtract the %esp by 4; thus, it breaks the 16-byte
alignment. Make sure the %esp is correctly aligned after the push by
subtracting 12 before the push.

Extra:
Add 'add $12, %esp' before the 'and $-16, %esp' to avoid over-estimating
for particular cases as suggested by Willy.

A test program to validate the %esp alignment on _start can be found at:

   https://lore.kernel.org/lkml/[email protected]

Cc: Zhangjin Wu <[email protected]>
Fixes: 2ab446336b17aad362c6decee29b4efd83a01979 ("tools/nolibc: i386: shrink _start with _start_c")
Reported-by: Nicholas Rosenberg <[email protected]>
Acked-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
Reviewed-by: Alviro Iskandar Setiawan <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
Signed-off-by: Thomas Weißschuh <[email protected]>
---
 tools/include/nolibc/arch-i386.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h
index 64415b9fac77..28c26a00a762 100644
--- a/tools/include/nolibc/arch-i386.h
+++ b/tools/include/nolibc/arch-i386.h
@@ -167,7 +167,9 @@ void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_
 	__asm__ volatile (
 		"xor  %ebp, %ebp\n"       /* zero the stack frame                                */
 		"mov  %esp, %eax\n"       /* save stack pointer to %eax, as arg1 of _start_c     */
-		"and  $-16, %esp\n"       /* last pushed argument must be 16-byte aligned        */
+		"add  $12, %esp\n"        /* avoid over-estimating after the 'and' & 'sub' below */
+		"and  $-16, %esp\n"       /* the %esp must be 16-byte aligned on 'call'          */
+		"sub  $12, %esp\n"        /* sub 12 to keep it aligned after the push %eax       */
 		"push %eax\n"             /* push arg1 on stack to support plain stack modes too */
 		"call _start_c\n"         /* transfer to c runtime                               */
 		"hlt\n"                   /* ensure it does not return                           */
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 02/19] MAINTAINERS: nolibc: update tree location
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 01/19] tools/nolibc: i386: Fix a stack misalign bug on _start Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 03/19] tools/nolibc: mark start_c as weak Paul E. McKenney
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

The nolibc tree moved out of Willys user namespace into its own.

Signed-off-by: Thomas Weißschuh <[email protected]>
Acked-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 90f13281d297..6c83087ea396 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15131,7 +15131,7 @@ NOLIBC HEADER FILE
 M:	Willy Tarreau <[email protected]>
 M:	Thomas Weißschuh <[email protected]>
 S:	Maintained
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nolibc/linux-nolibc.git
 F:	tools/include/nolibc/
 F:	tools/testing/selftests/nolibc/
 
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 03/19] tools/nolibc: mark start_c as weak
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 01/19] tools/nolibc: i386: Fix a stack misalign bug on _start Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 02/19] MAINTAINERS: nolibc: update tree location Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 04/19] tools/nolibc: add stdarg.h header Paul E. McKenney
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

Otherwise the different instances of _start_c from each compilation unit
will lead to linker errors:

/usr/bin/ld: /tmp/ccSNvRqs.o: in function `_start_c':
nolibc-test-foo.c:(.text.nolibc_memset+0x9): multiple definition of `_start_c'; /tmp/ccG25101.o:nolibc-test.c:(.text+0x1ea3): first defined here

Fixes: 17336755150b ("tools/nolibc: add new crt.h with _start_c")
Signed-off-by: Thomas Weißschuh <[email protected]>
Link: https://lore.kernel.org/lkml/20231012-nolibc-start_c-multiple-v1-1-fbfc73e0283f@weissschuh.net/
Link: https://lore.kernel.org/lkml/[email protected]/
Acked-by: Willy Tarreau <[email protected]>
---
 tools/include/nolibc/crt.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index a5f33fef1672..a05655b4ce1d 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -13,6 +13,7 @@ const unsigned long *_auxv __attribute__((weak));
 static void __stack_chk_init(void);
 static void exit(int);
 
+__attribute__((weak))
 void _start_c(long *sp)
 {
 	long argc;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 04/19] tools/nolibc: add stdarg.h header
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (2 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 03/19] tools/nolibc: mark start_c as weak Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 05/19] selftests/nolibc: use -nostdinc for nolibc-test Paul E. McKenney
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

This allows nolic to work with `-nostdinc` avoiding any reliance on
system headers.

The implementation has been lifted from musl libc 1.2.4.
There is already an implementation of stdarg.h in include/linux/stdarg.h
but that is GPL licensed and therefore not suitable for nolibc.

The used compiler builtins have been validated to be at least available
since GCC 4.1.2 and clang 3.0.0.

Signed-off-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
---
 tools/include/nolibc/Makefile |  1 +
 tools/include/nolibc/nolibc.h |  4 ++--
 tools/include/nolibc/stdarg.h | 16 ++++++++++++++++
 tools/include/nolibc/stdio.h  |  3 +--
 tools/include/nolibc/sys.h    |  2 +-
 5 files changed, 21 insertions(+), 5 deletions(-)
 create mode 100644 tools/include/nolibc/stdarg.h

diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index 909b6eb500fe..e69c26abe1ea 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -34,6 +34,7 @@ all_files := \
 		signal.h \
 		stackprotector.h \
 		std.h \
+		stdarg.h \
 		stdint.h \
 		stdlib.h \
 		string.h \
diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h
index 1f8d821000ac..989e707263a4 100644
--- a/tools/include/nolibc/nolibc.h
+++ b/tools/include/nolibc/nolibc.h
@@ -74,10 +74,10 @@
  *            -I../nolibc -o hello hello.c -lgcc
  *
  * The available standard (but limited) include files are:
- *   ctype.h, errno.h, signal.h, stdio.h, stdlib.h, string.h, time.h
+ *   ctype.h, errno.h, signal.h, stdarg.h, stdio.h, stdlib.h, string.h, time.h
  *
  * In addition, the following ones are expected to be provided by the compiler:
- *   float.h, stdarg.h, stddef.h
+ *   float.h, stddef.h
  *
  * The following ones which are part to the C standard are not provided:
  *   assert.h, locale.h, math.h, setjmp.h, limits.h
diff --git a/tools/include/nolibc/stdarg.h b/tools/include/nolibc/stdarg.h
new file mode 100644
index 000000000000..c628b5783da6
--- /dev/null
+++ b/tools/include/nolibc/stdarg.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Variadic argument support for NOLIBC
+ * Copyright (C) 2005-2020 Rich Felker, et al.
+ */
+
+#ifndef _NOLIBC_STDARG_H
+#define _NOLIBC_STDARG_H
+
+typedef __builtin_va_list va_list;
+#define va_start(v, l)   __builtin_va_start(v, l)
+#define va_end(v)        __builtin_va_end(v)
+#define va_arg(v, l)     __builtin_va_arg(v, l)
+#define va_copy(d, s)    __builtin_va_copy(d, s)
+
+#endif /* _NOLIBC_STDARG_H */
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index cae402c11e57..d7ef43973916 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -7,13 +7,12 @@
 #ifndef _NOLIBC_STDIO_H
 #define _NOLIBC_STDIO_H
 
-#include <stdarg.h>
-
 #include "std.h"
 #include "arch.h"
 #include "errno.h"
 #include "types.h"
 #include "sys.h"
+#include "stdarg.h"
 #include "stdlib.h"
 #include "string.h"
 
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index fdb6bd6c0e2f..b478750c9004 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -7,7 +7,6 @@
 #ifndef _NOLIBC_SYS_H
 #define _NOLIBC_SYS_H
 
-#include <stdarg.h>
 #include "std.h"
 
 /* system includes */
@@ -25,6 +24,7 @@
 
 #include "arch.h"
 #include "errno.h"
+#include "stdarg.h"
 #include "types.h"
 
 
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 05/19] selftests/nolibc: use -nostdinc for nolibc-test
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (3 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 04/19] tools/nolibc: add stdarg.h header Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 06/19] tools/nolibc: x86-64: Use `rep movsb` for `memcpy()` and `memmove()` Paul E. McKenney
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

Avoid any accidental reliance on system includes.

Signed-off-by: Thomas Weißschuh <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
---
 tools/testing/selftests/nolibc/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index dfe66776a331..689658f81a19 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -170,7 +170,7 @@ sysroot/$(ARCH)/include:
 ifneq ($(NOLIBC_SYSROOT),0)
 nolibc-test: nolibc-test.c sysroot/$(ARCH)/include
 	$(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
-	  -nostdlib -static -Isysroot/$(ARCH)/include $< -lgcc
+	  -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include $< -lgcc
 else
 nolibc-test: nolibc-test.c
 	$(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 06/19] tools/nolibc: x86-64: Use `rep movsb` for `memcpy()` and `memmove()`
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (4 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 05/19] selftests/nolibc: use -nostdinc for nolibc-test Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 07/19] tools/nolibc: x86-64: Use `rep stosb` for `memset()` Paul E. McKenney
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: gwml, kernel-team, w, Ammar Faizi, David Laight, Willy Tarreau,
	Thomas Weißschuh

From: Ammar Faizi <[email protected]>

Simplify memcpy() and memmove() on the x86-64 arch.

The x86-64 arch has a 'rep movsb' instruction, which can perform
memcpy() using only a single instruction, given:

    %rdi = destination
    %rsi = source
    %rcx = length

Additionally, it can also handle the overlapping case by setting DF=1
(backward copy), which can be used as the memmove() implementation.

Before this patch:
```
  00000000000010ab <memmove>:
    10ab: 48 89 f8              mov    %rdi,%rax
    10ae: 31 c9                 xor    %ecx,%ecx
    10b0: 48 39 f7              cmp    %rsi,%rdi
    10b3: 48 83 d1 ff           adc    $0xffffffffffffffff,%rcx
    10b7: 48 85 d2              test   %rdx,%rdx
    10ba: 74 25                 je     10e1 <memmove+0x36>
    10bc: 48 83 c9 01           or     $0x1,%rcx
    10c0: 48 39 f0              cmp    %rsi,%rax
    10c3: 48 c7 c7 ff ff ff ff  mov    $0xffffffffffffffff,%rdi
    10ca: 48 0f 43 fa           cmovae %rdx,%rdi
    10ce: 48 01 cf              add    %rcx,%rdi
    10d1: 44 8a 04 3e           mov    (%rsi,%rdi,1),%r8b
    10d5: 44 88 04 38           mov    %r8b,(%rax,%rdi,1)
    10d9: 48 01 cf              add    %rcx,%rdi
    10dc: 48 ff ca              dec    %rdx
    10df: 75 f0                 jne    10d1 <memmove+0x26>
    10e1: c3                    ret

  00000000000010e2 <memcpy>:
    10e2: 48 89 f8              mov    %rdi,%rax
    10e5: 48 85 d2              test   %rdx,%rdx
    10e8: 74 12                 je     10fc <memcpy+0x1a>
    10ea: 31 c9                 xor    %ecx,%ecx
    10ec: 40 8a 3c 0e           mov    (%rsi,%rcx,1),%dil
    10f0: 40 88 3c 08           mov    %dil,(%rax,%rcx,1)
    10f4: 48 ff c1              inc    %rcx
    10f7: 48 39 ca              cmp    %rcx,%rdx
    10fa: 75 f0                 jne    10ec <memcpy+0xa>
    10fc: c3                    ret
```

After this patch:
```
  // memmove is an alias for memcpy
  000000000040133b <memcpy>:
    40133b: 48 89 d1              mov    %rdx,%rcx
    40133e: 48 89 f8              mov    %rdi,%rax
    401341: 48 89 fa              mov    %rdi,%rdx
    401344: 48 29 f2              sub    %rsi,%rdx
    401347: 48 39 ca              cmp    %rcx,%rdx
    40134a: 72 03                 jb     40134f <memcpy+0x14>
    40134c: f3 a4                 rep movsb %ds:(%rsi),%es:(%rdi)
    40134e: c3                    ret
    40134f: 48 8d 7c 0f ff        lea    -0x1(%rdi,%rcx,1),%rdi
    401354: 48 8d 74 0e ff        lea    -0x1(%rsi,%rcx,1),%rsi
    401359: fd                    std
    40135a: f3 a4                 rep movsb %ds:(%rsi),%es:(%rdi)
    40135c: fc                    cld
    40135d: c3                    ret
```

v3:
  - Make memmove as an alias for memcpy (Willy).
  - Make the forward copy the likely case (Alviro).

v2:
  - Fix the broken memmove implementation (David).

Link: https://lore.kernel.org/lkml/[email protected]
Link: https://lore.kernel.org/lkml/[email protected]
Suggested-by: David Laight <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
Signed-off-by: Thomas Weißschuh <[email protected]>
---
 tools/include/nolibc/arch-x86_64.h | 29 +++++++++++++++++++++++++++++
 tools/include/nolibc/string.h      |  4 ++++
 2 files changed, 33 insertions(+)

diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index e5ccb926c903..aece7d895153 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -173,4 +173,33 @@ void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_
 	__builtin_unreachable();
 }
 
+#define NOLIBC_ARCH_HAS_MEMMOVE
+void *memmove(void *dst, const void *src, size_t len);
+
+#define NOLIBC_ARCH_HAS_MEMCPY
+void *memcpy(void *dst, const void *src, size_t len);
+
+__asm__ (
+".section .text.nolibc_memmove_memcpy\n"
+".weak memmove\n"
+".weak memcpy\n"
+"memmove:\n"
+"memcpy:\n"
+	"movq %rdx, %rcx\n\t"
+	"movq %rdi, %rax\n\t"
+	"movq %rdi, %rdx\n\t"
+	"subq %rsi, %rdx\n\t"
+	"cmpq %rcx, %rdx\n\t"
+	"jb   .Lbackward_copy\n\t"
+	"rep movsb\n\t"
+	"retq\n"
+".Lbackward_copy:"
+	"leaq -1(%rdi, %rcx, 1), %rdi\n\t"
+	"leaq -1(%rsi, %rcx, 1), %rsi\n\t"
+	"std\n\t"
+	"rep movsb\n\t"
+	"cld\n\t"
+	"retq\n"
+);
+
 #endif /* _NOLIBC_ARCH_X86_64_H */
diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
index 0c2e06c7c477..6eca267ec6fa 100644
--- a/tools/include/nolibc/string.h
+++ b/tools/include/nolibc/string.h
@@ -49,6 +49,7 @@ void *_nolibc_memcpy_down(void *dst, const void *src, size_t len)
 	return dst;
 }
 
+#ifndef NOLIBC_ARCH_HAS_MEMMOVE
 /* might be ignored by the compiler without -ffreestanding, then found as
  * missing.
  */
@@ -72,13 +73,16 @@ void *memmove(void *dst, const void *src, size_t len)
 	}
 	return dst;
 }
+#endif /* #ifndef NOLIBC_ARCH_HAS_MEMMOVE */
 
+#ifndef NOLIBC_ARCH_HAS_MEMCPY
 /* must be exported, as it's used by libgcc on ARM */
 __attribute__((weak,unused,section(".text.nolibc_memcpy")))
 void *memcpy(void *dst, const void *src, size_t len)
 {
 	return _nolibc_memcpy_up(dst, src, len);
 }
+#endif /* #ifndef NOLIBC_ARCH_HAS_MEMCPY */
 
 /* might be ignored by the compiler without -ffreestanding, then found as
  * missing.
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 07/19] tools/nolibc: x86-64: Use `rep stosb` for `memset()`
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (5 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 06/19] tools/nolibc: x86-64: Use `rep movsb` for `memcpy()` and `memmove()` Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 08/19] tools/nolibc: string: Remove the `_nolibc_memcpy_down()` function Paul E. McKenney
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: gwml, kernel-team, w, Ammar Faizi, Alviro Iskandar Setiawan,
	Willy Tarreau, Thomas Weißschuh

From: Ammar Faizi <[email protected]>

Simplify memset() on the x86-64 arch.

The x86-64 arch has a 'rep stosb' instruction, which can perform
memset() using only a single instruction, given:

    %al  = value (just like the second argument of memset())
    %rdi = destination
    %rcx = length

Before this patch:
```
  00000000000010c9 <memset>:
    10c9: 48 89 f8              mov    %rdi,%rax
    10cc: 48 85 d2              test   %rdx,%rdx
    10cf: 74 0e                 je     10df <memset+0x16>
    10d1: 31 c9                 xor    %ecx,%ecx
    10d3: 40 88 34 08           mov    %sil,(%rax,%rcx,1)
    10d7: 48 ff c1              inc    %rcx
    10da: 48 39 ca              cmp    %rcx,%rdx
    10dd: 75 f4                 jne    10d3 <memset+0xa>
    10df: c3                    ret
```

After this patch:
```
  0000000000001511 <memset>:
    1511: 96                    xchg   %eax,%esi
    1512: 48 89 d1              mov    %rdx,%rcx
    1515: 57                    push   %rdi
    1516: f3 aa                 rep stos %al,%es:(%rdi)
    1518: 58                    pop    %rax
    1519: c3                    ret
```

v2:
  - Use pushq %rdi / popq %rax (Alviro).
  - Use xchg %eax, %esi (Willy).

Link: https://lore.kernel.org/lkml/[email protected]
Suggested-by: Alviro Iskandar Setiawan <[email protected]>
Suggested-by: Willy Tarreau <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
Reviewed-by: Alviro Iskandar Setiawan <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
Signed-off-by: Thomas Weißschuh <[email protected]>
---
 tools/include/nolibc/arch-x86_64.h | 13 +++++++++++++
 tools/include/nolibc/string.h      |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index aece7d895153..68609f421934 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -179,6 +179,9 @@ void *memmove(void *dst, const void *src, size_t len);
 #define NOLIBC_ARCH_HAS_MEMCPY
 void *memcpy(void *dst, const void *src, size_t len);
 
+#define NOLIBC_ARCH_HAS_MEMSET
+void *memset(void *dst, int c, size_t len);
+
 __asm__ (
 ".section .text.nolibc_memmove_memcpy\n"
 ".weak memmove\n"
@@ -200,6 +203,16 @@ __asm__ (
 	"rep movsb\n\t"
 	"cld\n\t"
 	"retq\n"
+
+".section .text.nolibc_memset\n"
+".weak memset\n"
+"memset:\n"
+	"xchgl %eax, %esi\n\t"
+	"movq  %rdx, %rcx\n\t"
+	"pushq %rdi\n\t"
+	"rep stosb\n\t"
+	"popq  %rax\n\t"
+	"retq\n"
 );
 
 #endif /* _NOLIBC_ARCH_X86_64_H */
diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
index 6eca267ec6fa..1bad6121ef8c 100644
--- a/tools/include/nolibc/string.h
+++ b/tools/include/nolibc/string.h
@@ -84,6 +84,7 @@ void *memcpy(void *dst, const void *src, size_t len)
 }
 #endif /* #ifndef NOLIBC_ARCH_HAS_MEMCPY */
 
+#ifndef NOLIBC_ARCH_HAS_MEMSET
 /* might be ignored by the compiler without -ffreestanding, then found as
  * missing.
  */
@@ -99,6 +100,7 @@ void *memset(void *dst, int b, size_t len)
 	}
 	return dst;
 }
+#endif /* #ifndef NOLIBC_ARCH_HAS_MEMSET */
 
 static __attribute__((unused))
 char *strchr(const char *s, int c)
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 08/19] tools/nolibc: string: Remove the `_nolibc_memcpy_down()` function
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (6 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 07/19] tools/nolibc: x86-64: Use `rep stosb` for `memset()` Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 09/19] tools/nolibc: string: Remove the `_nolibc_memcpy_up()` function Paul E. McKenney
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: gwml, kernel-team, w, Ammar Faizi, Alviro Iskandar Setiawan,
	Willy Tarreau, Thomas Weißschuh

From: Ammar Faizi <[email protected]>

This nolibc internal function is not used. Delete it. It was probably
supposed to handle memmove(), but today the memmove() has its own
implementation.

Signed-off-by: Ammar Faizi <[email protected]>
Reviewed-by: Alviro Iskandar Setiawan <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
Signed-off-by: Thomas Weißschuh <[email protected]>
---
 tools/include/nolibc/string.h | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
index 1bad6121ef8c..22dcb3f566ba 100644
--- a/tools/include/nolibc/string.h
+++ b/tools/include/nolibc/string.h
@@ -39,16 +39,6 @@ void *_nolibc_memcpy_up(void *dst, const void *src, size_t len)
 	return dst;
 }
 
-static __attribute__((unused))
-void *_nolibc_memcpy_down(void *dst, const void *src, size_t len)
-{
-	while (len) {
-		len--;
-		((char *)dst)[len] = ((const char *)src)[len];
-	}
-	return dst;
-}
-
 #ifndef NOLIBC_ARCH_HAS_MEMMOVE
 /* might be ignored by the compiler without -ffreestanding, then found as
  * missing.
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 09/19] tools/nolibc: string: Remove the `_nolibc_memcpy_up()` function
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (7 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 08/19] tools/nolibc: string: Remove the `_nolibc_memcpy_down()` function Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 10/19] selftests/nolibc: libc-test: avoid -Wstringop-overflow warnings Paul E. McKenney
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: gwml, kernel-team, w, Ammar Faizi, Alviro Iskandar Setiawan,
	Willy Tarreau, Thomas Weißschuh

From: Ammar Faizi <[email protected]>

This function is only called by memcpy(), there is no real reason to
have this wrapper. Delete this function and move the code to memcpy()
directly.

Signed-off-by: Ammar Faizi <[email protected]>
Reviewed-by: Alviro Iskandar Setiawan <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
Signed-off-by: Thomas Weißschuh <[email protected]>
---
 tools/include/nolibc/string.h | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
index 22dcb3f566ba..a01c69dd495f 100644
--- a/tools/include/nolibc/string.h
+++ b/tools/include/nolibc/string.h
@@ -27,18 +27,6 @@ int memcmp(const void *s1, const void *s2, size_t n)
 	return c1;
 }
 
-static __attribute__((unused))
-void *_nolibc_memcpy_up(void *dst, const void *src, size_t len)
-{
-	size_t pos = 0;
-
-	while (pos < len) {
-		((char *)dst)[pos] = ((const char *)src)[pos];
-		pos++;
-	}
-	return dst;
-}
-
 #ifndef NOLIBC_ARCH_HAS_MEMMOVE
 /* might be ignored by the compiler without -ffreestanding, then found as
  * missing.
@@ -70,7 +58,13 @@ void *memmove(void *dst, const void *src, size_t len)
 __attribute__((weak,unused,section(".text.nolibc_memcpy")))
 void *memcpy(void *dst, const void *src, size_t len)
 {
-	return _nolibc_memcpy_up(dst, src, len);
+	size_t pos = 0;
+
+	while (pos < len) {
+		((char *)dst)[pos] = ((const char *)src)[pos];
+		pos++;
+	}
+	return dst;
 }
 #endif /* #ifndef NOLIBC_ARCH_HAS_MEMCPY */
 
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6)
@ 2023-10-12 19:32 Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 01/19] tools/nolibc: i386: Fix a stack misalign bug on _start Paul E. McKenney
                   ` (18 more replies)
  0 siblings, 19 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, ammarfaizi2

Hello!

This series contains nolibc updates, with the first three (1-3) being
urgent for v6.6 and the remainder (4-19) being for the upcoming v6.7
merge window.

1.	tools/nolibc: i386: Fix a stack misalign bug on _start, courtesy
	of Ammar Faizi.

2.	MAINTAINERS: nolibc: update tree location, courtesy of Thomas
	Weißschuh.

3.	tools/nolibc: mark start_c as weak, courtesy of Thomas Weißschuh.

4.	tools/nolibc: add stdarg.h header, courtesy of Thomas Weißschuh.

5.	selftests/nolibc: use -nostdinc for nolibc-test, courtesy of
	Thomas Weißschuh.

6.	tools/nolibc: x86-64: Use `rep movsb` for `memcpy()` and
	`memmove()`, courtesy of Ammar Faizi.

7.	tools/nolibc: x86-64: Use `rep stosb` for `memset()`, courtesy
	of Ammar Faizi.

8.	tools/nolibc: string: Remove the `_nolibc_memcpy_down()` function,
	courtesy of Ammar Faizi.

9.	tools/nolibc: string: Remove the `_nolibc_memcpy_up()` function,
	courtesy of Ammar Faizi.

10.	selftests/nolibc: libc-test: avoid -Wstringop-overflow warnings,
	courtesy of Thomas Weißschuh.

11.	selftests/nolibc: don't embed initramfs into kernel image,
	courtesy of Thomas Weißschuh.

12.	selftests/nolibc: allow building i386 with multiarch compiler,
	courtesy of Thomas Weißschuh.

13.	tools/nolibc: avoid unused parameter warnings for ENOSYS
	fallbacks, courtesy of Thomas Weißschuh.

14.	tools/nolibc: don't define new syscall number, courtesy of
	Thomas Weißschuh.

15.	tools/nolibc: automatically detect necessity to use pselect6,
	courtesy of Thomas Weißschuh.

16.	tools/nolibc: drop test for getauxval(AT_PAGESZ), courtesy of
	Thomas Weißschuh.

17.	tools/nolibc: add support for constructors and destructors,
	courtesy of Thomas Weißschuh.

18.	selftests/nolibc: use qemu-system-ppc64 for ppc64le, courtesy
	of Thomas Weißschuh.

19.	selftests/nolibc: add tests for multi-object linkage, courtesy
	of Thomas Weißschuh.

						Thanx, Paul

------------------------------------------------------------------------

 b/MAINTAINERS                                          |    2 
 b/tools/include/nolibc/Makefile                        |    1 
 b/tools/include/nolibc/arch-aarch64.h                  |    3 
 b/tools/include/nolibc/arch-i386.h                     |    4 -
 b/tools/include/nolibc/arch-loongarch.h                |    4 -
 b/tools/include/nolibc/arch-riscv.h                    |    3 
 b/tools/include/nolibc/arch-x86_64.h                   |   29 ++++++++
 b/tools/include/nolibc/crt.h                           |    1 
 b/tools/include/nolibc/nolibc.h                        |    4 -
 b/tools/include/nolibc/stdarg.h                        |   16 ++++
 b/tools/include/nolibc/stdio.h                         |    3 
 b/tools/include/nolibc/string.h                        |    4 +
 b/tools/include/nolibc/sys.h                           |    2 
 b/tools/testing/selftests/nolibc/.gitignore            |    1 
 b/tools/testing/selftests/nolibc/Makefile              |    2 
 b/tools/testing/selftests/nolibc/nolibc-test-linkage.c |   26 +++++++
 b/tools/testing/selftests/nolibc/nolibc-test-linkage.h |    9 ++
 b/tools/testing/selftests/nolibc/nolibc-test.c         |    6 -
 tools/include/nolibc/arch-x86_64.h                     |   13 +++
 tools/include/nolibc/crt.h                             |   23 ++++++
 tools/include/nolibc/string.h                          |   32 ++------
 tools/include/nolibc/sys.h                             |   61 +++++++++--------
 tools/testing/selftests/nolibc/Makefile                |   57 +++++++++------
 tools/testing/selftests/nolibc/nolibc-test.c           |   22 +++++-
 24 files changed, 234 insertions(+), 94 deletions(-)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH nolibc 10/19] selftests/nolibc: libc-test: avoid -Wstringop-overflow warnings
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (8 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 09/19] tools/nolibc: string: Remove the `_nolibc_memcpy_up()` function Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 11/19] selftests/nolibc: don't embed initramfs into kernel image Paul E. McKenney
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh

From: Thomas Weißschuh <[email protected]>

Newer versions of glibc annotate the poll() function with
__attribute__(access) which triggers a compiler warning inside the
testcase poll_fault.
Avoid this by using a plain NULL which is enough for the testcase.
To avoid potential future warnings also adapt the other EFAULT
testcases, except select_fault as NULL is a valid value for its
argument.

nolibc-test.c: In function ‘run_syscall’:
nolibc-test.c:338:62: warning: ‘poll’ writing 8 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
  338 |         do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syserr2(expr, expret, experr1, experr2, llen); } while (0)
      |                                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nolibc-test.c:341:9: note: in expansion of macro ‘EXPECT_SYSER2’
  341 |         EXPECT_SYSER2(cond, expr, expret, experr, 0)
      |         ^~~~~~~~~~~~~
nolibc-test.c:905:47: note: in expansion of macro ‘EXPECT_SYSER’
  905 |                 CASE_TEST(poll_fault);        EXPECT_SYSER(1, poll((void *)1, 1, 0), -1, EFAULT); break;
      |                                               ^~~~~~~~~~~~
cc1: note: destination object is likely at address zero
In file included from /usr/include/poll.h:1,
                 from nolibc-test.c:33:
/usr/include/sys/poll.h:54:12: note: in a call to function ‘poll’ declared with attribute ‘access (write_only, 1, 2)’
   54 | extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
      |            ^~~~

Signed-off-by: Thomas Weißschuh <[email protected]>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index fb3bf91462e2..a3ee4496bf0a 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -894,14 +894,14 @@ int run_syscall(int min, int max)
 		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
 		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
 		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;
-		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap((void *)1, 0), -1, EINVAL); break;
+		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap(NULL, 0), -1, EINVAL); break;
 		CASE_TEST(mmap_munmap_good);  EXPECT_SYSZR(1, test_mmap_munmap()); break;
 		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
 		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
 		CASE_TEST(pipe);              EXPECT_SYSZR(1, test_pipe()); break;
 		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
 		CASE_TEST(poll_stdout);       EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break;
-		CASE_TEST(poll_fault);        EXPECT_SYSER(1, poll((void *)1, 1, 0), -1, EFAULT); break;
+		CASE_TEST(poll_fault);        EXPECT_SYSER(1, poll(NULL, 1, 0), -1, EFAULT); break;
 		CASE_TEST(prctl);             EXPECT_SYSER(1, prctl(PR_SET_NAME, (unsigned long)NULL, 0, 0, 0), -1, EFAULT); break;
 		CASE_TEST(read_badf);         EXPECT_SYSER(1, read(-1, &tmp, 1), -1, EBADF); break;
 		CASE_TEST(rmdir_blah);        EXPECT_SYSER(1, rmdir("/blah"), -1, ENOENT); break;
@@ -910,7 +910,7 @@ int run_syscall(int min, int max)
 		CASE_TEST(select_stdout);     EXPECT_SYSNE(1, ({ fd_set fds; FD_ZERO(&fds); FD_SET(1, &fds); select(2, NULL, &fds, NULL, NULL); }), -1); break;
 		CASE_TEST(select_fault);      EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break;
 		CASE_TEST(stat_blah);         EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break;
-		CASE_TEST(stat_fault);        EXPECT_SYSER(1, stat((void *)1, &stat_buf), -1, EFAULT); break;
+		CASE_TEST(stat_fault);        EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;
 		CASE_TEST(stat_timestamps);   EXPECT_SYSZR(1, test_stat_timestamps()); break;
 		CASE_TEST(symlink_root);      EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;
 		CASE_TEST(unlink_root);       EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 11/19] selftests/nolibc: don't embed initramfs into kernel image
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (9 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 10/19] selftests/nolibc: libc-test: avoid -Wstringop-overflow warnings Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 12/19] selftests/nolibc: allow building i386 with multiarch compiler Paul E. McKenney
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Nicolas Schier

From: Thomas Weißschuh <[email protected]>

When the initramfs is embedded into the kernel each rebuild of it will
trigger a full kernel relink and all the expensive postprocessing steps.

Currently nolibc-test and therefore the initramfs are always rebuild,
even without source changes, leading to lots of slow kernel relinks.

Instead of linking the initramfs into the kernel assemble it manually
and pass it explicitly to qemu.
This avoids all of the kernel relinks.

Signed-off-by: Thomas Weißschuh <[email protected]>
Reviewed-by: Nicolas Schier <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
 tools/testing/selftests/nolibc/.gitignore |  1 +
 tools/testing/selftests/nolibc/Makefile   | 42 ++++++++++++++---------
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/tools/testing/selftests/nolibc/.gitignore b/tools/testing/selftests/nolibc/.gitignore
index 52f613cdad54..5119f9f7afd2 100644
--- a/tools/testing/selftests/nolibc/.gitignore
+++ b/tools/testing/selftests/nolibc/.gitignore
@@ -1,4 +1,5 @@
 /initramfs/
+/initramfs.cpio
 /libc-test
 /nolibc-test
 /run.out
diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 689658f81a19..ee6a9ad28cfd 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -131,18 +131,20 @@ REPORT  ?= awk '/\[OK\][\r]*$$/{p++} /\[FAIL\][\r]*$$/{if (!f) printf("\n"); f++
 
 help:
 	@echo "Supported targets under selftests/nolibc:"
-	@echo "  all          call the \"run\" target below"
-	@echo "  help         this help"
-	@echo "  sysroot      create the nolibc sysroot here (uses \$$ARCH)"
-	@echo "  nolibc-test  build the executable (uses \$$CC and \$$CROSS_COMPILE)"
-	@echo "  libc-test    build an executable using the compiler's default libc instead"
-	@echo "  run-user     runs the executable under QEMU (uses \$$XARCH, \$$TEST)"
-	@echo "  initramfs    prepare the initramfs with nolibc-test"
-	@echo "  defconfig    create a fresh new default config (uses \$$XARCH)"
-	@echo "  kernel       (re)build the kernel with the initramfs (uses \$$XARCH)"
-	@echo "  run          runs the kernel in QEMU after building it (uses \$$XARCH, \$$TEST)"
-	@echo "  rerun        runs a previously prebuilt kernel in QEMU (uses \$$XARCH, \$$TEST)"
-	@echo "  clean        clean the sysroot, initramfs, build and output files"
+	@echo "  all               call the \"run\" target below"
+	@echo "  help              this help"
+	@echo "  sysroot           create the nolibc sysroot here (uses \$$ARCH)"
+	@echo "  nolibc-test       build the executable (uses \$$CC and \$$CROSS_COMPILE)"
+	@echo "  libc-test         build an executable using the compiler's default libc instead"
+	@echo "  run-user          runs the executable under QEMU (uses \$$XARCH, \$$TEST)"
+	@echo "  initramfs.cpio    prepare the initramfs archive with nolibc-test"
+	@echo "  initramfs         prepare the initramfs tree with nolibc-test"
+	@echo "  defconfig         create a fresh new default config (uses \$$XARCH)"
+	@echo "  kernel            (re)build the kernel (uses \$$XARCH)"
+	@echo "  kernel-standalone (re)build the kernel with the initramfs (uses \$$XARCH)"
+	@echo "  run               runs the kernel in QEMU after building it (uses \$$XARCH, \$$TEST)"
+	@echo "  rerun             runs a previously prebuilt kernel in QEMU (uses \$$XARCH, \$$TEST)"
+	@echo "  clean             clean the sysroot, initramfs, build and output files"
 	@echo ""
 	@echo "The output file is \"run.out\". Test ranges may be passed using \$$TEST."
 	@echo ""
@@ -195,6 +197,9 @@ run-user: nolibc-test
 	$(Q)qemu-$(QEMU_ARCH) ./nolibc-test > "$(CURDIR)/run.out" || :
 	$(Q)$(REPORT) $(CURDIR)/run.out
 
+initramfs.cpio: kernel nolibc-test
+	$(QUIET_GEN)echo 'file /init nolibc-test 755 0 0' | $(srctree)/usr/gen_init_cpio - > initramfs.cpio
+
 initramfs: nolibc-test
 	$(QUIET_MKDIR)mkdir -p initramfs
 	$(call QUIET_INSTALL, initramfs/init)
@@ -203,17 +208,20 @@ initramfs: nolibc-test
 defconfig:
 	$(Q)$(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) mrproper $(DEFCONFIG) prepare
 
-kernel: initramfs
+kernel:
+	$(Q)$(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) $(IMAGE_NAME)
+
+kernel-standalone: initramfs
 	$(Q)$(MAKE) -C $(srctree) ARCH=$(ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) $(IMAGE_NAME) CONFIG_INITRAMFS_SOURCE=$(CURDIR)/initramfs
 
 # run the tests after building the kernel
-run: kernel
-	$(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(srctree)/$(IMAGE)" -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
+run: kernel initramfs.cpio
+	$(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(srctree)/$(IMAGE)" -initrd initramfs.cpio -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
 	$(Q)$(REPORT) $(CURDIR)/run.out
 
 # re-run the tests from an existing kernel
 rerun:
-	$(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(srctree)/$(IMAGE)" -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
+	$(Q)qemu-system-$(QEMU_ARCH) -display none -no-reboot -kernel "$(srctree)/$(IMAGE)" -initrd initramfs.cpio -serial stdio $(QEMU_ARGS) > "$(CURDIR)/run.out"
 	$(Q)$(REPORT) $(CURDIR)/run.out
 
 # report with existing test log
@@ -227,6 +235,8 @@ clean:
 	$(Q)rm -f nolibc-test
 	$(call QUIET_CLEAN, libc-test)
 	$(Q)rm -f libc-test
+	$(call QUIET_CLEAN, initramfs.cpio)
+	$(Q)rm -rf initramfs.cpio
 	$(call QUIET_CLEAN, initramfs)
 	$(Q)rm -rf initramfs
 	$(call QUIET_CLEAN, run.out)
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 12/19] selftests/nolibc: allow building i386 with multiarch compiler
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (10 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 11/19] selftests/nolibc: don't embed initramfs into kernel image Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 13/19] tools/nolibc: avoid unused parameter warnings for ENOSYS fallbacks Paul E. McKenney
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

When building with a multiarch-capable compiler, like those provided by
common distributions the -m32 argument is required to build 32bit code.

Wrap it in cc-option in case the compiler is not multiarch-capable.

Signed-off-by: Thomas Weißschuh <[email protected]>
Acked-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
 tools/testing/selftests/nolibc/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index ee6a9ad28cfd..891aa396163d 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -113,6 +113,7 @@ else
 Q=@
 endif
 
+CFLAGS_i386 = $(call cc-option,-m32)
 CFLAGS_ppc = -m32 -mbig-endian -mno-vsx $(call cc-option,-mmultiple)
 CFLAGS_ppc64 = -m64 -mbig-endian -mno-vsx $(call cc-option,-mmultiple)
 CFLAGS_ppc64le = -m64 -mlittle-endian -mno-vsx $(call cc-option,-mabi=elfv2)
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 13/19] tools/nolibc: avoid unused parameter warnings for ENOSYS fallbacks
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (11 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 12/19] selftests/nolibc: allow building i386 with multiarch compiler Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 14/19] tools/nolibc: don't define new syscall number Paul E. McKenney
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

The ENOSYS fallback code does not use its functions parameters.
This can lead to compiler warnings about unused parameters.

Explicitly avoid these warnings.

Signed-off-by: Thomas Weißschuh <[email protected]>
Acked-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
 tools/include/nolibc/sys.h | 44 +++++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 17 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index b478750c9004..8389820e1928 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -43,6 +43,16 @@
 		: __sysret_arg;                         /* return original value */ \
 })
 
+/* Syscall ENOSYS helper: Avoids unused-parameter warnings and provides a
+ * debugging hook.
+ */
+
+static __inline__ int __nolibc_enosys(const char *syscall, ...)
+{
+	(void)syscall;
+	return -ENOSYS;
+}
+
 
 /* Functions in this file only describe syscalls. They're declared static so
  * that the compiler usually decides to inline them while still being allowed
@@ -133,7 +143,7 @@ int sys_chmod(const char *path, mode_t mode)
 #elif defined(__NR_chmod)
 	return my_syscall2(__NR_chmod, path, mode);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, path, mode);
 #endif
 }
 
@@ -156,7 +166,7 @@ int sys_chown(const char *path, uid_t owner, gid_t group)
 #elif defined(__NR_chown)
 	return my_syscall3(__NR_chown, path, owner, group);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, path, owner, group);
 #endif
 }
 
@@ -230,7 +240,7 @@ int sys_dup2(int old, int new)
 #elif defined(__NR_dup2)
 	return my_syscall2(__NR_dup2, old, new);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, old, new);
 #endif
 }
 
@@ -312,7 +322,7 @@ pid_t sys_fork(void)
 #elif defined(__NR_fork)
 	return my_syscall0(__NR_fork);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__);
 #endif
 }
 #endif
@@ -486,7 +496,7 @@ int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
 #ifdef __NR_gettimeofday
 	return my_syscall2(__NR_gettimeofday, tv, tz);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, tv, tz);
 #endif
 }
 
@@ -563,7 +573,7 @@ int sys_link(const char *old, const char *new)
 #elif defined(__NR_link)
 	return my_syscall2(__NR_link, old, new);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, old, new);
 #endif
 }
 
@@ -584,7 +594,7 @@ off_t sys_lseek(int fd, off_t offset, int whence)
 #ifdef __NR_lseek
 	return my_syscall3(__NR_lseek, fd, offset, whence);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, fd, offset, whence);
 #endif
 }
 
@@ -607,7 +617,7 @@ int sys_mkdir(const char *path, mode_t mode)
 #elif defined(__NR_mkdir)
 	return my_syscall2(__NR_mkdir, path, mode);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, path, mode);
 #endif
 }
 
@@ -629,7 +639,7 @@ int sys_rmdir(const char *path)
 #elif defined(__NR_unlinkat)
 	return my_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, path);
 #endif
 }
 
@@ -652,7 +662,7 @@ long sys_mknod(const char *path, mode_t mode, dev_t dev)
 #elif defined(__NR_mknod)
 	return my_syscall3(__NR_mknod, path, mode, dev);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, path, mode, dev);
 #endif
 }
 
@@ -742,7 +752,7 @@ int sys_open(const char *path, int flags, mode_t mode)
 #elif defined(__NR_open)
 	return my_syscall3(__NR_open, path, flags, mode);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, path, flags, mode);
 #endif
 }
 
@@ -842,7 +852,7 @@ int sys_poll(struct pollfd *fds, int nfds, int timeout)
 #elif defined(__NR_poll)
 	return my_syscall3(__NR_poll, fds, nfds, timeout);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, fds, nfds, timeout);
 #endif
 }
 
@@ -934,7 +944,7 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva
 #endif
 	return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, nfds, rfds, wfds, efds, timeout);
 #endif
 }
 
@@ -989,7 +999,7 @@ int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct sta
 #ifdef __NR_statx
 	return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, fd, path, flags, mask, buf);
 #endif
 }
 
@@ -1047,7 +1057,7 @@ int sys_symlink(const char *old, const char *new)
 #elif defined(__NR_symlink)
 	return my_syscall2(__NR_symlink, old, new);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, old, new);
 #endif
 }
 
@@ -1104,7 +1114,7 @@ int sys_unlink(const char *path)
 #elif defined(__NR_unlink)
 	return my_syscall1(__NR_unlink, path);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, path);
 #endif
 }
 
@@ -1127,7 +1137,7 @@ pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
 #ifdef __NR_wait4
 	return my_syscall4(__NR_wait4, pid, status, options, rusage);
 #else
-	return -ENOSYS;
+	return __nolibc_enosys(__func__, pid, status, options, rusage);
 #endif
 }
 
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 14/19] tools/nolibc: don't define new syscall number
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (12 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 13/19] tools/nolibc: avoid unused parameter warnings for ENOSYS fallbacks Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 15/19] tools/nolibc: automatically detect necessity to use pselect6 Paul E. McKenney
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

All symbols created by nolibc are also visible to user code.
Syscall constants are expected to come from the kernel headers and
should not be made up by nolibc.

Refactor the logic to avoid defining syscall numbers.
Also the new code is easier to understand.

Signed-off-by: Thomas Weißschuh <[email protected]>
Acked-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
 tools/include/nolibc/sys.h | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 8389820e1928..f05144e46b67 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -938,11 +938,10 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva
 		t.tv_nsec = timeout->tv_usec * 1000;
 	}
 	return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
-#elif defined(__NR__newselect) || defined(__NR_select)
-#ifndef __NR__newselect
-#define __NR__newselect __NR_select
-#endif
+#elif defined(__NR__newselect)
 	return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
+#elif defined(__NR_select)
+	return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout);
 #else
 	return __nolibc_enosys(__func__, nfds, rfds, wfds, efds, timeout);
 #endif
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 15/19] tools/nolibc: automatically detect necessity to use pselect6
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (13 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 14/19] tools/nolibc: don't define new syscall number Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 16/19] tools/nolibc: drop test for getauxval(AT_PAGESZ) Paul E. McKenney
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

We can automatically detect if pselect6 is needed or not from the kernel
headers. This removes the need to manually specify it.

Signed-off-by: Thomas Weißschuh <[email protected]>
Acked-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
 tools/include/nolibc/arch-aarch64.h   |  3 ---
 tools/include/nolibc/arch-loongarch.h |  4 +---
 tools/include/nolibc/arch-riscv.h     |  3 ---
 tools/include/nolibc/sys.h            | 10 +++++-----
 4 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/tools/include/nolibc/arch-aarch64.h b/tools/include/nolibc/arch-aarch64.h
index 6c33c46848e3..b23ac1f04035 100644
--- a/tools/include/nolibc/arch-aarch64.h
+++ b/tools/include/nolibc/arch-aarch64.h
@@ -20,10 +20,7 @@
  *   - the arguments are cast to long and assigned into the target registers
  *     which are then simply passed as registers to the asm code, so that we
  *     don't have to experience issues with register constraints.
- *
- * On aarch64, select() is not implemented so we have to use pselect6().
  */
-#define __ARCH_WANT_SYS_PSELECT6
 
 #define my_syscall0(num)                                                      \
 ({                                                                            \
diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
index bf98f6220195..3f8ef8f86c0f 100644
--- a/tools/include/nolibc/arch-loongarch.h
+++ b/tools/include/nolibc/arch-loongarch.h
@@ -19,10 +19,8 @@
  *   - the arguments are cast to long and assigned into the target
  *     registers which are then simply passed as registers to the asm code,
  *     so that we don't have to experience issues with register constraints.
- *
- * On LoongArch, select() is not implemented so we have to use pselect6().
  */
-#define __ARCH_WANT_SYS_PSELECT6
+
 #define _NOLIBC_SYSCALL_CLOBBERLIST \
 	"memory", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8"
 
diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index 950cc2283fd7..1927c643c739 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -19,10 +19,7 @@
  *   - the arguments are cast to long and assigned into the target
  *     registers which are then simply passed as registers to the asm code,
  *     so that we don't have to experience issues with register constraints.
- *
- * On riscv, select() is not implemented so we have to use pselect6().
  */
-#define __ARCH_WANT_SYS_PSELECT6
 
 #define my_syscall0(num)                                                      \
 ({                                                                            \
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index f05144e46b67..2f359cb03d10 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -930,7 +930,11 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva
 		struct timeval *t;
 	} arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout };
 	return my_syscall1(__NR_select, &arg);
-#elif defined(__ARCH_WANT_SYS_PSELECT6) && defined(__NR_pselect6)
+#elif defined(__NR__newselect)
+	return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
+#elif defined(__NR_select)
+	return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout);
+#elif defined(__NR_pselect6)
 	struct timespec t;
 
 	if (timeout) {
@@ -938,10 +942,6 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva
 		t.tv_nsec = timeout->tv_usec * 1000;
 	}
 	return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
-#elif defined(__NR__newselect)
-	return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
-#elif defined(__NR_select)
-	return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout);
 #else
 	return __nolibc_enosys(__func__, nfds, rfds, wfds, efds, timeout);
 #endif
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 16/19] tools/nolibc: drop test for getauxval(AT_PAGESZ)
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (14 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 15/19] tools/nolibc: automatically detect necessity to use pselect6 Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 17/19] tools/nolibc: add support for constructors and destructors Paul E. McKenney
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh

From: Thomas Weißschuh <[email protected]>

Other testcases are already testing the same functionality:
* auxv_AT_UID tests getauxval() in general.
* test_getpagesize() tests pagesize() which directly calls
  getauxval(AT_PAGESZ).

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Thomas Weißschuh <[email protected]>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index a3ee4496bf0a..7e3936c182dc 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -630,7 +630,6 @@ int run_startup(int min, int max)
 		CASE_TEST(environ_HOME);     EXPECT_PTRNZ(1, getenv("HOME")); break;
 		CASE_TEST(auxv_addr);        EXPECT_PTRGT(test_auxv != (void *)-1, test_auxv, brk); break;
 		CASE_TEST(auxv_AT_UID);      EXPECT_EQ(1, getauxval(AT_UID), getuid()); break;
-		CASE_TEST(auxv_AT_PAGESZ);   EXPECT_GE(1, getauxval(AT_PAGESZ), 4096); break;
 		case __LINE__:
 			return ret; /* must be last */
 		/* note: do not set any defaults so as to permit holes above */
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 17/19] tools/nolibc: add support for constructors and destructors
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (15 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 16/19] tools/nolibc: drop test for getauxval(AT_PAGESZ) Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 18/19] selftests/nolibc: use qemu-system-ppc64 for ppc64le Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 19/19] selftests/nolibc: add tests for multi-object linkage Paul E. McKenney
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

With the startup code moved to C, implementing support for
constructors and deconstructors is fairly easy to implement.

Examples for code size impact:

   text	   data	    bss	    dec	    hex	filename
  21837	    104	     88	  22029	   560d	nolibc-test.before
  22135	    120	     88	  22343	   5747	nolibc-test.after
  21970	    104	     88	  22162	   5692 nolibc-test.after-only-crt.h-changes

The sections are defined by [0].

[0] https://refspecs.linuxfoundation.org/elf/gabi4+/ch5.dynamic.html

Signed-off-by: Thomas Weißschuh <[email protected]>
Acked-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
---
 tools/include/nolibc/crt.h                   | 23 +++++++++++++++++++-
 tools/testing/selftests/nolibc/nolibc-test.c | 17 +++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index a05655b4ce1d..43b551468c2a 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -13,12 +13,23 @@ const unsigned long *_auxv __attribute__((weak));
 static void __stack_chk_init(void);
 static void exit(int);
 
+extern void (*const __preinit_array_start[])(void) __attribute__((weak));
+extern void (*const __preinit_array_end[])(void) __attribute__((weak));
+
+extern void (*const __init_array_start[])(void) __attribute__((weak));
+extern void (*const __init_array_end[])(void) __attribute__((weak));
+
+extern void (*const __fini_array_start[])(void) __attribute__((weak));
+extern void (*const __fini_array_end[])(void) __attribute__((weak));
+
 __attribute__((weak))
 void _start_c(long *sp)
 {
 	long argc;
 	char **argv;
 	char **envp;
+	int exitcode;
+	void (* const *func)(void);
 	const unsigned long *auxv;
 	/* silence potential warning: conflicting types for 'main' */
 	int _nolibc_main(int, char **, char **) __asm__ ("main");
@@ -55,8 +66,18 @@ void _start_c(long *sp)
 		;
 	_auxv = auxv;
 
+	for (func = __preinit_array_start; func < __preinit_array_end; func++)
+		(*func)();
+	for (func = __init_array_start; func < __init_array_end; func++)
+		(*func)();
+
 	/* go to application */
-	exit(_nolibc_main(argc, argv, envp));
+	exitcode = _nolibc_main(argc, argv, envp);
+
+	for (func = __fini_array_end; func > __fini_array_start;)
+		(*--func)();
+
+	exit(exitcode);
 }
 
 #endif /* _NOLIBC_CRT_H */
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 7e3936c182dc..8da7f15d010e 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -57,6 +57,9 @@ static int test_argc;
 /* will be used by some test cases as readable file, please don't write it */
 static const char *argv0;
 
+/* will be used by constructor tests */
+static int constructor_test_value;
+
 /* definition of a series of tests */
 struct test {
 	const char *name;              /* test name */
@@ -594,6 +597,19 @@ int expect_strne(const char *expr, int llen, const char *cmp)
 #define CASE_TEST(name) \
 	case __LINE__: llen += printf("%d %s", test, #name);
 
+/* constructors validate that they are executed in definition order */
+__attribute__((constructor))
+static void constructor1(void)
+{
+	constructor_test_value = 1;
+}
+
+__attribute__((constructor))
+static void constructor2(void)
+{
+	constructor_test_value *= 2;
+}
+
 int run_startup(int min, int max)
 {
 	int test;
@@ -630,6 +646,7 @@ int run_startup(int min, int max)
 		CASE_TEST(environ_HOME);     EXPECT_PTRNZ(1, getenv("HOME")); break;
 		CASE_TEST(auxv_addr);        EXPECT_PTRGT(test_auxv != (void *)-1, test_auxv, brk); break;
 		CASE_TEST(auxv_AT_UID);      EXPECT_EQ(1, getauxval(AT_UID), getuid()); break;
+		CASE_TEST(constructor);      EXPECT_EQ(1, constructor_test_value, 2); break;
 		case __LINE__:
 			return ret; /* must be last */
 		/* note: do not set any defaults so as to permit holes above */
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 18/19] selftests/nolibc: use qemu-system-ppc64 for ppc64le
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (16 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 17/19] tools/nolibc: add support for constructors and destructors Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  2023-10-12 19:32 ` [PATCH nolibc 19/19] selftests/nolibc: add tests for multi-object linkage Paul E. McKenney
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

qemu-system-ppc64 can handle both big and little endian kernels.

While some setups, like Debian, provide a symlink to execute
qemu-system-ppc64 as qemu-system-ppc64le, others, like ArchLinux, do not.

So always use qemu-system-ppc64 directly.

Signed-off-by: Thomas Weißschuh <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Acked-by: Willy Tarreau <[email protected]>
---
 tools/testing/selftests/nolibc/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 891aa396163d..af60e07d3c12 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -82,7 +82,7 @@ QEMU_ARCH_arm        = arm
 QEMU_ARCH_mips       = mipsel  # works with malta_defconfig
 QEMU_ARCH_ppc        = ppc
 QEMU_ARCH_ppc64      = ppc64
-QEMU_ARCH_ppc64le    = ppc64le
+QEMU_ARCH_ppc64le    = ppc64
 QEMU_ARCH_riscv      = riscv64
 QEMU_ARCH_s390       = s390x
 QEMU_ARCH_loongarch  = loongarch64
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH nolibc 19/19] selftests/nolibc: add tests for multi-object linkage
  2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
                   ` (17 preceding siblings ...)
  2023-10-12 19:32 ` [PATCH nolibc 18/19] selftests/nolibc: use qemu-system-ppc64 for ppc64le Paul E. McKenney
@ 2023-10-12 19:32 ` Paul E. McKenney
  18 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2023-10-12 19:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: gwml, kernel-team, w, Thomas Weißschuh, Willy Tarreau

From: Thomas Weißschuh <[email protected]>

While uncommon, nolibc executables can be linked together from multiple
compilation units.
Add some tests to make sure everything works in that case.

Signed-off-by: Thomas Weißschuh <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Acked-by: Willy Tarreau <[email protected]>
---
 tools/testing/selftests/nolibc/Makefile       | 12 ++++-----
 .../selftests/nolibc/nolibc-test-linkage.c    | 26 +++++++++++++++++++
 .../selftests/nolibc/nolibc-test-linkage.h    |  9 +++++++
 tools/testing/selftests/nolibc/nolibc-test.c  |  4 +++
 4 files changed, 45 insertions(+), 6 deletions(-)
 create mode 100644 tools/testing/selftests/nolibc/nolibc-test-linkage.c
 create mode 100644 tools/testing/selftests/nolibc/nolibc-test-linkage.h

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index af60e07d3c12..a0fc07253baf 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -171,17 +171,17 @@ sysroot/$(ARCH)/include:
 	$(Q)mv sysroot/sysroot sysroot/$(ARCH)
 
 ifneq ($(NOLIBC_SYSROOT),0)
-nolibc-test: nolibc-test.c sysroot/$(ARCH)/include
+nolibc-test: nolibc-test.c nolibc-test-linkage.c sysroot/$(ARCH)/include
 	$(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
-	  -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include $< -lgcc
+	  -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include nolibc-test.c nolibc-test-linkage.c -lgcc
 else
-nolibc-test: nolibc-test.c
+nolibc-test: nolibc-test.c nolibc-test-linkage.c
 	$(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
-	  -nostdlib -static -include ../../../include/nolibc/nolibc.h $< -lgcc
+	  -nostdlib -static -include ../../../include/nolibc/nolibc.h nolibc-test.c nolibc-test-linkage.c -lgcc
 endif
 
-libc-test: nolibc-test.c
-	$(QUIET_CC)$(HOSTCC) -o $@ $<
+libc-test: nolibc-test.c nolibc-test-linkage.c
+	$(QUIET_CC)$(HOSTCC) -o $@ nolibc-test.c nolibc-test-linkage.c
 
 # local libc-test
 run-libc-test: libc-test
diff --git a/tools/testing/selftests/nolibc/nolibc-test-linkage.c b/tools/testing/selftests/nolibc/nolibc-test-linkage.c
new file mode 100644
index 000000000000..5ff4c8a1db2a
--- /dev/null
+++ b/tools/testing/selftests/nolibc/nolibc-test-linkage.c
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include "nolibc-test-linkage.h"
+
+#ifndef NOLIBC
+#include <errno.h>
+#endif
+
+void *linkage_test_errno_addr(void)
+{
+	return &errno;
+}
+
+int linkage_test_constructor_test_value;
+
+__attribute__((constructor))
+static void constructor1(void)
+{
+	linkage_test_constructor_test_value = 2;
+}
+
+__attribute__((constructor))
+static void constructor2(void)
+{
+	linkage_test_constructor_test_value *= 3;
+}
diff --git a/tools/testing/selftests/nolibc/nolibc-test-linkage.h b/tools/testing/selftests/nolibc/nolibc-test-linkage.h
new file mode 100644
index 000000000000..c66473070d73
--- /dev/null
+++ b/tools/testing/selftests/nolibc/nolibc-test-linkage.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _NOLIBC_TEST_LINKAGE_H
+#define _NOLIBC_TEST_LINKAGE_H
+
+void *linkage_test_errno_addr(void);
+extern int linkage_test_constructor_test_value;
+
+#endif /* _NOLIBC_TEST_LINKAGE_H */
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 8da7f15d010e..2f10541e6f38 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -41,6 +41,8 @@
 #endif
 #endif
 
+#include "nolibc-test-linkage.h"
+
 /* for the type of int_fast16_t and int_fast32_t, musl differs from glibc and nolibc */
 #define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2)))
 #define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1)
@@ -647,6 +649,8 @@ int run_startup(int min, int max)
 		CASE_TEST(auxv_addr);        EXPECT_PTRGT(test_auxv != (void *)-1, test_auxv, brk); break;
 		CASE_TEST(auxv_AT_UID);      EXPECT_EQ(1, getauxval(AT_UID), getuid()); break;
 		CASE_TEST(constructor);      EXPECT_EQ(1, constructor_test_value, 2); break;
+		CASE_TEST(linkage_errno);    EXPECT_PTREQ(1, linkage_test_errno_addr(), &errno); break;
+		CASE_TEST(linkage_constr);   EXPECT_EQ(1, linkage_test_constructor_test_value, 6); break;
 		case __LINE__:
 			return ret; /* must be last */
 		/* note: do not set any defaults so as to permit holes above */
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2023-10-12 19:32 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-12 19:32 [PATCH nolibc 0/19] Updates to nolibc for v6.7 (and three for v6.6) Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 01/19] tools/nolibc: i386: Fix a stack misalign bug on _start Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 02/19] MAINTAINERS: nolibc: update tree location Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 03/19] tools/nolibc: mark start_c as weak Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 04/19] tools/nolibc: add stdarg.h header Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 05/19] selftests/nolibc: use -nostdinc for nolibc-test Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 06/19] tools/nolibc: x86-64: Use `rep movsb` for `memcpy()` and `memmove()` Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 07/19] tools/nolibc: x86-64: Use `rep stosb` for `memset()` Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 08/19] tools/nolibc: string: Remove the `_nolibc_memcpy_down()` function Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 09/19] tools/nolibc: string: Remove the `_nolibc_memcpy_up()` function Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 10/19] selftests/nolibc: libc-test: avoid -Wstringop-overflow warnings Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 11/19] selftests/nolibc: don't embed initramfs into kernel image Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 12/19] selftests/nolibc: allow building i386 with multiarch compiler Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 13/19] tools/nolibc: avoid unused parameter warnings for ENOSYS fallbacks Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 14/19] tools/nolibc: don't define new syscall number Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 15/19] tools/nolibc: automatically detect necessity to use pselect6 Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 16/19] tools/nolibc: drop test for getauxval(AT_PAGESZ) Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 17/19] tools/nolibc: add support for constructors and destructors Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 18/19] selftests/nolibc: use qemu-system-ppc64 for ppc64le Paul E. McKenney
2023-10-12 19:32 ` [PATCH nolibc 19/19] selftests/nolibc: add tests for multi-object linkage Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox