summaryrefslogtreecommitdiff
path: root/tools/include
diff options
context:
space:
mode:
Diffstat (limited to 'tools/include')
-rw-r--r--tools/include/linux/slab.h2
-rw-r--r--tools/include/nolibc/Makefile4
-rw-r--r--tools/include/nolibc/alloca.h15
-rw-r--r--tools/include/nolibc/arch-arm.h12
-rw-r--r--tools/include/nolibc/arch-arm64.h2
-rw-r--r--tools/include/nolibc/arch-loongarch.h2
-rw-r--r--tools/include/nolibc/arch-m68k.h2
-rw-r--r--tools/include/nolibc/arch-mips.h108
-rw-r--r--tools/include/nolibc/arch-openrisc.h160
-rw-r--r--tools/include/nolibc/arch-parisc.h185
-rw-r--r--tools/include/nolibc/arch-powerpc.h20
-rw-r--r--tools/include/nolibc/arch-riscv.h2
-rw-r--r--tools/include/nolibc/arch-s390.h2
-rw-r--r--tools/include/nolibc/arch-sh.h2
-rw-r--r--tools/include/nolibc/arch-sparc.h2
-rw-r--r--tools/include/nolibc/arch-x86.h74
-rw-r--r--tools/include/nolibc/arch.h4
-rw-r--r--tools/include/nolibc/assert.h36
-rw-r--r--tools/include/nolibc/compiler.h4
-rw-r--r--tools/include/nolibc/crt.h8
-rw-r--r--tools/include/nolibc/errno.h4
-rw-r--r--tools/include/nolibc/fcntl.h45
-rw-r--r--tools/include/nolibc/getopt.h2
-rw-r--r--tools/include/nolibc/nolibc.h2
-rw-r--r--tools/include/nolibc/stackprotector.h5
-rw-r--r--tools/include/nolibc/sys.h43
-rw-r--r--tools/include/nolibc/sys/mman.h6
-rw-r--r--tools/include/nolibc/unistd.h24
-rw-r--r--tools/include/uapi/asm-generic/errno.h2
-rw-r--r--tools/include/uapi/linux/bpf.h33
-rw-r--r--tools/include/uapi/linux/btf.h26
-rw-r--r--tools/include/uapi/linux/if_link.h2
-rw-r--r--tools/include/uapi/linux/netdev.h2
-rw-r--r--tools/include/uapi/linux/openat2.h43
34 files changed, 737 insertions, 148 deletions
diff --git a/tools/include/linux/slab.h b/tools/include/linux/slab.h
index 6d8e9413d5a4..2e63c2e726aa 100644
--- a/tools/include/linux/slab.h
+++ b/tools/include/linux/slab.h
@@ -183,7 +183,7 @@ __kmem_cache_create(const char *name, unsigned int size, unsigned int align,
default: __kmem_cache_create)(__name, __object_size, __args, __VA_ARGS__)
void kmem_cache_free_bulk(struct kmem_cache *cachep, size_t size, void **list);
-int kmem_cache_alloc_bulk(struct kmem_cache *cachep, gfp_t gfp, size_t size,
+bool kmem_cache_alloc_bulk(struct kmem_cache *cachep, gfp_t gfp, size_t size,
void **list);
struct slab_sheaf *
kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size);
diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index 7455097cff69..00fd2e566d75 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -17,9 +17,11 @@ endif
# it defaults to this nolibc directory.
OUTPUT ?= $(CURDIR)/
-architectures := arm arm64 loongarch m68k mips powerpc riscv s390 sh sparc x86
+architectures := 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 \
+ assert.h \
byteswap.h \
compiler.h \
crt.h \
diff --git a/tools/include/nolibc/alloca.h b/tools/include/nolibc/alloca.h
new file mode 100644
index 000000000000..448233a79e6e
--- /dev/null
+++ b/tools/include/nolibc/alloca.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * alloca() for NOLIBC
+ * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net>
+ */
+
+/* make sure to include all global symbols */
+#include "nolibc.h"
+
+#ifndef _NOLIBC_ALLOCA_H
+#define _NOLIBC_ALLOCA_H
+
+#define alloca(size) __builtin_alloca(size)
+
+#endif /* _NOLIBC_ALLOCA_H */
diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index a4d3a777a051..8681922e05ca 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -7,8 +7,11 @@
#ifndef _NOLIBC_ARCH_ARM_H
#define _NOLIBC_ARCH_ARM_H
+#include <linux/unistd.h>
+
#include "compiler.h"
#include "crt.h"
+#include "std.h"
/* Syscalls for ARM in ARM or Thumb modes :
* - registers are 32-bit
@@ -186,7 +189,7 @@
#ifndef NOLIBC_NO_RUNTIME
/* startup code */
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
"mov r0, sp\n" /* save stack pointer to %r0, as arg1 of _start_c */
@@ -196,4 +199,11 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
}
#endif /* NOLIBC_NO_RUNTIME */
+static __attribute__((unused))
+int _sys_ftruncate64(int fd, uint32_t length0, uint32_t length1)
+{
+ return __nolibc_syscall4(__NR_ftruncate64, fd, 0, length0, length1);
+}
+#define _sys_ftruncate64 _sys_ftruncate64
+
#endif /* _NOLIBC_ARCH_ARM_H */
diff --git a/tools/include/nolibc/arch-arm64.h b/tools/include/nolibc/arch-arm64.h
index 28b3c7536ad6..814bcc13b4b2 100644
--- a/tools/include/nolibc/arch-arm64.h
+++ b/tools/include/nolibc/arch-arm64.h
@@ -143,7 +143,7 @@
#ifndef NOLIBC_NO_RUNTIME
/* startup code */
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
"mov x0, sp\n" /* save stack pointer to x0, as arg1 of _start_c */
diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
index 86fb34bbf185..3abed96a15e8 100644
--- a/tools/include/nolibc/arch-loongarch.h
+++ b/tools/include/nolibc/arch-loongarch.h
@@ -144,7 +144,7 @@
#ifndef NOLIBC_NO_RUNTIME
/* startup code */
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
"move $a0, $sp\n" /* save stack pointer to $a0, as arg1 of _start_c */
diff --git a/tools/include/nolibc/arch-m68k.h b/tools/include/nolibc/arch-m68k.h
index 81d34c219a42..341f434a530c 100644
--- a/tools/include/nolibc/arch-m68k.h
+++ b/tools/include/nolibc/arch-m68k.h
@@ -130,7 +130,7 @@
#ifndef NOLIBC_NO_RUNTIME
void _start(void);
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
"movel %sp, %sp@-\n"
diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index bb9d580ea1b1..26ad413cec62 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -7,8 +7,11 @@
#ifndef _NOLIBC_ARCH_MIPS_H
#define _NOLIBC_ARCH_MIPS_H
+#include <linux/unistd.h>
+
#include "compiler.h"
#include "crt.h"
+#include "std.h"
#if !defined(_ABIO32) && !defined(_ABIN32) && !defined(_ABI64)
#error Unsupported MIPS ABI
@@ -55,6 +58,8 @@
#define _NOLIBC_SYSCALL_STACK_RESERVE "addiu $sp, $sp, -32\n"
#define _NOLIBC_SYSCALL_STACK_UNRESERVE "addiu $sp, $sp, 32\n"
+#define _NOLIBC_SYSCALL_REG register long
+
#else /* _ABIN32 || _ABI64 */
/* binutils, GCC and clang disagree about register aliases, use numbers instead. */
@@ -66,12 +71,14 @@
#define _NOLIBC_SYSCALL_STACK_RESERVE
#define _NOLIBC_SYSCALL_STACK_UNRESERVE
+#define _NOLIBC_SYSCALL_REG register long long
+
#endif /* _ABIO32 */
#define __nolibc_syscall0(num) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg4 __asm__ ("a3"); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("a3"); \
\
__asm__ volatile ( \
_NOLIBC_SYSCALL_STACK_RESERVE \
@@ -86,9 +93,9 @@
#define __nolibc_syscall1(num, arg1) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg1 __asm__ ("a0") = (long)(arg1); \
- register long _arg4 __asm__ ("a3"); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg1 __asm__ ("a0") = __nolibc_arg_to_reg(arg1); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("a3"); \
\
__asm__ volatile ( \
_NOLIBC_SYSCALL_STACK_RESERVE \
@@ -104,10 +111,10 @@
#define __nolibc_syscall2(num, arg1, arg2) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg1 __asm__ ("a0") = (long)(arg1); \
- register long _arg2 __asm__ ("a1") = (long)(arg2); \
- register long _arg4 __asm__ ("a3"); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg1 __asm__ ("a0") = __nolibc_arg_to_reg(arg1); \
+ _NOLIBC_SYSCALL_REG _arg2 __asm__ ("a1") = __nolibc_arg_to_reg(arg2); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("a3"); \
\
__asm__ volatile ( \
_NOLIBC_SYSCALL_STACK_RESERVE \
@@ -123,11 +130,11 @@
#define __nolibc_syscall3(num, arg1, arg2, arg3) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg1 __asm__ ("a0") = (long)(arg1); \
- register long _arg2 __asm__ ("a1") = (long)(arg2); \
- register long _arg3 __asm__ ("a2") = (long)(arg3); \
- register long _arg4 __asm__ ("a3"); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg1 __asm__ ("a0") = __nolibc_arg_to_reg(arg1); \
+ _NOLIBC_SYSCALL_REG _arg2 __asm__ ("a1") = __nolibc_arg_to_reg(arg2); \
+ _NOLIBC_SYSCALL_REG _arg3 __asm__ ("a2") = __nolibc_arg_to_reg(arg3); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("a3"); \
\
__asm__ volatile ( \
_NOLIBC_SYSCALL_STACK_RESERVE \
@@ -143,11 +150,11 @@
#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg1 __asm__ ("a0") = (long)(arg1); \
- register long _arg2 __asm__ ("a1") = (long)(arg2); \
- register long _arg3 __asm__ ("a2") = (long)(arg3); \
- register long _arg4 __asm__ ("a3") = (long)(arg4); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg1 __asm__ ("a0") = __nolibc_arg_to_reg(arg1); \
+ _NOLIBC_SYSCALL_REG _arg2 __asm__ ("a1") = __nolibc_arg_to_reg(arg2); \
+ _NOLIBC_SYSCALL_REG _arg3 __asm__ ("a2") = __nolibc_arg_to_reg(arg3); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("a3") = __nolibc_arg_to_reg(arg4); \
\
__asm__ volatile ( \
_NOLIBC_SYSCALL_STACK_RESERVE \
@@ -165,12 +172,12 @@
#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg1 __asm__ ("a0") = (long)(arg1); \
- register long _arg2 __asm__ ("a1") = (long)(arg2); \
- register long _arg3 __asm__ ("a2") = (long)(arg3); \
- register long _arg4 __asm__ ("a3") = (long)(arg4); \
- register long _arg5 = (long)(arg5); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg1 __asm__ ("a0") = __nolibc_arg_to_reg(arg1); \
+ _NOLIBC_SYSCALL_REG _arg2 __asm__ ("a1") = __nolibc_arg_to_reg(arg2); \
+ _NOLIBC_SYSCALL_REG _arg3 __asm__ ("a2") = __nolibc_arg_to_reg(arg3); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("a3") = __nolibc_arg_to_reg(arg4); \
+ _NOLIBC_SYSCALL_REG _arg5 = __nolibc_arg_to_reg(arg5); \
\
__asm__ volatile ( \
_NOLIBC_SYSCALL_STACK_RESERVE \
@@ -187,13 +194,13 @@
#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg1 __asm__ ("a0") = (long)(arg1); \
- register long _arg2 __asm__ ("a1") = (long)(arg2); \
- register long _arg3 __asm__ ("a2") = (long)(arg3); \
- register long _arg4 __asm__ ("a3") = (long)(arg4); \
- register long _arg5 = (long)(arg5); \
- register long _arg6 = (long)(arg6); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg1 __asm__ ("a0") = __nolibc_arg_to_reg(arg1); \
+ _NOLIBC_SYSCALL_REG _arg2 __asm__ ("a1") = __nolibc_arg_to_reg(arg2); \
+ _NOLIBC_SYSCALL_REG _arg3 __asm__ ("a2") = __nolibc_arg_to_reg(arg3); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("a3") = __nolibc_arg_to_reg(arg4); \
+ _NOLIBC_SYSCALL_REG _arg5 = __nolibc_arg_to_reg(arg5); \
+ _NOLIBC_SYSCALL_REG _arg6 = __nolibc_arg_to_reg(arg6); \
\
__asm__ volatile ( \
_NOLIBC_SYSCALL_STACK_RESERVE \
@@ -214,12 +221,12 @@
#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg1 __asm__ ("$4") = (long)(arg1); \
- register long _arg2 __asm__ ("$5") = (long)(arg2); \
- register long _arg3 __asm__ ("$6") = (long)(arg3); \
- register long _arg4 __asm__ ("$7") = (long)(arg4); \
- register long _arg5 __asm__ ("$8") = (long)(arg5); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg1 __asm__ ("$4") = __nolibc_arg_to_reg(arg1); \
+ _NOLIBC_SYSCALL_REG _arg2 __asm__ ("$5") = __nolibc_arg_to_reg(arg2); \
+ _NOLIBC_SYSCALL_REG _arg3 __asm__ ("$6") = __nolibc_arg_to_reg(arg3); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("$7") = __nolibc_arg_to_reg(arg4); \
+ _NOLIBC_SYSCALL_REG _arg5 __asm__ ("$8") = __nolibc_arg_to_reg(arg5); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -233,13 +240,13 @@
#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
({ \
- register long _num __asm__ ("v0") = (num); \
- register long _arg1 __asm__ ("$4") = (long)(arg1); \
- register long _arg2 __asm__ ("$5") = (long)(arg2); \
- register long _arg3 __asm__ ("$6") = (long)(arg3); \
- register long _arg4 __asm__ ("$7") = (long)(arg4); \
- register long _arg5 __asm__ ("$8") = (long)(arg5); \
- register long _arg6 __asm__ ("$9") = (long)(arg6); \
+ _NOLIBC_SYSCALL_REG _num __asm__ ("v0") = (num); \
+ _NOLIBC_SYSCALL_REG _arg1 __asm__ ("$4") = __nolibc_arg_to_reg(arg1); \
+ _NOLIBC_SYSCALL_REG _arg2 __asm__ ("$5") = __nolibc_arg_to_reg(arg2); \
+ _NOLIBC_SYSCALL_REG _arg3 __asm__ ("$6") = __nolibc_arg_to_reg(arg3); \
+ _NOLIBC_SYSCALL_REG _arg4 __asm__ ("$7") = __nolibc_arg_to_reg(arg4); \
+ _NOLIBC_SYSCALL_REG _arg5 __asm__ ("$8") = __nolibc_arg_to_reg(arg5); \
+ _NOLIBC_SYSCALL_REG _arg6 __asm__ ("$9") = __nolibc_arg_to_reg(arg6); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -257,7 +264,7 @@
#ifndef NOLIBC_NO_RUNTIME
/* startup code, note that it's called __start on MIPS */
void __start(void);
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector __start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector __start(void)
{
__asm__ volatile (
"move $a0, $sp\n" /* save stack pointer to $a0, as arg1 of _start_c */
@@ -278,4 +285,13 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector __
}
#endif /* NOLIBC_NO_RUNTIME */
+#if defined(_ABIO32)
+static __attribute__((unused))
+int _sys_ftruncate64(int fd, uint32_t length0, uint32_t length1)
+{
+ return __nolibc_syscall4(__NR_ftruncate64, fd, 0, length0, length1);
+}
+#define _sys_ftruncate64 _sys_ftruncate64
+#endif
+
#endif /* _NOLIBC_ARCH_MIPS_H */
diff --git a/tools/include/nolibc/arch-openrisc.h b/tools/include/nolibc/arch-openrisc.h
new file mode 100644
index 000000000000..5ef82fd9cc64
--- /dev/null
+++ b/tools/include/nolibc/arch-openrisc.h
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * OpenRISC specific definitions for NOLIBC
+ * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net>
+ */
+
+#ifndef _NOLIBC_ARCH_OPENRISC_H
+#define _NOLIBC_ARCH_OPENRISC_H
+
+#include "compiler.h"
+#include "crt.h"
+
+/*
+ * Syscalls for OpenRISC:
+ * - syscall number is passed in r11
+ * - arguments are in r3, r4, r5, r6, r7, r8
+ * - the system call is performed by calling l.sys 1
+ * - syscall return value is in r11
+ */
+
+#define _NOLIBC_SYSCALL_CLOBBERLIST \
+ "r12", "r13", "r15", "r17", "r19", "r21", "r23", "r25", "r27", "r29", "r31", "memory"
+
+#define __nolibc_syscall0(num) \
+({ \
+ register long _num __asm__ ("r11") = (num); \
+ \
+ __asm__ volatile ( \
+ "l.sys 1\n" \
+ : "+r"(_num) \
+ : \
+ : "r3", "r4", "r5", "r6", "r7", "r8", \
+ _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _num; \
+})
+
+#define __nolibc_syscall1(num, arg1) \
+({ \
+ register long _num __asm__ ("r11") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ \
+ __asm__ volatile ( \
+ "l.sys 1\n" \
+ : "+r"(_num) \
+ : "r"(_arg1) \
+ : "r4", "r5", "r6", "r7", "r8", _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _num; \
+})
+
+#define __nolibc_syscall2(num, arg1, arg2) \
+({ \
+ register long _num __asm__ ("r11") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ \
+ __asm__ volatile ( \
+ "l.sys 1\n" \
+ : "+r"(_num) \
+ : "r"(_arg1), "r"(_arg2) \
+ : "r5", "r6", "r7", "r8", _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _num; \
+})
+
+#define __nolibc_syscall3(num, arg1, arg2, arg3) \
+({ \
+ register long _num __asm__ ("r11") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ register long _arg3 __asm__ ("r5") = (long)(arg3); \
+ \
+ __asm__ volatile ( \
+ "l.sys 1\n" \
+ : "+r"(_num) \
+ : "r"(_arg1), "r"(_arg2), "r"(_arg3) \
+ : "r6", "r7", "r8", _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _num; \
+})
+
+#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \
+({ \
+ register long _num __asm__ ("r11") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ register long _arg3 __asm__ ("r5") = (long)(arg3); \
+ register long _arg4 __asm__ ("r6") = (long)(arg4); \
+ \
+ __asm__ volatile ( \
+ "l.sys 1\n" \
+ : "+r"(_num) \
+ : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4) \
+ : "r7", "r8", _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _num; \
+})
+
+#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
+({ \
+ register long _num __asm__ ("r11") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ register long _arg3 __asm__ ("r5") = (long)(arg3); \
+ register long _arg4 __asm__ ("r6") = (long)(arg4); \
+ register long _arg5 __asm__ ("r7") = (long)(arg5); \
+ \
+ __asm__ volatile ( \
+ "l.sys 1\n" \
+ : "+r"(_num) \
+ : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) \
+ : "r8", _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _num; \
+})
+
+#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ \
+ register long _num __asm__ ("r11") = (num); \
+ register long _arg1 __asm__ ("r3") = (long)(arg1); \
+ register long _arg2 __asm__ ("r4") = (long)(arg2); \
+ register long _arg3 __asm__ ("r5") = (long)(arg3); \
+ register long _arg4 __asm__ ("r6") = (long)(arg4); \
+ register long _arg5 __asm__ ("r7") = (long)(arg5); \
+ register long _arg6 __asm__ ("r8") = (long)(arg6); \
+ \
+ __asm__ volatile ( \
+ "l.sys 1\n" \
+ : "+r"(_num) \
+ : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
+ "r"(_arg6) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _num; \
+})
+
+#ifndef NOLIBC_NO_RUNTIME
+/* startup code */
+void _start_wrapper(void);
+void __attribute__((weak,noreturn))
+__nolibc_entrypoint __nolibc_no_stack_protector
+_start_wrapper(void)
+{
+ __asm__ volatile (
+ ".global _start\n" /* The C function will have a prologue, */
+ ".type _start, @function\n" /* corrupting "sp/r1" */
+ ".weak _start\n"
+ "_start:\n"
+
+ "l.jal _start_c\n" /* transfer to c runtime */
+ "l.or r3,r1,r1\n" /* save stack pointer to r3, as arg1 of _start_c */
+
+ ".size _start, .-_start\n"
+ );
+ __nolibc_entrypoint_epilogue();
+}
+#endif /* NOLIBC_NO_RUNTIME */
+
+#endif /* _NOLIBC_ARCH_OPENRISC_H */
diff --git a/tools/include/nolibc/arch-parisc.h b/tools/include/nolibc/arch-parisc.h
new file mode 100644
index 000000000000..417043ecbc53
--- /dev/null
+++ b/tools/include/nolibc/arch-parisc.h
@@ -0,0 +1,185 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * parisc/hppa (32-bit) specific definitions for NOLIBC
+ * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net>
+ */
+
+#ifndef _NOLIBC_ARCH_PARISC_H
+#define _NOLIBC_ARCH_PARISC_H
+
+#if defined(__LP64__)
+#error 64-bit not supported
+#endif
+
+#include "compiler.h"
+#include "crt.h"
+
+/* Syscalls for parisc :
+ * - syscall number is passed in r20
+ * - arguments are in r26 to r21
+ * - the system call is performed by calling "ble 0x100(%sr2, %r0)",
+ * the instruction after that is in the delay slot and executed before
+ * the jump to 0x100 actually happens, use it to load the syscall number
+ * - syscall return comes in r28
+ * - 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.
+ */
+
+#define _NOLIBC_SYSCALL_CLOBBERLIST \
+ "memory", "%r1", "%r2", "%r4", "%r20", "%r29", "%r31"
+
+#define __nolibc_syscall0(num) \
+({ \
+ register long _ret __asm__ ("r28"); \
+ \
+ __asm__ volatile ( \
+ "ble 0x100(%%sr2, %%r0)\n\t" \
+ "copy %1, %%r20\n\t" \
+ : "=r"(_ret) \
+ : "r"(num) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, \
+ "%r21", "%r22", "%r23", "%r24", "%r25", "%r26" \
+ ); \
+ _ret; \
+})
+
+#define __nolibc_syscall1(num, arg1) \
+({ \
+ register long _ret __asm__ ("r28"); \
+ register long _arg1 __asm__ ("r26") = (long)(arg1); \
+ \
+ __asm__ volatile ( \
+ "ble 0x100(%%sr2, %%r0)\n\t" \
+ "copy %2, %%r20\n\t" \
+ : "=r"(_ret), \
+ "+r"(_arg1) \
+ : "r"(num) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, \
+ "%r21", "%r22", "%r23", "%r24", "%r25" \
+ ); \
+ _ret; \
+})
+
+#define __nolibc_syscall2(num, arg1, arg2) \
+({ \
+ register long _ret __asm__ ("r28"); \
+ register long _arg1 __asm__ ("r26") = (long)(arg1); \
+ register long _arg2 __asm__ ("r25") = (long)(arg2); \
+ \
+ __asm__ volatile ( \
+ "ble 0x100(%%sr2, %%r0)\n\t" \
+ "copy %3, %%r20\n\t" \
+ : "=r"(_ret), \
+ "+r"(_arg1), "+r"(_arg2) \
+ : "r"(num) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, \
+ "%r21", "%r22", "%r23", "%r24" \
+ ); \
+ _ret; \
+})
+
+#define __nolibc_syscall3(num, arg1, arg2, arg3) \
+({ \
+ register long _ret __asm__ ("r28"); \
+ register long _arg1 __asm__ ("r26") = (long)(arg1); \
+ register long _arg2 __asm__ ("r25") = (long)(arg2); \
+ register long _arg3 __asm__ ("r24") = (long)(arg3); \
+ \
+ __asm__ volatile ( \
+ "ble 0x100(%%sr2, %%r0)\n\t" \
+ "copy %4, %%r20\n\t" \
+ : "=r"(_ret), \
+ "+r"(_arg1), "+r"(_arg2), "+r"(_arg3) \
+ : "r"(num) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, \
+ "%r21", "%r22", "%r23" \
+ ); \
+ _ret; \
+})
+
+#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \
+({ \
+ register long _ret __asm__ ("r28"); \
+ register long _arg1 __asm__ ("r26") = (long)(arg1); \
+ register long _arg2 __asm__ ("r25") = (long)(arg2); \
+ register long _arg3 __asm__ ("r24") = (long)(arg3); \
+ register long _arg4 __asm__ ("r23") = (long)(arg4); \
+ \
+ __asm__ volatile ( \
+ "ble 0x100(%%sr2, %%r0)\n\t" \
+ "copy %5, %%r20\n\t" \
+ : "=r"(_ret), \
+ "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4) \
+ : "r"(num) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, \
+ "%r21", "%r22" \
+ ); \
+ _ret; \
+})
+
+#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
+({ \
+ register long _ret __asm__ ("r28"); \
+ register long _arg1 __asm__ ("r26") = (long)(arg1); \
+ register long _arg2 __asm__ ("r25") = (long)(arg2); \
+ register long _arg3 __asm__ ("r24") = (long)(arg3); \
+ register long _arg4 __asm__ ("r23") = (long)(arg4); \
+ register long _arg5 __asm__ ("r22") = (long)(arg5); \
+ \
+ __asm__ volatile ( \
+ "ble 0x100(%%sr2, %%r0)\n\t" \
+ "copy %6, %%r20\n\t" \
+ : "=r"(_ret), \
+ "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4), \
+ "+r"(_arg5) \
+ : "r"(num) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST, \
+ "%r21" \
+ ); \
+ _ret; \
+})
+
+#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ \
+ register long _ret __asm__ ("r28"); \
+ register long _arg1 __asm__ ("r26") = (long)(arg1); \
+ register long _arg2 __asm__ ("r25") = (long)(arg2); \
+ register long _arg3 __asm__ ("r24") = (long)(arg3); \
+ register long _arg4 __asm__ ("r23") = (long)(arg4); \
+ register long _arg5 __asm__ ("r22") = (long)(arg5); \
+ register long _arg6 __asm__ ("r21") = (long)(arg6); \
+ \
+ __asm__ volatile ( \
+ "ble 0x100(%%sr2, %%r0)\n\t" \
+ "copy %7, %%r20\n\t" \
+ : "=r"(_ret), \
+ "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4), \
+ "+r"(_arg5), "+r"(_arg6) \
+ : "r"(num) \
+ : _NOLIBC_SYSCALL_CLOBBERLIST \
+ ); \
+ _ret; \
+})
+
+#ifndef NOLIBC_NO_RUNTIME
+/* startup code */
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
+{
+ __asm__ volatile (
+ ".import $global$\n" /* Set up the dp register */
+ "ldil L%$global$, %dp\n"
+ "ldo R%$global$(%r27), %dp\n"
+
+ "b _start_c\n" /* Call _start_c, the load below is executed first */
+
+ "ldo -4(%r24), %r26\n" /* The sp register is special on parisc.
+ * r24 points to argv. Subtract 4 to get &argc.
+ * Pass that as first argument to _start_c.
+ */
+ );
+ __nolibc_entrypoint_epilogue();
+}
+#endif /* NOLIBC_NO_RUNTIME */
+
+#endif /* _NOLIBC_ARCH_PARISC_H */
diff --git a/tools/include/nolibc/arch-powerpc.h b/tools/include/nolibc/arch-powerpc.h
index ef878868aa4a..a1ab91d55384 100644
--- a/tools/include/nolibc/arch-powerpc.h
+++ b/tools/include/nolibc/arch-powerpc.h
@@ -7,8 +7,11 @@
#ifndef _NOLIBC_ARCH_POWERPC_H
#define _NOLIBC_ARCH_POWERPC_H
+#include <linux/unistd.h>
+
#include "compiler.h"
#include "crt.h"
+#include "std.h"
/* Syscalls for PowerPC :
* - stack is 16-byte aligned
@@ -177,15 +180,15 @@
* "omit-frame-pointer" fails with __attribute__((no_stack_protector)) but
* works with __attribute__((__optimize__("-fno-stack-protector")))
*/
-#ifdef __no_stack_protector
-#undef __no_stack_protector
-#define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
+#ifdef __nolibc_no_stack_protector
+#undef __nolibc_no_stack_protector
+#define __nolibc_no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
#endif
#endif /* !__powerpc64__ */
#ifndef NOLIBC_NO_RUNTIME
/* startup code */
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
#ifdef __powerpc64__
#if _CALL_ELF == 2
@@ -218,4 +221,13 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
}
#endif /* NOLIBC_NO_RUNTIME */
+#if !defined(__powerpc64__)
+static __attribute__((unused))
+int _sys_ftruncate64(int fd, uint32_t length0, uint32_t length1)
+{
+ return __nolibc_syscall4(__NR_ftruncate64, fd, 0, length0, length1);
+}
+#define _sys_ftruncate64 _sys_ftruncate64
+#endif
+
#endif /* _NOLIBC_ARCH_POWERPC_H */
diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index 386ebb9f5b08..1e84ed2e63b3 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -141,7 +141,7 @@
#ifndef NOLIBC_NO_RUNTIME
/* startup code */
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
".option push\n"
diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/arch-s390.h
index 4e69123ae484..3f05c01aecc6 100644
--- a/tools/include/nolibc/arch-s390.h
+++ b/tools/include/nolibc/arch-s390.h
@@ -145,7 +145,7 @@
#ifndef NOLIBC_NO_RUNTIME
/* startup code */
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
"lgr %r2, %r15\n" /* save stack pointer to %r2, as arg1 of _start_c */
diff --git a/tools/include/nolibc/arch-sh.h b/tools/include/nolibc/arch-sh.h
index b5a64ceeec97..a32378fd621f 100644
--- a/tools/include/nolibc/arch-sh.h
+++ b/tools/include/nolibc/arch-sh.h
@@ -143,7 +143,7 @@
#ifndef NOLIBC_NO_RUNTIME
/* startup code */
void _start_wrapper(void);
-void __attribute__((weak,noreturn)) __nolibc_entrypoint __no_stack_protector _start_wrapper(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start_wrapper(void)
{
__asm__ volatile (
".global _start\n" /* The C function will have a prologue, */
diff --git a/tools/include/nolibc/arch-sparc.h b/tools/include/nolibc/arch-sparc.h
index 240539d069a8..ddae9bc10dfe 100644
--- a/tools/include/nolibc/arch-sparc.h
+++ b/tools/include/nolibc/arch-sparc.h
@@ -154,7 +154,7 @@
#ifndef NOLIBC_NO_RUNTIME
/* startup code */
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
/*
diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h
index 769ba01a8629..fe152ac2650b 100644
--- a/tools/include/nolibc/arch-x86.h
+++ b/tools/include/nolibc/arch-x86.h
@@ -165,7 +165,7 @@
* 2) The deepest stack frame should be set to zero
*
*/
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
"xor %ebp, %ebp\n" /* zero the stack frame */
@@ -202,8 +202,8 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
#define __nolibc_syscall0(num) \
({ \
- long _ret; \
- register long _num __asm__ ("rax") = (num); \
+ long long _ret; \
+ register long long _num __asm__ ("rax") = (num); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -216,9 +216,9 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
#define __nolibc_syscall1(num, arg1) \
({ \
- long _ret; \
- register long _num __asm__ ("rax") = (num); \
- register long _arg1 __asm__ ("rdi") = (long)(arg1); \
+ long long _ret; \
+ register long long _num __asm__ ("rax") = (num); \
+ register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -232,10 +232,10 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
#define __nolibc_syscall2(num, arg1, arg2) \
({ \
- long _ret; \
- register long _num __asm__ ("rax") = (num); \
- register long _arg1 __asm__ ("rdi") = (long)(arg1); \
- register long _arg2 __asm__ ("rsi") = (long)(arg2); \
+ long long _ret; \
+ register long long _num __asm__ ("rax") = (num); \
+ register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+ register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -249,11 +249,11 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
#define __nolibc_syscall3(num, arg1, arg2, arg3) \
({ \
- long _ret; \
- register long _num __asm__ ("rax") = (num); \
- register long _arg1 __asm__ ("rdi") = (long)(arg1); \
- register long _arg2 __asm__ ("rsi") = (long)(arg2); \
- register long _arg3 __asm__ ("rdx") = (long)(arg3); \
+ long long _ret; \
+ register long long _num __asm__ ("rax") = (num); \
+ register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+ register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
+ register long long _arg3 __asm__ ("rdx") = __nolibc_arg_to_reg(arg3); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -267,12 +267,12 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \
({ \
- long _ret; \
- register long _num __asm__ ("rax") = (num); \
- register long _arg1 __asm__ ("rdi") = (long)(arg1); \
- register long _arg2 __asm__ ("rsi") = (long)(arg2); \
- register long _arg3 __asm__ ("rdx") = (long)(arg3); \
- register long _arg4 __asm__ ("r10") = (long)(arg4); \
+ long long _ret; \
+ register long long _num __asm__ ("rax") = (num); \
+ register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+ register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
+ register long long _arg3 __asm__ ("rdx") = __nolibc_arg_to_reg(arg3); \
+ register long long _arg4 __asm__ ("r10") = __nolibc_arg_to_reg(arg4); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -286,13 +286,13 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \
({ \
- long _ret; \
- register long _num __asm__ ("rax") = (num); \
- register long _arg1 __asm__ ("rdi") = (long)(arg1); \
- register long _arg2 __asm__ ("rsi") = (long)(arg2); \
- register long _arg3 __asm__ ("rdx") = (long)(arg3); \
- register long _arg4 __asm__ ("r10") = (long)(arg4); \
- register long _arg5 __asm__ ("r8") = (long)(arg5); \
+ long long _ret; \
+ register long long _num __asm__ ("rax") = (num); \
+ register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+ register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
+ register long long _arg3 __asm__ ("rdx") = __nolibc_arg_to_reg(arg3); \
+ register long long _arg4 __asm__ ("r10") = __nolibc_arg_to_reg(arg4); \
+ register long long _arg5 __asm__ ("r8") = __nolibc_arg_to_reg(arg5); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -306,14 +306,14 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \
({ \
- long _ret; \
- register long _num __asm__ ("rax") = (num); \
- register long _arg1 __asm__ ("rdi") = (long)(arg1); \
- register long _arg2 __asm__ ("rsi") = (long)(arg2); \
- register long _arg3 __asm__ ("rdx") = (long)(arg3); \
- register long _arg4 __asm__ ("r10") = (long)(arg4); \
- register long _arg5 __asm__ ("r8") = (long)(arg5); \
- register long _arg6 __asm__ ("r9") = (long)(arg6); \
+ long long _ret; \
+ register long long _num __asm__ ("rax") = (num); \
+ register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+ register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
+ register long long _arg3 __asm__ ("rdx") = __nolibc_arg_to_reg(arg3); \
+ register long long _arg4 __asm__ ("r10") = __nolibc_arg_to_reg(arg4); \
+ register long long _arg5 __asm__ ("r8") = __nolibc_arg_to_reg(arg5); \
+ register long long _arg6 __asm__ ("r9") = __nolibc_arg_to_reg(arg6); \
\
__asm__ volatile ( \
"syscall\n" \
@@ -333,7 +333,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
* 2) The deepest stack frame should be zero (the %rbp).
*
*/
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void)
{
__asm__ volatile (
"xor %ebp, %ebp\n" /* zero the stack frame */
diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h
index a3adaf433f2c..b69d9c5ec5c6 100644
--- a/tools/include/nolibc/arch.h
+++ b/tools/include/nolibc/arch.h
@@ -28,6 +28,10 @@
#include "arch-m68k.h"
#elif defined(__sh__)
#include "arch-sh.h"
+#elif defined(__or1k__)
+#include "arch-openrisc.h"
+#elif defined(__hppa__)
+#include "arch-parisc.h"
#else
#error Unsupported Architecture
#endif
diff --git a/tools/include/nolibc/assert.h b/tools/include/nolibc/assert.h
new file mode 100644
index 000000000000..84ff8ad9ab07
--- /dev/null
+++ b/tools/include/nolibc/assert.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Assert for NOLIBC
+ * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net>
+ */
+
+/* make sure to include all global symbols */
+#include "nolibc.h"
+
+#ifndef _NOLIBC_ASSERT_H
+#define _NOLIBC_ASSERT_H
+
+#include "errno.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+#endif /* _NOLIBC_ASSERT_H */
+
+/* NDEBUG needs to be evaluated on *each* inclusion */
+#ifdef assert
+#undef assert
+#endif
+
+#ifndef NDEBUG
+#define assert(expr) \
+({ \
+ if (!(expr)) { \
+ fprintf(stderr, "%s: %s:%d: %s: Assertion `%s' failed.\n", \
+ program_invocation_short_name, __FILE__, __LINE__, __func__, \
+ #expr); \
+ abort(); \
+ } \
+})
+#else
+#define assert(expr) ((void)0)
+#endif
diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compiler.h
index b56570bf9f69..f2d7a81d0d7c 100644
--- a/tools/include/nolibc/compiler.h
+++ b/tools/include/nolibc/compiler.h
@@ -36,9 +36,9 @@
#endif /* defined(__SSP__) ... */
#if __nolibc_has_attribute(no_stack_protector)
-# define __no_stack_protector __attribute__((no_stack_protector))
+# define __nolibc_no_stack_protector __attribute__((no_stack_protector))
#else
-# define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
+# define __nolibc_no_stack_protector __attribute__((__optimize__("-fno-stack-protector")))
#endif /* __nolibc_has_attribute(no_stack_protector) */
#if __nolibc_has_attribute(__fallthrough__)
diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index d8ce91fd2e3b..714256228914 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -7,6 +7,10 @@
#ifndef _NOLIBC_CRT_H
#define _NOLIBC_CRT_H
+#define __nolibc_arg_to_reg(_a) \
+ __builtin_choose_expr(__builtin_classify_type(_a) == __builtin_classify_type(NULL), \
+ (unsigned long)(_a), (_a))
+
#ifndef NOLIBC_NO_RUNTIME
#include "compiler.h"
@@ -47,7 +51,7 @@ char *__nolibc_program_invocation_short_name(char *long_name)
#endif /* NOLIBC_IGNORE_ERRNO */
void _start_c(long *sp);
-__attribute__((weak,used)) __nolibc_no_sanitize_undefined
+__attribute__((weak,used)) __nolibc_no_sanitize_undefined __nolibc_no_stack_protector
void _start_c(long *sp)
{
long argc;
@@ -89,7 +93,7 @@ void _start_c(long *sp)
/* find _auxv */
for (auxv = (void *)envp; *auxv++;)
- ;
+ __asm__("");
_auxv = auxv;
#ifndef NOLIBC_IGNORE_ERRNO
diff --git a/tools/include/nolibc/errno.h b/tools/include/nolibc/errno.h
index bab83692ea1c..a2325596d550 100644
--- a/tools/include/nolibc/errno.h
+++ b/tools/include/nolibc/errno.h
@@ -15,8 +15,8 @@
#ifndef NOLIBC_IGNORE_ERRNO
#define SET_ERRNO(v) do { errno = (v); } while (0)
int errno __attribute__((weak));
-char *program_invocation_name __attribute__((weak)) = "";
-char *program_invocation_short_name __attribute__((weak)) = "";
+char *program_invocation_name __attribute__((weak)) = (char *)"";
+char *program_invocation_short_name __attribute__((weak)) = (char *)"";
#else
#define SET_ERRNO(v) do { } while (0)
#define program_invocation_name ""
diff --git a/tools/include/nolibc/fcntl.h b/tools/include/nolibc/fcntl.h
index ed2f5553c65a..d4b6af60d4cc 100644
--- a/tools/include/nolibc/fcntl.h
+++ b/tools/include/nolibc/fcntl.h
@@ -14,6 +14,20 @@
#include "types.h"
#include "sys.h"
+#define __nolibc_open_flags(_flags) ((_flags) | O_LARGEFILE)
+
+#define __nolibc_open_mode(_flags) \
+({ \
+ mode_t _mode; \
+ va_list args; \
+ \
+ va_start(args, (_flags)); \
+ _mode = va_arg(args, mode_t); \
+ va_end(args); \
+ \
+ _mode; \
+})
+
/*
* int openat(int dirfd, const char *path, int flags[, mode_t mode]);
*/
@@ -27,17 +41,8 @@ int _sys_openat(int dirfd, const char *path, int flags, mode_t mode)
static __attribute__((unused))
int openat(int dirfd, const char *path, int flags, ...)
{
- mode_t mode = 0;
-
- if (flags & O_CREAT) {
- va_list args;
-
- va_start(args, flags);
- mode = va_arg(args, mode_t);
- va_end(args);
- }
-
- return __sysret(_sys_openat(dirfd, path, flags, mode));
+ return __sysret(_sys_openat(dirfd, path, __nolibc_open_flags(flags),
+ __nolibc_open_mode(flags)));
}
/*
@@ -53,17 +58,17 @@ int _sys_open(const char *path, int flags, mode_t mode)
static __attribute__((unused))
int open(const char *path, int flags, ...)
{
- mode_t mode = 0;
-
- if (flags & O_CREAT) {
- va_list args;
+ return __sysret(_sys_open(path, __nolibc_open_flags(flags), __nolibc_open_mode(flags)));
+}
- va_start(args, flags);
- mode = va_arg(args, mode_t);
- va_end(args);
- }
+/*
+ * int creat(const char *path, mode_t mode);
+ */
- return __sysret(_sys_open(path, flags, mode));
+static __attribute__((unused))
+int creat(const char *path, mode_t mode)
+{
+ return open(path, O_CREAT | O_WRONLY | O_TRUNC, mode);
}
#endif /* _NOLIBC_FCNTL_H */
diff --git a/tools/include/nolibc/getopt.h b/tools/include/nolibc/getopt.h
index 87565e3b6a33..3ad140f692df 100644
--- a/tools/include/nolibc/getopt.h
+++ b/tools/include/nolibc/getopt.h
@@ -71,7 +71,7 @@ int getopt(int argc, char * const argv[], const char *optstring)
d = optstring[i++];
} while (d && d != c);
- if (d != c || c == ':') {
+ if (!d || d != c || c == ':') {
optopt = c;
if (optstring[0] != ':' && opterr)
fprintf(stderr, "%s: unrecognized option: %c\n", argv[0], *optchar);
diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h
index f4120f65fe79..faa94f247281 100644
--- a/tools/include/nolibc/nolibc.h
+++ b/tools/include/nolibc/nolibc.h
@@ -133,6 +133,8 @@
#include "err.h"
#include "byteswap.h"
#include "endian.h"
+#include "assert.h"
+#include "alloca.h"
/* Used by programs to avoid std includes */
#define NOLIBC
diff --git a/tools/include/nolibc/stackprotector.h b/tools/include/nolibc/stackprotector.h
index ae8b1d3a374d..916a92062ba0 100644
--- a/tools/include/nolibc/stackprotector.h
+++ b/tools/include/nolibc/stackprotector.h
@@ -40,9 +40,10 @@ void __stack_chk_fail_local(void)
__attribute__((weak,used,section(".data.nolibc_stack_chk")))
uintptr_t __stack_chk_guard;
-static __no_stack_protector void __stack_chk_init(void)
+static __nolibc_no_stack_protector void __stack_chk_init(void)
{
- __nolibc_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0);
+ __nolibc_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard),
+ GRND_INSECURE | GRND_NONBLOCK);
/* a bit more randomness in case getrandom() fails, ensure the guard is never 0 */
if (__stack_chk_guard != (uintptr_t) &__stack_chk_guard)
__stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 6335fd51f07f..548f94d96ed2 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -45,16 +45,41 @@
: __sysret_arg; /* return original value */ \
})
-/* Syscall ENOSYS helper: Avoids unused-parameter warnings and provides a
- * debugging hook.
+/* Syscall ENOSYS helper: Avoids unused-parameter warnings, provides compile
+ * time validation and a debugging hook.
*/
+#if defined(NOLIBC_COMPILE_TIME_ENOSYS)
static __inline__ int __nolibc_enosys(const char *syscall, ...)
{
(void)syscall;
return -ENOSYS;
}
+#elif __nolibc_has_attribute(error)
+__attribute__((error("system call not implemented")))
+extern int __nolibc_enosys(const char *syscall, ...);
+
+#else
+static __inline__ int __nolibc_enosys(const char *syscall, ...)
+{
+ extern int __nolibc_enosys_error;
+ (void)syscall;
+
+ return __nolibc_enosys_error;
+}
+#endif
+
+
+/*
+ * Helper for 32-bit machines where a 64-bit syscall arg needs to be split into
+ * two 32-bit parts while making sure the order of the low/high parts are correct
+ * for the endianness:
+ * __NOLIBC_LLARGPART(x, 0), __NOLIBC_LLARGPART(x, 1)
+ */
+#define __NOLIBC_LLARGPART(_arg, _part) \
+ (((union { long long ll; long l[2]; }) { .ll = _arg }).l[_part])
+
/* Functions in this file only describe syscalls. They're declared static so
* that the compiler usually decides to inline them while still being allowed
@@ -87,7 +112,7 @@ static __inline__ int __nolibc_enosys(const char *syscall, ...)
static __attribute__((unused))
void *_sys_brk(void *addr)
{
- return (void *)__nolibc_syscall1(__NR_brk, addr);
+ return (void *)(unsigned long)__nolibc_syscall1(__NR_brk, addr);
}
static __attribute__((unused))
@@ -597,12 +622,18 @@ int link(const char *old, const char *new)
static __attribute__((unused))
off_t _sys_lseek(int fd, off_t offset, int whence)
{
-#if defined(__NR_llseek)
+#if defined(__NR_llseek) || defined(__NR__llseek)
__kernel_loff_t loff = 0;
+ int ret, nr_llseek;
off_t result;
- int ret;
- ret = __nolibc_syscall5(__NR_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence);
+#if defined(__NR_llseek)
+ nr_llseek = __NR_llseek;
+#else
+ nr_llseek = __NR__llseek;
+#endif
+
+ ret = __nolibc_syscall5(nr_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence);
if (ret < 0)
result = ret;
else
diff --git a/tools/include/nolibc/sys/mman.h b/tools/include/nolibc/sys/mman.h
index 91d77a51412d..72bc1d43d1d4 100644
--- a/tools/include/nolibc/sys/mman.h
+++ b/tools/include/nolibc/sys/mman.h
@@ -27,7 +27,7 @@ void *_sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
n = __NR_mmap;
#endif
- return (void *)__nolibc_syscall6(n, addr, length, prot, flags, fd, offset);
+ return (void *)(unsigned long)__nolibc_syscall6(n, addr, length, prot, flags, fd, offset);
}
#endif
@@ -46,8 +46,8 @@ void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
static __attribute__((unused))
void *_sys_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address)
{
- return (void *)__nolibc_syscall5(__NR_mremap, old_address, old_size,
- new_size, flags, new_address);
+ return (void *)(unsigned long)__nolibc_syscall5(__NR_mremap, old_address, old_size,
+ new_size, flags, new_address);
}
static __attribute__((unused))
diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h
index 5882a6862066..79599ceef45d 100644
--- a/tools/include/nolibc/unistd.h
+++ b/tools/include/nolibc/unistd.h
@@ -48,6 +48,30 @@ int access(const char *path, int amode)
return faccessat(AT_FDCWD, path, amode, 0);
}
+#if !defined(_sys_ftruncate64) && defined(__NR_ftruncate64)
+static __attribute__((unused))
+int _sys_ftruncate64(int fd, uint32_t length0, uint32_t length1)
+{
+ return __nolibc_syscall3(__NR_ftruncate64, fd, length0, length1);
+}
+#define _sys_ftruncate64 _sys_ftruncate64
+#endif
+
+static __attribute__((unused))
+int _sys_ftruncate(int fd, off_t length)
+{
+#if defined(_sys_ftruncate64)
+ return _sys_ftruncate64(fd, __NOLIBC_LLARGPART(length, 0), __NOLIBC_LLARGPART(length, 1));
+#else
+ return __nolibc_syscall2(__NR_ftruncate, fd, length);
+#endif
+}
+
+static __attribute__((unused))
+int ftruncate(int fd, off_t length)
+{
+ return __sysret(_sys_ftruncate(fd, length));
+}
static __attribute__((unused))
int msleep(unsigned int msecs)
diff --git a/tools/include/uapi/asm-generic/errno.h b/tools/include/uapi/asm-generic/errno.h
index 92e7ae493ee3..bd78e69e0a43 100644
--- a/tools/include/uapi/asm-generic/errno.h
+++ b/tools/include/uapi/asm-generic/errno.h
@@ -122,4 +122,6 @@
#define EHWPOISON 133 /* Memory page has hardware error */
+#define EFTYPE 134 /* Wrong file type for the intended operation */
+
#endif
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 677be9a47347..89b36de5fdbb 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -994,6 +994,7 @@ enum bpf_cmd {
BPF_PROG_STREAM_READ_BY_FD,
BPF_PROG_ASSOC_STRUCT_OPS,
__MAX_BPF_CMD,
+ BPF_COMMON_ATTRS = 1 << 16, /* Indicate carrying syscall common attrs. */
};
enum bpf_map_type {
@@ -1046,6 +1047,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_CGRP_STORAGE,
BPF_MAP_TYPE_ARENA,
BPF_MAP_TYPE_INSN_ARRAY,
+ BPF_MAP_TYPE_RHASH,
__MAX_BPF_MAP_TYPE
};
@@ -1154,6 +1156,9 @@ enum bpf_attach_type {
BPF_TRACE_KPROBE_SESSION,
BPF_TRACE_UPROBE_SESSION,
BPF_TRACE_FSESSION,
+ BPF_TRACE_FENTRY_MULTI,
+ BPF_TRACE_FEXIT_MULTI,
+ BPF_TRACE_FSESSION_MULTI,
__MAX_BPF_ATTACH_TYPE
};
@@ -1178,6 +1183,7 @@ enum bpf_link_type {
BPF_LINK_TYPE_UPROBE_MULTI = 12,
BPF_LINK_TYPE_NETKIT = 13,
BPF_LINK_TYPE_SOCKMAP = 14,
+ BPF_LINK_TYPE_TRACING_MULTI = 15,
__MAX_BPF_LINK_TYPE,
};
@@ -1321,7 +1327,11 @@ enum {
* BPF_TRACE_UPROBE_MULTI attach type to create return probe.
*/
enum {
- BPF_F_UPROBE_MULTI_RETURN = (1U << 0)
+ /* Get return uprobe. */
+ BPF_F_UPROBE_MULTI_RETURN = (1U << 0),
+
+ /* Get path from provided path_fd. */
+ BPF_F_UPROBE_MULTI_PATH_FD = (1U << 1),
};
/* link_create.netfilter.flags used in LINK_CREATE command for
@@ -1500,6 +1510,13 @@ struct bpf_stack_build_id {
};
};
+struct bpf_common_attr {
+ __aligned_u64 log_buf;
+ __u32 log_size;
+ __u32 log_level;
+ __u32 log_true_size;
+};
+
#define BPF_OBJ_NAME_LEN 16U
enum {
@@ -1537,6 +1554,11 @@ union bpf_attr {
*
* BPF_MAP_TYPE_ARENA - contains the address where user space
* is going to mmap() the arena. It has to be page aligned.
+ *
+ * BPF_MAP_TYPE_RHASH - initial table size hint
+ * (nelem_hint). 0 = use rhashtable default. Must be
+ * <= min(max_entries, U16_MAX). Upper 32 bits reserved,
+ * must be zero.
*/
__u64 map_extra;
@@ -1846,6 +1868,7 @@ union bpf_attr {
__u32 cnt;
__u32 flags;
__u32 pid;
+ __u32 path_fd;
} uprobe_multi;
struct {
union {
@@ -1861,6 +1884,11 @@ union bpf_attr {
};
__u64 expected_revision;
} cgroup;
+ struct {
+ __aligned_u64 ids;
+ __aligned_u64 cookies;
+ __u32 cnt;
+ } tracing_multi;
};
} link_create;
@@ -6698,6 +6726,7 @@ struct bpf_prog_info {
__u32 verified_insns;
__u32 attach_btf_obj_id;
__u32 attach_btf_id;
+ __u32 :32;
} __attribute__((aligned(8)));
struct bpf_map_info {
@@ -6719,6 +6748,7 @@ struct bpf_map_info {
__u64 map_extra;
__aligned_u64 hash;
__u32 hash_size;
+ __u32 :32;
} __attribute__((aligned(8)));
struct bpf_btf_info {
@@ -7236,6 +7266,7 @@ enum {
TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */
SK_BPF_CB_FLAGS = 1009, /* Get or set sock ops flags in socket */
SK_BPF_BYPASS_PROT_MEM = 1010, /* Get or Set sk->sk_bypass_prot_mem */
+
};
enum {
diff --git a/tools/include/uapi/linux/btf.h b/tools/include/uapi/linux/btf.h
index 638615ebddc2..618167cab4e6 100644
--- a/tools/include/uapi/linux/btf.h
+++ b/tools/include/uapi/linux/btf.h
@@ -33,20 +33,22 @@ struct btf_header {
__u32 layout_len; /* length of layout section */
};
-/* Max # of type identifier */
-#define BTF_MAX_TYPE 0x000fffff
-/* Max offset into the string section */
-#define BTF_MAX_NAME_OFFSET 0x00ffffff
-/* Max # of struct/union/enum members or func args */
-#define BTF_MAX_VLEN 0xffff
+enum btf_max {
+ /* Max possible kind */
+ BTF_MAX_KIND = 0x0000007f,
+ /* Max # of type identifier */
+ BTF_MAX_TYPE = 0x000fffff,
+ /* Max offset into the string section */
+ BTF_MAX_NAME_OFFSET = 0x00ffffff,
+ /* Max # of struct/union/enum members or func args */
+ BTF_MAX_VLEN = 0x00ffffff,
+};
struct btf_type {
__u32 name_off;
/* "info" bits arrangement
- * bits 0-15: vlen (e.g. # of struct's members)
- * bits 16-23: unused
- * bits 24-28: kind (e.g. int, ptr, array...etc)
- * bits 29-30: unused
+ * bits 0-23: vlen (e.g. # of struct's members)
+ * bits 24-30: kind (e.g. int, ptr, array...etc)
* bit 31: kind_flag, currently used by
* struct, union, enum, fwd, enum64,
* decl_tag and type_tag
@@ -65,8 +67,8 @@ struct btf_type {
};
};
-#define BTF_INFO_KIND(info) (((info) >> 24) & 0x1f)
-#define BTF_INFO_VLEN(info) ((info) & 0xffff)
+#define BTF_INFO_KIND(info) (((info) >> 24) & 0x7f)
+#define BTF_INFO_VLEN(info) ((info) & 0xffffff)
#define BTF_INFO_KFLAG(info) ((info) >> 31)
enum {
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index 7e46ca4cd31b..757ce5e9426e 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -1526,6 +1526,8 @@ enum {
IFLA_BOND_MISSED_MAX,
IFLA_BOND_NS_IP6_TARGET,
IFLA_BOND_COUPLED_CONTROL,
+ IFLA_BOND_BROADCAST_NEIGH,
+ IFLA_BOND_LACP_STRICT,
__IFLA_BOND_MAX,
};
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
index 7df1056a35fd..2f3ab75e8cc0 100644
--- a/tools/include/uapi/linux/netdev.h
+++ b/tools/include/uapi/linux/netdev.h
@@ -97,6 +97,8 @@ enum {
};
enum {
+ NETDEV_A_IO_URING_PROVIDER_INFO_RX_BUF_LEN = 1,
+
__NETDEV_A_IO_URING_PROVIDER_INFO_MAX,
NETDEV_A_IO_URING_PROVIDER_INFO_MAX = (__NETDEV_A_IO_URING_PROVIDER_INFO_MAX - 1)
};
diff --git a/tools/include/uapi/linux/openat2.h b/tools/include/uapi/linux/openat2.h
new file mode 100644
index 000000000000..4759c471676c
--- /dev/null
+++ b/tools/include/uapi/linux/openat2.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_OPENAT2_H
+#define _LINUX_OPENAT2_H
+
+#include <linux/types.h>
+
+/*
+ * Arguments for how openat2(2) should open the target path. If only @flags and
+ * @mode are non-zero, then openat2(2) operates very similarly to openat(2).
+ *
+ * However, unlike openat(2), unknown or invalid bits in @flags result in
+ * -EINVAL rather than being silently ignored. @mode must be zero unless one of
+ * {O_CREAT, O_TMPFILE} are set.
+ *
+ * @flags: O_* flags.
+ * @mode: O_CREAT/O_TMPFILE file mode.
+ * @resolve: RESOLVE_* flags.
+ */
+struct open_how {
+ __u64 flags;
+ __u64 mode;
+ __u64 resolve;
+};
+
+/* how->resolve flags for openat2(2). */
+#define RESOLVE_NO_XDEV 0x01 /* Block mount-point crossings
+ (includes bind-mounts). */
+#define RESOLVE_NO_MAGICLINKS 0x02 /* Block traversal through procfs-style
+ "magic-links". */
+#define RESOLVE_NO_SYMLINKS 0x04 /* Block traversal through all symlinks
+ (implies OEXT_NO_MAGICLINKS) */
+#define RESOLVE_BENEATH 0x08 /* Block "lexical" trickery like
+ "..", symlinks, and absolute
+ paths which escape the dirfd. */
+#define RESOLVE_IN_ROOT 0x10 /* Make all jumps to "/" and ".."
+ be scoped inside the dirfd
+ (similar to chroot(2)). */
+#define RESOLVE_CACHED 0x20 /* Only complete if resolution can be
+ completed through cached lookup. May
+ return -EAGAIN if that's not
+ possible. */
+
+#endif /* _LINUX_OPENAT2_H */