Skip to content

Commit c904998

Browse files
committed
Merge tag 'nolibc.2023.10.23a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu
Pull nolibc updates from Paul McKenney: - Add stdarg.h header and a few additional system-call upgrades - Add support for constructors and destructors - Add tests to verify the ability to link multiple .o files against nolibc - Numerous string-function optimizations and improvements - Prevent redundant kernel relinks by avoiding embedding of initramfs into the kernel image - Allow building i386 with multiarch compiler and make ppc64le use qemu-system-ppc64 - Miscellaneous fixups, including addition of -nostdinc for nolibc-test, avoiding -Wstringop-overflow warnings, and avoiding unused parameter warnings for ENOSYS fallbacks * tag 'nolibc.2023.10.23a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu: selftests/nolibc: add tests for multi-object linkage selftests/nolibc: use qemu-system-ppc64 for ppc64le tools/nolibc: add support for constructors and destructors tools/nolibc: drop test for getauxval(AT_PAGESZ) tools/nolibc: automatically detect necessity to use pselect6 tools/nolibc: don't define new syscall number tools/nolibc: avoid unused parameter warnings for ENOSYS fallbacks selftests/nolibc: allow building i386 with multiarch compiler selftests/nolibc: don't embed initramfs into kernel image selftests/nolibc: libc-test: avoid -Wstringop-overflow warnings tools/nolibc: string: Remove the `_nolibc_memcpy_up()` function tools/nolibc: string: Remove the `_nolibc_memcpy_down()` function tools/nolibc: x86-64: Use `rep stosb` for `memset()` tools/nolibc: x86-64: Use `rep movsb` for `memcpy()` and `memmove()` selftests/nolibc: use -nostdinc for nolibc-test tools/nolibc: add stdarg.h header
2 parents eb55307 + b8c60e8 commit c904998

File tree

16 files changed

+225
-88
lines changed

16 files changed

+225
-88
lines changed

tools/include/nolibc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ all_files := \
3434
signal.h \
3535
stackprotector.h \
3636
std.h \
37+
stdarg.h \
3738
stdint.h \
3839
stdlib.h \
3940
string.h \

tools/include/nolibc/arch-aarch64.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@
2020
* - the arguments are cast to long and assigned into the target registers
2121
* which are then simply passed as registers to the asm code, so that we
2222
* don't have to experience issues with register constraints.
23-
*
24-
* On aarch64, select() is not implemented so we have to use pselect6().
2523
*/
26-
#define __ARCH_WANT_SYS_PSELECT6
2724

