diff options
Diffstat (limited to 'tools/include')
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 */ |
