diff options
Diffstat (limited to 'tools/include')
| -rw-r--r-- | tools/include/nolibc/Makefile | 19 | ||||
| -rw-r--r-- | tools/include/nolibc/arch-arm.h | 7 | ||||
| -rw-r--r-- | tools/include/nolibc/arch-hexagon.h | 159 | ||||
| -rw-r--r-- | tools/include/nolibc/arch-mips.h | 8 | ||||
| -rw-r--r-- | tools/include/nolibc/arch-parisc.h | 28 | ||||
| -rw-r--r-- | tools/include/nolibc/arch-powerpc.h | 7 | ||||
| -rw-r--r-- | tools/include/nolibc/arch-sh.h | 18 | ||||
| -rw-r--r-- | tools/include/nolibc/arch-x86.h | 2 | ||||
| -rw-r--r-- | tools/include/nolibc/arch.h | 7 | ||||
| -rw-r--r-- | tools/include/nolibc/compiler.h | 9 | ||||
| -rw-r--r-- | tools/include/nolibc/dirent.h | 25 | ||||
| -rw-r--r-- | tools/include/nolibc/err.h | 2 | ||||
| -rw-r--r-- | tools/include/nolibc/nolibc.h | 1 | ||||
| -rw-r--r-- | tools/include/nolibc/stdlib.h | 12 | ||||
| -rw-r--r-- | tools/include/nolibc/sys.h | 60 | ||||
| -rw-r--r-- | tools/include/nolibc/sys/select.h | 6 | ||||
| -rw-r--r-- | tools/include/nolibc/sys/sendfile.h | 41 | ||||
| -rw-r--r-- | tools/include/nolibc/types.h | 2 | ||||
| -rw-r--r-- | tools/include/nolibc/unistd.h | 4 |
19 files changed, 369 insertions, 48 deletions
diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile index 6d213d372bf8..0880be0f6ef5 100644 --- a/tools/include/nolibc/Makefile +++ b/tools/include/nolibc/Makefile @@ -17,7 +17,23 @@ endif # it defaults to this nolibc directory. OUTPUT ?= $(CURDIR)/ -architectures := alpha arm arm64 loongarch m68k mips openrisc parisc powerpc riscv s390 sh sparc x86 +architectures := \ + alpha \ + arm \ + arm64 \ + hexagon \ + loongarch \ + m68k \ + mips \ + openrisc \ + parisc \ + powerpc \ + riscv \ + s390 \ + sh \ + sparc \ + x86 \ + arch_files := arch.h $(addsuffix .h, $(addprefix arch-, $(architectures))) all_files := \ alloca.h \ @@ -59,6 +75,7 @@ all_files := \ sys/reboot.h \ sys/resource.h \ sys/select.h \ + sys/sendfile.h \ sys/stat.h \ sys/syscall.h \ sys/sysmacros.h \ diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h index b88686fb19c4..b5b3456c75cb 100644 --- a/tools/include/nolibc/arch-arm.h +++ b/tools/include/nolibc/arch-arm.h @@ -196,11 +196,6 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote } #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 +#define __NOLIBC_PAD_64BIT_SYSCALL_ARGUMENT_PAIR #endif /* _NOLIBC_ARCH_ARM_H */ diff --git a/tools/include/nolibc/arch-hexagon.h b/tools/include/nolibc/arch-hexagon.h new file mode 100644 index 000000000000..68f73529a6dd --- /dev/null +++ b/tools/include/nolibc/arch-hexagon.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * hexagon specific definitions for NOLIBC + * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net> + */ + +#ifndef _NOLIBC_ARCH_HEXAGON_H +#define _NOLIBC_ARCH_HEXAGON_H + +#include <linux/unistd.h> + +#include "compiler.h" +#include "crt.h" + +/* + * Syscalls for hexagon: + * - syscall number is passed in r6 + * - arguments are in r0, r1, r2, r3, r4, r5 + * - the system call is performed by calling trap0(#1) + * - syscall return value is in r0 + */ + +#define _NOLIBC_SYSCALL_CLOBBERLIST "memory" + +#define __nolibc_syscall0(num) \ +({ \ + register long _num __asm__ ("r6") = (num); \ + register long _arg1 __asm__ ("r0"); \ + \ + __asm__ volatile ( \ + "trap0(#1)\n" \ + : "=r"(_arg1) \ + : "r"(_num) \ + : _NOLIBC_SYSCALL_CLOBBERLIST \ + ); \ + _arg1; \ +}) + +#define __nolibc_syscall1(num, arg1) \ +({ \ + register long _num __asm__ ("r6") = (num); \ + register long _arg1 __asm__ ("r0") = (long)(arg1); \ + \ + __asm__ volatile ( \ + "trap0(#1)\n" \ + : "+r"(_arg1) \ + : "r"(_num) \ + : _NOLIBC_SYSCALL_CLOBBERLIST \ + ); \ + _arg1; \ +}) + +#define __nolibc_syscall2(num, arg1, arg2) \ +({ \ + register long _num __asm__ ("r6") = (num); \ + register long _arg1 __asm__ ("r0") = (long)(arg1); \ + register long _arg2 __asm__ ("r1") = (long)(arg2); \ + \ + __asm__ volatile ( \ + "trap0(#1)\n" \ + : "+r"(_arg1) \ + : "r"(_arg2), \ + "r"(_num) \ + : _NOLIBC_SYSCALL_CLOBBERLIST \ + ); \ + _arg1; \ +}) + +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ +({ \ + register long _num __asm__ ("r6") = (num); \ + register long _arg1 __asm__ ("r0") = (long)(arg1); \ + register long _arg2 __asm__ ("r1") = (long)(arg2); \ + register long _arg3 __asm__ ("r2") = (long)(arg3); \ + \ + __asm__ volatile ( \ + "trap0(#1)\n" \ + : "+r"(_arg1) \ + : "r"(_arg2), "r"(_arg3), \ + "r"(_num) \ + : _NOLIBC_SYSCALL_CLOBBERLIST \ + ); \ + _arg1; \ +}) + +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ +({ \ + register long _num __asm__ ("r6") = (num); \ + register long _arg1 __asm__ ("r0") = (long)(arg1); \ + register long _arg2 __asm__ ("r1") = (long)(arg2); \ + register long _arg3 __asm__ ("r2") = (long)(arg3); \ + register long _arg4 __asm__ ("r3") = (long)(arg4); \ + \ + __asm__ volatile ( \ + "trap0(#1)\n" \ + : "+r"(_arg1) \ + : "r"(_arg2), "r"(_arg3), "r"(_arg4), \ + "r"(_num) \ + : _NOLIBC_SYSCALL_CLOBBERLIST \ + ); \ + _arg1; \ +}) + +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +({ \ + register long _num __asm__ ("r6") = (num); \ + register long _arg1 __asm__ ("r0") = (long)(arg1); \ + register long _arg2 __asm__ ("r1") = (long)(arg2); \ + register long _arg3 __asm__ ("r2") = (long)(arg3); \ + register long _arg4 __asm__ ("r3") = (long)(arg4); \ + register long _arg5 __asm__ ("r4") = (long)(arg5); \ + \ + __asm__ volatile ( \ + "trap0(#1)\n" \ + : "+r"(_arg1) \ + : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ + "r"(_num) \ + : _NOLIBC_SYSCALL_CLOBBERLIST \ + ); \ + _arg1; \ +}) + +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +({ \ + register long _num __asm__ ("r6") = (num); \ + register long _arg1 __asm__ ("r0") = (long)(arg1); \ + register long _arg2 __asm__ ("r1") = (long)(arg2); \ + register long _arg3 __asm__ ("r2") = (long)(arg3); \ + register long _arg4 __asm__ ("r3") = (long)(arg4); \ + register long _arg5 __asm__ ("r4") = (long)(arg5); \ + register long _arg6 __asm__ ("r5") = (long)(arg6); \ + \ + __asm__ volatile ( \ + "trap0(#1)\n" \ + : "+r"(_arg1) \ + : "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \ + "r"(_num) \ + : _NOLIBC_SYSCALL_CLOBBERLIST \ + ); \ + _arg1; \ +}) + +#ifndef NOLIBC_NO_RUNTIME +/* startup code */ +void __attribute__((weak, noreturn)) +__nolibc_entrypoint __nolibc_no_stack_protector +_start(void) +{ + __asm__ volatile ( + "r0 = sp\n" /* save stack pointer to r0, as arg1 of _start_c */ + "call _start_c\n" /* transfer to c runtime */ + ); + __nolibc_entrypoint_epilogue(); +} +#endif /* NOLIBC_NO_RUNTIME */ + +#define __NOLIBC_PAD_64BIT_SYSCALL_ARGUMENT_PAIR + +#endif /* _NOLIBC_ARCH_HEXAGON_H */ diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h index 26ad413cec62..c0da0cc309ce 100644 --- a/tools/include/nolibc/arch-mips.h +++ b/tools/include/nolibc/arch-mips.h @@ -72,6 +72,7 @@ #define _NOLIBC_SYSCALL_STACK_UNRESERVE #define _NOLIBC_SYSCALL_REG register long long +#define __NOLIBC_BITS_PER_SYSCALL_ARG 64 #endif /* _ABIO32 */ @@ -286,12 +287,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote #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 +#define __NOLIBC_PAD_64BIT_SYSCALL_ARGUMENT_PAIR #endif #endif /* _NOLIBC_ARCH_MIPS_H */ diff --git a/tools/include/nolibc/arch-parisc.h b/tools/include/nolibc/arch-parisc.h index 417043ecbc53..bf57ba16055c 100644 --- a/tools/include/nolibc/arch-parisc.h +++ b/tools/include/nolibc/arch-parisc.h @@ -7,9 +7,7 @@ #ifndef _NOLIBC_ARCH_PARISC_H #define _NOLIBC_ARCH_PARISC_H -#if defined(__LP64__) -#error 64-bit not supported -#endif +#include <linux/unistd.h> #include "compiler.h" #include "crt.h" @@ -167,9 +165,15 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void) { __asm__ volatile ( +#ifdef __LP64__ + ".import __gp\n" /* Set up the dp register */ + "ldil L%__gp, %dp\n" + "ldo R%__gp(%dp), %dp\n" +#else ".import $global$\n" /* Set up the dp register */ "ldil L%$global$, %dp\n" - "ldo R%$global$(%r27), %dp\n" + "ldo R%$global$(%dp), %dp\n" +#endif "b _start_c\n" /* Call _start_c, the load below is executed first */ @@ -182,4 +186,20 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote } #endif /* NOLIBC_NO_RUNTIME */ +#ifdef __LP64__ +/* + * This override is normally only meant for 32-bit architectures. + * But parisc 64-bit has __NR_ftruncate64, so this path is taken. + * Add an unused second argument to satisfy the calling convention. + */ +static __attribute__((unused)) +int _sys_ftruncate64(int fd, uint64_t length, uint64_t unused) +{ + (void)unused; + + return __nolibc_syscall2(__NR_ftruncate64, fd, length); +} +#define _sys_ftruncate64 _sys_ftruncate64 +#endif + #endif /* _NOLIBC_ARCH_PARISC_H */ diff --git a/tools/include/nolibc/arch-powerpc.h b/tools/include/nolibc/arch-powerpc.h index dbe2e5205aaa..a4711638cb66 100644 --- a/tools/include/nolibc/arch-powerpc.h +++ b/tools/include/nolibc/arch-powerpc.h @@ -222,12 +222,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote #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 +#define __NOLIBC_PAD_64BIT_SYSCALL_ARGUMENT_PAIR #endif #endif /* _NOLIBC_ARCH_POWERPC_H */ diff --git a/tools/include/nolibc/arch-sh.h b/tools/include/nolibc/arch-sh.h index a32378fd621f..996cfbe1bee3 100644 --- a/tools/include/nolibc/arch-sh.h +++ b/tools/include/nolibc/arch-sh.h @@ -10,6 +10,8 @@ #include "compiler.h" #include "crt.h" +#include <linux/unistd.h> + /* * Syscalls for SuperH: * - registers are 32bit wide @@ -161,4 +163,20 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote } #endif /* NOLIBC_NO_RUNTIME */ +static __attribute__((unused)) +ssize_t _sys_pread(int fd, void *buf, size_t count, off_t offset) +{ + return __nolibc_syscall6(__NR_pread64, fd, buf, count, 0, + __NOLIBC_LLARGPART(offset, 0), __NOLIBC_LLARGPART(offset, 1)); +} +#define _sys_pread _sys_pread + +static __attribute__((unused)) +ssize_t _sys_pwrite(int fd, const void *buf, size_t count, off_t offset) +{ + return __nolibc_syscall6(__NR_pwrite64, fd, buf, count, 0, + __NOLIBC_LLARGPART(offset, 0), __NOLIBC_LLARGPART(offset, 1)); +} +#define _sys_pwrite _sys_pwrite + #endif /* _NOLIBC_ARCH_SH_H */ diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h index 577e9b682eb3..0638f9316749 100644 --- a/tools/include/nolibc/arch-x86.h +++ b/tools/include/nolibc/arch-x86.h @@ -386,5 +386,7 @@ __asm__ ( ".popsection\n" ); +#define __NOLIBC_BITS_PER_SYSCALL_ARG 64 + #endif /* !defined(__x86_64__) */ #endif /* _NOLIBC_ARCH_X86_H */ diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h index 06cc2dbe7a33..79ed5900f2a7 100644 --- a/tools/include/nolibc/arch.h +++ b/tools/include/nolibc/arch.h @@ -34,8 +34,15 @@ #include "arch-parisc.h" #elif defined(__alpha__) #include "arch-alpha.h" +#elif defined(__hexagon__) +#include "arch-hexagon.h" #else #error Unsupported Architecture #endif + +#ifndef __NOLIBC_BITS_PER_SYSCALL_ARG +#define __NOLIBC_BITS_PER_SYSCALL_ARG __BITS_PER_LONG +#endif + #endif /* _NOLIBC_ARCH_H */ diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compiler.h index f2d7a81d0d7c..375c45ce81c8 100644 --- a/tools/include/nolibc/compiler.h +++ b/tools/include/nolibc/compiler.h @@ -90,4 +90,13 @@ # define __nolibc_no_sanitize_undefined #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]) + #endif /* _NOLIBC_COMPILER_H */ diff --git a/tools/include/nolibc/dirent.h b/tools/include/nolibc/dirent.h index 4e02ef25e72d..19857369de2a 100644 --- a/tools/include/nolibc/dirent.h +++ b/tools/include/nolibc/dirent.h @@ -30,10 +30,23 @@ typedef struct { static __attribute__((unused)) DIR *fdopendir(int fd) { + struct stat buf; + int ret; + if (fd < 0) { SET_ERRNO(EBADF); return NULL; } + + ret = fstat(fd, &buf); + if (ret < 0) + return NULL; + + if (!S_ISDIR(buf.st_mode)) { + SET_ERRNO(ENOTDIR); + return NULL; + } + return (DIR *)(intptr_t)~fd; } @@ -42,10 +55,11 @@ DIR *opendir(const char *name) { int fd; - fd = open(name, O_RDONLY); + fd = open(name, O_RDONLY | O_DIRECTORY); if (fd == -1) return NULL; - return fdopendir(fd); + + return (DIR *)(intptr_t)~fd; } static __attribute__((unused)) @@ -67,6 +81,7 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) struct linux_dirent64 *ldir = (void *)buf; intptr_t i = (intptr_t)dirp; int fd, ret; + off_t off; if (i >= 0) return EBADF; @@ -86,9 +101,9 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) * readdir() can only return one entry at a time. * Make sure the non-returned ones are not skipped. */ - ret = _sys_lseek(fd, ldir->d_off, SEEK_SET); - if (ret < 0) - return -ret; + off = _sys_lseek(fd, ldir->d_off, SEEK_SET); + if (off < 0) + return -off; entry->d_ino = ldir->d_ino; /* the destination should always be big enough */ diff --git a/tools/include/nolibc/err.h b/tools/include/nolibc/err.h index e22ae87a7289..61978d537ed8 100644 --- a/tools/include/nolibc/err.h +++ b/tools/include/nolibc/err.h @@ -60,7 +60,7 @@ void verr(int eval, const char *fmt, va_list args) static __attribute__((noreturn, unused)) void verrx(int eval, const char *fmt, va_list args) { - warnx(fmt, args); + vwarnx(fmt, args); exit(eval); } diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h index faa94f247281..352a207bbedc 100644 --- a/tools/include/nolibc/nolibc.h +++ b/tools/include/nolibc/nolibc.h @@ -106,6 +106,7 @@ #include "sys/reboot.h" #include "sys/resource.h" #include "sys/select.h" +#include "sys/sendfile.h" #include "sys/stat.h" #include "sys/syscall.h" #include "sys/sysmacros.h" diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h index 1816c2368b68..1c5a914c0f23 100644 --- a/tools/include/nolibc/stdlib.h +++ b/tools/include/nolibc/stdlib.h @@ -130,9 +130,11 @@ void *malloc(size_t len) { struct nolibc_heap *heap; - /* Always allocate memory with size multiple of 4096. */ - len = sizeof(*heap) + len; - len = (len + 4095UL) & -4096UL; + if (__builtin_expect(__builtin_add_overflow(len, sizeof(*heap), &len), 0)) { + SET_ERRNO(ENOMEM); + return NULL; + } + heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); if (__builtin_expect(heap == MAP_FAILED, 0)) @@ -143,7 +145,7 @@ void *malloc(size_t len) } static __attribute__((unused)) -void *calloc(size_t size, size_t nmemb) +void *calloc(size_t nmemb, size_t size) { size_t x; @@ -230,7 +232,7 @@ int _nolibc_u64toa_base(uint64_t in, char *buffer, unsigned int base, uint64_t r /* Generate least significant digit first */ do { -#if defined(__SIZEOF_INT128__) && !defined(__mips__) && !defined(__sparc__) +#if defined(__SIZEOF_INT128__) && !defined(__mips__) && !defined(__sparc__) && !defined(__hppa__) q = ((unsigned __int128)in * recip) >> 64; #else uint64_t p = (uint32_t)in * (recip >> 32); diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h index 548f94d96ed2..b63fa6c618c5 100644 --- a/tools/include/nolibc/sys.h +++ b/tools/include/nolibc/sys.h @@ -71,16 +71,6 @@ static __inline__ int __nolibc_enosys(const char *syscall, ...) #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 * to pass a pointer to one of their instances. Each syscall exists in two @@ -756,6 +746,56 @@ int pivot_root(const char *new, const char *old) /* + * ssize_t pread(int fd, void *buf, size_t count, off_t offset); + * ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); + */ + +#ifndef _sys_pread +static __attribute__((unused)) +ssize_t _sys_pread(int fd, void *buf, size_t count, off_t offset) +{ +#if __NOLIBC_BITS_PER_SYSCALL_ARG == 64 + return __nolibc_syscall4(__NR_pread64, fd, buf, count, offset); +#elif defined(__NOLIBC_PAD_64BIT_SYSCALL_ARGUMENT_PAIR) + return __nolibc_syscall6(__NR_pread64, fd, buf, count, 0, + __NOLIBC_LLARGPART(offset, 0), __NOLIBC_LLARGPART(offset, 1)); +#else + return __nolibc_syscall5(__NR_pread64, fd, buf, count, + __NOLIBC_LLARGPART(offset, 0), __NOLIBC_LLARGPART(offset, 1)); +#endif +} +#endif /* _sys_pread */ + +static __attribute__((unused)) +ssize_t pread(int fd, void *buf, size_t count, off_t offset) +{ + return __sysret(_sys_pread(fd, buf, count, offset)); +} + +#ifndef _sys_pwrite +static __attribute__((unused)) +ssize_t _sys_pwrite(int fd, const void *buf, size_t count, off_t offset) +{ +#if __NOLIBC_BITS_PER_SYSCALL_ARG == 64 + return __nolibc_syscall4(__NR_pwrite64, fd, buf, count, offset); +#elif defined(__NOLIBC_PAD_64BIT_SYSCALL_ARGUMENT_PAIR) + return __nolibc_syscall6(__NR_pwrite64, fd, buf, count, 0, + __NOLIBC_LLARGPART(offset, 0), __NOLIBC_LLARGPART(offset, 1)); +#else + return __nolibc_syscall5(__NR_pwrite64, fd, buf, count, + __NOLIBC_LLARGPART(offset, 0), __NOLIBC_LLARGPART(offset, 1)); +#endif +} +#endif /* _sys_pwrite */ + +static __attribute__((unused)) +ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) +{ + return __sysret(_sys_pwrite(fd, buf, count, offset)); +} + + +/* * ssize_t read(int fd, void *buf, size_t count); */ diff --git a/tools/include/nolibc/sys/select.h b/tools/include/nolibc/sys/select.h index 6d65d9ef3d6a..f299c79939f5 100644 --- a/tools/include/nolibc/sys/select.h +++ b/tools/include/nolibc/sys/select.h @@ -26,7 +26,7 @@ typedef struct { int __fd = (fd); \ if (__fd >= 0) \ __set->fds[__fd / FD_SETIDXMASK] &= \ - ~(1U << (__fd & FD_SETBITMASK)); \ + ~(1UL << (__fd & FD_SETBITMASK)); \ } while (0) #define FD_SET(fd, set) do { \ @@ -34,7 +34,7 @@ typedef struct { int __fd = (fd); \ if (__fd >= 0) \ __set->fds[__fd / FD_SETIDXMASK] |= \ - 1 << (__fd & FD_SETBITMASK); \ + 1UL << (__fd & FD_SETBITMASK); \ } while (0) #define FD_ISSET(fd, set) ({ \ @@ -43,7 +43,7 @@ typedef struct { int __r = 0; \ if (__fd >= 0) \ __r = !!(__set->fds[__fd / FD_SETIDXMASK] & \ -1U << (__fd & FD_SETBITMASK)); \ +1UL << (__fd & FD_SETBITMASK)); \ __r; \ }) diff --git a/tools/include/nolibc/sys/sendfile.h b/tools/include/nolibc/sys/sendfile.h new file mode 100644 index 000000000000..ac7d85847718 --- /dev/null +++ b/tools/include/nolibc/sys/sendfile.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * sendfile for NOLIBC + * Copyright (C) 2026 Daniel Palmer <daniel@thingy.jp> + */ + +/* make sure to include all global symbols */ +#include "../nolibc.h" + +#ifndef _NOLIBC_SYS_SENDFILE_H +#define _NOLIBC_SYS_SENDFILE_H + +#include "../sys.h" +#include <linux/unistd.h> + +/* + * ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); + */ + +static __attribute__((unused)) +ssize_t _sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count) +{ + __nolibc_static_assert(sizeof(*offset) == sizeof(__kernel_loff_t)); + +#ifdef __NR_sendfile64 + /* 32-bit applications use sendfile64 so offset is treated as a __kernel_loff_t */ + return __nolibc_syscall4(__NR_sendfile64, out_fd, in_fd, offset, count); +#else + __nolibc_static_assert(sizeof(*offset) == sizeof(__kernel_off_t)); + + return __nolibc_syscall4(__NR_sendfile, out_fd, in_fd, offset, count); +#endif +} + +static __attribute__((unused)) +ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) +{ + return __sysret(_sys_sendfile(out_fd, in_fd, offset, count)); +} + +#endif /* _NOLIBC_SYS_SENDFILE_H */ diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h index 8f3cb18df7f1..4373bd8a5b5f 100644 --- a/tools/include/nolibc/types.h +++ b/tools/include/nolibc/types.h @@ -119,7 +119,7 @@ struct timeval { #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) #define WIFEXITED(status) (((status) & 0x7f) == 0) #define WTERMSIG(status) ((status) & 0x7f) -#define WIFSIGNALED(status) ((status) - 1 < 0xff) +#define WIFSIGNALED(status) ((status) - 1U < 0xff) /* standard exit() codes */ #define EXIT_SUCCESS 0 diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h index a264a20da13d..939d4e05a55d 100644 --- a/tools/include/nolibc/unistd.h +++ b/tools/include/nolibc/unistd.h @@ -52,7 +52,11 @@ int access(const char *path, int amode) static __attribute__((unused)) int _sys_ftruncate64(int fd, uint32_t length0, uint32_t length1) { +#if defined(__NOLIBC_PAD_64BIT_SYSCALL_ARGUMENT_PAIR) + return __nolibc_syscall4(__NR_ftruncate64, fd, 0, length0, length1); +#else return __nolibc_syscall3(__NR_ftruncate64, fd, length0, length1); +#endif } #define _sys_ftruncate64 _sys_ftruncate64 #endif |