2825
#define my_syscall0(num) \
2926
({ \

tools/include/nolibc/arch-loongarch.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@
1919
* - the arguments are cast to long and assigned into the target
2020
* registers which are then simply passed as registers to the asm code,
2121
* so that we don't have to experience issues with register constraints.
22-
*
23-
* On LoongArch, select() is not implemented so we have to use pselect6().
2422
*/
25-
#define __ARCH_WANT_SYS_PSELECT6
23+
2624
#define _NOLIBC_SYSCALL_CLOBBERLIST \
2725
"memory", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8"
2826

tools/include/nolibc/arch-riscv.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@
1919
* - the arguments are cast to long and assigned into the target
2020
* registers which are then simply passed as registers to the asm code,
2121
* so that we don't have to experience issues with register constraints.
22-
*
23-
* On riscv, select() is not implemented so we have to use pselect6().
2422
*/
25-
#define __ARCH_WANT_SYS_PSELECT6
2623

2724
#define my_syscall0(num) \
2825
({ \

tools/include/nolibc/arch-x86_64.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,46 @@ void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_
173173
__builtin_unreachable();
174174
}
175175

176+
#define NOLIBC_ARCH_HAS_MEMMOVE
177+
void *memmove(void *dst, const void *src, size_t len);
178+
179+
#define NOLIBC_ARCH_HAS_MEMCPY
180+
void *memcpy(void *dst, const void *src, size_t len);
181+
182+
#define NOLIBC_ARCH_HAS_MEMSET
183+
void *memset(void *dst, int c, size_t len);
184+
185+
__asm__ (
186+
".section .text.nolibc_memmove_memcpy\n"
187+
".weak memmove\n"
188+
".weak memcpy\n"
189+
"memmove:\n"
190+
"memcpy:\n"
191+
"movq %rdx, %rcx\n\t"
192+
"movq %rdi, %rax\n\t"
193+
"movq %rdi, %rdx\n\t"
194+
"subq %rsi, %rdx\n\t"
195+
"cmpq %rcx, %rdx\n\t"
196+
"jb .Lbackward_copy\n\t"
197+
"rep movsb\n\t"
198+
"retq\n"
199+
".Lbackward_copy:"
200+
"leaq -1(%rdi, %rcx, 1), %rdi\n\t"
201+
"leaq -1(%rsi, %rcx, 1), %rsi\n\t"
202+
"std\n\t"
203+
"rep movsb\n\t"
204+
"cld\n\t"
205+
"retq\n"
206+
207+
".section .text.nolibc_memset\n"
208+
".weak memset\n"
209+
"memset:\n"
210+
"xchgl %eax, %esi\n\t"
211+
"movq %rdx, %rcx\n\t"
212+
"pushq %rdi\n\t"
213+
"rep stosb\n\t"
214+
"popq %rax\n\t"
215+
"retq\n"
216+
);
217+
176218
#endif /* _NOLIBC_ARCH_X86_64_H */

tools/include/nolibc/crt.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,23 @@ const unsigned long *_auxv __attribute__((weak));
1313
static void __stack_chk_init(void);
1414
static void exit(int);
1515

16+
extern void (*const __preinit_array_start[])(void) __attribute__((weak));
17+
extern void (*const __preinit_array_end[])(void) __attribute__((weak));
18+
19+
extern void (*const __init_array_start[])(void) __attribute__((weak));
20+
extern void (*const __init_array_end[])(void) __attribute__((weak));
21+
22+
extern void (*const __fini_array_start[])(void) __attribute__((weak));
23+
extern void (*const __fini_array_end[])(void) __attribute__((weak));
24+
1625
__attribute__((weak))
1726
void _start_c(long *sp)
1827
{
1928
long argc;
2029
char **argv;
2130
char **envp;
31+
int exitcode;
32+
void (* const *func)(void);
2233
const unsigned long *auxv;
2334
/* silence potential warning: conflicting types for 'main' */
2435
int _nolibc_main(int, char **, char **) __asm__ ("main");
@@ -55,8 +66,18 @@ void _start_c(long *sp)
5566
;
5667
_auxv = auxv;
5768

69+
for (func = __preinit_array_start; func < __preinit_array_end; func++)
70+
(*func)();
71+
for (func = __init_array_start; func < __init_array_end; func++)
72+
(*func)();
73+
5874
/* go to application */
59-
exit(_nolibc_main(argc, argv, envp));
75+
exitcode = _nolibc_main(argc, argv, envp);
76+
77+
for (func = __fini_array_end; func > __fini_array_start;)
78+
(*--func)();
79+
80+
exit(exitcode);
6081
}
6182

6283
#endif /* _NOLIBC_CRT_H */

tools/include/nolibc/nolibc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@
7474
* -I../nolibc -o hello hello.c -lgcc
7575
*
7676
* The available standard (but limited) include files are:
77-
* ctype.h, errno.h, signal.h, stdio.h, stdlib.h, string.h, time.h
77+
* ctype.h, errno.h, signal.h, stdarg.h, stdio.h, stdlib.h, string.h, time.h
7878
*
7979
* In addition, the following ones are expected to be provided by the compiler:
80-
* float.h, stdarg.h, stddef.h
80+
* float.h, stddef.h
8181
*
8282
* The following ones which are part to the C standard are not provided:
8383
* assert.h, locale.h, math.h, setjmp.h, limits.h

tools/include/nolibc/stdarg.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2+
/*
3+
* Variadic argument support for NOLIBC
4+
* Copyright (C) 2005-2020 Rich Felker, et al.
5+
*/
6+
7+
#ifndef _NOLIBC_STDARG_H
8+
#define _NOLIBC_STDARG_H
9+
10+
typedef __builtin_va_list va_list;
11+
#define va_start(v, l) __builtin_va_start(v, l)
12+
#define va_end(v) __builtin_va_end(v)
13+
#define va_arg(v, l) __builtin_va_arg(v, l)
14+
#define va_copy(d, s) __builtin_va_copy(d, s)
15+
16+
#endif /* _NOLIBC_STDARG_H */

tools/include/nolibc/stdio.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@
77
#ifndef _NOLIBC_STDIO_H
88
#define _NOLIBC_STDIO_H
99

10-
#include <stdarg.h>
11-
1210
#include "std.h"
1311
#include "arch.h"
1412
#include "errno.h"
1513
#include "types.h"
1614
#include "sys.h"
15+
#include "stdarg.h"
1716
#include "stdlib.h"
1817
#include "string.h"
1918

tools/include/nolibc/string.h

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,7 @@ int memcmp(const void *s1, const void *s2, size_t n)
2727
return c1;
2828
}
2929

30-
static __attribute__((unused))
31-
void *_nolibc_memcpy_up(void *dst, const void *src, size_t len)
32-
{
33-
size_t pos = 0;
34-
35-
while (pos < len) {
36-
((char *)dst)[pos] = ((const char *)src)[pos];
37-
pos++;
38-
}
39-
return dst;
40-
}
41-
42-
static __attribute__((unused))
43-
void *_nolibc_memcpy_down(void *dst, const void *src, size_t len)
44-
{
45-
while (len) {
46-
len--;
47-
((char *)dst)[len] = ((const char *)src)[len];
48-
}
49-
return dst;
50-
}
51-
30+
#ifndef NOLIBC_ARCH_HAS_MEMMOVE
5231
/* might be ignored by the compiler without -ffreestanding, then found as
5332
* missing.
5433
*/
@@ -72,14 +51,24 @@ void *memmove(void *dst, const void *src, size_t len)
7251
}
7352
return dst;
7453
}
54+
#endif /* #ifndef NOLIBC_ARCH_HAS_MEMMOVE */
7555

56+
#ifndef NOLIBC_ARCH_HAS_MEMCPY
7657
/* must be exported, as it's used by libgcc on ARM */
7758
__attribute__((weak,unused,section(".text.nolibc_memcpy")))
7859
void *memcpy(void *dst, const void *src, size_t len)
7960
{
80-
return _nolibc_memcpy_up(dst, src, len);
61+
size_t pos = 0;
62+
63+
while (pos < len) {
64+
((char *)dst)[pos] = ((const char *)src)[pos];
65+
pos++;
66+
}
67+
return dst;
8168
}
69+
#endif /* #ifndef NOLIBC_ARCH_HAS_MEMCPY */
8270

71+
#ifndef NOLIBC_ARCH_HAS_MEMSET
8372
/* might be ignored by the compiler without -ffreestanding, then found as
8473
* missing.
8574
*/
@@ -95,6 +84,7 @@ void *memset(void *dst, int b, size_t len)
9584
}
9685
return dst;
9786
}
87+
#endif /* #ifndef NOLIBC_ARCH_HAS_MEMSET */
9888

9989
static __attribute__((unused))
10090
char *strchr(const char *s, int c)

0 commit comments

Comments
 (0)