Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nolibc-20251130-for-6.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/nolibc/linux-nolibc

Pull nolibc updates from Thomas Weißschuh:

- Preparations to the use of nolibc in UML:
- Cleanup of sparse warnings
- Library mode without _start()
- More consistency when disabling errno

- Unconditional installation of all architecture support files

- Always 64-bit wide ino_t and off_t

- Various cleanups and bug fixes

* tag 'nolibc-20251130-for-6.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/nolibc/linux-nolibc: (25 commits)
selftests/nolibc: error out on linker warnings
selftests/nolibc: use lld to link loongarch binaries
tools/nolibc: remove more __nolibc_enosys() fallbacks
tools/nolibc: remove now superfluous overflow check in llseek
tools/nolibc: use 64-bit off_t
tools/nolibc: prefer the llseek syscall
tools/nolibc: handle 64-bit off_t for llseek
tools/nolibc: use 64-bit ino_t
tools/nolibc: avoid using plain integer as NULL pointer
tools/nolibc: add support for fchdir()
tools/nolibc: clean up outdated comments in generic arch.h
tools/nolibc: make the "headers" target install all supported archs
tools/nolibc: add the more portable inttypes.h
tools/nolibc: provide the portable sys/select.h
tools/nolibc: add missing memchr() to string.h
tools/nolibc: fix misleading help message regarding installation path
tools/nolibc: add uio.h with readv and writev
tools/nolibc: add option to disable runtime
tools/nolibc: use __fallthrough__ rather than fallthrough
tools/nolibc: implement %m if errno is not defined
...

+290 -163
+9 -13
tools/include/nolibc/Makefile
··· 23 23 Q=@ 24 24 endif 25 25 26 - arch_file := arch-$(ARCH).h 26 + arch_files := arch.h $(wildcard arch-*.h) 27 27 all_files := \ 28 28 compiler.h \ 29 29 crt.h \ ··· 33 33 errno.h \ 34 34 fcntl.h \ 35 35 getopt.h \ 36 + inttypes.h \ 36 37 limits.h \ 37 38 math.h \ 38 39 nolibc.h \ ··· 57 56 sys/random.h \ 58 57 sys/reboot.h \ 59 58 sys/resource.h \ 59 + sys/select.h \ 60 60 sys/stat.h \ 61 61 sys/syscall.h \ 62 62 sys/sysmacros.h \ 63 63 sys/time.h \ 64 64 sys/timerfd.h \ 65 65 sys/types.h \ 66 + sys/uio.h \ 66 67 sys/utsname.h \ 67 68 sys/wait.h \ 68 69 time.h \ ··· 82 79 @echo "Supported targets under nolibc:" 83 80 @echo " all call \"headers\"" 84 81 @echo " clean clean the sysroot" 85 - @echo " headers prepare a sysroot in tools/include/nolibc/sysroot" 82 + @echo " headers prepare a multi-arch sysroot in \$${OUTPUT}sysroot" 86 83 @echo " headers_standalone like \"headers\", and also install kernel headers" 87 84 @echo " help this help" 88 85 @echo "" ··· 93 90 @echo " OUTPUT = $(OUTPUT)" 94 91 @echo "" 95 92 93 + # installs headers for all archs at once. 96 94 headers: 97 - $(Q)mkdir -p $(OUTPUT)sysroot 98 - $(Q)mkdir -p $(OUTPUT)sysroot/include 99 - $(Q)cp --parents $(all_files) $(OUTPUT)sysroot/include/ 100 - $(Q)if [ "$(ARCH)" = "i386" -o "$(ARCH)" = "x86_64" ]; then \ 101 - cat arch-x86.h; \ 102 - elif [ -e "$(arch_file)" ]; then \ 103 - cat $(arch_file); \ 104 - else \ 105 - echo "Fatal: architecture $(ARCH) not yet supported by nolibc." >&2; \ 106 - exit 1; \ 107 - fi > $(OUTPUT)sysroot/include/arch.h 95 + $(Q)mkdir -p "$(OUTPUT)sysroot" 96 + $(Q)mkdir -p "$(OUTPUT)sysroot/include" 97 + $(Q)cp --parents $(arch_files) $(all_files) "$(OUTPUT)sysroot/include/" 108 98 109 99 headers_standalone: headers 110 100 $(Q)$(MAKE) -C $(srctree) headers
+2
tools/include/nolibc/arch-arm.h
··· 184 184 _arg1; \ 185 185 }) 186 186 187 + #ifndef NOLIBC_NO_RUNTIME 187 188 /* startup code */ 188 189 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 189 190 { ··· 194 193 ); 195 194 __nolibc_entrypoint_epilogue(); 196 195 } 196 + #endif /* NOLIBC_NO_RUNTIME */ 197 197 198 198 #endif /* _NOLIBC_ARCH_ARM_H */
+2
tools/include/nolibc/arch-arm64.h
··· 141 141 _arg1; \ 142 142 }) 143 143 144 + #ifndef NOLIBC_NO_RUNTIME 144 145 /* startup code */ 145 146 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 146 147 { ··· 151 150 ); 152 151 __nolibc_entrypoint_epilogue(); 153 152 } 153 + #endif /* NOLIBC_NO_RUNTIME */ 154 154 #endif /* _NOLIBC_ARCH_ARM64_H */
+2
tools/include/nolibc/arch-loongarch.h
··· 142 142 _arg1; \ 143 143 }) 144 144 145 + #ifndef NOLIBC_NO_RUNTIME 145 146 /* startup code */ 146 147 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 147 148 { ··· 152 151 ); 153 152 __nolibc_entrypoint_epilogue(); 154 153 } 154 + #endif /* NOLIBC_NO_RUNTIME */ 155 155 156 156 #endif /* _NOLIBC_ARCH_LOONGARCH_H */
+2
tools/include/nolibc/arch-m68k.h
··· 128 128 _num; \ 129 129 }) 130 130 131 + #ifndef NOLIBC_NO_RUNTIME 131 132 void _start(void); 132 133 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 133 134 { ··· 138 137 ); 139 138 __nolibc_entrypoint_epilogue(); 140 139 } 140 + #endif /* NOLIBC_NO_RUNTIME */ 141 141 142 142 #endif /* _NOLIBC_ARCH_M68K_H */
+2
tools/include/nolibc/arch-mips.h
··· 245 245 246 246 #endif /* _ABIO32 */ 247 247 248 + #ifndef NOLIBC_NO_RUNTIME 248 249 /* startup code, note that it's called __start on MIPS */ 249 250 void __start(void); 250 251 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector __start(void) ··· 267 266 ); 268 267 __nolibc_entrypoint_epilogue(); 269 268 } 269 + #endif /* NOLIBC_NO_RUNTIME */ 270 270 271 271 #endif /* _NOLIBC_ARCH_MIPS_H */
+2
tools/include/nolibc/arch-powerpc.h
··· 183 183 #endif 184 184 #endif /* !__powerpc64__ */ 185 185 186 + #ifndef NOLIBC_NO_RUNTIME 186 187 /* startup code */ 187 188 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 188 189 { ··· 216 215 #endif 217 216 __nolibc_entrypoint_epilogue(); 218 217 } 218 + #endif /* NOLIBC_NO_RUNTIME */ 219 219 220 220 #endif /* _NOLIBC_ARCH_POWERPC_H */
+2
tools/include/nolibc/arch-riscv.h
··· 139 139 _arg1; \ 140 140 }) 141 141 142 + #ifndef NOLIBC_NO_RUNTIME 142 143 /* startup code */ 143 144 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 144 145 { ··· 153 152 ); 154 153 __nolibc_entrypoint_epilogue(); 155 154 } 155 + #endif /* NOLIBC_NO_RUNTIME */ 156 156 157 157 #endif /* _NOLIBC_ARCH_RISCV_H */
+2
tools/include/nolibc/arch-s390.h
··· 139 139 _arg1; \ 140 140 }) 141 141 142 + #ifndef NOLIBC_NO_RUNTIME 142 143 /* startup code */ 143 144 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 144 145 { ··· 151 150 ); 152 151 __nolibc_entrypoint_epilogue(); 153 152 } 153 + #endif /* NOLIBC_NO_RUNTIME */ 154 154 155 155 struct s390_mmap_arg_struct { 156 156 unsigned long addr;
+2
tools/include/nolibc/arch-sh.h
··· 140 140 _ret; \ 141 141 }) 142 142 143 + #ifndef NOLIBC_NO_RUNTIME 143 144 /* startup code */ 144 145 void _start_wrapper(void); 145 146 void __attribute__((weak,noreturn)) __nolibc_entrypoint __no_stack_protector _start_wrapper(void) ··· 159 158 ); 160 159 __nolibc_entrypoint_epilogue(); 161 160 } 161 + #endif /* NOLIBC_NO_RUNTIME */ 162 162 163 163 #endif /* _NOLIBC_ARCH_SH_H */
+2
tools/include/nolibc/arch-sparc.h
··· 152 152 _arg1; \ 153 153 }) 154 154 155 + #ifndef NOLIBC_NO_RUNTIME 155 156 /* startup code */ 156 157 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 157 158 { ··· 170 169 ); 171 170 __nolibc_entrypoint_epilogue(); 172 171 } 172 + #endif /* NOLIBC_NO_RUNTIME */ 173 173 174 174 static pid_t getpid(void); 175 175
+8 -2
tools/include/nolibc/arch-x86.h
··· 157 157 _eax; \ 158 158 }) 159 159 160 + #ifndef NOLIBC_NO_RUNTIME 160 161 /* startup code */ 161 162 /* 162 163 * i386 System V ABI mandates: ··· 177 176 ); 178 177 __nolibc_entrypoint_epilogue(); 179 178 } 179 + #endif /* NOLIBC_NO_RUNTIME */ 180 180 181 181 #else /* !defined(__x86_64__) */ 182 182 ··· 325 323 _ret; \ 326 324 }) 327 325 326 + #ifndef NOLIBC_NO_RUNTIME 328 327 /* startup code */ 329 328 /* 330 329 * x86-64 System V ABI mandates: ··· 343 340 ); 344 341 __nolibc_entrypoint_epilogue(); 345 342 } 343 + #endif /* NOLIBC_NO_RUNTIME */ 346 344 347 345 #define NOLIBC_ARCH_HAS_MEMMOVE 348 346 void *memmove(void *dst, const void *src, size_t len); ··· 355 351 void *memset(void *dst, int c, size_t len); 356 352 357 353 __asm__ ( 358 - ".section .text.nolibc_memmove_memcpy\n" 354 + ".pushsection .text.nolibc_memmove_memcpy\n" 359 355 ".weak memmove\n" 360 356 ".weak memcpy\n" 361 357 "memmove:\n" ··· 375 371 "rep movsb\n\t" 376 372 "cld\n\t" 377 373 "retq\n" 374 + ".popsection\n" 378 375 379 - ".section .text.nolibc_memset\n" 376 + ".pushsection .text.nolibc_memset\n" 380 377 ".weak memset\n" 381 378 "memset:\n" 382 379 "xchgl %eax, %esi\n\t" ··· 386 381 "rep stosb\n\t" 387 382 "popq %rax\n\t" 388 383 "retq\n" 384 + ".popsection\n" 389 385 ); 390 386 391 387 #endif /* !defined(__x86_64__) */
-9
tools/include/nolibc/arch.h
··· 3 3 * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu> 4 4 */ 5 5 6 - /* Below comes the architecture-specific code. For each architecture, we have 7 - * the syscall declarations and the _start code definition. This is the only 8 - * global part. On all architectures the kernel puts everything in the stack 9 - * before jumping to _start just above us, without any return address (_start 10 - * is not a function but an entry point). So at the stack pointer we find argc. 11 - * Then argv[] begins, and ends at the first NULL. Then we have envp which 12 - * starts and ends with a NULL as well. So envp=argv+argc+1. 13 - */ 14 - 15 6 #ifndef _NOLIBC_ARCH_H 16 7 #define _NOLIBC_ARCH_H 17 8
+2 -2
tools/include/nolibc/compiler.h
··· 41 41 # define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector"))) 42 42 #endif /* __nolibc_has_attribute(no_stack_protector) */ 43 43 44 - #if __nolibc_has_attribute(fallthrough) 45 - # define __nolibc_fallthrough do { } while (0); __attribute__((fallthrough)) 44 + #if __nolibc_has_attribute(__fallthrough__) 45 + # define __nolibc_fallthrough do { } while (0); __attribute__((__fallthrough__)) 46 46 #else 47 47 # define __nolibc_fallthrough do { } while (0) 48 48 #endif /* __nolibc_has_attribute(fallthrough) */
+3
tools/include/nolibc/crt.h
··· 7 7 #ifndef _NOLIBC_CRT_H 8 8 #define _NOLIBC_CRT_H 9 9 10 + #ifndef NOLIBC_NO_RUNTIME 11 + 10 12 #include "compiler.h" 11 13 12 14 char **environ __attribute__((weak)); ··· 90 88 exit(exitcode); 91 89 } 92 90 91 + #endif /* NOLIBC_NO_RUNTIME */ 93 92 #endif /* _NOLIBC_CRT_H */
+3 -3
tools/include/nolibc/dirent.h
··· 86 86 * readdir() can only return one entry at a time. 87 87 * Make sure the non-returned ones are not skipped. 88 88 */ 89 - ret = lseek(fd, ldir->d_off, SEEK_SET); 90 - if (ret == -1) 91 - return errno; 89 + ret = sys_lseek(fd, ldir->d_off, SEEK_SET); 90 + if (ret < 0) 91 + return -ret; 92 92 93 93 entry->d_ino = ldir->d_ino; 94 94 /* the destination should always be big enough */
+1 -1
tools/include/nolibc/getopt.h
··· 78 78 return '?'; 79 79 } 80 80 if (optstring[i] == ':') { 81 - optarg = 0; 81 + optarg = NULL; 82 82 if (optstring[i + 1] != ':' || __optpos) { 83 83 optarg = argv[optind++]; 84 84 if (__optpos)
+3
tools/include/nolibc/inttypes.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2 + 3 + #include "nolibc.h"
+2
tools/include/nolibc/nolibc.h
··· 104 104 #include "sys/random.h" 105 105 #include "sys/reboot.h" 106 106 #include "sys/resource.h" 107 + #include "sys/select.h" 107 108 #include "sys/stat.h" 108 109 #include "sys/syscall.h" 109 110 #include "sys/sysmacros.h" 110 111 #include "sys/time.h" 111 112 #include "sys/timerfd.h" 113 + #include "sys/uio.h" 112 114 #include "sys/utsname.h" 113 115 #include "sys/wait.h" 114 116 #include "ctype.h"
+2
tools/include/nolibc/stackprotector.h
··· 9 9 10 10 #include "compiler.h" 11 11 12 + #ifndef NOLIBC_NO_RUNTIME 12 13 #if defined(_NOLIBC_STACKPROTECTOR) 13 14 14 15 #include "sys.h" ··· 50 49 #else /* !defined(_NOLIBC_STACKPROTECTOR) */ 51 50 static void __stack_chk_init(void) {} 52 51 #endif /* defined(_NOLIBC_STACKPROTECTOR) */ 52 + #endif /* NOLIBC_NO_RUNTIME */ 53 53 54 54 #endif /* _NOLIBC_STACKPROTECTOR_H */
+2 -2
tools/include/nolibc/std.h
··· 20 20 21 21 /* those are commonly provided by sys/types.h */ 22 22 typedef unsigned int dev_t; 23 - typedef unsigned long ino_t; 23 + typedef uint64_t ino_t; 24 24 typedef unsigned int mode_t; 25 25 typedef signed int pid_t; 26 26 typedef unsigned int uid_t; 27 27 typedef unsigned int gid_t; 28 28 typedef unsigned long nlink_t; 29 - typedef signed long off_t; 29 + typedef int64_t off_t; 30 30 typedef signed long blksize_t; 31 31 typedef signed long blkcnt_t; 32 32 typedef __kernel_time_t time_t;
+8 -2
tools/include/nolibc/stdio.h
··· 321 321 if (!outstr) 322 322 outstr="(null)"; 323 323 } 324 - #ifndef NOLIBC_IGNORE_ERRNO 325 324 else if (c == 'm') { 325 + #ifdef NOLIBC_IGNORE_ERRNO 326 + outstr = "unknown error"; 327 + #else 326 328 outstr = strerror(errno); 327 - } 328 329 #endif /* NOLIBC_IGNORE_ERRNO */ 330 + } 329 331 else if (c == '%') { 330 332 /* queue it verbatim */ 331 333 continue; ··· 602 600 static __attribute__((unused)) 603 601 void perror(const char *msg) 604 602 { 603 + #ifdef NOLIBC_IGNORE_ERRNO 604 + fprintf(stderr, "%s%sunknown error\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : ""); 605 + #else 605 606 fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno); 607 + #endif 606 608 } 607 609 608 610 static __attribute__((unused))
+2
tools/include/nolibc/stdlib.h
··· 100 100 munmap(heap, heap->len); 101 101 } 102 102 103 + #ifndef NOLIBC_NO_RUNTIME 103 104 /* getenv() tries to find the environment variable named <name> in the 104 105 * environment array pointed to by global variable "environ" which must be 105 106 * declared as a char **, and must be terminated by a NULL (it is recommended ··· 123 122 } 124 123 return NULL; 125 124 } 125 + #endif /* NOLIBC_NO_RUNTIME */ 126 126 127 127 static __attribute__((unused)) 128 128 void *malloc(size_t len)
+15
tools/include/nolibc/string.h
··· 93 93 } 94 94 #endif /* #ifndef NOLIBC_ARCH_HAS_MEMSET */ 95 95 96 + #ifndef NOLIBC_ARCH_HAS_MEMCHR 97 + static __attribute__((unused)) 98 + void *memchr(const void *s, int c, size_t len) 99 + { 100 + char *p = (char *)s; 101 + 102 + while (len--) { 103 + if (*p == (char)c) 104 + return p; 105 + p++; 106 + } 107 + return NULL; 108 + } 109 + #endif /* #ifndef NOLIBC_ARCH_HAS_MEMCHR */ 110 + 96 111 static __attribute__((unused)) 97 112 char *strchr(const char *s, int c) 98 113 {
+20 -54
tools/include/nolibc/sys.h
··· 106 106 void *sbrk(intptr_t inc) 107 107 { 108 108 /* first call to find current end */ 109 - void *ret = sys_brk(0); 109 + void *ret = sys_brk(NULL); 110 110 111 111 if (ret && sys_brk(ret + inc) == ret + inc) 112 112 return ret + inc; ··· 118 118 119 119 /* 120 120 * int chdir(const char *path); 121 + * int fchdir(int fildes); 121 122 */ 122 123 123 124 static __attribute__((unused)) ··· 131 130 int chdir(const char *path) 132 131 { 133 132 return __sysret(sys_chdir(path)); 133 + } 134 + 135 + static __attribute__((unused)) 136 + int sys_fchdir(int fildes) 137 + { 138 + return my_syscall1(__NR_fchdir, fildes); 139 + } 140 + 141 + static __attribute__((unused)) 142 + int fchdir(int fildes) 143 + { 144 + return __sysret(sys_fchdir(fildes)); 134 145 } 135 146 136 147 ··· 525 512 return sys_gettid(); 526 513 } 527 514 515 + #ifndef NOLIBC_NO_RUNTIME 528 516 static unsigned long getauxval(unsigned long key); 529 517 530 518 /* ··· 537 523 { 538 524 return __sysret((int)getauxval(AT_PAGESZ) ?: -ENOENT); 539 525 } 540 - 526 + #endif /* NOLIBC_NO_RUNTIME */ 541 527 542 528 /* 543 529 * uid_t getuid(void); ··· 605 591 static __attribute__((unused)) 606 592 off_t sys_lseek(int fd, off_t offset, int whence) 607 593 { 608 - #if defined(__NR_lseek) 609 - return my_syscall3(__NR_lseek, fd, offset, whence); 610 - #else 594 + #if defined(__NR_llseek) 611 595 __kernel_loff_t loff = 0; 612 596 off_t result; 613 597 int ret; 614 598 615 - /* Only exists on 32bit where nolibc off_t is also 32bit */ 616 - ret = my_syscall5(__NR_llseek, fd, 0, offset, &loff, whence); 599 + ret = my_syscall5(__NR_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence); 617 600 if (ret < 0) 618 601 result = ret; 619 - else if (loff != (off_t)loff) 620 - result = -EOVERFLOW; 621 602 else 622 603 result = loff; 623 604 624 605 return result; 606 + #else 607 + return my_syscall3(__NR_lseek, fd, offset, whence); 625 608 #endif 626 609 } 627 610 ··· 763 752 int sched_yield(void) 764 753 { 765 754 return __sysret(sys_sched_yield()); 766 - } 767 - 768 - 769 - /* 770 - * int select(int nfds, fd_set *read_fds, fd_set *write_fds, 771 - * fd_set *except_fds, struct timeval *timeout); 772 - */ 773 - 774 - static __attribute__((unused)) 775 - int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) 776 - { 777 - #if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect) 778 - struct sel_arg_struct { 779 - unsigned long n; 780 - fd_set *r, *w, *e; 781 - struct timeval *t; 782 - } arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout }; 783 - return my_syscall1(__NR_select, &arg); 784 - #elif defined(__NR__newselect) 785 - return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout); 786 - #elif defined(__NR_select) 787 - return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout); 788 - #elif defined(__NR_pselect6) 789 - struct timespec t; 790 - 791 - if (timeout) { 792 - t.tv_sec = timeout->tv_sec; 793 - t.tv_nsec = timeout->tv_usec * 1000; 794 - } 795 - return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 796 - #else 797 - struct __kernel_timespec t; 798 - 799 - if (timeout) { 800 - t.tv_sec = timeout->tv_sec; 801 - t.tv_nsec = timeout->tv_usec * 1000; 802 - } 803 - return my_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 804 - #endif 805 - } 806 - 807 - static __attribute__((unused)) 808 - int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) 809 - { 810 - return __sysret(sys_select(nfds, rfds, wfds, efds, timeout)); 811 755 } 812 756 813 757
+3
tools/include/nolibc/sys/auxv.h
··· 10 10 #ifndef _NOLIBC_SYS_AUXV_H 11 11 #define _NOLIBC_SYS_AUXV_H 12 12 13 + #ifndef NOLIBC_NO_RUNTIME 14 + 13 15 #include "../crt.h" 14 16 15 17 static __attribute__((unused)) ··· 40 38 return ret; 41 39 } 42 40 41 + #endif /* NOLIBC_NO_RUNTIME */ 43 42 #endif /* _NOLIBC_SYS_AUXV_H */
-5
tools/include/nolibc/sys/mman.h
··· 31 31 } 32 32 #endif 33 33 34 - /* Note that on Linux, MAP_FAILED is -1 so we can use the generic __sysret() 35 - * which returns -1 upon error and still satisfy user land that checks for 36 - * MAP_FAILED. 37 - */ 38 - 39 34 static __attribute__((unused)) 40 35 void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) 41 36 {
+1 -1
tools/include/nolibc/sys/reboot.h
··· 28 28 static __attribute__((unused)) 29 29 int reboot(int cmd) 30 30 { 31 - return __sysret(sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0)); 31 + return __sysret(sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, NULL)); 32 32 } 33 33 34 34 #endif /* _NOLIBC_SYS_REBOOT_H */
+103
tools/include/nolibc/sys/select.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2 + 3 + #include "../nolibc.h" 4 + 5 + #ifndef _NOLIBC_SYS_SELECT_H 6 + #define _NOLIBC_SYS_SELECT_H 7 + 8 + #include <linux/time.h> 9 + #include <linux/unistd.h> 10 + 11 + /* commonly an fd_set represents 256 FDs */ 12 + #ifndef FD_SETSIZE 13 + #define FD_SETSIZE 256 14 + #endif 15 + 16 + #define FD_SETIDXMASK (8 * sizeof(unsigned long)) 17 + #define FD_SETBITMASK (8 * sizeof(unsigned long)-1) 18 + 19 + /* for select() */ 20 + typedef struct { 21 + unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK]; 22 + } fd_set; 23 + 24 + #define FD_CLR(fd, set) do { \ 25 + fd_set *__set = (set); \ 26 + int __fd = (fd); \ 27 + if (__fd >= 0) \ 28 + __set->fds[__fd / FD_SETIDXMASK] &= \ 29 + ~(1U << (__fd & FD_SETBITMASK)); \ 30 + } while (0) 31 + 32 + #define FD_SET(fd, set) do { \ 33 + fd_set *__set = (set); \ 34 + int __fd = (fd); \ 35 + if (__fd >= 0) \ 36 + __set->fds[__fd / FD_SETIDXMASK] |= \ 37 + 1 << (__fd & FD_SETBITMASK); \ 38 + } while (0) 39 + 40 + #define FD_ISSET(fd, set) ({ \ 41 + fd_set *__set = (set); \ 42 + int __fd = (fd); \ 43 + int __r = 0; \ 44 + if (__fd >= 0) \ 45 + __r = !!(__set->fds[__fd / FD_SETIDXMASK] & \ 46 + 1U << (__fd & FD_SETBITMASK)); \ 47 + __r; \ 48 + }) 49 + 50 + #define FD_ZERO(set) do { \ 51 + fd_set *__set = (set); \ 52 + int __idx; \ 53 + int __size = (FD_SETSIZE+FD_SETBITMASK) / FD_SETIDXMASK;\ 54 + for (__idx = 0; __idx < __size; __idx++) \ 55 + __set->fds[__idx] = 0; \ 56 + } while (0) 57 + 58 + /* 59 + * int select(int nfds, fd_set *read_fds, fd_set *write_fds, 60 + * fd_set *except_fds, struct timeval *timeout); 61 + */ 62 + 63 + static __attribute__((unused)) 64 + int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) 65 + { 66 + #if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect) 67 + struct sel_arg_struct { 68 + unsigned long n; 69 + fd_set *r, *w, *e; 70 + struct timeval *t; 71 + } arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout }; 72 + return my_syscall1(__NR_select, &arg); 73 + #elif defined(__NR__newselect) 74 + return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout); 75 + #elif defined(__NR_select) 76 + return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout); 77 + #elif defined(__NR_pselect6) 78 + struct timespec t; 79 + 80 + if (timeout) { 81 + t.tv_sec = timeout->tv_sec; 82 + t.tv_nsec = timeout->tv_usec * 1000; 83 + } 84 + return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 85 + #else 86 + struct __kernel_timespec t; 87 + 88 + if (timeout) { 89 + t.tv_sec = timeout->tv_sec; 90 + t.tv_nsec = timeout->tv_usec * 1000; 91 + } 92 + return my_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 93 + #endif 94 + } 95 + 96 + static __attribute__((unused)) 97 + int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) 98 + { 99 + return __sysret(sys_select(nfds, rfds, wfds, efds, timeout)); 100 + } 101 + 102 + 103 + #endif /* _NOLIBC_SYS_SELECT_H */
+49
tools/include/nolibc/sys/uio.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2 + /* 3 + * uio for NOLIBC 4 + * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu> 5 + * Copyright (C) 2025 Intel Corporation 6 + */ 7 + 8 + /* make sure to include all global symbols */ 9 + #include "../nolibc.h" 10 + 11 + #ifndef _NOLIBC_SYS_UIO_H 12 + #define _NOLIBC_SYS_UIO_H 13 + 14 + #include "../sys.h" 15 + #include <linux/uio.h> 16 + 17 + 18 + /* 19 + * ssize_t readv(int fd, const struct iovec *iovec, int count); 20 + */ 21 + static __attribute__((unused)) 22 + ssize_t sys_readv(int fd, const struct iovec *iovec, int count) 23 + { 24 + return my_syscall3(__NR_readv, fd, iovec, count); 25 + } 26 + 27 + static __attribute__((unused)) 28 + ssize_t readv(int fd, const struct iovec *iovec, int count) 29 + { 30 + return __sysret(sys_readv(fd, iovec, count)); 31 + } 32 + 33 + /* 34 + * ssize_t writev(int fd, const struct iovec *iovec, int count); 35 + */ 36 + static __attribute__((unused)) 37 + ssize_t sys_writev(int fd, const struct iovec *iovec, int count) 38 + { 39 + return my_syscall3(__NR_writev, fd, iovec, count); 40 + } 41 + 42 + static __attribute__((unused)) 43 + ssize_t writev(int fd, const struct iovec *iovec, int count) 44 + { 45 + return __sysret(sys_writev(fd, iovec, count)); 46 + } 47 + 48 + 49 + #endif /* _NOLIBC_SYS_UIO_H */
+12 -6
tools/include/nolibc/sys/wait.h
··· 65 65 66 66 switch (info.si_code) { 67 67 case 0: 68 - *status = 0; 68 + if (status) 69 + *status = 0; 69 70 break; 70 71 case CLD_EXITED: 71 - *status = (info.si_status & 0xff) << 8; 72 + if (status) 73 + *status = (info.si_status & 0xff) << 8; 72 74 break; 73 75 case CLD_KILLED: 74 - *status = info.si_status & 0x7f; 76 + if (status) 77 + *status = info.si_status & 0x7f; 75 78 break; 76 79 case CLD_DUMPED: 77 - *status = (info.si_status & 0x7f) | 0x80; 80 + if (status) 81 + *status = (info.si_status & 0x7f) | 0x80; 78 82 break; 79 83 case CLD_STOPPED: 80 84 case CLD_TRAPPED: 81 - *status = (info.si_status << 8) + 0x7f; 85 + if (status) 86 + *status = (info.si_status << 8) + 0x7f; 82 87 break; 83 88 case CLD_CONTINUED: 84 - *status = 0xffff; 89 + if (status) 90 + *status = 0xffff; 85 91 break; 86 92 default: 87 93 return -1;
+4 -12
tools/include/nolibc/time.h
··· 89 89 { 90 90 #if defined(__NR_clock_settime) 91 91 return my_syscall2(__NR_clock_settime, clockid, tp); 92 - #elif defined(__NR_clock_settime64) 92 + #else 93 93 struct __kernel_timespec ktp; 94 94 95 95 __nolibc_timespec_user_to_kernel(tp, &ktp); 96 96 return my_syscall2(__NR_clock_settime64, clockid, &ktp); 97 - #else 98 - return __nolibc_enosys(__func__, clockid, tp); 99 97 #endif 100 98 } 101 99 ··· 109 111 { 110 112 #if defined(__NR_clock_nanosleep) 111 113 return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp); 112 - #elif defined(__NR_clock_nanosleep_time64) 114 + #else 113 115 struct __kernel_timespec krqtp, krmtp; 114 116 int ret; 115 117 ··· 118 120 if (rmtp) 119 121 __nolibc_timespec_kernel_to_user(&krmtp, rmtp); 120 122 return ret; 121 - #else 122 - return __nolibc_enosys(__func__, clockid, flags, rqtp, rmtp); 123 123 #endif 124 124 } 125 125 ··· 191 195 { 192 196 #if defined(__NR_timer_gettime) 193 197 return my_syscall2(__NR_timer_gettime, timerid, curr_value); 194 - #elif defined(__NR_timer_gettime64) 198 + #else 195 199 struct __kernel_itimerspec kcurr_value; 196 200 int ret; 197 201 ··· 199 203 __nolibc_timespec_kernel_to_user(&kcurr_value.it_interval, &curr_value->it_interval); 200 204 __nolibc_timespec_kernel_to_user(&kcurr_value.it_value, &curr_value->it_value); 201 205 return ret; 202 - #else 203 - return __nolibc_enosys(__func__, timerid, curr_value); 204 206 #endif 205 207 } 206 208 ··· 214 220 { 215 221 #if defined(__NR_timer_settime) 216 222 return my_syscall4(__NR_timer_settime, timerid, flags, new_value, old_value); 217 - #elif defined(__NR_timer_settime64) 223 + #else 218 224 struct __kernel_itimerspec knew_value, kold_value; 219 225 int ret; 220 226 ··· 226 232 __nolibc_timespec_kernel_to_user(&kold_value.it_value, &old_value->it_value); 227 233 } 228 234 return ret; 229 - #else 230 - return __nolibc_enosys(__func__, timerid, flags, new_value, old_value); 231 235 #endif 232 236 } 233 237
-47
tools/include/nolibc/types.h
··· 70 70 #define DT_LNK 0xa 71 71 #define DT_SOCK 0xc 72 72 73 - /* commonly an fd_set represents 256 FDs */ 74 - #ifndef FD_SETSIZE 75 - #define FD_SETSIZE 256 76 - #endif 77 - 78 73 /* PATH_MAX and MAXPATHLEN are often used and found with plenty of different 79 74 * values. 80 75 */ ··· 109 114 /* standard exit() codes */ 110 115 #define EXIT_SUCCESS 0 111 116 #define EXIT_FAILURE 1 112 - 113 - #define FD_SETIDXMASK (8 * sizeof(unsigned long)) 114 - #define FD_SETBITMASK (8 * sizeof(unsigned long)-1) 115 - 116 - /* for select() */ 117 - typedef struct { 118 - unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK]; 119 - } fd_set; 120 - 121 - #define FD_CLR(fd, set) do { \ 122 - fd_set *__set = (set); \ 123 - int __fd = (fd); \ 124 - if (__fd >= 0) \ 125 - __set->fds[__fd / FD_SETIDXMASK] &= \ 126 - ~(1U << (__fd & FD_SETBITMASK)); \ 127 - } while (0) 128 - 129 - #define FD_SET(fd, set) do { \ 130 - fd_set *__set = (set); \ 131 - int __fd = (fd); \ 132 - if (__fd >= 0) \ 133 - __set->fds[__fd / FD_SETIDXMASK] |= \ 134 - 1 << (__fd & FD_SETBITMASK); \ 135 - } while (0) 136 - 137 - #define FD_ISSET(fd, set) ({ \ 138 - fd_set *__set = (set); \ 139 - int __fd = (fd); \ 140 - int __r = 0; \ 141 - if (__fd >= 0) \ 142 - __r = !!(__set->fds[__fd / FD_SETIDXMASK] & \ 143 - 1U << (__fd & FD_SETBITMASK)); \ 144 - __r; \ 145 - }) 146 - 147 - #define FD_ZERO(set) do { \ 148 - fd_set *__set = (set); \ 149 - int __idx; \ 150 - int __size = (FD_SETSIZE+FD_SETBITMASK) / FD_SETIDXMASK;\ 151 - for (__idx = 0; __idx < __size; __idx++) \ 152 - __set->fds[__idx] = 0; \ 153 - } while (0) 154 117 155 118 /* for getdents64() */ 156 119 struct linux_dirent64 {
+3 -3
tools/include/nolibc/unistd.h
··· 54 54 { 55 55 struct timeval my_timeval = { msecs / 1000, (msecs % 1000) * 1000 }; 56 56 57 - if (sys_select(0, 0, 0, 0, &my_timeval) < 0) 57 + if (sys_select(0, NULL, NULL, NULL, &my_timeval) < 0) 58 58 return (my_timeval.tv_sec * 1000) + 59 59 (my_timeval.tv_usec / 1000) + 60 60 !!(my_timeval.tv_usec % 1000); ··· 67 67 { 68 68 struct timeval my_timeval = { seconds, 0 }; 69 69 70 - if (sys_select(0, 0, 0, 0, &my_timeval) < 0) 70 + if (sys_select(0, NULL, NULL, NULL, &my_timeval) < 0) 71 71 return my_timeval.tv_sec + !!my_timeval.tv_usec; 72 72 else 73 73 return 0; ··· 78 78 { 79 79 struct timeval my_timeval = { usecs / 1000000, usecs % 1000000 }; 80 80 81 - return sys_select(0, 0, 0, 0, &my_timeval); 81 + return sys_select(0, NULL, NULL, NULL, &my_timeval); 82 82 } 83 83 84 84 static __attribute__((unused))
+1
tools/testing/selftests/nolibc/Makefile.nolibc
··· 225 225 CFLAGS_mipsn32be = -EB -mabi=n32 -march=mips64r6 226 226 CFLAGS_mips64le = -EL -mabi=64 -march=mips64r6 227 227 CFLAGS_mips64be = -EB -mabi=64 -march=mips64r2 228 + CFLAGS_loongarch = $(if $(LLVM),-fuse-ld=lld) 228 229 CFLAGS_sparc32 = $(call cc-option,-m32) 229 230 CFLAGS_sh4 = -ml -m4 230 231 ifeq ($(origin XARCH),command line)
+13
tools/testing/selftests/nolibc/nolibc-test.c
··· 25 25 #include <sys/sysmacros.h> 26 26 #include <sys/time.h> 27 27 #include <sys/timerfd.h> 28 + #include <sys/uio.h> 28 29 #include <sys/utsname.h> 29 30 #include <sys/wait.h> 30 31 #include <dirent.h> ··· 1283 1282 int proc; 1284 1283 int test; 1285 1284 int tmp; 1285 + struct iovec iov_one = { 1286 + .iov_base = &tmp, 1287 + .iov_len = 1, 1288 + }; 1286 1289 int ret = 0; 1287 1290 void *p1, *p2; 1288 1291 int has_gettid = 1; ··· 1348 1343 CASE_TEST(dup3_0); tmp = dup3(0, 100, 0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break; 1349 1344 CASE_TEST(dup3_m1); tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break; 1350 1345 CASE_TEST(execve_root); EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break; 1346 + CASE_TEST(fchdir_stdin); EXPECT_SYSER(1, fchdir(STDIN_FILENO), -1, ENOTDIR); break; 1347 + CASE_TEST(fchdir_badfd); EXPECT_SYSER(1, fchdir(-1), -1, EBADF); break; 1351 1348 CASE_TEST(file_stream); EXPECT_SYSZR(1, test_file_stream()); break; 1352 1349 CASE_TEST(fork); EXPECT_SYSZR(1, test_fork(FORK_STANDARD)); break; 1353 1350 CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break; ··· 1402 1395 CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break; 1403 1396 CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break; 1404 1397 CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break; 1398 + CASE_TEST(readv_badf); EXPECT_SYSER(1, readv(-1, &iov_one, 1), -1, EBADF); break; 1399 + CASE_TEST(readv_zero); EXPECT_SYSZR(1, readv(1, NULL, 0)); break; 1400 + CASE_TEST(writev_badf); EXPECT_SYSER(1, writev(-1, &iov_one, 1), -1, EBADF); break; 1401 + CASE_TEST(writev_zero); EXPECT_SYSZR(1, writev(1, NULL, 0)); break; 1405 1402 CASE_TEST(syscall_noargs); EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break; 1406 1403 CASE_TEST(syscall_args); EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break; 1407 1404 CASE_TEST(namespace); EXPECT_SYSZR(euid0 && proc, test_namespace()); break; ··· 1551 1540 CASE_TEST(abs); EXPECT_EQ(1, abs(-10), 10); break; 1552 1541 CASE_TEST(abs_noop); EXPECT_EQ(1, abs(10), 10); break; 1553 1542 CASE_TEST(difftime); EXPECT_ZR(1, test_difftime()); break; 1543 + CASE_TEST(memchr_foobar6_o); EXPECT_STREQ(1, memchr("foobar", 'o', 6), "oobar"); break; 1544 + CASE_TEST(memchr_foobar3_b); EXPECT_STRZR(1, memchr("foobar", 'b', 3)); break; 1554 1545 1555 1546 case __LINE__: 1556 1547 return ret; /* must be last */
+1 -1
tools/testing/selftests/nolibc/run-tests.sh
··· 169 169 cross_compile=$(realpath "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/${ct_arch}-${ct_abi}-") 170 170 build_dir="${build_location}/${arch}" 171 171 if [ "$werror" -ne 0 ]; then 172 - CFLAGS_EXTRA="$CFLAGS_EXTRA -Werror" 172 + CFLAGS_EXTRA="$CFLAGS_EXTRA -Werror -Wl,--fatal-warnings" 173 173 fi 174 174 MAKE=(make -f Makefile.nolibc -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" LLVM="${llvm}" O="${build_dir}") 175 175