diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-14 17:13:09 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-14 17:13:09 -0700 |
| commit | ee60c510fb3468ec6fab98419218c4e7b37e2ca3 (patch) | |
| tree | a7748768691d1accaf7e2c4522df58a7c8bf969d | |
| parent | 3203a08c1266689c204fb8f10d6bb5186921fce2 (diff) | |
| parent | b070dc36291fec966ad915f80a4f239b5c70c290 (diff) | |
Merge tag 'nolibc-20260412-for-7.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/nolibc/linux-nolibc
Pull nolibc updates from Thomas Weißschuh:
- Many new features and optimizations to printf()
- Rename non-standard symbols to avoid collisions with application code
- Support for byteswap.h, endian.h, err.h and asprintf()
- 64-bit dev_t
- Smaller cleanups and fixes to the code and build system
* tag 'nolibc-20260412-for-7.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/nolibc/linux-nolibc: (61 commits)
selftests/nolibc: use gcc 15
tools/nolibc: support UBSAN on gcc
tools/nolibc: create __nolibc_no_sanitize_ubsan
selftests/nolibc: don't skip tests for unimplemented syscalls anymore
selftests/nolibc: explicitly handle ENOSYS from ptrace()
tools/nolibc: add byteorder conversions
tools/nolibc: add the _syscall() macro
tools/nolibc: move the call to __sysret() into syscall()
tools/nolibc: rename the internal macros used in syscall()
selftests/nolibc: only use libgcc when really necessary
selftests/nolibc: test the memory allocator
tools/nolibc: check for overflow in calloc() without divisions
tools/nolibc: add support for asprintf()
tools/nolibc: use __builtin_offsetof()
tools/nolibc: use makedev() in fstatat()
tools/nolibc: handle all major and minor numbers in makedev() and friends
tools/nolibc: make dev_t 64 bits wide
tools/nolibc: move the logic of makedev() and friends into functions
selftests/nolibc: add a test for stat().st_rdev
selftests/nolibc: add some tests for makedev() and friends
...
55 files changed, 1453 insertions, 757 deletions
diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile index 1958dda98895..7455097cff69 100644 --- a/tools/include/nolibc/Makefile +++ b/tools/include/nolibc/Makefile @@ -17,19 +17,17 @@ endif # it defaults to this nolibc directory. OUTPUT ?= $(CURDIR)/ -ifeq ($(V),1) -Q= -else -Q=@ -endif - -arch_files := arch.h $(wildcard arch-*.h) +architectures := arm arm64 loongarch m68k mips powerpc riscv s390 sh sparc x86 +arch_files := arch.h $(addsuffix .h, $(addprefix arch-, $(architectures))) all_files := \ + byteswap.h \ compiler.h \ crt.h \ ctype.h \ dirent.h \ elf.h \ + endian.h \ + err.h \ errno.h \ fcntl.h \ getopt.h \ @@ -96,12 +94,10 @@ help: # installs headers for all archs at once. headers: - $(Q)mkdir -p "$(OUTPUT)sysroot" $(Q)mkdir -p "$(OUTPUT)sysroot/include" $(Q)cp --parents $(arch_files) $(all_files) "$(OUTPUT)sysroot/include/" headers_standalone: headers - $(Q)$(MAKE) -C $(srctree) headers $(Q)$(MAKE) -C $(srctree) headers_install INSTALL_HDR_PATH=$(OUTPUT)sysroot CFLAGS_s390 := -m64 diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h index 251c42579028..a4d3a777a051 100644 --- a/tools/include/nolibc/arch-arm.h +++ b/tools/include/nolibc/arch-arm.h @@ -50,7 +50,7 @@ #endif /* end THUMB */ -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__(_NOLIBC_SYSCALL_REG) = (num); \ register long _arg1 __asm__ ("r0"); \ @@ -67,7 +67,7 @@ _arg1; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__(_NOLIBC_SYSCALL_REG) = (num); \ register long _arg1 __asm__ ("r0") = (long)(arg1); \ @@ -84,7 +84,7 @@ _arg1; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__(_NOLIBC_SYSCALL_REG) = (num); \ register long _arg1 __asm__ ("r0") = (long)(arg1); \ @@ -102,7 +102,7 @@ _arg1; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__(_NOLIBC_SYSCALL_REG) = (num); \ register long _arg1 __asm__ ("r0") = (long)(arg1); \ @@ -121,7 +121,7 @@ _arg1; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__(_NOLIBC_SYSCALL_REG) = (num); \ register long _arg1 __asm__ ("r0") = (long)(arg1); \ @@ -141,7 +141,7 @@ _arg1; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__(_NOLIBC_SYSCALL_REG) = (num); \ register long _arg1 __asm__ ("r0") = (long)(arg1); \ @@ -162,7 +162,7 @@ _arg1; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__(_NOLIBC_SYSCALL_REG) = (num); \ register long _arg1 __asm__ ("r0") = (long)(arg1); \ diff --git a/tools/include/nolibc/arch-arm64.h b/tools/include/nolibc/arch-arm64.h index 080a55a7144e..28b3c7536ad6 100644 --- a/tools/include/nolibc/arch-arm64.h +++ b/tools/include/nolibc/arch-arm64.h @@ -22,7 +22,7 @@ * don't have to experience issues with register constraints. */ -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__ ("x8") = (num); \ register long _arg1 __asm__ ("x0"); \ @@ -36,7 +36,7 @@ _arg1; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__ ("x8") = (num); \ register long _arg1 __asm__ ("x0") = (long)(arg1); \ @@ -51,7 +51,7 @@ _arg1; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__ ("x8") = (num); \ register long _arg1 __asm__ ("x0") = (long)(arg1); \ @@ -67,7 +67,7 @@ _arg1; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__ ("x8") = (num); \ register long _arg1 __asm__ ("x0") = (long)(arg1); \ @@ -84,7 +84,7 @@ _arg1; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__ ("x8") = (num); \ register long _arg1 __asm__ ("x0") = (long)(arg1); \ @@ -102,7 +102,7 @@ _arg1; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("x8") = (num); \ register long _arg1 __asm__ ("x0") = (long)(arg1); \ @@ -121,7 +121,7 @@ _arg1; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("x8") = (num); \ register long _arg1 __asm__ ("x0") = (long)(arg1); \ diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h index c894176c3f89..86fb34bbf185 100644 --- a/tools/include/nolibc/arch-loongarch.h +++ b/tools/include/nolibc/arch-loongarch.h @@ -24,7 +24,7 @@ #define _NOLIBC_SYSCALL_CLOBBERLIST \ "memory", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8" -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0"); \ @@ -38,7 +38,7 @@ _arg1; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -52,7 +52,7 @@ _arg1; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -68,7 +68,7 @@ _arg1; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -85,7 +85,7 @@ _arg1; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -103,7 +103,7 @@ _arg1; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -122,7 +122,7 @@ _arg1; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ diff --git a/tools/include/nolibc/arch-m68k.h b/tools/include/nolibc/arch-m68k.h index 2a4fbada5e79..81d34c219a42 100644 --- a/tools/include/nolibc/arch-m68k.h +++ b/tools/include/nolibc/arch-m68k.h @@ -15,7 +15,7 @@ #define _NOLIBC_SYSCALL_CLOBBERLIST "memory" -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__ ("d0") = (num); \ \ @@ -28,7 +28,7 @@ _num; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__ ("d0") = (num); \ register long _arg1 __asm__ ("d1") = (long)(arg1); \ @@ -42,7 +42,7 @@ _num; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__ ("d0") = (num); \ register long _arg1 __asm__ ("d1") = (long)(arg1); \ @@ -57,7 +57,7 @@ _num; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__ ("d0") = (num); \ register long _arg1 __asm__ ("d1") = (long)(arg1); \ @@ -73,7 +73,7 @@ _num; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__ ("d0") = (num); \ register long _arg1 __asm__ ("d1") = (long)(arg1); \ @@ -90,7 +90,7 @@ _num; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("d0") = (num); \ register long _arg1 __asm__ ("d1") = (long)(arg1); \ @@ -108,7 +108,7 @@ _num; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("d0") = (num); \ register long _arg1 __asm__ ("d1") = (long)(arg1); \ diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h index a72506ceec6b..bb9d580ea1b1 100644 --- a/tools/include/nolibc/arch-mips.h +++ b/tools/include/nolibc/arch-mips.h @@ -39,11 +39,19 @@ * - stack is 16-byte aligned */ +#if !defined(__mips_isa_rev) || __mips_isa_rev < 6 +#define _NOLIBC_SYSCALL_CLOBBER_HI_LO "hi", "lo" +#else +#define _NOLIBC_SYSCALL_CLOBBER_HI_LO "$0" +#endif + #if defined(_ABIO32) #define _NOLIBC_SYSCALL_CLOBBERLIST \ - "memory", "cc", "at", "v1", "hi", "lo", \ - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9" + "memory", "cc", "at", "v1", \ + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", \ + _NOLIBC_SYSCALL_CLOBBER_HI_LO + #define _NOLIBC_SYSCALL_STACK_RESERVE "addiu $sp, $sp, -32\n" #define _NOLIBC_SYSCALL_STACK_UNRESERVE "addiu $sp, $sp, 32\n" @@ -52,14 +60,15 @@ /* binutils, GCC and clang disagree about register aliases, use numbers instead. */ #define _NOLIBC_SYSCALL_CLOBBERLIST \ "memory", "cc", "at", "v1", \ - "10", "11", "12", "13", "14", "15", "24", "25" + "10", "11", "12", "13", "14", "15", "24", "25", \ + _NOLIBC_SYSCALL_CLOBBER_HI_LO #define _NOLIBC_SYSCALL_STACK_RESERVE #define _NOLIBC_SYSCALL_STACK_UNRESERVE #endif /* _ABIO32 */ -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg4 __asm__ ("a3"); \ @@ -75,7 +84,7 @@ _arg4 ? -_num : _num; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -93,7 +102,7 @@ _arg4 ? -_num : _num; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -112,7 +121,7 @@ _arg4 ? -_num : _num; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -132,7 +141,7 @@ _arg4 ? -_num : _num; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -154,7 +163,7 @@ #if defined(_ABIO32) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -176,7 +185,7 @@ _arg4 ? -_num : _num; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -203,7 +212,7 @@ #else /* _ABIN32 || _ABI64 */ -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg1 __asm__ ("$4") = (long)(arg1); \ @@ -222,7 +231,7 @@ _arg4 ? -_num : _num; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("v0") = (num); \ register long _arg1 __asm__ ("$4") = (long)(arg1); \ diff --git a/tools/include/nolibc/arch-powerpc.h b/tools/include/nolibc/arch-powerpc.h index e0c7e0b81f7c..ef878868aa4a 100644 --- a/tools/include/nolibc/arch-powerpc.h +++ b/tools/include/nolibc/arch-powerpc.h @@ -25,7 +25,7 @@ #define _NOLIBC_SYSCALL_CLOBBERLIST \ "memory", "cr0", "r12", "r11", "r10", "r9" -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _ret __asm__ ("r3"); \ register long _num __asm__ ("r0") = (num); \ @@ -42,7 +42,7 @@ _ret; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _ret __asm__ ("r3"); \ register long _num __asm__ ("r0") = (num); \ @@ -61,7 +61,7 @@ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _ret __asm__ ("r3"); \ register long _num __asm__ ("r0") = (num); \ @@ -81,7 +81,7 @@ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _ret __asm__ ("r3"); \ register long _num __asm__ ("r0") = (num); \ @@ -102,7 +102,7 @@ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _ret __asm__ ("r3"); \ register long _num __asm__ ("r0") = (num); \ @@ -125,7 +125,7 @@ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _ret __asm__ ("r3"); \ register long _num __asm__ ("r0") = (num); \ @@ -148,7 +148,7 @@ _ret; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _ret __asm__ ("r3"); \ register long _num __asm__ ("r0") = (num); \ diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h index 1c00cacf57e1..386ebb9f5b08 100644 --- a/tools/include/nolibc/arch-riscv.h +++ b/tools/include/nolibc/arch-riscv.h @@ -21,7 +21,7 @@ * so that we don't have to experience issues with register constraints. */ -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0"); \ @@ -35,7 +35,7 @@ _arg1; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -49,7 +49,7 @@ _arg1; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -65,7 +65,7 @@ _arg1; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -82,7 +82,7 @@ _arg1; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -100,7 +100,7 @@ _arg1; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ @@ -119,7 +119,7 @@ _arg1; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("a7") = (num); \ register long _arg1 __asm__ ("a0") = (long)(arg1); \ diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/arch-s390.h index 904281e95f99..4e69123ae484 100644 --- a/tools/include/nolibc/arch-s390.h +++ b/tools/include/nolibc/arch-s390.h @@ -28,7 +28,7 @@ * */ -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__ ("1") = (num); \ register long _rc __asm__ ("2"); \ @@ -42,7 +42,7 @@ _rc; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__ ("1") = (num); \ register long _arg1 __asm__ ("2") = (long)(arg1); \ @@ -56,7 +56,7 @@ _arg1; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__ ("1") = (num); \ register long _arg1 __asm__ ("2") = (long)(arg1); \ @@ -71,7 +71,7 @@ _arg1; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__ ("1") = (num); \ register long _arg1 __asm__ ("2") = (long)(arg1); \ @@ -87,7 +87,7 @@ _arg1; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__ ("1") = (num); \ register long _arg1 __asm__ ("2") = (long)(arg1); \ @@ -104,7 +104,7 @@ _arg1; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("1") = (num); \ register long _arg1 __asm__ ("2") = (long)(arg1); \ @@ -123,7 +123,7 @@ _arg1; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("1") = (num); \ register long _arg1 __asm__ ("2") = (long)(arg1); \ @@ -167,8 +167,8 @@ struct s390_mmap_arg_struct { }; static __attribute__((unused)) -void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, - off_t offset) +void *_sys_mmap(void *addr, size_t length, int prot, int flags, int fd, + off_t offset) { struct s390_mmap_arg_struct args = { .addr = (unsigned long)addr, @@ -179,22 +179,22 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, .offset = (unsigned long)offset }; - return (void *)my_syscall1(__NR_mmap, &args); + return (void *)__nolibc_syscall1(__NR_mmap, &args); } -#define sys_mmap sys_mmap +#define _sys_mmap _sys_mmap static __attribute__((unused)) -pid_t sys_fork(void) +pid_t _sys_fork(void) { - return my_syscall5(__NR_clone, 0, SIGCHLD, 0, 0, 0); + return __nolibc_syscall5(__NR_clone, 0, SIGCHLD, 0, 0, 0); } -#define sys_fork sys_fork +#define _sys_fork _sys_fork static __attribute__((unused)) -pid_t sys_vfork(void) +pid_t _sys_vfork(void) { - return my_syscall5(__NR_clone, 0, CLONE_VM | CLONE_VFORK | SIGCHLD, 0, 0, 0); + return __nolibc_syscall5(__NR_clone, 0, CLONE_VM | CLONE_VFORK | SIGCHLD, 0, 0, 0); } -#define sys_vfork sys_vfork +#define _sys_vfork _sys_vfork #endif /* _NOLIBC_ARCH_S390_H */ diff --git a/tools/include/nolibc/arch-sh.h b/tools/include/nolibc/arch-sh.h index 7a421197d104..b5a64ceeec97 100644 --- a/tools/include/nolibc/arch-sh.h +++ b/tools/include/nolibc/arch-sh.h @@ -19,7 +19,7 @@ * - syscall return value is in r0 */ -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__ ("r3") = (num); \ register long _ret __asm__ ("r0"); \ @@ -33,7 +33,7 @@ _ret; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__ ("r3") = (num); \ register long _ret __asm__ ("r0"); \ @@ -48,7 +48,7 @@ _ret; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__ ("r3") = (num); \ register long _ret __asm__ ("r0"); \ @@ -64,7 +64,7 @@ _ret; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__ ("r3") = (num); \ register long _ret __asm__ ("r0"); \ @@ -81,7 +81,7 @@ _ret; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__ ("r3") = (num); \ register long _ret __asm__ ("r0"); \ @@ -99,7 +99,7 @@ _ret; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("r3") = (num); \ register long _ret __asm__ ("r0"); \ @@ -119,7 +119,7 @@ _ret; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("r3") = (num); \ register long _ret __asm__ ("r0"); \ diff --git a/tools/include/nolibc/arch-sparc.h b/tools/include/nolibc/arch-sparc.h index 2ebb5686e105..240539d069a8 100644 --- a/tools/include/nolibc/arch-sparc.h +++ b/tools/include/nolibc/arch-sparc.h @@ -38,7 +38,7 @@ #endif /* __arch64__ */ -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ register long _num __asm__ ("g1") = (num); \ register long _arg1 __asm__ ("o0"); \ @@ -52,7 +52,7 @@ _arg1; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ register long _num __asm__ ("g1") = (num); \ register long _arg1 __asm__ ("o0") = (long)(arg1); \ @@ -66,7 +66,7 @@ _arg1; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ register long _num __asm__ ("g1") = (num); \ register long _arg1 __asm__ ("o0") = (long)(arg1); \ @@ -81,7 +81,7 @@ _arg1; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ register long _num __asm__ ("g1") = (num); \ register long _arg1 __asm__ ("o0") = (long)(arg1); \ @@ -97,7 +97,7 @@ _arg1; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ register long _num __asm__ ("g1") = (num); \ register long _arg1 __asm__ ("o0") = (long)(arg1); \ @@ -114,7 +114,7 @@ _arg1; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ register long _num __asm__ ("g1") = (num); \ register long _arg1 __asm__ ("o0") = (long)(arg1); \ @@ -132,7 +132,7 @@ _arg1; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ register long _num __asm__ ("g1") = (num); \ register long _arg1 __asm__ ("o0") = (long)(arg1); \ @@ -175,12 +175,12 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s static pid_t getpid(void); static __attribute__((unused)) -pid_t sys_fork(void) +pid_t _sys_fork(void) { pid_t parent, ret; parent = getpid(); - ret = my_syscall0(__NR_fork); + ret = __nolibc_syscall0(__NR_fork); /* The syscall returns the parent pid in the child instead of 0 */ if (ret == parent) @@ -188,15 +188,15 @@ pid_t sys_fork(void) else return ret; } -#define sys_fork sys_fork +#define _sys_fork _sys_fork static __attribute__((unused)) -pid_t sys_vfork(void) +pid_t _sys_vfork(void) { pid_t parent, ret; parent = getpid(); - ret = my_syscall0(__NR_vfork); + ret = __nolibc_syscall0(__NR_vfork); /* The syscall returns the parent pid in the child instead of 0 */ if (ret == parent) @@ -204,6 +204,6 @@ pid_t sys_vfork(void) else return ret; } -#define sys_vfork sys_vfork +#define _sys_vfork _sys_vfork #endif /* _NOLIBC_ARCH_SPARC_H */ diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h index f6c43ac5377b..769ba01a8629 100644 --- a/tools/include/nolibc/arch-x86.h +++ b/tools/include/nolibc/arch-x86.h @@ -30,7 +30,7 @@ */ #define __ARCH_WANT_SYS_OLD_SELECT -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ long _ret; \ register long _num __asm__ ("eax") = (num); \ @@ -44,7 +44,7 @@ _ret; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ long _ret; \ register long _num __asm__ ("eax") = (num); \ @@ -60,7 +60,7 @@ _ret; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ long _ret; \ register long _num __asm__ ("eax") = (num); \ @@ -77,7 +77,7 @@ _ret; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ long _ret; \ register long _num __asm__ ("eax") = (num); \ @@ -95,7 +95,7 @@ _ret; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ long _ret; \ register long _num __asm__ ("eax") = (num); \ @@ -114,7 +114,7 @@ _ret; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ long _ret; \ register long _num __asm__ ("eax") = (num); \ @@ -134,27 +134,27 @@ _ret; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ -({ \ - long _eax = (long)(num); \ - long _arg6 = (long)(arg6); /* Always in memory */ \ - __asm__ volatile ( \ - "pushl %[_arg6]\n\t" \ - "pushl %%ebp\n\t" \ - "movl 4(%%esp),%%ebp\n\t" \ - "int $0x80\n\t" \ - "popl %%ebp\n\t" \ - "addl $4,%%esp\n\t" \ - : "+a"(_eax) /* %eax */ \ - : "b"(arg1), /* %ebx */ \ - "c"(arg2), /* %ecx */ \ - "d"(arg3), /* %edx */ \ - "S"(arg4), /* %esi */ \ - "D"(arg5), /* %edi */ \ - [_arg6]"m"(_arg6) /* memory */ \ - : "memory", "cc" \ - ); \ - _eax; \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +({ \ + long _eax = (long)(num); \ + long _arg6 = (long)(arg6); /* Always in memory */ \ + __asm__ volatile ( \ + "pushl %[_arg6]\n\t" \ + "pushl %%ebp\n\t" \ + "movl 4(%%esp),%%ebp\n\t" \ + "int $0x80\n\t" \ + "popl %%ebp\n\t" \ + "addl $4,%%esp\n\t" \ + : "+a"(_eax) /* %eax */ \ + : "b"(arg1), /* %ebx */ \ + "c"(arg2), /* %ecx */ \ + "d"(arg3), /* %edx */ \ + "S"(arg4), /* %esi */ \ + "D"(arg5), /* %edi */ \ + [_arg6]"m"(_arg6) /* memory */ \ + : "memory", "cc" \ + ); \ + _eax; \ }) #ifndef NOLIBC_NO_RUNTIME @@ -200,7 +200,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s * */ -#define my_syscall0(num) \ +#define __nolibc_syscall0(num) \ ({ \ long _ret; \ register long _num __asm__ ("rax") = (num); \ @@ -214,7 +214,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s _ret; \ }) -#define my_syscall1(num, arg1) \ +#define __nolibc_syscall1(num, arg1) \ ({ \ long _ret; \ register long _num __asm__ ("rax") = (num); \ @@ -230,7 +230,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s _ret; \ }) -#define my_syscall2(num, arg1, arg2) \ +#define __nolibc_syscall2(num, arg1, arg2) \ ({ \ long _ret; \ register long _num __asm__ ("rax") = (num); \ @@ -247,7 +247,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s _ret; \ }) -#define my_syscall3(num, arg1, arg2, arg3) \ +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ ({ \ long _ret; \ register long _num __asm__ ("rax") = (num); \ @@ -265,7 +265,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s _ret; \ }) -#define my_syscall4(num, arg1, arg2, arg3, arg4) \ +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ ({ \ long _ret; \ register long _num __asm__ ("rax") = (num); \ @@ -284,7 +284,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s _ret; \ }) -#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ ({ \ long _ret; \ register long _num __asm__ ("rax") = (num); \ @@ -304,7 +304,7 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s _ret; \ }) -#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ long _ret; \ register long _num __asm__ ("rax") = (num); \ diff --git a/tools/include/nolibc/byteswap.h b/tools/include/nolibc/byteswap.h new file mode 100644 index 000000000000..45bbf9609d7a --- /dev/null +++ b/tools/include/nolibc/byteswap.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * Byte swapping for NOLIBC + * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net> + */ + +/* make sure to include all global symbols */ +#include "nolibc.h" + +#ifndef _NOLIBC_BYTESWAP_H +#define _NOLIBC_BYTESWAP_H + +#include "stdint.h" + +#include <linux/swab.h> + +#define bswap_16(_x) __swab16(_x) +#define bswap_32(_x) __swab32(_x) +#define bswap_64(_x) __swab64(_x) + +#endif /* _NOLIBC_BYTESWAP_H */ diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compiler.h index a8c7619dcdde..b56570bf9f69 100644 --- a/tools/include/nolibc/compiler.h +++ b/tools/include/nolibc/compiler.h @@ -47,6 +47,12 @@ # define __nolibc_fallthrough do { } while (0) #endif /* __nolibc_has_attribute(fallthrough) */ +#if defined(__STDC_VERSION__) +# define __nolibc_stdc_version __STDC_VERSION__ +#else +# define __nolibc_stdc_version 0 +#endif + #define __nolibc_version(_major, _minor, _patch) ((_major) * 10000 + (_minor) * 100 + (_patch)) #ifdef __GNUC__ @@ -63,7 +69,7 @@ # define __nolibc_clang_version 0 #endif /* __clang__ */ -#if __STDC_VERSION__ >= 201112L || \ +#if __nolibc_stdc_version >= 201112L || \ __nolibc_gnuc_version >= __nolibc_version(4, 6, 0) || \ __nolibc_clang_version >= __nolibc_version(3, 0, 0) # define __nolibc_static_assert(_t) _Static_assert(_t, "") @@ -71,4 +77,17 @@ # define __nolibc_static_assert(_t) #endif +/* Make the optimizer believe the variable can be manipulated arbitrarily. */ +#define _NOLIBC_OPTIMIZER_HIDE_VAR(var) __asm__ ("" : "+r" (var)) + +#if __nolibc_has_feature(undefined_behavior_sanitizer) +# if defined(__clang__) +# define __nolibc_no_sanitize_undefined __attribute__((no_sanitize("function"))) +# else +# define __nolibc_no_sanitize_undefined __attribute__((no_sanitize_undefined)) +# endif +#else +# define __nolibc_no_sanitize_undefined +#endif + #endif /* _NOLIBC_COMPILER_H */ diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h index d9262998dae9..d8ce91fd2e3b 100644 --- a/tools/include/nolibc/crt.h +++ b/tools/include/nolibc/crt.h @@ -17,6 +17,7 @@ const unsigned long *_auxv __attribute__((weak)); void _start(void); static void __stack_chk_init(void); static void exit(int); +static char *strrchr(const char *s, int c); extern void (*const __preinit_array_start[])(int, char **, char**) __attribute__((weak)); extern void (*const __preinit_array_end[])(int, char **, char**) __attribute__((weak)); @@ -27,11 +28,26 @@ extern void (*const __init_array_end[])(int, char **, char**) __attribute__((wea extern void (*const __fini_array_start[])(void) __attribute__((weak)); extern void (*const __fini_array_end[])(void) __attribute__((weak)); +#ifndef NOLIBC_IGNORE_ERRNO +extern char *program_invocation_name __attribute__((weak)); +extern char *program_invocation_short_name __attribute__((weak)); + +static __inline__ +char *__nolibc_program_invocation_short_name(char *long_name) +{ + + char *short_name; + + short_name = strrchr(long_name, '/'); + if (!short_name || !short_name[0]) + return long_name; + + return short_name + 1; +} +#endif /* NOLIBC_IGNORE_ERRNO */ + void _start_c(long *sp); -__attribute__((weak,used)) -#if __nolibc_has_feature(undefined_behavior_sanitizer) - __attribute__((no_sanitize("function"))) -#endif +__attribute__((weak,used)) __nolibc_no_sanitize_undefined void _start_c(long *sp) { long argc; @@ -76,6 +92,13 @@ void _start_c(long *sp) ; _auxv = auxv; +#ifndef NOLIBC_IGNORE_ERRNO + if (argc > 0 && argv[0]) { + program_invocation_name = argv[0]; + program_invocation_short_name = __nolibc_program_invocation_short_name(argv[0]); + } +#endif /* NOLIBC_IGNORE_ERRNO */ + for (ctor_func = __preinit_array_start; ctor_func < __preinit_array_end; ctor_func++) (*ctor_func)(argc, argv, envp); for (ctor_func = __init_array_start; ctor_func < __init_array_end; ctor_func++) diff --git a/tools/include/nolibc/dirent.h b/tools/include/nolibc/dirent.h index 61a122a60327..4e02ef25e72d 100644 --- a/tools/include/nolibc/dirent.h +++ b/tools/include/nolibc/dirent.h @@ -73,7 +73,7 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) fd = ~i; - ret = sys_getdents64(fd, ldir, sizeof(buf)); + ret = _sys_getdents64(fd, ldir, sizeof(buf)); if (ret < 0) return -ret; if (ret == 0) { @@ -86,7 +86,7 @@ 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); + ret = _sys_lseek(fd, ldir->d_off, SEEK_SET); if (ret < 0) return -ret; diff --git a/tools/include/nolibc/endian.h b/tools/include/nolibc/endian.h new file mode 100644 index 000000000000..ccc016ecd5ec --- /dev/null +++ b/tools/include/nolibc/endian.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * Byte order conversion for NOLIBC + * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net> + */ + +/* make sure to include all global symbols */ +#include "nolibc.h" + +#ifndef _NOLIBC_ENDIAN_H +#define _NOLIBC_ENDIAN_H + +#include "stdint.h" + +#include <asm/byteorder.h> + +#define htobe16(_x) __cpu_to_be16(_x) +#define htole16(_x) __cpu_to_le16(_x) +#define be16toh(_x) __be16_to_cpu(_x) +#define le16toh(_x) __le16_to_cpu(_x) + +#define htobe32(_x) __cpu_to_be32(_x) +#define htole32(_x) __cpu_to_le32(_x) +#define be32toh(_x) __be32_to_cpu(_x) +#define le32toh(_x) __le32_to_cpu(_x) + +#define htobe64(_x) __cpu_to_be64(_x) +#define htole64(_x) __cpu_to_le64(_x) +#define be64toh(_x) __be64_to_cpu(_x) +#define le64toh(_x) __le64_to_cpu(_x) + +#endif /* _NOLIBC_ENDIAN_H */ diff --git a/tools/include/nolibc/err.h b/tools/include/nolibc/err.h new file mode 100644 index 000000000000..e22ae87a7289 --- /dev/null +++ b/tools/include/nolibc/err.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * formatted error message for NOLIBC + * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net> + */ + +/* make sure to include all global symbols */ +#include "nolibc.h" + +#ifndef _NOLIBC_ERR_H +#define _NOLIBC_ERR_H + +#include "errno.h" +#include "stdarg.h" +#include "sys.h" + +static __attribute__((unused)) +void vwarn(const char *fmt, va_list args) +{ + fprintf(stderr, "%s: ", program_invocation_short_name); + vfprintf(stderr, fmt, args); + fprintf(stderr, ": %m\n"); +} + +static __attribute__((unused)) +void vwarnx(const char *fmt, va_list args) +{ + fprintf(stderr, "%s: ", program_invocation_short_name); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); +} + +static __attribute__((unused)) +void warn(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vwarn(fmt, args); + va_end(args); +} + +static __attribute__((unused)) +void warnx(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vwarnx(fmt, args); + va_end(args); +} + +static __attribute__((noreturn, unused)) +void verr(int eval, const char *fmt, va_list args) +{ + vwarn(fmt, args); + exit(eval); +} + +static __attribute__((noreturn, unused)) +void verrx(int eval, const char *fmt, va_list args) +{ + warnx(fmt, args); + exit(eval); +} + +static __attribute__((noreturn, unused)) +void err(int eval, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + verr(eval, fmt, args); + va_end(args); +} + +static __attribute__((noreturn, unused)) +void errx(int eval, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + verrx(eval, fmt, args); + va_end(args); +} + +#endif /* _NOLIBC_ERR_H */ diff --git a/tools/include/nolibc/errno.h b/tools/include/nolibc/errno.h index 08a33c40ec0c..bab83692ea1c 100644 --- a/tools/include/nolibc/errno.h +++ b/tools/include/nolibc/errno.h @@ -15,8 +15,12 @@ #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)) = ""; #else #define SET_ERRNO(v) do { } while (0) +#define program_invocation_name "" +#define program_invocation_short_name "" #endif diff --git a/tools/include/nolibc/fcntl.h b/tools/include/nolibc/fcntl.h index bff2e542f20f..ed2f5553c65a 100644 --- a/tools/include/nolibc/fcntl.h +++ b/tools/include/nolibc/fcntl.h @@ -19,9 +19,9 @@ */ static __attribute__((unused)) -int sys_openat(int dirfd, const char *path, int flags, mode_t mode) +int _sys_openat(int dirfd, const char *path, int flags, mode_t mode) { - return my_syscall4(__NR_openat, dirfd, path, flags, mode); + return __nolibc_syscall4(__NR_openat, dirfd, path, flags, mode); } static __attribute__((unused)) @@ -37,7 +37,7 @@ int openat(int dirfd, const char *path, int flags, ...) va_end(args); } - return __sysret(sys_openat(dirfd, path, flags, mode)); + return __sysret(_sys_openat(dirfd, path, flags, mode)); } /* @@ -45,9 +45,9 @@ int openat(int dirfd, const char *path, int flags, ...) */ static __attribute__((unused)) -int sys_open(const char *path, int flags, mode_t mode) +int _sys_open(const char *path, int flags, mode_t mode) { - return my_syscall4(__NR_openat, AT_FDCWD, path, flags, mode); + return __nolibc_syscall4(__NR_openat, AT_FDCWD, path, flags, mode); } static __attribute__((unused)) @@ -63,7 +63,7 @@ int open(const char *path, int flags, ...) va_end(args); } - return __sysret(sys_open(path, flags, mode)); + return __sysret(_sys_open(path, flags, mode)); } #endif /* _NOLIBC_FCNTL_H */ diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h index 9c7f43b9218b..f4120f65fe79 100644 --- a/tools/include/nolibc/nolibc.h +++ b/tools/include/nolibc/nolibc.h @@ -12,24 +12,24 @@ * * Syscalls are split into 3 levels: * - The lower level is the arch-specific syscall() definition, consisting in - * assembly code in compound expressions. These are called my_syscall0() to - * my_syscall6() depending on the number of arguments. All input arguments + * assembly code in compound expressions. These are called __nolibc_syscall0() to + * __nolibc_syscall6() depending on the number of arguments. All input arguments * are castto a long stored in a register. These expressions always return * the syscall's return value as a signed long value which is often either * a pointer or the negated errno value. * * - The second level is mostly architecture-independent. It is made of - * static functions called sys_<name>() which rely on my_syscallN() + * static functions called _sys_<name>() which rely on __nolibc_syscallN() * depending on the syscall definition. These functions are responsible * for exposing the appropriate types for the syscall arguments (int, * pointers, etc) and for setting the appropriate return type (often int). * A few of them are architecture-specific because the syscalls are not all * mapped exactly the same among architectures. For example, some archs do - * not implement select() and need pselect6() instead, so the sys_select() + * not implement select() and need pselect6() instead, so the _sys_select() * function will have to abstract this. * * - The third level is the libc call definition. It exposes the lower raw - * sys_<name>() calls in a way that looks like what a libc usually does, + * _sys_<name>() calls in a way that looks like what a libc usually does, * takes care of specific input values, and of setting errno upon error. * There can be minor variations compared to standard libc calls. * @@ -130,6 +130,9 @@ #include "getopt.h" #include "poll.h" #include "math.h" +#include "err.h" +#include "byteswap.h" +#include "endian.h" /* Used by programs to avoid std includes */ #define NOLIBC diff --git a/tools/include/nolibc/poll.h b/tools/include/nolibc/poll.h index e854c94647b1..dbcf883da237 100644 --- a/tools/include/nolibc/poll.h +++ b/tools/include/nolibc/poll.h @@ -21,7 +21,7 @@ */ static __attribute__((unused)) -int sys_poll(struct pollfd *fds, int nfds, int timeout) +int _sys_poll(struct pollfd *fds, int nfds, int timeout) { #if defined(__NR_ppoll_time64) struct __kernel_timespec t; @@ -30,7 +30,7 @@ int sys_poll(struct pollfd *fds, int nfds, int timeout) t.tv_sec = timeout / 1000; t.tv_nsec = (timeout % 1000) * 1000000; } - return my_syscall5(__NR_ppoll_time64, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0); + return __nolibc_syscall5(__NR_ppoll_time64, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0); #else struct __kernel_old_timespec t; @@ -38,14 +38,14 @@ int sys_poll(struct pollfd *fds, int nfds, int timeout) t.tv_sec = timeout / 1000; t.tv_nsec = (timeout % 1000) * 1000000; } - return my_syscall5(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0); + return __nolibc_syscall5(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0); #endif } static __attribute__((unused)) int poll(struct pollfd *fds, int nfds, int timeout) { - return __sysret(sys_poll(fds, nfds, timeout)); + return __sysret(_sys_poll(fds, nfds, timeout)); } #endif /* _NOLIBC_POLL_H */ diff --git a/tools/include/nolibc/sched.h b/tools/include/nolibc/sched.h index 32221562c166..7a5f6d9484c8 100644 --- a/tools/include/nolibc/sched.h +++ b/tools/include/nolibc/sched.h @@ -19,15 +19,15 @@ */ static __attribute__((unused)) -int sys_setns(int fd, int nstype) +int _sys_setns(int fd, int nstype) { - return my_syscall2(__NR_setns, fd, nstype); + return __nolibc_syscall2(__NR_setns, fd, nstype); } static __attribute__((unused)) int setns(int fd, int nstype) { - return __sysret(sys_setns(fd, nstype)); + return __sysret(_sys_setns(fd, nstype)); } @@ -36,15 +36,15 @@ int setns(int fd, int nstype) */ static __attribute__((unused)) -int sys_unshare(int flags) +int _sys_unshare(int flags) { - return my_syscall1(__NR_unshare, flags); + return __nolibc_syscall1(__NR_unshare, flags); } static __attribute__((unused)) int unshare(int flags) { - return __sysret(sys_unshare(flags)); + return __sysret(_sys_unshare(flags)); } #endif /* _NOLIBC_SCHED_H */ diff --git a/tools/include/nolibc/signal.h b/tools/include/nolibc/signal.h index ac13e53ac31d..99a0489fe3e8 100644 --- a/tools/include/nolibc/signal.h +++ b/tools/include/nolibc/signal.h @@ -20,7 +20,7 @@ int raise(int signal); __attribute__((weak,unused,section(".text.nolibc_raise"))) int raise(int signal) { - return sys_kill(sys_getpid(), signal); + return _sys_kill(_sys_getpid(), signal); } #endif /* _NOLIBC_SIGNAL_H */ diff --git a/tools/include/nolibc/stackprotector.h b/tools/include/nolibc/stackprotector.h index 7123aa056cb0..ae8b1d3a374d 100644 --- a/tools/include/nolibc/stackprotector.h +++ b/tools/include/nolibc/stackprotector.h @@ -24,9 +24,9 @@ __attribute__((weak,used,noreturn,section(".text.nolibc_stack_chk"))) void __stack_chk_fail(void) { pid_t pid; - my_syscall3(__NR_write, STDERR_FILENO, "!!Stack smashing detected!!\n", 28); - pid = my_syscall0(__NR_getpid); - my_syscall2(__NR_kill, pid, SIGABRT); + __nolibc_syscall3(__NR_write, STDERR_FILENO, "!!Stack smashing detected!!\n", 28); + pid = __nolibc_syscall0(__NR_getpid); + __nolibc_syscall2(__NR_kill, pid, SIGABRT); for (;;); } @@ -42,7 +42,7 @@ uintptr_t __stack_chk_guard; static __no_stack_protector void __stack_chk_init(void) { - my_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0); + __nolibc_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0); /* 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/std.h b/tools/include/nolibc/std.h index b9a116123902..dc2dc46f8ca8 100644 --- a/tools/include/nolibc/std.h +++ b/tools/include/nolibc/std.h @@ -19,7 +19,7 @@ #include <linux/types.h> /* those are commonly provided by sys/types.h */ -typedef unsigned int dev_t; +typedef uint64_t dev_t; typedef uint64_t ino_t; typedef unsigned int mode_t; typedef signed int pid_t; diff --git a/tools/include/nolibc/stddef.h b/tools/include/nolibc/stddef.h index ecbd13eab1f5..a3976341afdd 100644 --- a/tools/include/nolibc/stddef.h +++ b/tools/include/nolibc/stddef.h @@ -18,7 +18,7 @@ #endif #ifndef offsetof -#define offsetof(TYPE, FIELD) ((size_t) &((TYPE *)0)->FIELD) +#define offsetof(TYPE, FIELD) __builtin_offsetof(TYPE, FIELD) #endif #endif /* _NOLIBC_STDDEF_H */ diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 233318b0d0f0..ebdd413d13ec 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -291,156 +291,371 @@ int fseek(FILE *stream, long offset, int whence) } -/* minimal printf(). It supports the following formats: - * - %[l*]{d,u,c,x,p} - * - %s - * - unknown modifiers are ignored. +/* printf(). Supports most of the normal integer and string formats. + * - %[#0-+ ][width|*[.precision|*}][{l,t,z,ll,L,j,q}]{c,d,i,u,o,x,X,p,s,m,%} + * - %% generates a single % + * - %m outputs strerror(errno). + * - %X outputs a..f the same as %x. + * - No support for floating point or wide characters. + * - Invalid formats are copied to the output buffer. + * + * Called by vfprintf() and snprintf() to do the actual formatting. + * The callers provide a callback function to save the formatted data. + * The callback function is called multiple times: + * - for each group of literal characters in the format string. + * - for field padding. + * - for each conversion specifier. + * - with (NULL, 0) at the end of the __nolibc_printf. + * If the callback returns non-zero __nolibc_printf() immediately returns -1. */ -typedef int (*__nolibc_printf_cb)(intptr_t state, const char *buf, size_t size); -static __attribute__((unused, format(printf, 4, 0))) -int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char *fmt, va_list args) +typedef int (*__nolibc_printf_cb)(void *state, const char *buf, size_t size); + +/* This code uses 'flag' variables that are indexed by the low 6 bits + * of characters to optimise checks for multiple characters. + * + * _NOLIBC_PF_FLAGS_CONTAIN(flags, 'a', 'b'. ...) + * returns non-zero if the bit for any of the specified characters is set. + * + * _NOLIBC_PF_CHAR_IS_ONE_OF(ch, 'a', 'b'. ...) + * returns the flag bit for ch if it is one of the specified characters. + * All the characters must be in the same 32 character block (non-alphabetic, + * upper case, or lower case) of the ASCII character set. + */ +#define _NOLIBC_PF_FLAG(ch) (1u << ((ch) & 0x1f)) +#define _NOLIBC_PF_FLAG_NZ(ch) ((ch) ? _NOLIBC_PF_FLAG(ch) : 0) +#define _NOLIBC_PF_FLAG8(cmp_1, cmp_2, cmp_3, cmp_4, cmp_5, cmp_6, cmp_7, cmp_8, ...) \ + (_NOLIBC_PF_FLAG_NZ(cmp_1) | _NOLIBC_PF_FLAG_NZ(cmp_2) | \ + _NOLIBC_PF_FLAG_NZ(cmp_3) | _NOLIBC_PF_FLAG_NZ(cmp_4) | \ + _NOLIBC_PF_FLAG_NZ(cmp_5) | _NOLIBC_PF_FLAG_NZ(cmp_6) | \ + _NOLIBC_PF_FLAG_NZ(cmp_7) | _NOLIBC_PF_FLAG_NZ(cmp_8)) +#define _NOLIBC_PF_FLAGS_CONTAIN(flags, ...) \ + ((flags) & _NOLIBC_PF_FLAG8(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0)) +#define _NOLIBC_PF_CHAR_IS_ONE_OF(ch, cmp_1, ...) \ + ((unsigned int)(ch) - (cmp_1 & 0xe0) > 0x1f ? 0 : \ + _NOLIBC_PF_FLAGS_CONTAIN(_NOLIBC_PF_FLAG(ch), cmp_1, __VA_ARGS__)) + +static __attribute__((unused, format(printf, 3, 0))) +int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list args) { - char escape, lpref, c; + char ch; unsigned long long v; - unsigned int written, width; - size_t len, ofs, w; - char tmpbuf[21]; + long long signed_v; + int written, width, precision, len; + unsigned int flags, ch_flag; + char outbuf[2 + 31 + 22 + 1]; + char *out; const char *outstr; + unsigned int sign_prefix; + int got_width; - written = ofs = escape = lpref = 0; + written = 0; while (1) { - c = fmt[ofs++]; + outstr = fmt; + ch = *fmt++; + if (!ch) + break; + width = 0; + flags = 0; + if (ch != '%') { + while (*fmt && *fmt != '%') + fmt++; + /* Output characters from the format string. */ + len = fmt - outstr; + goto do_output; + } - if (escape) { - /* we're in an escape sequence, ofs == 1 */ - escape = 0; + /* we're in a format sequence */ - /* width */ - while (c >= '0' && c <= '9') { - width *= 10; - width += c - '0'; + /* Conversion flag characters */ + while (1) { + ch = *fmt++; + ch_flag = _NOLIBC_PF_CHAR_IS_ONE_OF(ch, ' ', '#', '+', '-', '0'); + if (!ch_flag) + break; + flags |= ch_flag; + } - c = fmt[ofs++]; + /* Width and precision */ + for (got_width = 0;; ch = *fmt++) { + if (ch == '*') { + precision = va_arg(args, int); + ch = *fmt++; + } else { + for (precision = 0; ch >= '0' && ch <= '9'; ch = *fmt++) + precision = precision * 10 + (ch - '0'); + } + if (got_width) + break; + width = precision; + if (ch != '.') { + /* Default precision for strings */ + precision = -1; + break; + } + got_width = 1; + } + /* A negative width (e.g. from "%*s") requests left justify. */ + if (width < 0) { + width = -width; + flags |= _NOLIBC_PF_FLAG('-'); + } + + /* Length modifier. + * They miss the conversion flags characters " #+-0" so can go into flags. + * Change both L and ll to j (all always 64bit). + */ + if (ch == 'L') + ch = 'j'; + ch_flag = _NOLIBC_PF_CHAR_IS_ONE_OF(ch, 'l', 't', 'z', 'j', 'q'); + if (ch_flag != 0) { + if (ch == 'l' && fmt[0] == 'l') { + fmt++; + ch_flag = _NOLIBC_PF_FLAG('j'); + } + flags |= ch_flag; + ch = *fmt++; + } + + /* Conversion specifiers. */ + + /* Numeric and pointer conversion specifiers. + * + * Use an explicit bound check (rather than _NOLIBC_PF_CHAR_IS_ONE_OF()) + * so that 'X' can be allowed through. + * 'X' gets treated and 'x' because _NOLIBC_PF_FLAG() returns the same + * value for both. + * + * We need to check for "%p" or "%#x" later, merging here gives better code. + * But '#' collides with 'c' so shift right. + */ + ch_flag = _NOLIBC_PF_FLAG(ch) | (flags & _NOLIBC_PF_FLAG('#')) >> 1; + if (((ch >= 'a' && ch <= 'z') || ch == 'X') && + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'o', 'x', 'p', 's')) { + /* 'long' is needed for pointer/string conversions and ltz lengths. + * A single test can be used provided 'p' (the same bit as '0') + * is masked from flags. + */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag | (flags & ~_NOLIBC_PF_FLAG('p')), + 'p', 's', 'l', 't', 'z')) { + v = va_arg(args, unsigned long); + signed_v = (long)v; + } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, 'j', 'q')) { + v = va_arg(args, unsigned long long); + signed_v = v; + } else { + v = va_arg(args, unsigned int); + signed_v = (int)v; + } + + if (ch == 'c') { + /* "%c" - single character. */ + outbuf[0] = v; + len = 1; + outstr = outbuf; + goto do_output; } - if (c == 'c' || c == 'd' || c == 'u' || c == 'x' || c == 'p') { - char *out = tmpbuf; - - if (c == 'p') - v = va_arg(args, unsigned long); - else if (lpref) { - if (lpref > 1) - v = va_arg(args, unsigned long long); - else - v = va_arg(args, unsigned long); - } else - v = va_arg(args, unsigned int); - - if (c == 'd') { - /* sign-extend the value */ - if (lpref == 0) - v = (long long)(int)v; - else if (lpref == 1) - v = (long long)(long)v; + if (ch == 's') { + /* "%s" - character string. */ + outstr = (const char *)(uintptr_t)v; + if (!outstr) { + outstr = "(null)"; + /* Match glibc, nothing output if precision too small */ + len = precision < 0 || precision >= 6 ? 6 : 0; + goto do_output; } + goto do_strlen_output; + } - switch (c) { - case 'c': - out[0] = v; - out[1] = 0; - break; - case 'd': - i64toa_r(v, out); - break; - case 'u': - u64toa_r(v, out); - break; - case 'p': - *(out++) = '0'; - *(out++) = 'x'; - __nolibc_fallthrough; - default: /* 'x' and 'p' above */ - u64toh_r(v, out); - break; + /* The 'sign_prefix' can be zero, one or two ("0x") characters. + * Prepended least significant byte first stopping on a zero byte. + */ + sign_prefix = 0; + + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i')) { + /* "%d" and "%i" - signed decimal numbers. */ + if (signed_v < 0) { + sign_prefix = '-'; + v = -(signed_v + 1); + v++; + } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, '+')) { + sign_prefix = '+'; + } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, ' ')) { + sign_prefix = ' '; } - outstr = tmpbuf; + } else { + /* "#o" requires that the output always starts with a '0'. + * This needs another check after any zero padding to avoid + * adding an extra leading '0'. + */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'o') && + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, '#' - 1)) + sign_prefix = '0'; } - else if (c == 's') { - outstr = va_arg(args, char *); - if (!outstr) - outstr="(null)"; + + /* The value is converted offset into the buffer so that + * 31 zero pad characters and the sign/prefix can be added in front. + * The longest digit string is 22 + 1 for octal conversions. + */ + out = outbuf + 2 + 31; + + if (v == 0) { + /* There are special rules for zero. */ + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p')) { + /* "%p" match glibc, precision is ignored */ + outstr = "(nil)"; + len = 5; + goto do_output; + } + if (!precision) { + /* Explicit %nn.0d, no digits output (except for %#.0o) */ + len = 0; + goto prepend_sign; + } + /* All other formats (including "%#x") just output "0". */ + out[0] = '0'; + len = 1; + } else { + /* Convert the number to ascii in the required base. */ + unsigned long long recip; + unsigned int base; + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i', 'u')) { + base = 10; + recip = _NOLIBC_U64TOA_RECIP(10); + } else if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'o')) { + base = 8; + recip = _NOLIBC_U64TOA_RECIP(8); + } else { + base = 16; + recip = _NOLIBC_U64TOA_RECIP(16); + if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'p', '#' - 1)) { + /* "%p" and "%#x" need "0x" prepending. */ + sign_prefix = '0' << 8 | 'x'; + } + } + len = _nolibc_u64toa_base(v, out, base, recip); } - else if (c == 'm') { -#ifdef NOLIBC_IGNORE_ERRNO - outstr = "unknown error"; -#else - outstr = strerror(errno); -#endif /* NOLIBC_IGNORE_ERRNO */ + + /* Add zero padding */ + if (precision < 0) { + /* No explicit precision (or negative from "%.*s"). */ + if (!_NOLIBC_PF_FLAGS_CONTAIN(flags, '0')) + goto no_zero_padding; + if (_NOLIBC_PF_FLAGS_CONTAIN(flags, '-')) + /* Left justify overrides zero pad */ + goto no_zero_padding; + /* eg "%05d", Zero pad to field width less sign. + * Note that precision can end up negative so all + * the variables have to be 'signed int'. + */ + precision = width; + if (sign_prefix) { + precision--; + if (sign_prefix >= 256) + precision--; + } } - else if (c == '%') { - /* queue it verbatim */ - continue; + if (precision > 31) + /* Don't run off the start of outbuf[], arbitrary limit + * longer than the longest number field. */ + precision = 31; + for (; len < precision; len++) { + /* Stop gcc generating horrid code and memset(). */ + _NOLIBC_OPTIMIZER_HIDE_VAR(len); + *--out = '0'; } - else { - /* modifiers or final 0 */ - if (c == 'l') { - /* long format prefix, maintain the escape */ - lpref++; - } else if (c == 'j') { - lpref = 2; +no_zero_padding: + + /* %#o has set sign_prefix to '0', but we don't want so add an extra + * leading zero here. + * Since the only other byte values of sign_prefix are ' ', '+' and '-' + * it is enough to check that out[] doesn't already start with sign_prefix. + */ + if (sign_prefix - *out) { +prepend_sign: + /* Add the 0, 1 or 2 ("0x") sign/prefix characters at the front. */ + for (; sign_prefix; sign_prefix >>= 8) { + /* Force gcc to increment len inside the loop. */ + _NOLIBC_OPTIMIZER_HIDE_VAR(len); + len++; + *--out = sign_prefix; } - escape = 1; - goto do_escape; } - len = strlen(outstr); - goto flush_str; + outstr = out; + goto do_output; } - /* not an escape sequence */ - if (c == 0 || c == '%') { - /* flush pending data on escape or end */ - escape = 1; - lpref = 0; - outstr = fmt; - len = ofs - 1; - flush_str: - if (n) { - w = len < n ? len : n; - n -= w; - while (width-- > w) { - if (cb(state, " ", 1) != 0) - return -1; - written += 1; - } - if (cb(state, outstr, w) != 0) - return -1; - } + if (ch == 'm') { +#ifdef NOLIBC_IGNORE_ERRNO + outstr = "unknown error"; +#else + outstr = strerror(errno); +#endif /* NOLIBC_IGNORE_ERRNO */ + goto do_strlen_output; + } - written += len; - do_escape: - if (c == 0) - break; - fmt += ofs; - ofs = 0; - continue; + if (ch != '%') { + /* Invalid format: back up to output the format characters */ + fmt = outstr + 1; + /* and output a '%' now. */ } + /* %% is documented as a 'conversion specifier'. + * Any flags, precision or length modifier are ignored. + */ + len = 1; + width = 0; + outstr = fmt - 1; + goto do_output; + +do_strlen_output: + /* Open coded strnlen() (slightly smaller). */ + for (len = 0; precision < 0 || len < precision; len++) + if (!outstr[len]) + break; - /* literal char, just queue it */ +do_output: + written += len; + + /* Stop gcc back-merging this code into one of the conditionals above. */ + _NOLIBC_OPTIMIZER_HIDE_VAR(len); + + /* Output the characters on the required side of any padding. */ + width -= len; + flags = _NOLIBC_PF_FLAGS_CONTAIN(flags, '-'); + if (flags && cb(state, outstr, len) != 0) + return -1; + while (width > 0) { + /* Output pad in 16 byte blocks with the small block first. */ + int pad_len = ((width - 1) & 15) + 1; + width -= pad_len; + written += pad_len; + if (cb(state, " ", pad_len) != 0) + return -1; + } + if (!flags && cb(state, outstr, len) != 0) + return -1; } + + /* Request a final '\0' be added to the snprintf() output. + * This may be the only call of the cb() function. + */ + if (cb(state, NULL, 0) != 0) + return -1; + return written; } -static int __nolibc_fprintf_cb(intptr_t state, const char *buf, size_t size) +static int __nolibc_fprintf_cb(void *stream, const char *buf, size_t size) { - return _fwrite(buf, size, (FILE *)state); + return _fwrite(buf, size, stream); } static __attribute__((unused, format(printf, 2, 0))) int vfprintf(FILE *stream, const char *fmt, va_list args) { - return __nolibc_printf(__nolibc_fprintf_cb, (intptr_t)stream, SIZE_MAX, fmt, args); + return __nolibc_printf(__nolibc_fprintf_cb, stream, fmt, args); } static __attribute__((unused, format(printf, 1, 0))) @@ -498,26 +713,54 @@ int dprintf(int fd, const char *fmt, ...) return ret; } -static int __nolibc_sprintf_cb(intptr_t _state, const char *buf, size_t size) +struct __nolibc_sprintf_cb_state { + char *buf; + size_t space; +}; + +static int __nolibc_sprintf_cb(void *v_state, const char *buf, size_t size) { - char **state = (char **)_state; + struct __nolibc_sprintf_cb_state *state = v_state; + size_t space = state->space; + char *tgt; + + /* Truncate the request to fit in the output buffer space. + * The last byte is reserved for the terminating '\0'. + * state->space can only be zero for snprintf(NULL, 0, fmt, args) + * so this normally lets through calls with 'size == 0'. + */ + if (size >= space) { + if (space <= 1) + return 0; + size = space - 1; + } + tgt = state->buf; + + /* __nolibc_printf() ends with cb(state, NULL, 0) to request the output + * buffer be '\0' terminated. + * That will be the only cb() call for, eg, snprintf(buf, sz, ""). + * Zero lengths can occur at other times (eg "%s" for an empty string). + * Unconditionally write the '\0' byte to reduce code size, it is + * normally overwritten by the data being output. + * There is no point adding a '\0' after copied data - there is always + * another call. + */ + *tgt = '\0'; + if (size) { + state->space = space - size; + state->buf = tgt + size; + memcpy(tgt, buf, size); + } - memcpy(*state, buf, size); - *state += size; return 0; } static __attribute__((unused, format(printf, 3, 0))) int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { - char *state = buf; - int ret; + struct __nolibc_sprintf_cb_state state = { .buf = buf, .space = size }; - ret = __nolibc_printf(__nolibc_sprintf_cb, (intptr_t)&state, size, fmt, args); - if (ret < 0) - return ret; - buf[(size_t)ret < size ? (size_t)ret : size - 1] = '\0'; - return ret; + return __nolibc_printf(__nolibc_sprintf_cb, &state, fmt, args); } static __attribute__((unused, format(printf, 3, 4))) @@ -552,6 +795,56 @@ int sprintf(char *buf, const char *fmt, ...) return ret; } +static __attribute__((unused, format(printf, 2, 0))) +int __nolibc_vasprintf(char **strp, const char *fmt, va_list args1, va_list args2) +{ + int len1, len2; + char *buf; + + len1 = vsnprintf(NULL, 0, fmt, args1); + if (len1 < 0) + return -1; + + buf = malloc(len1 + 1); + if (!buf) + return -1; + + len2 = vsnprintf(buf, len1 + 1, fmt, args2); + if (len2 < 0) { + free(buf); + return -1; + } + + *strp = buf; + return len1; +} + +static __attribute__((unused, format(printf, 2, 0))) +int vasprintf(char **strp, const char *fmt, va_list args) +{ + va_list args2; + int ret; + + va_copy(args2, args); + ret = __nolibc_vasprintf(strp, fmt, args, args2); + va_end(args2); + + return ret; +} + +static __attribute__((unused, format(printf, 2, 3))) +int asprintf(char **strp, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = vasprintf(strp, fmt, args); + va_end(args); + + return ret; +} + static __attribute__((unused)) int vsscanf(const char *str, const char *format, va_list args) { @@ -683,13 +976,29 @@ int setvbuf(FILE *stream __attribute__((unused)), } static __attribute__((unused)) -const char *strerror(int errno) +int strerror_r(int errnum, char *buf, size_t buflen) +{ + if (buflen < 18) + return ERANGE; + + __builtin_memcpy(buf, "errno=", 6); + i64toa_r(errnum, buf + 6); + return 0; +} + +static __attribute__((unused)) +const char *strerror(int errnum) { - static char buf[18] = "errno="; + static char buf[18]; + char *b = buf; + + /* Force gcc to use 'register offset' to access buf[]. */ + _NOLIBC_OPTIMIZER_HIDE_VAR(b); - i64toa_r(errno, &buf[6]); + /* Use strerror_r() to avoid having the only .data in small programs. */ + strerror_r(errnum, b, sizeof(buf)); - return buf; + return b; } #endif /* _NOLIBC_STDIO_H */ diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h index f184e108ed0a..1816c2368b68 100644 --- a/tools/include/nolibc/stdlib.h +++ b/tools/include/nolibc/stdlib.h @@ -55,7 +55,7 @@ void abort(void); __attribute__((weak,unused,noreturn,section(".text.nolibc_abort"))) void abort(void) { - sys_kill(sys_getpid(), SIGABRT); + _sys_kill(_sys_getpid(), SIGABRT); for (;;); } @@ -145,9 +145,9 @@ void *malloc(size_t len) static __attribute__((unused)) void *calloc(size_t size, size_t nmemb) { - size_t x = size * nmemb; + size_t x; - if (__builtin_expect(size && ((x / size) != nmemb), 0)) { + if (__builtin_expect(__builtin_mul_overflow(size, nmemb, &x), 0)) { SET_ERRNO(ENOMEM); return NULL; } @@ -188,36 +188,91 @@ void *realloc(void *old_ptr, size_t new_size) return ret; } -/* Converts the unsigned long integer <in> to its hex representation into +/* Converts the unsigned 64bit integer <in> to base <base> ascii into * buffer <buffer>, which must be long enough to store the number and the - * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The - * buffer is filled from the first byte, and the number of characters emitted - * (not counting the trailing zero) is returned. The function is constructed - * in a way to optimize the code size and avoid any divide that could add a - * dependency on large external functions. + * trailing zero. The buffer is filled from the first byte, and the number + * of characters emitted (not counting the trailing zero) is returned. + * The function uses 'multiply by reciprocal' for the divisions and + * requires the caller pass the correct reciprocal. + * + * Note that unlike __div64_const32() in asm-generic/div64.h there isn't + * an extra shift done (by ___p), the reciprocal has to be lower resulting + * in a slightly low quotient. + * Keep things simple by correcting for the error. + * This also saves calculating the 'low * low' product (e2 below) which is + * very unlikely to be significant. + * + * Some maths: + * recip = p2 / base - e1; // With e1 < base. + * q = (recip * in - e2) / p2; // With e2 < p2. + * = base / in - (e1 * in + e2) / p2; + * > base / in - (e1 * p2 + p2) / p2; + * = base / in - ((e1 + 1) * p2) / p2; + * > base / in - base; + * So the maximum error is less than 'base'. + * Hence the largest possible digit is '2 * base - 1'. + * For base 10 e1 is 6 and you can get digits of 15 (eg from 2**64-1). + * Error e1 is largest for a base that is a factor of 2**64+1, the smallest is 274177 + * and converting 2**42-1 in base 274177 does generate a digit of 274177+274175. + * This all means only a single correction is needed rather than a loop. + * + * __int128 isn't used for mips because gcc prior to 10.0 will call + * __multi3 for MIPS64r6. The same also happens for SPARC and clang. */ -static __attribute__((unused)) -int utoh_r(unsigned long in, char *buffer) +#define _NOLIBC_U64TOA_RECIP(base) ((base) & 1 ? ~0ull / (base) : (1ull << 63) / ((base) / 2)) +static __attribute__((unused, noinline)) +int _nolibc_u64toa_base(uint64_t in, char *buffer, unsigned int base, uint64_t recip) { - signed char pos = (~0UL > 0xfffffffful) ? 60 : 28; - int digits = 0; - int dig; + unsigned int digits = 0; + unsigned int dig; + uint64_t q; + char *p; + /* Generate least significant digit first */ do { - dig = in >> pos; - in -= (uint64_t)dig << pos; - pos -= 4; - if (dig || digits || pos < 0) { - if (dig > 9) - dig += 'a' - '0' - 10; - buffer[digits++] = '0' + dig; +#if defined(__SIZEOF_INT128__) && !defined(__mips__) && !defined(__sparc__) + q = ((unsigned __int128)in * recip) >> 64; +#else + uint64_t p = (uint32_t)in * (recip >> 32); + q = (in >> 32) * (recip >> 32) + (p >> 32); + p = (uint32_t)p + (in >> 32) * (uint32_t)recip; + q += p >> 32; +#endif + dig = in - q * base; + /* Correct for any rounding errors */ + if (dig >= base) { + dig -= base; + q++; } - } while (pos >= 0); + if (dig > 9) + dig += 'a' - '0' - 10; + buffer[digits++] = '0' + dig; + } while ((in = q)); buffer[digits] = 0; + + /* Order reverse to result */ + for (p = buffer + digits - 1; p > buffer; buffer++, p--) { + dig = *buffer; + *buffer = *p; + *p = dig; + } + return digits; } +/* Converts the unsigned long integer <in> to its hex representation into + * buffer <buffer>, which must be long enough to store the number and the + * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The + * buffer is filled from the first byte, and the number of characters emitted + * (not counting the trailing zero) is returned. + */ +static __inline__ __attribute__((unused)) +int utoh_r(unsigned long in, char *buffer) +{ + return _nolibc_u64toa_base(in, buffer, 16, _NOLIBC_U64TOA_RECIP(16)); +} + /* converts unsigned long <in> to an hex string using the static itoa_buffer * and returns the pointer to that string. */ @@ -233,30 +288,11 @@ char *utoh(unsigned long in) * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for * 4294967295 in 32-bit). The buffer is filled from the first byte, and the * number of characters emitted (not counting the trailing zero) is returned. - * The function is constructed in a way to optimize the code size and avoid - * any divide that could add a dependency on large external functions. */ -static __attribute__((unused)) +static __inline__ __attribute__((unused)) int utoa_r(unsigned long in, char *buffer) { - unsigned long lim; - int digits = 0; - int pos = (~0UL > 0xfffffffful) ? 19 : 9; - int dig; - - do { - for (dig = 0, lim = 1; dig < pos; dig++) - lim *= 10; - - if (digits || in >= lim || !pos) { - for (dig = 0; in >= lim; dig++) - in -= lim; - buffer[digits++] = '0' + dig; - } - } while (pos--); - - buffer[digits] = 0; - return digits; + return _nolibc_u64toa_base(in, buffer, 10, _NOLIBC_U64TOA_RECIP(10)); } /* Converts the signed long integer <in> to its string representation into @@ -324,34 +360,12 @@ char *utoa(unsigned long in) * buffer <buffer>, which must be long enough to store the number and the * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from * the first byte, and the number of characters emitted (not counting the - * trailing zero) is returned. The function is constructed in a way to optimize - * the code size and avoid any divide that could add a dependency on large - * external functions. + * trailing zero) is returned. */ -static __attribute__((unused)) +static __inline__ __attribute__((unused)) int u64toh_r(uint64_t in, char *buffer) { - signed char pos = 60; - int digits = 0; - int dig; - - do { - if (sizeof(long) >= 8) { - dig = (in >> pos) & 0xF; - } else { - /* 32-bit platforms: avoid a 64-bit shift */ - uint32_t d = (pos >= 32) ? (in >> 32) : in; - dig = (d >> (pos & 31)) & 0xF; - } - if (dig > 9) - dig += 'a' - '0' - 10; - pos -= 4; - if (dig || digits || pos < 0) - buffer[digits++] = '0' + dig; - } while (pos >= 0); - - buffer[digits] = 0; - return digits; + return _nolibc_u64toa_base(in, buffer, 16, _NOLIBC_U64TOA_RECIP(16)); } /* converts uint64_t <in> to an hex string using the static itoa_buffer and @@ -368,31 +382,12 @@ char *u64toh(uint64_t in) * buffer <buffer>, which must be long enough to store the number and the * trailing zero (21 bytes for 18446744073709551615). The buffer is filled from * the first byte, and the number of characters emitted (not counting the - * trailing zero) is returned. The function is constructed in a way to optimize - * the code size and avoid any divide that could add a dependency on large - * external functions. + * trailing zero) is returned. */ -static __attribute__((unused)) +static __inline__ __attribute__((unused)) int u64toa_r(uint64_t in, char *buffer) { - unsigned long long lim; - int digits = 0; - int pos = 19; /* start with the highest possible digit */ - int dig; - - do { - for (dig = 0, lim = 1; dig < pos; dig++) - lim *= 10; - - if (digits || in >= lim || !pos) { - for (dig = 0; in >= lim; dig++) - in -= lim; - buffer[digits++] = '0' + dig; - } - } while (pos--); - - buffer[digits] = 0; - return digits; + return _nolibc_u64toa_base(in, buffer, 10, _NOLIBC_U64TOA_RECIP(10)); } /* Converts the signed 64-bit integer <in> to its string representation into diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h index 403ee9ce8389..6335fd51f07f 100644 --- a/tools/include/nolibc/sys.h +++ b/tools/include/nolibc/sys.h @@ -63,7 +63,7 @@ static __inline__ int __nolibc_enosys(const char *syscall, ...) * - the "internal" ones, which matches the raw syscall interface at the * kernel level, which may sometimes slightly differ from the documented * libc-level ones. For example most of them return either a valid value - * or -errno. All of these are prefixed with "sys_". They may be called + * or -errno. All of these are prefixed with "_sys_". They may be called * by non-portable applications if desired. * * - the "exported" ones, whose interface must closely match the one @@ -85,15 +85,15 @@ static __inline__ int __nolibc_enosys(const char *syscall, ...) */ static __attribute__((unused)) -void *sys_brk(void *addr) +void *_sys_brk(void *addr) { - return (void *)my_syscall1(__NR_brk, addr); + return (void *)__nolibc_syscall1(__NR_brk, addr); } static __attribute__((unused)) int brk(void *addr) { - void *ret = sys_brk(addr); + void *ret = _sys_brk(addr); if (!ret) { SET_ERRNO(ENOMEM); @@ -106,9 +106,9 @@ static __attribute__((unused)) void *sbrk(intptr_t inc) { /* first call to find current end */ - void *ret = sys_brk(NULL); + void *ret = _sys_brk(NULL); - if (ret && sys_brk(ret + inc) == ret + inc) + if (ret && _sys_brk(ret + inc) == ret + inc) return ret + inc; SET_ERRNO(ENOMEM); @@ -122,27 +122,27 @@ void *sbrk(intptr_t inc) */ static __attribute__((unused)) -int sys_chdir(const char *path) +int _sys_chdir(const char *path) { - return my_syscall1(__NR_chdir, path); + return __nolibc_syscall1(__NR_chdir, path); } static __attribute__((unused)) int chdir(const char *path) { - return __sysret(sys_chdir(path)); + return __sysret(_sys_chdir(path)); } static __attribute__((unused)) -int sys_fchdir(int fildes) +int _sys_fchdir(int fildes) { - return my_syscall1(__NR_fchdir, fildes); + return __nolibc_syscall1(__NR_fchdir, fildes); } static __attribute__((unused)) int fchdir(int fildes) { - return __sysret(sys_fchdir(fildes)); + return __sysret(_sys_fchdir(fildes)); } @@ -151,19 +151,19 @@ int fchdir(int fildes) */ static __attribute__((unused)) -int sys_chmod(const char *path, mode_t mode) +int _sys_chmod(const char *path, mode_t mode) { #if defined(__NR_fchmodat) - return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0); + return __nolibc_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0); #else - return my_syscall2(__NR_chmod, path, mode); + return __nolibc_syscall2(__NR_chmod, path, mode); #endif } static __attribute__((unused)) int chmod(const char *path, mode_t mode) { - return __sysret(sys_chmod(path, mode)); + return __sysret(_sys_chmod(path, mode)); } @@ -172,19 +172,19 @@ int chmod(const char *path, mode_t mode) */ static __attribute__((unused)) -int sys_chown(const char *path, uid_t owner, gid_t group) +int _sys_chown(const char *path, uid_t owner, gid_t group) { #if defined(__NR_fchownat) - return my_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0); + return __nolibc_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0); #else - return my_syscall3(__NR_chown, path, owner, group); + return __nolibc_syscall3(__NR_chown, path, owner, group); #endif } static __attribute__((unused)) int chown(const char *path, uid_t owner, gid_t group) { - return __sysret(sys_chown(path, owner, group)); + return __sysret(_sys_chown(path, owner, group)); } @@ -193,15 +193,15 @@ int chown(const char *path, uid_t owner, gid_t group) */ static __attribute__((unused)) -int sys_chroot(const char *path) +int _sys_chroot(const char *path) { - return my_syscall1(__NR_chroot, path); + return __nolibc_syscall1(__NR_chroot, path); } static __attribute__((unused)) int chroot(const char *path) { - return __sysret(sys_chroot(path)); + return __sysret(_sys_chroot(path)); } @@ -210,15 +210,15 @@ int chroot(const char *path) */ static __attribute__((unused)) -int sys_close(int fd) +int _sys_close(int fd) { - return my_syscall1(__NR_close, fd); + return __nolibc_syscall1(__NR_close, fd); } static __attribute__((unused)) int close(int fd) { - return __sysret(sys_close(fd)); + return __sysret(_sys_close(fd)); } @@ -227,15 +227,15 @@ int close(int fd) */ static __attribute__((unused)) -int sys_dup(int fd) +int _sys_dup(int fd) { - return my_syscall1(__NR_dup, fd); + return __nolibc_syscall1(__NR_dup, fd); } static __attribute__((unused)) int dup(int fd) { - return __sysret(sys_dup(fd)); + return __sysret(_sys_dup(fd)); } @@ -244,7 +244,7 @@ int dup(int fd) */ static __attribute__((unused)) -int sys_dup2(int old, int new) +int _sys_dup2(int old, int new) { #if defined(__NR_dup3) int ret, nr_fcntl; @@ -256,20 +256,20 @@ int sys_dup2(int old, int new) #endif if (old == new) { - ret = my_syscall2(nr_fcntl, old, F_GETFD); + ret = __nolibc_syscall2(nr_fcntl, old, F_GETFD); return ret < 0 ? ret : old; } - return my_syscall3(__NR_dup3, old, new, 0); + return __nolibc_syscall3(__NR_dup3, old, new, 0); #else - return my_syscall2(__NR_dup2, old, new); + return __nolibc_syscall2(__NR_dup2, old, new); #endif } static __attribute__((unused)) int dup2(int old, int new) { - return __sysret(sys_dup2(old, new)); + return __sysret(_sys_dup2(old, new)); } @@ -279,15 +279,15 @@ int dup2(int old, int new) #if defined(__NR_dup3) static __attribute__((unused)) -int sys_dup3(int old, int new, int flags) +int _sys_dup3(int old, int new, int flags) { - return my_syscall3(__NR_dup3, old, new, flags); + return __nolibc_syscall3(__NR_dup3, old, new, flags); } static __attribute__((unused)) int dup3(int old, int new, int flags) { - return __sysret(sys_dup3(old, new, flags)); + return __sysret(_sys_dup3(old, new, flags)); } #endif @@ -297,15 +297,15 @@ int dup3(int old, int new, int flags) */ static __attribute__((unused)) -int sys_execve(const char *filename, char *const argv[], char *const envp[]) +int _sys_execve(const char *filename, char *const argv[], char *const envp[]) { - return my_syscall3(__NR_execve, filename, argv, envp); + return __nolibc_syscall3(__NR_execve, filename, argv, envp); } static __attribute__((unused)) int execve(const char *filename, char *const argv[], char *const envp[]) { - return __sysret(sys_execve(filename, argv, envp)); + return __sysret(_sys_execve(filename, argv, envp)); } @@ -314,16 +314,16 @@ int execve(const char *filename, char *const argv[], char *const envp[]) */ static __attribute__((noreturn,unused)) -void sys_exit(int status) +void _sys_exit(int status) { - my_syscall1(__NR_exit, status & 255); + __nolibc_syscall1(__NR_exit, status & 255); while(1); /* shut the "noreturn" warnings. */ } static __attribute__((noreturn,unused)) void _exit(int status) { - sys_exit(status); + _sys_exit(status); } static __attribute__((noreturn,unused)) @@ -337,18 +337,18 @@ void exit(int status) * pid_t fork(void); */ -#ifndef sys_fork +#ifndef _sys_fork static __attribute__((unused)) -pid_t sys_fork(void) +pid_t _sys_fork(void) { #if defined(__NR_clone) /* note: some archs only have clone() and not fork(). Different archs * have a different API, but most archs have the flags on first arg and * will not use the rest with no other flag. */ - return my_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0); + return __nolibc_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0); #else - return my_syscall0(__NR_fork); + return __nolibc_syscall0(__NR_fork); #endif } #endif @@ -356,18 +356,18 @@ pid_t sys_fork(void) static __attribute__((unused)) pid_t fork(void) { - return __sysret(sys_fork()); + return __sysret(_sys_fork()); } -#ifndef sys_vfork +#ifndef _sys_vfork static __attribute__((unused)) -pid_t sys_vfork(void) +pid_t _sys_vfork(void) { #if defined(__NR_clone) - /* See the note in sys_fork(). */ - return my_syscall5(__NR_clone, CLONE_VM | CLONE_VFORK | SIGCHLD, 0, 0, 0, 0); + /* See the note in _sys_fork(). */ + return __nolibc_syscall5(__NR_clone, CLONE_VM | CLONE_VFORK | SIGCHLD, 0, 0, 0, 0); #elif defined(__NR_vfork) - return my_syscall0(__NR_vfork); + return __nolibc_syscall0(__NR_vfork); #endif } #endif @@ -375,7 +375,7 @@ pid_t sys_vfork(void) static __attribute__((unused)) pid_t vfork(void) { - return __sysret(sys_vfork()); + return __sysret(_sys_vfork()); } /* @@ -383,15 +383,15 @@ pid_t vfork(void) */ static __attribute__((unused)) -int sys_fsync(int fd) +int _sys_fsync(int fd) { - return my_syscall1(__NR_fsync, fd); + return __nolibc_syscall1(__NR_fsync, fd); } static __attribute__((unused)) int fsync(int fd) { - return __sysret(sys_fsync(fd)); + return __sysret(_sys_fsync(fd)); } @@ -400,15 +400,15 @@ int fsync(int fd) */ static __attribute__((unused)) -int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count) +int _sys_getdents64(int fd, struct linux_dirent64 *dirp, int count) { - return my_syscall3(__NR_getdents64, fd, dirp, count); + return __nolibc_syscall3(__NR_getdents64, fd, dirp, count); } static __attribute__((unused)) int getdents64(int fd, struct linux_dirent64 *dirp, int count) { - return __sysret(sys_getdents64(fd, dirp, count)); + return __sysret(_sys_getdents64(fd, dirp, count)); } @@ -417,19 +417,19 @@ int getdents64(int fd, struct linux_dirent64 *dirp, int count) */ static __attribute__((unused)) -uid_t sys_geteuid(void) +uid_t _sys_geteuid(void) { #if defined(__NR_geteuid32) - return my_syscall0(__NR_geteuid32); + return __nolibc_syscall0(__NR_geteuid32); #else - return my_syscall0(__NR_geteuid); + return __nolibc_syscall0(__NR_geteuid); #endif } static __attribute__((unused)) uid_t geteuid(void) { - return sys_geteuid(); + return _sys_geteuid(); } @@ -438,15 +438,15 @@ uid_t geteuid(void) */ static __attribute__((unused)) -pid_t sys_getpgid(pid_t pid) +pid_t _sys_getpgid(pid_t pid) { - return my_syscall1(__NR_getpgid, pid); + return __nolibc_syscall1(__NR_getpgid, pid); } static __attribute__((unused)) pid_t getpgid(pid_t pid) { - return __sysret(sys_getpgid(pid)); + return __sysret(_sys_getpgid(pid)); } @@ -455,15 +455,15 @@ pid_t getpgid(pid_t pid) */ static __attribute__((unused)) -pid_t sys_getpgrp(void) +pid_t _sys_getpgrp(void) { - return sys_getpgid(0); + return _sys_getpgid(0); } static __attribute__((unused)) pid_t getpgrp(void) { - return sys_getpgrp(); + return _sys_getpgrp(); } @@ -472,15 +472,15 @@ pid_t getpgrp(void) */ static __attribute__((unused)) -pid_t sys_getpid(void) +pid_t _sys_getpid(void) { - return my_syscall0(__NR_getpid); + return __nolibc_syscall0(__NR_getpid); } static __attribute__((unused)) pid_t getpid(void) { - return sys_getpid(); + return _sys_getpid(); } @@ -489,15 +489,15 @@ pid_t getpid(void) */ static __attribute__((unused)) -pid_t sys_getppid(void) +pid_t _sys_getppid(void) { - return my_syscall0(__NR_getppid); + return __nolibc_syscall0(__NR_getppid); } static __attribute__((unused)) pid_t getppid(void) { - return sys_getppid(); + return _sys_getppid(); } @@ -506,15 +506,15 @@ pid_t getppid(void) */ static __attribute__((unused)) -pid_t sys_gettid(void) +pid_t _sys_gettid(void) { - return my_syscall0(__NR_gettid); + return __nolibc_syscall0(__NR_gettid); } static __attribute__((unused)) pid_t gettid(void) { - return sys_gettid(); + return _sys_gettid(); } #ifndef NOLIBC_NO_RUNTIME @@ -536,19 +536,19 @@ int getpagesize(void) */ static __attribute__((unused)) -uid_t sys_getuid(void) +uid_t _sys_getuid(void) { #if defined(__NR_getuid32) - return my_syscall0(__NR_getuid32); + return __nolibc_syscall0(__NR_getuid32); #else - return my_syscall0(__NR_getuid); + return __nolibc_syscall0(__NR_getuid); #endif } static __attribute__((unused)) uid_t getuid(void) { - return sys_getuid(); + return _sys_getuid(); } @@ -557,15 +557,15 @@ uid_t getuid(void) */ static __attribute__((unused)) -int sys_kill(pid_t pid, int signal) +int _sys_kill(pid_t pid, int signal) { - return my_syscall2(__NR_kill, pid, signal); + return __nolibc_syscall2(__NR_kill, pid, signal); } static __attribute__((unused)) int kill(pid_t pid, int signal) { - return __sysret(sys_kill(pid, signal)); + return __sysret(_sys_kill(pid, signal)); } @@ -574,19 +574,19 @@ int kill(pid_t pid, int signal) */ static __attribute__((unused)) -int sys_link(const char *old, const char *new) +int _sys_link(const char *old, const char *new) { #if defined(__NR_linkat) - return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0); + return __nolibc_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0); #else - return my_syscall2(__NR_link, old, new); + return __nolibc_syscall2(__NR_link, old, new); #endif } static __attribute__((unused)) int link(const char *old, const char *new) { - return __sysret(sys_link(old, new)); + return __sysret(_sys_link(old, new)); } @@ -595,14 +595,14 @@ int link(const char *old, const char *new) */ static __attribute__((unused)) -off_t sys_lseek(int fd, off_t offset, int whence) +off_t _sys_lseek(int fd, off_t offset, int whence) { #if defined(__NR_llseek) __kernel_loff_t loff = 0; off_t result; int ret; - ret = my_syscall5(__NR_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence); + ret = __nolibc_syscall5(__NR_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence); if (ret < 0) result = ret; else @@ -610,14 +610,14 @@ off_t sys_lseek(int fd, off_t offset, int whence) return result; #else - return my_syscall3(__NR_lseek, fd, offset, whence); + return __nolibc_syscall3(__NR_lseek, fd, offset, whence); #endif } static __attribute__((unused)) off_t lseek(int fd, off_t offset, int whence) { - return __sysret(sys_lseek(fd, offset, whence)); + return __sysret(_sys_lseek(fd, offset, whence)); } @@ -626,19 +626,19 @@ off_t lseek(int fd, off_t offset, int whence) */ static __attribute__((unused)) -int sys_mkdir(const char *path, mode_t mode) +int _sys_mkdir(const char *path, mode_t mode) { #if defined(__NR_mkdirat) - return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode); + return __nolibc_syscall3(__NR_mkdirat, AT_FDCWD, path, mode); #else - return my_syscall2(__NR_mkdir, path, mode); + return __nolibc_syscall2(__NR_mkdir, path, mode); #endif } static __attribute__((unused)) int mkdir(const char *path, mode_t mode) { - return __sysret(sys_mkdir(path, mode)); + return __sysret(_sys_mkdir(path, mode)); } /* @@ -646,19 +646,19 @@ int mkdir(const char *path, mode_t mode) */ static __attribute__((unused)) -int sys_rmdir(const char *path) +int _sys_rmdir(const char *path) { #if defined(__NR_rmdir) - return my_syscall1(__NR_rmdir, path); + return __nolibc_syscall1(__NR_rmdir, path); #else - return my_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR); + return __nolibc_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR); #endif } static __attribute__((unused)) int rmdir(const char *path) { - return __sysret(sys_rmdir(path)); + return __sysret(_sys_rmdir(path)); } @@ -667,19 +667,19 @@ int rmdir(const char *path) */ static __attribute__((unused)) -long sys_mknod(const char *path, mode_t mode, dev_t dev) +long _sys_mknod(const char *path, mode_t mode, dev_t dev) { #if defined(__NR_mknodat) - return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev); + return __nolibc_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev); #else - return my_syscall3(__NR_mknod, path, mode, dev); + return __nolibc_syscall3(__NR_mknod, path, mode, dev); #endif } static __attribute__((unused)) int mknod(const char *path, mode_t mode, dev_t dev) { - return __sysret(sys_mknod(path, mode, dev)); + return __sysret(_sys_mknod(path, mode, dev)); } @@ -689,15 +689,15 @@ int mknod(const char *path, mode_t mode, dev_t dev) */ static __attribute__((unused)) -int sys_pipe2(int pipefd[2], int flags) +int _sys_pipe2(int pipefd[2], int flags) { - return my_syscall2(__NR_pipe2, pipefd, flags); + return __nolibc_syscall2(__NR_pipe2, pipefd, flags); } static __attribute__((unused)) int pipe2(int pipefd[2], int flags) { - return __sysret(sys_pipe2(pipefd, flags)); + return __sysret(_sys_pipe2(pipefd, flags)); } static __attribute__((unused)) @@ -712,15 +712,15 @@ int pipe(int pipefd[2]) */ static __attribute__((unused)) -int sys_pivot_root(const char *new, const char *old) +int _sys_pivot_root(const char *new, const char *old) { - return my_syscall2(__NR_pivot_root, new, old); + return __nolibc_syscall2(__NR_pivot_root, new, old); } static __attribute__((unused)) int pivot_root(const char *new, const char *old) { - return __sysret(sys_pivot_root(new, old)); + return __sysret(_sys_pivot_root(new, old)); } @@ -729,15 +729,15 @@ int pivot_root(const char *new, const char *old) */ static __attribute__((unused)) -ssize_t sys_read(int fd, void *buf, size_t count) +ssize_t _sys_read(int fd, void *buf, size_t count) { - return my_syscall3(__NR_read, fd, buf, count); + return __nolibc_syscall3(__NR_read, fd, buf, count); } static __attribute__((unused)) ssize_t read(int fd, void *buf, size_t count) { - return __sysret(sys_read(fd, buf, count)); + return __sysret(_sys_read(fd, buf, count)); } @@ -746,15 +746,15 @@ ssize_t read(int fd, void *buf, size_t count) */ static __attribute__((unused)) -int sys_sched_yield(void) +int _sys_sched_yield(void) { - return my_syscall0(__NR_sched_yield); + return __nolibc_syscall0(__NR_sched_yield); } static __attribute__((unused)) int sched_yield(void) { - return __sysret(sys_sched_yield()); + return __sysret(_sys_sched_yield()); } @@ -763,15 +763,15 @@ int sched_yield(void) */ static __attribute__((unused)) -int sys_setpgid(pid_t pid, pid_t pgid) +int _sys_setpgid(pid_t pid, pid_t pgid) { - return my_syscall2(__NR_setpgid, pid, pgid); + return __nolibc_syscall2(__NR_setpgid, pid, pgid); } static __attribute__((unused)) int setpgid(pid_t pid, pid_t pgid) { - return __sysret(sys_setpgid(pid, pgid)); + return __sysret(_sys_setpgid(pid, pgid)); } /* @@ -790,15 +790,15 @@ pid_t setpgrp(void) */ static __attribute__((unused)) -pid_t sys_setsid(void) +pid_t _sys_setsid(void) { - return my_syscall0(__NR_setsid); + return __nolibc_syscall0(__NR_setsid); } static __attribute__((unused)) pid_t setsid(void) { - return __sysret(sys_setsid()); + return __sysret(_sys_setsid()); } @@ -807,19 +807,19 @@ pid_t setsid(void) */ static __attribute__((unused)) -int sys_symlink(const char *old, const char *new) +int _sys_symlink(const char *old, const char *new) { #if defined(__NR_symlinkat) - return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new); + return __nolibc_syscall3(__NR_symlinkat, old, AT_FDCWD, new); #else - return my_syscall2(__NR_symlink, old, new); + return __nolibc_syscall2(__NR_symlink, old, new); #endif } static __attribute__((unused)) int symlink(const char *old, const char *new) { - return __sysret(sys_symlink(old, new)); + return __sysret(_sys_symlink(old, new)); } @@ -828,15 +828,15 @@ int symlink(const char *old, const char *new) */ static __attribute__((unused)) -mode_t sys_umask(mode_t mode) +mode_t _sys_umask(mode_t mode) { - return my_syscall1(__NR_umask, mode); + return __nolibc_syscall1(__NR_umask, mode); } static __attribute__((unused)) mode_t umask(mode_t mode) { - return sys_umask(mode); + return _sys_umask(mode); } @@ -845,15 +845,15 @@ mode_t umask(mode_t mode) */ static __attribute__((unused)) -int sys_umount2(const char *path, int flags) +int _sys_umount2(const char *path, int flags) { - return my_syscall2(__NR_umount2, path, flags); + return __nolibc_syscall2(__NR_umount2, path, flags); } static __attribute__((unused)) int umount2(const char *path, int flags) { - return __sysret(sys_umount2(path, flags)); + return __sysret(_sys_umount2(path, flags)); } @@ -862,19 +862,19 @@ int umount2(const char *path, int flags) */ static __attribute__((unused)) -int sys_unlink(const char *path) +int _sys_unlink(const char *path) { #if defined(__NR_unlinkat) - return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0); + return __nolibc_syscall3(__NR_unlinkat, AT_FDCWD, path, 0); #else - return my_syscall1(__NR_unlink, path); + return __nolibc_syscall1(__NR_unlink, path); #endif } static __attribute__((unused)) int unlink(const char *path) { - return __sysret(sys_unlink(path)); + return __sysret(_sys_unlink(path)); } @@ -883,15 +883,15 @@ int unlink(const char *path) */ static __attribute__((unused)) -ssize_t sys_write(int fd, const void *buf, size_t count) +ssize_t _sys_write(int fd, const void *buf, size_t count) { - return my_syscall3(__NR_write, fd, buf, count); + return __nolibc_syscall3(__NR_write, fd, buf, count); } static __attribute__((unused)) ssize_t write(int fd, const void *buf, size_t count) { - return __sysret(sys_write(fd, buf, count)); + return __sysret(_sys_write(fd, buf, count)); } @@ -900,15 +900,15 @@ ssize_t write(int fd, const void *buf, size_t count) */ static __attribute__((unused)) -int sys_memfd_create(const char *name, unsigned int flags) +int _sys_memfd_create(const char *name, unsigned int flags) { - return my_syscall2(__NR_memfd_create, name, flags); + return __nolibc_syscall2(__NR_memfd_create, name, flags); } static __attribute__((unused)) int memfd_create(const char *name, unsigned int flags) { - return __sysret(sys_memfd_create(name, flags)); + return __sysret(_sys_memfd_create(name, flags)); } #endif /* _NOLIBC_SYS_H */ diff --git a/tools/include/nolibc/sys/ioctl.h b/tools/include/nolibc/sys/ioctl.h index fc880687e02a..f062a7b806cf 100644 --- a/tools/include/nolibc/sys/ioctl.h +++ b/tools/include/nolibc/sys/ioctl.h @@ -19,11 +19,11 @@ */ static __attribute__((unused)) -long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +long _sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { - return my_syscall3(__NR_ioctl, fd, cmd, arg); + return __nolibc_syscall3(__NR_ioctl, fd, cmd, arg); } -#define ioctl(fd, cmd, arg) __sysret(sys_ioctl(fd, cmd, (unsigned long)(arg))) +#define ioctl(fd, cmd, arg) __sysret(_sys_ioctl(fd, cmd, (unsigned long)(arg))) #endif /* _NOLIBC_SYS_IOCTL_H */ diff --git a/tools/include/nolibc/sys/mman.h b/tools/include/nolibc/sys/mman.h index 77084ac3405a..91d77a51412d 100644 --- a/tools/include/nolibc/sys/mman.h +++ b/tools/include/nolibc/sys/mman.h @@ -13,10 +13,10 @@ #include "../arch.h" #include "../sys.h" -#ifndef sys_mmap +#ifndef _sys_mmap static __attribute__((unused)) -void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, - off_t offset) +void *_sys_mmap(void *addr, size_t length, int prot, int flags, int fd, + off_t offset) { int n; @@ -27,14 +27,14 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, n = __NR_mmap; #endif - return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset); + return (void *)__nolibc_syscall6(n, addr, length, prot, flags, fd, offset); } #endif static __attribute__((unused)) void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { - void *ret = sys_mmap(addr, length, prot, flags, fd, offset); + void *ret = _sys_mmap(addr, length, prot, flags, fd, offset); if ((unsigned long)ret >= -4095UL) { SET_ERRNO(-(long)ret); @@ -44,16 +44,16 @@ 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) +void *_sys_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address) { - return (void *)my_syscall5(__NR_mremap, old_address, old_size, - new_size, flags, new_address); + return (void *)__nolibc_syscall5(__NR_mremap, old_address, old_size, + new_size, flags, new_address); } static __attribute__((unused)) void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address) { - void *ret = sys_mremap(old_address, old_size, new_size, flags, new_address); + void *ret = _sys_mremap(old_address, old_size, new_size, flags, new_address); if ((unsigned long)ret >= -4095UL) { SET_ERRNO(-(long)ret); @@ -63,15 +63,15 @@ void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, voi } static __attribute__((unused)) -int sys_munmap(void *addr, size_t length) +int _sys_munmap(void *addr, size_t length) { - return my_syscall2(__NR_munmap, addr, length); + return __nolibc_syscall2(__NR_munmap, addr, length); } static __attribute__((unused)) int munmap(void *addr, size_t length) { - return __sysret(sys_munmap(addr, length)); + return __sysret(_sys_munmap(addr, length)); } #endif /* _NOLIBC_SYS_MMAN_H */ diff --git a/tools/include/nolibc/sys/mount.h b/tools/include/nolibc/sys/mount.h index e39ec02ea24c..8d3128ebc536 100644 --- a/tools/include/nolibc/sys/mount.h +++ b/tools/include/nolibc/sys/mount.h @@ -20,10 +20,10 @@ * const void *data); */ static __attribute__((unused)) -int sys_mount(const char *src, const char *tgt, const char *fst, - unsigned long flags, const void *data) +int _sys_mount(const char *src, const char *tgt, const char *fst, + unsigned long flags, const void *data) { - return my_syscall5(__NR_mount, src, tgt, fst, flags, data); + return __nolibc_syscall5(__NR_mount, src, tgt, fst, flags, data); } static __attribute__((unused)) @@ -31,7 +31,7 @@ int mount(const char *src, const char *tgt, const char *fst, unsigned long flags, const void *data) { - return __sysret(sys_mount(src, tgt, fst, flags, data)); + return __sysret(_sys_mount(src, tgt, fst, flags, data)); } #endif /* _NOLIBC_SYS_MOUNT_H */ diff --git a/tools/include/nolibc/sys/prctl.h b/tools/include/nolibc/sys/prctl.h index 0205907b6ac8..3e11d3e5af12 100644 --- a/tools/include/nolibc/sys/prctl.h +++ b/tools/include/nolibc/sys/prctl.h @@ -20,17 +20,17 @@ */ static __attribute__((unused)) -int sys_prctl(int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) +int _sys_prctl(int option, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5) { - return my_syscall5(__NR_prctl, option, arg2, arg3, arg4, arg5); + return __nolibc_syscall5(__NR_prctl, option, arg2, arg3, arg4, arg5); } static __attribute__((unused)) int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { - return __sysret(sys_prctl(option, arg2, arg3, arg4, arg5)); + return __sysret(_sys_prctl(option, arg2, arg3, arg4, arg5)); } #endif /* _NOLIBC_SYS_PRCTL_H */ diff --git a/tools/include/nolibc/sys/ptrace.h b/tools/include/nolibc/sys/ptrace.h index 72ca28541633..4c4820f4f336 100644 --- a/tools/include/nolibc/sys/ptrace.h +++ b/tools/include/nolibc/sys/ptrace.h @@ -19,15 +19,15 @@ * long ptrace(int op, pid_t pid, void *addr, void *data); */ static __attribute__((unused)) -long sys_ptrace(int op, pid_t pid, void *addr, void *data) +long _sys_ptrace(int op, pid_t pid, void *addr, void *data) { - return my_syscall4(__NR_ptrace, op, pid, addr, data); + return __nolibc_syscall4(__NR_ptrace, op, pid, addr, data); } static __attribute__((unused)) ssize_t ptrace(int op, pid_t pid, void *addr, void *data) { - return __sysret(sys_ptrace(op, pid, addr, data)); + return __sysret(_sys_ptrace(op, pid, addr, data)); } #endif /* _NOLIBC_SYS_PTRACE_H */ diff --git a/tools/include/nolibc/sys/random.h b/tools/include/nolibc/sys/random.h index cd5d25c571a8..6d055b00bd90 100644 --- a/tools/include/nolibc/sys/random.h +++ b/tools/include/nolibc/sys/random.h @@ -20,15 +20,15 @@ */ static __attribute__((unused)) -ssize_t sys_getrandom(void *buf, size_t buflen, unsigned int flags) +ssize_t _sys_getrandom(void *buf, size_t buflen, unsigned int flags) { - return my_syscall3(__NR_getrandom, buf, buflen, flags); + return __nolibc_syscall3(__NR_getrandom, buf, buflen, flags); } static __attribute__((unused)) ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) { - return __sysret(sys_getrandom(buf, buflen, flags)); + return __sysret(_sys_getrandom(buf, buflen, flags)); } #endif /* _NOLIBC_SYS_RANDOM_H */ diff --git a/tools/include/nolibc/sys/reboot.h b/tools/include/nolibc/sys/reboot.h index 38274c64a722..73cbca37c1f0 100644 --- a/tools/include/nolibc/sys/reboot.h +++ b/tools/include/nolibc/sys/reboot.h @@ -20,15 +20,15 @@ */ static __attribute__((unused)) -ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg) +ssize_t _sys_reboot(int magic1, int magic2, int cmd, void *arg) { - return my_syscall4(__NR_reboot, magic1, magic2, cmd, arg); + return __nolibc_syscall4(__NR_reboot, magic1, magic2, cmd, arg); } static __attribute__((unused)) int reboot(int cmd) { - return __sysret(sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, NULL)); + return __sysret(_sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, NULL)); } #endif /* _NOLIBC_SYS_REBOOT_H */ diff --git a/tools/include/nolibc/sys/resource.h b/tools/include/nolibc/sys/resource.h index b990f914dc56..f35de1c4e9ad 100644 --- a/tools/include/nolibc/sys/resource.h +++ b/tools/include/nolibc/sys/resource.h @@ -20,10 +20,10 @@ */ static __attribute__((unused)) -int sys_prlimit64(pid_t pid, int resource, - const struct rlimit64 *new_limit, struct rlimit64 *old_limit) +int _sys_prlimit64(pid_t pid, int resource, + const struct rlimit64 *new_limit, struct rlimit64 *old_limit) { - return my_syscall4(__NR_prlimit64, pid, resource, new_limit, old_limit); + return __nolibc_syscall4(__NR_prlimit64, pid, resource, new_limit, old_limit); } static __attribute__((unused)) @@ -32,7 +32,7 @@ int getrlimit(int resource, struct rlimit *rlim) struct rlimit64 rlim64; int ret; - ret = __sysret(sys_prlimit64(0, resource, NULL, &rlim64)); + ret = __sysret(_sys_prlimit64(0, resource, NULL, &rlim64)); rlim->rlim_cur = rlim64.rlim_cur; rlim->rlim_max = rlim64.rlim_max; @@ -47,7 +47,7 @@ int setrlimit(int resource, const struct rlimit *rlim) .rlim_max = rlim->rlim_max, }; - return __sysret(sys_prlimit64(0, resource, &rlim64, NULL)); + return __sysret(_sys_prlimit64(0, resource, &rlim64, NULL)); } #endif /* _NOLIBC_SYS_RESOURCE_H */ diff --git a/tools/include/nolibc/sys/select.h b/tools/include/nolibc/sys/select.h index 80cb3755ba18..6d65d9ef3d6a 100644 --- a/tools/include/nolibc/sys/select.h +++ b/tools/include/nolibc/sys/select.h @@ -61,7 +61,7 @@ typedef struct { */ static __attribute__((unused)) -int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) +int _sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) { #if defined(__NR_pselect6_time64) struct __kernel_timespec t; @@ -70,7 +70,8 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva t.tv_sec = timeout->tv_sec; t.tv_nsec = (uint32_t)timeout->tv_usec * 1000; } - return my_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); + return __nolibc_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, + timeout ? &t : NULL, NULL); #else struct __kernel_old_timespec t; @@ -78,14 +79,15 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva t.tv_sec = timeout->tv_sec; t.tv_nsec = (uint32_t)timeout->tv_usec * 1000; } - return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); + return __nolibc_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, + timeout ? &t : NULL, NULL); #endif } static __attribute__((unused)) int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) { - return __sysret(sys_select(nfds, rfds, wfds, efds, timeout)); + return __sysret(_sys_select(nfds, rfds, wfds, efds, timeout)); } diff --git a/tools/include/nolibc/sys/stat.h b/tools/include/nolibc/sys/stat.h index 8b4d80e3ea03..07ae715ff253 100644 --- a/tools/include/nolibc/sys/stat.h +++ b/tools/include/nolibc/sys/stat.h @@ -13,6 +13,7 @@ #include "../arch.h" #include "../types.h" #include "../sys.h" +#include "../sys/sysmacros.h" /* * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf); @@ -23,10 +24,10 @@ */ static __attribute__((unused)) -int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf) +int _sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf) { #ifdef __NR_statx - return my_syscall5(__NR_statx, fd, path, flags, mask, buf); + return __nolibc_syscall5(__NR_statx, fd, path, flags, mask, buf); #else return __nolibc_enosys(__func__, fd, path, flags, mask, buf); #endif @@ -35,7 +36,7 @@ int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct sta static __attribute__((unused)) int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf) { - return __sysret(sys_statx(fd, path, flags, mask, buf)); + return __sysret(_sys_statx(fd, path, flags, mask, buf)); } @@ -45,21 +46,17 @@ int fstatat(int fd, const char *path, struct stat *buf, int flag) struct statx statx; long ret; - ret = __sysret(sys_statx(fd, path, flag | AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &statx)); + ret = __sysret(_sys_statx(fd, path, flag | AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &statx)); if (ret == -1) return ret; - buf->st_dev = ((statx.stx_dev_minor & 0xff) - | (statx.stx_dev_major << 8) - | ((statx.stx_dev_minor & ~0xff) << 12)); + buf->st_dev = makedev(statx.stx_dev_major, statx.stx_dev_minor); buf->st_ino = statx.stx_ino; buf->st_mode = statx.stx_mode; buf->st_nlink = statx.stx_nlink; buf->st_uid = statx.stx_uid; buf->st_gid = statx.stx_gid; - buf->st_rdev = ((statx.stx_rdev_minor & 0xff) - | (statx.stx_rdev_major << 8) - | ((statx.stx_rdev_minor & ~0xff) << 12)); + buf->st_rdev = makedev(statx.stx_rdev_major, statx.stx_rdev_minor); buf->st_size = statx.stx_size; buf->st_blksize = statx.stx_blksize; buf->st_blocks = statx.stx_blocks; diff --git a/tools/include/nolibc/sys/syscall.h b/tools/include/nolibc/sys/syscall.h index 4bf97f1386a0..7f06314fcf0d 100644 --- a/tools/include/nolibc/sys/syscall.h +++ b/tools/include/nolibc/sys/syscall.h @@ -10,10 +10,11 @@ #ifndef _NOLIBC_SYS_SYSCALL_H #define _NOLIBC_SYS_SYSCALL_H -#define __syscall_narg(_0, _1, _2, _3, _4, _5, _6, N, ...) N -#define _syscall_narg(...) __syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0) -#define _syscall(N, ...) __sysret(my_syscall##N(__VA_ARGS__)) -#define _syscall_n(N, ...) _syscall(N, __VA_ARGS__) -#define syscall(...) _syscall_n(_syscall_narg(__VA_ARGS__), ##__VA_ARGS__) +#define ___nolibc_syscall_narg(_0, _1, _2, _3, _4, _5, _6, N, ...) N +#define __nolibc_syscall_narg(...) ___nolibc_syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0) +#define __nolibc_syscall(N, ...) __nolibc_syscall##N(__VA_ARGS__) +#define __nolibc_syscall_n(N, ...) __nolibc_syscall(N, __VA_ARGS__) +#define _syscall(...) __nolibc_syscall_n(__nolibc_syscall_narg(__VA_ARGS__), ##__VA_ARGS__) +#define syscall(...) __sysret(_syscall(__VA_ARGS__)) #endif /* _NOLIBC_SYS_SYSCALL_H */ diff --git a/tools/include/nolibc/sys/sysmacros.h b/tools/include/nolibc/sys/sysmacros.h index 37c33f030f02..ff9dd85ca59c 100644 --- a/tools/include/nolibc/sys/sysmacros.h +++ b/tools/include/nolibc/sys/sysmacros.h @@ -12,9 +12,26 @@ #include "../std.h" -/* WARNING, it only deals with the 4096 first majors and 256 first minors */ -#define makedev(major, minor) ((dev_t)((((major) & 0xfff) << 8) | ((minor) & 0xff))) -#define major(dev) ((unsigned int)(((dev) >> 8) & 0xfff)) -#define minor(dev) ((unsigned int)((dev) & 0xff)) +static __inline__ dev_t __nolibc_makedev(unsigned int maj, unsigned int min) +{ + return (((dev_t)maj & ~0xfff) << 32) | ((maj & 0xfff) << 8) | + (((dev_t)min & ~0xff) << 12) | (min & 0xff); +} + +#define makedev(maj, min) __nolibc_makedev(maj, min) + +static __inline__ unsigned int __nolibc_major(dev_t dev) +{ + return ((dev >> 32) & ~0xfff) | ((dev >> 8) & 0xfff); +} + +#define major(dev) __nolibc_major(dev) + +static __inline__ unsigned int __nolibc_minor(dev_t dev) +{ + return ((dev >> 12) & ~0xff) | (dev & 0xff); +} + +#define minor(dev) __nolibc_minor(dev) #endif /* _NOLIBC_SYS_SYSMACROS_H */ diff --git a/tools/include/nolibc/sys/time.h b/tools/include/nolibc/sys/time.h index afdb7e326df1..c3bb47f69f06 100644 --- a/tools/include/nolibc/sys/time.h +++ b/tools/include/nolibc/sys/time.h @@ -13,21 +13,21 @@ #include "../arch.h" #include "../sys.h" -static int sys_clock_gettime(clockid_t clockid, struct timespec *tp); +static int _sys_clock_gettime(clockid_t clockid, struct timespec *tp); /* * int gettimeofday(struct timeval *tv, struct timezone *tz); */ static __attribute__((unused)) -int sys_gettimeofday(struct timeval *tv, struct timezone *tz) +int _sys_gettimeofday(struct timeval *tv, struct timezone *tz) { (void) tz; /* Non-NULL tz is undefined behaviour */ struct timespec tp; int ret; - ret = sys_clock_gettime(CLOCK_REALTIME, &tp); + ret = _sys_clock_gettime(CLOCK_REALTIME, &tp); if (!ret && tv) { tv->tv_sec = tp.tv_sec; tv->tv_usec = (uint32_t)tp.tv_nsec / 1000; @@ -39,7 +39,7 @@ int sys_gettimeofday(struct timeval *tv, struct timezone *tz) static __attribute__((unused)) int gettimeofday(struct timeval *tv, struct timezone *tz) { - return __sysret(sys_gettimeofday(tv, tz)); + return __sysret(_sys_gettimeofday(tv, tz)); } #endif /* _NOLIBC_SYS_TIME_H */ diff --git a/tools/include/nolibc/sys/timerfd.h b/tools/include/nolibc/sys/timerfd.h index 29fd92bd47d2..cb7fef37a7a4 100644 --- a/tools/include/nolibc/sys/timerfd.h +++ b/tools/include/nolibc/sys/timerfd.h @@ -17,47 +17,47 @@ static __attribute__((unused)) -int sys_timerfd_create(int clockid, int flags) +int _sys_timerfd_create(int clockid, int flags) { - return my_syscall2(__NR_timerfd_create, clockid, flags); + return __nolibc_syscall2(__NR_timerfd_create, clockid, flags); } static __attribute__((unused)) int timerfd_create(int clockid, int flags) { - return __sysret(sys_timerfd_create(clockid, flags)); + return __sysret(_sys_timerfd_create(clockid, flags)); } static __attribute__((unused)) -int sys_timerfd_gettime(int fd, struct itimerspec *curr_value) +int _sys_timerfd_gettime(int fd, struct itimerspec *curr_value) { #if defined(__NR_timerfd_gettime64) __nolibc_assert_time64_type(curr_value->it_value.tv_sec); - return my_syscall2(__NR_timerfd_gettime64, fd, curr_value); + return __nolibc_syscall2(__NR_timerfd_gettime64, fd, curr_value); #else __nolibc_assert_native_time64(); - return my_syscall2(__NR_timerfd_gettime, fd, curr_value); + return __nolibc_syscall2(__NR_timerfd_gettime, fd, curr_value); #endif } static __attribute__((unused)) int timerfd_gettime(int fd, struct itimerspec *curr_value) { - return __sysret(sys_timerfd_gettime(fd, curr_value)); + return __sysret(_sys_timerfd_gettime(fd, curr_value)); } static __attribute__((unused)) -int sys_timerfd_settime(int fd, int flags, - const struct itimerspec *new_value, struct itimerspec *old_value) +int _sys_timerfd_settime(int fd, int flags, + const struct itimerspec *new_value, struct itimerspec *old_value) { #if defined(__NR_timerfd_settime64) __nolibc_assert_time64_type(new_value->it_value.tv_sec); - return my_syscall4(__NR_timerfd_settime64, fd, flags, new_value, old_value); + return __nolibc_syscall4(__NR_timerfd_settime64, fd, flags, new_value, old_value); #else __nolibc_assert_native_time64(); - return my_syscall4(__NR_timerfd_settime, fd, flags, new_value, old_value); + return __nolibc_syscall4(__NR_timerfd_settime, fd, flags, new_value, old_value); #endif } @@ -65,7 +65,7 @@ static __attribute__((unused)) int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value) { - return __sysret(sys_timerfd_settime(fd, flags, new_value, old_value)); + return __sysret(_sys_timerfd_settime(fd, flags, new_value, old_value)); } #endif /* _NOLIBC_SYS_TIMERFD_H */ diff --git a/tools/include/nolibc/sys/uio.h b/tools/include/nolibc/sys/uio.h index 7ad42b927d2f..06bf17ddd5d2 100644 --- a/tools/include/nolibc/sys/uio.h +++ b/tools/include/nolibc/sys/uio.h @@ -19,30 +19,30 @@ * ssize_t readv(int fd, const struct iovec *iovec, int count); */ static __attribute__((unused)) -ssize_t sys_readv(int fd, const struct iovec *iovec, int count) +ssize_t _sys_readv(int fd, const struct iovec *iovec, int count) { - return my_syscall3(__NR_readv, fd, iovec, count); + return __nolibc_syscall3(__NR_readv, fd, iovec, count); } static __attribute__((unused)) ssize_t readv(int fd, const struct iovec *iovec, int count) { - return __sysret(sys_readv(fd, iovec, count)); + return __sysret(_sys_readv(fd, iovec, count)); } /* * ssize_t writev(int fd, const struct iovec *iovec, int count); */ static __attribute__((unused)) -ssize_t sys_writev(int fd, const struct iovec *iovec, int count) +ssize_t _sys_writev(int fd, const struct iovec *iovec, int count) { - return my_syscall3(__NR_writev, fd, iovec, count); + return __nolibc_syscall3(__NR_writev, fd, iovec, count); } static __attribute__((unused)) ssize_t writev(int fd, const struct iovec *iovec, int count) { - return __sysret(sys_writev(fd, iovec, count)); + return __sysret(_sys_writev(fd, iovec, count)); } diff --git a/tools/include/nolibc/sys/utsname.h b/tools/include/nolibc/sys/utsname.h index 01023e1bb439..2aaf873b7985 100644 --- a/tools/include/nolibc/sys/utsname.h +++ b/tools/include/nolibc/sys/utsname.h @@ -28,15 +28,15 @@ struct utsname { }; static __attribute__((unused)) -int sys_uname(struct utsname *buf) +int _sys_uname(struct utsname *buf) { - return my_syscall1(__NR_uname, buf); + return __nolibc_syscall1(__NR_uname, buf); } static __attribute__((unused)) int uname(struct utsname *buf) { - return __sysret(sys_uname(buf)); + return __sysret(_sys_uname(buf)); } #endif /* _NOLIBC_SYS_UTSNAME_H */ diff --git a/tools/include/nolibc/sys/wait.h b/tools/include/nolibc/sys/wait.h index 9d9319ba92cb..7a1feb2b66fc 100644 --- a/tools/include/nolibc/sys/wait.h +++ b/tools/include/nolibc/sys/wait.h @@ -21,15 +21,15 @@ */ static __attribute__((unused)) -int sys_waitid(int which, pid_t pid, siginfo_t *infop, int options, struct rusage *rusage) +int _sys_waitid(int which, pid_t pid, siginfo_t *infop, int options, struct rusage *rusage) { - return my_syscall5(__NR_waitid, which, pid, infop, options, rusage); + return __nolibc_syscall5(__NR_waitid, which, pid, infop, options, rusage); } static __attribute__((unused)) int waitid(int which, pid_t pid, siginfo_t *infop, int options) { - return __sysret(sys_waitid(which, pid, infop, options, NULL)); + return __sysret(_sys_waitid(which, pid, infop, options, NULL)); } diff --git a/tools/include/nolibc/time.h b/tools/include/nolibc/time.h index f9257d6a7878..9ba930710ff9 100644 --- a/tools/include/nolibc/time.h +++ b/tools/include/nolibc/time.h @@ -33,69 +33,69 @@ */ static __attribute__((unused)) -int sys_clock_getres(clockid_t clockid, struct timespec *res) +int _sys_clock_getres(clockid_t clockid, struct timespec *res) { #if defined(__NR_clock_getres_time64) __nolibc_assert_time64_type(res->tv_sec); - return my_syscall2(__NR_clock_getres_time64, clockid, res); + return __nolibc_syscall2(__NR_clock_getres_time64, clockid, res); #else __nolibc_assert_native_time64(); - return my_syscall2(__NR_clock_getres, clockid, res); + return __nolibc_syscall2(__NR_clock_getres, clockid, res); #endif } static __attribute__((unused)) int clock_getres(clockid_t clockid, struct timespec *res) { - return __sysret(sys_clock_getres(clockid, res)); + return __sysret(_sys_clock_getres(clockid, res)); } static __attribute__((unused)) -int sys_clock_gettime(clockid_t clockid, struct timespec *tp) +int _sys_clock_gettime(clockid_t clockid, struct timespec *tp) { #if defined(__NR_clock_gettime64) __nolibc_assert_time64_type(tp->tv_sec); - return my_syscall2(__NR_clock_gettime64, clockid, tp); + return __nolibc_syscall2(__NR_clock_gettime64, clockid, tp); #else __nolibc_assert_native_time64(); - return my_syscall2(__NR_clock_gettime, clockid, tp); + return __nolibc_syscall2(__NR_clock_gettime, clockid, tp); #endif } static __attribute__((unused)) int clock_gettime(clockid_t clockid, struct timespec *tp) { - return __sysret(sys_clock_gettime(clockid, tp)); + return __sysret(_sys_clock_gettime(clockid, tp)); } static __attribute__((unused)) -int sys_clock_settime(clockid_t clockid, struct timespec *tp) +int _sys_clock_settime(clockid_t clockid, struct timespec *tp) { #if defined(__NR_clock_settime64) __nolibc_assert_time64_type(tp->tv_sec); - return my_syscall2(__NR_clock_settime64, clockid, tp); + return __nolibc_syscall2(__NR_clock_settime64, clockid, tp); #else __nolibc_assert_native_time64(); - return my_syscall2(__NR_clock_settime, clockid, tp); + return __nolibc_syscall2(__NR_clock_settime, clockid, tp); #endif } static __attribute__((unused)) int clock_settime(clockid_t clockid, struct timespec *tp) { - return __sysret(sys_clock_settime(clockid, tp)); + return __sysret(_sys_clock_settime(clockid, tp)); } static __attribute__((unused)) -int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, - struct timespec *rmtp) +int _sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, + struct timespec *rmtp) { #if defined(__NR_clock_nanosleep_time64) __nolibc_assert_time64_type(rqtp->tv_sec); - return my_syscall4(__NR_clock_nanosleep_time64, clockid, flags, rqtp, rmtp); + return __nolibc_syscall4(__NR_clock_nanosleep_time64, clockid, flags, rqtp, rmtp); #else __nolibc_assert_native_time64(); - return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp); + return __nolibc_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp); #endif } @@ -104,7 +104,7 @@ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, struct timespec *rmtp) { /* Directly return a positive error number */ - return -sys_clock_nanosleep(clockid, flags, rqtp, rmtp); + return -_sys_clock_nanosleep(clockid, flags, rqtp, rmtp); } static __inline__ @@ -116,7 +116,7 @@ double difftime(time_t time1, time_t time2) static __inline__ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) { - return __sysret(sys_clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rmtp)); + return __sysret(_sys_clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rmtp)); } @@ -126,7 +126,7 @@ time_t time(time_t *tptr) struct timeval tv; /* note, cannot fail here */ - sys_gettimeofday(&tv, NULL); + _sys_gettimeofday(&tv, NULL); if (tptr) *tptr = tv.tv_sec; @@ -141,57 +141,57 @@ time_t time(time_t *tptr) */ static __attribute__((unused)) -int sys_timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid) +int _sys_timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid) { - return my_syscall3(__NR_timer_create, clockid, evp, timerid); + return __nolibc_syscall3(__NR_timer_create, clockid, evp, timerid); } static __attribute__((unused)) int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid) { - return __sysret(sys_timer_create(clockid, evp, timerid)); + return __sysret(_sys_timer_create(clockid, evp, timerid)); } static __attribute__((unused)) -int sys_timer_delete(timer_t timerid) +int _sys_timer_delete(timer_t timerid) { - return my_syscall1(__NR_timer_delete, timerid); + return __nolibc_syscall1(__NR_timer_delete, timerid); } static __attribute__((unused)) int timer_delete(timer_t timerid) { - return __sysret(sys_timer_delete(timerid)); + return __sysret(_sys_timer_delete(timerid)); } static __attribute__((unused)) -int sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value) +int _sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value) { #if defined(__NR_timer_gettime64) __nolibc_assert_time64_type(curr_value->it_value.tv_sec); - return my_syscall2(__NR_timer_gettime64, timerid, curr_value); + return __nolibc_syscall2(__NR_timer_gettime64, timerid, curr_value); #else __nolibc_assert_native_time64(); - return my_syscall2(__NR_timer_gettime, timerid, curr_value); + return __nolibc_syscall2(__NR_timer_gettime, timerid, curr_value); #endif } static __attribute__((unused)) int timer_gettime(timer_t timerid, struct itimerspec *curr_value) { - return __sysret(sys_timer_gettime(timerid, curr_value)); + return __sysret(_sys_timer_gettime(timerid, curr_value)); } static __attribute__((unused)) -int sys_timer_settime(timer_t timerid, int flags, - const struct itimerspec *new_value, struct itimerspec *old_value) +int _sys_timer_settime(timer_t timerid, int flags, + const struct itimerspec *new_value, struct itimerspec *old_value) { #if defined(__NR_timer_settime64) __nolibc_assert_time64_type(new_value->it_value.tv_sec); - return my_syscall4(__NR_timer_settime64, timerid, flags, new_value, old_value); + return __nolibc_syscall4(__NR_timer_settime64, timerid, flags, new_value, old_value); #else __nolibc_assert_native_time64(); - return my_syscall4(__NR_timer_settime, timerid, flags, new_value, old_value); + return __nolibc_syscall4(__NR_timer_settime, timerid, flags, new_value, old_value); #endif } @@ -199,7 +199,7 @@ static __attribute__((unused)) int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec *old_value) { - return __sysret(sys_timer_settime(timerid, flags, new_value, old_value)); + return __sysret(_sys_timer_settime(timerid, flags, new_value, old_value)); } #endif /* _NOLIBC_TIME_H */ diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h index bb5e80f3f05d..5882a6862066 100644 --- a/tools/include/nolibc/unistd.h +++ b/tools/include/nolibc/unistd.h @@ -31,15 +31,15 @@ */ static __attribute__((unused)) -int sys_faccessat(int fd, const char *path, int amode, int flag) +int _sys_faccessat(int fd, const char *path, int amode, int flag) { - return my_syscall4(__NR_faccessat, fd, path, amode, flag); + return __nolibc_syscall4(__NR_faccessat, fd, path, amode, flag); } static __attribute__((unused)) int faccessat(int fd, const char *path, int amode, int flag) { - return __sysret(sys_faccessat(fd, path, amode, flag)); + return __sysret(_sys_faccessat(fd, path, amode, flag)); } static __attribute__((unused)) @@ -54,7 +54,7 @@ int msleep(unsigned int msecs) { struct timeval my_timeval = { msecs / 1000, (msecs % 1000) * 1000 }; - if (sys_select(0, NULL, NULL, NULL, &my_timeval) < 0) + if (_sys_select(0, NULL, NULL, NULL, &my_timeval) < 0) return (my_timeval.tv_sec * 1000) + (my_timeval.tv_usec / 1000) + !!(my_timeval.tv_usec % 1000); @@ -67,7 +67,7 @@ unsigned int sleep(unsigned int seconds) { struct timeval my_timeval = { seconds, 0 }; - if (sys_select(0, NULL, NULL, NULL, &my_timeval) < 0) + if (_sys_select(0, NULL, NULL, NULL, &my_timeval) < 0) return my_timeval.tv_sec + !!my_timeval.tv_usec; else return 0; @@ -78,7 +78,7 @@ int usleep(unsigned int usecs) { struct timeval my_timeval = { usecs / 1000000, usecs % 1000000 }; - return sys_select(0, NULL, NULL, NULL, &my_timeval); + return _sys_select(0, NULL, NULL, NULL, &my_timeval); } static __attribute__((unused)) diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile index 0370489d938b..6bace04227a7 100644 --- a/tools/testing/selftests/nolibc/Makefile +++ b/tools/testing/selftests/nolibc/Makefile @@ -13,9 +13,9 @@ $(OUTPUT)/nolibc-test: CFLAGS = -nostdlib -nostdinc -static \ -isystem $(top_srcdir)/tools/include/nolibc -isystem $(top_srcdir)/usr/include \ $(CFLAGS_NOLIBC_TEST) $(OUTPUT)/nolibc-test: LDLIBS = $(if $(LLVM),,-lgcc) -$(OUTPUT)/nolibc-test: nolibc-test.c nolibc-test-linkage.c | headers +$(OUTPUT)/nolibc-test: $(NOLIBC_TEST_SOURCES) | headers -$(OUTPUT)/libc-test: nolibc-test.c nolibc-test-linkage.c +$(OUTPUT)/libc-test: $(NOLIBC_TEST_SOURCES) $(call msg,CC,,$@) $(Q)$(LINK.c) $^ -o $@ diff --git a/tools/testing/selftests/nolibc/Makefile.include b/tools/testing/selftests/nolibc/Makefile.include index 66287fafbbe0..96fe2bc2191e 100644 --- a/tools/testing/selftests/nolibc/Makefile.include +++ b/tools/testing/selftests/nolibc/Makefile.include @@ -5,6 +5,9 @@ _CFLAGS_STACKPROTECTOR ?= $(call try-run, \ echo 'void foo(void) {}' | $(CC) -x c - -o - -S $(CLANG_CROSS_FLAGS) $(__CFLAGS_STACKPROTECTOR) | grep -q __stack_chk_guard, \ $(__CFLAGS_STACKPROTECTOR)) _CFLAGS_SANITIZER ?= $(call cc-option,-fsanitize=undefined -fsanitize-trap=all) -CFLAGS_NOLIBC_TEST ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 -W -Wall -Wextra \ +CFLAGS_NOLIBC_TEST ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \ + -W -Wall -Wextra -Wundef \ $(call cc-option,-fno-stack-protector) $(call cc-option,-Wmissing-prototypes) \ $(_CFLAGS_STACKPROTECTOR) $(_CFLAGS_SANITIZER) + +NOLIBC_TEST_SOURCES := nolibc-test.c nolibc-test-linkage.c nolibc-test-ignore-errno.c diff --git a/tools/testing/selftests/nolibc/Makefile.nolibc b/tools/testing/selftests/nolibc/Makefile.nolibc index f5704193038f..f30bc68470cc 100644 --- a/tools/testing/selftests/nolibc/Makefile.nolibc +++ b/tools/testing/selftests/nolibc/Makefile.nolibc @@ -232,23 +232,14 @@ ifeq ($(origin XARCH),command line) CFLAGS_XARCH = $(CFLAGS_$(XARCH)) endif +LDLIBS_ppc = $(if $(LLVM),,-lgcc) +LDLIBS = $(LDLIBS_$(XARCH)) + include Makefile.include CFLAGS ?= $(CFLAGS_NOLIBC_TEST) $(CFLAGS_XARCH) $(CFLAGS_EXTRA) LDFLAGS := -LIBGCC := -lgcc - -ifeq ($(ARCH),x86) -# Not needed on x86, probably not present for x32 -LIBGCC := -endif - -ifneq ($(LLVM),) -# Not needed for clang -LIBGCC := -endif - # Modify CFLAGS based on LLVM= include $(srctree)/tools/scripts/Makefile.include @@ -302,12 +293,12 @@ sysroot/$(ARCH)/include: $(Q)$(MAKE) -C $(srctree)/tools/include/nolibc ARCH=$(ARCH) OUTPUT=$(CURDIR)/sysroot/ headers_standalone headers_check $(Q)mv sysroot/sysroot sysroot/$(ARCH) -nolibc-test: nolibc-test.c nolibc-test-linkage.c sysroot/$(ARCH)/include +nolibc-test: $(NOLIBC_TEST_SOURCES) sysroot/$(ARCH)/include $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \ - -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include nolibc-test.c nolibc-test-linkage.c $(LIBGCC) + -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include $(NOLIBC_TEST_SOURCES) $(LDLIBS) -libc-test: nolibc-test.c nolibc-test-linkage.c - $(QUIET_CC)$(HOSTCC) -o $@ nolibc-test.c nolibc-test-linkage.c +libc-test: $(NOLIBC_TEST_SOURCES) + $(QUIET_CC)$(HOSTCC) -o $@ $(NOLIBC_TEST_SOURCES) # local libc-test run-libc-test: libc-test diff --git a/tools/testing/selftests/nolibc/nolibc-test-ignore-errno.c b/tools/testing/selftests/nolibc/nolibc-test-ignore-errno.c new file mode 100644 index 000000000000..aea816da4fca --- /dev/null +++ b/tools/testing/selftests/nolibc/nolibc-test-ignore-errno.c @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#define NOLIBC_IGNORE_ERRNO + +/* Include all of nolibc and make sure everything compiles */ +#include <stdlib.h> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index 1b9d3b2e2491..d3c4facb54c0 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -42,6 +42,9 @@ #include <unistd.h> #include <limits.h> #include <ctype.h> +#include <stdbool.h> +#include <byteswap.h> +#include <endian.h> #pragma GCC diagnostic ignored "-Wmissing-prototypes" @@ -66,6 +69,8 @@ static const char *argv0; /* will be used by constructor tests */ static int constructor_test_value; +static const int is_le = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__; + static const int is_nolibc = #ifdef NOLIBC 1 @@ -74,6 +79,30 @@ static const int is_nolibc = #endif ; +static const int is_glibc = +#ifdef __GLIBC__ + 1 +#else + 0 +#endif +; + +#if !defined(NOLIBC) +/* Some disabled tests may not compile. */ + +/* strlcat() and strlcpy() may not be in the system headers. */ +#undef strlcat +#undef strlcpy +#define strlcat(d, s, l) 0 +#define strlcpy(d, s, l) 0 + +/* readdir_r() is likely to be marked deprecated */ +#undef readdir_r +#define readdir_r(dir, dirent, result) ((errno = EINVAL), -1) + +#define _syscall(...) 0 +#endif + /* definition of a series of tests */ struct test { const char *name; /* test name */ @@ -142,21 +171,6 @@ static const char *errorname(int err) } } -static void align_result(size_t llen) -{ - const size_t align = 64; - char buf[align]; - size_t n; - - if (llen >= align) - return; - - n = align - llen; - memset(buf, ' ', n); - buf[n] = '\0'; - fputs(buf, stdout); -} - enum RESULT { OK, FAIL, @@ -174,8 +188,10 @@ static void result(int llen, enum RESULT r) else msg = " [FAIL]"; - align_result(llen); - puts(msg); + llen = 64 - llen; + if (llen < 0) + llen = 0; + printf("%*s%s\n", llen, "", msg); } /* The tests below are intended to be used by the macroes, which evaluate @@ -304,10 +320,7 @@ int expect_syszr(int expr, int llen) { int ret = 0; - if (errno == ENOSYS) { - llen += printf(" = ENOSYS"); - result(llen, SKIPPED); - } else if (expr) { + if (expr) { ret = 1; llen += printf(" = %d %s ", expr, errorname(errno)); result(llen, FAIL); @@ -347,10 +360,7 @@ int expect_sysne(int expr, int llen, int val) { int ret = 0; - if (errno == ENOSYS) { - llen += printf(" = ENOSYS"); - result(llen, SKIPPED); - } else if (expr == val) { + if (expr == val) { ret = 1; llen += printf(" = %d %s ", expr, errorname(errno)); result(llen, FAIL); @@ -375,9 +385,7 @@ int expect_syserr2(int expr, int expret, int experr1, int experr2, int llen) int _errno = errno; llen += printf(" = %d %s ", expr, errorname(_errno)); - if (errno == ENOSYS) { - result(llen, SKIPPED); - } else if (expr != expret || (_errno != experr1 && _errno != experr2)) { + if (expr != expret || (_errno != experr1 && _errno != experr2)) { ret = 1; if (experr2 == 0) llen += printf(" != (%d %s) ", expret, errorname(experr1)); @@ -701,6 +709,37 @@ static void constructor2(int argc, char **argv, char **envp) constructor_test_value |= 1 << 1; } +int test_program_invocation_name(void) +{ + char buf[100]; + char *dirsep; + ssize_t r; + int fd; + + fd = open("/proc/self/cmdline", O_RDONLY); + if (fd == -1) + return 1; + + r = read(fd, buf, sizeof(buf)); + close(fd); + if (r < 1 || r == sizeof(buf)) + return 1; + + buf[r - 1] = '\0'; + + if (strcmp(program_invocation_name, buf) != 0) + return 1; + + dirsep = strrchr(buf, '/'); + if (!dirsep || dirsep[1] == '\0') + return 1; + + if (strcmp(program_invocation_short_name, dirsep + 1) != 0) + return 1; + + return 0; +} + int run_startup(int min, int max) { int test; @@ -715,6 +754,7 @@ int run_startup(int min, int max) #ifdef NOLIBC test_auxv = _auxv; #endif + bool proc = access("/proc", R_OK) == 0; for (test = min; test >= 0 && test <= max; test++) { int llen = 0; /* line length */ @@ -740,6 +780,7 @@ int run_startup(int min, int max) CASE_TEST(constructor); EXPECT_EQ(is_nolibc, constructor_test_value, 0x3); break; CASE_TEST(linkage_errno); EXPECT_PTREQ(1, linkage_test_errno_addr(), &errno); break; CASE_TEST(linkage_constr); EXPECT_EQ(1, linkage_test_constructor_test_value, 0x3); break; + CASE_TEST(prog_name); EXPECT_ZR(proc, test_program_invocation_name()); break; case __LINE__: return ret; /* must be last */ /* note: do not set any defaults so as to permit holes above */ @@ -866,7 +907,7 @@ int test_file_stream(void) errno = 0; r = fwrite("foo", 1, 3, f); - if (r != 0 || errno != EBADF) { + if (r != 0 || ((is_nolibc || is_glibc) && errno != EBADF)) { fclose(f); return -1; } @@ -1408,7 +1449,7 @@ int run_syscall(int min, int max) CASE_TEST(fork); EXPECT_SYSZR(1, test_fork(FORK_STANDARD)); break; CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break; CASE_TEST(getdents64_null); EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break; - CASE_TEST(directories); EXPECT_SYSZR(proc, test_dirent()); break; + CASE_TEST(directories); EXPECT_SYSZR(is_nolibc && proc, test_dirent()); break; CASE_TEST(getrandom); EXPECT_SYSZR(1, test_getrandom()); break; CASE_TEST(gettimeofday_tv); EXPECT_SYSZR(1, gettimeofday(&tv, NULL)); break; CASE_TEST(gettimeofday_tv_tz);EXPECT_SYSZR(1, gettimeofday(&tv, &tz)); break; @@ -1442,6 +1483,7 @@ int run_syscall(int min, int max) CASE_TEST(select_fault); EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break; CASE_TEST(stat_blah); EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break; CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break; + CASE_TEST(stat_rdev); EXPECT_SYSZR(1, ({ int ret = stat("/dev/null", &stat_buf); ret ?: stat_buf.st_rdev != makedev(1, 3); })); break; CASE_TEST(stat_timestamps); EXPECT_SYSZR(1, test_stat_timestamps()); break; CASE_TEST(symlink_root); EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break; CASE_TEST(timer); EXPECT_SYSZR(1, test_timer()); break; @@ -1460,9 +1502,11 @@ int run_syscall(int min, int max) CASE_TEST(readv_zero); EXPECT_SYSZR(1, readv(0, NULL, 0)); break; CASE_TEST(writev_badf); EXPECT_SYSER(1, writev(-1, &iov_one, 1), -1, EBADF); break; CASE_TEST(writev_zero); EXPECT_SYSZR(1, writev(1, NULL, 0)); break; - CASE_TEST(ptrace); EXPECT_SYSER(1, ptrace(PTRACE_CONT, getpid(), NULL, NULL), -1, ESRCH); break; + CASE_TEST(ptrace); tmp = ptrace(PTRACE_CONT, getpid(), NULL, NULL); EXPECT_SYSER(tmp != -1 && errno != ENOSYS, tmp, -1, EFAULT); break; CASE_TEST(syscall_noargs); EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break; CASE_TEST(syscall_args); EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break; + CASE_TEST(_syscall_noargs); EXPECT_SYSEQ(is_nolibc, _syscall(__NR_getpid), getpid()); break; + CASE_TEST(_syscall_args); EXPECT_SYSEQ(is_nolibc, _syscall(__NR_statx, 0, NULL, 0, 0, NULL), -EFAULT); break; CASE_TEST(namespace); EXPECT_SYSZR(euid0 && proc, test_namespace()); break; case __LINE__: return ret; /* must be last */ @@ -1511,6 +1555,60 @@ int test_time_types(void) return 0; } +int test_malloc(void) +{ + size_t sz_array1, sz_array2, sz_array3; + int *array1, *array2, *array3; + int pagesize = getpagesize(); + size_t idx; + + if (pagesize < 0) + return 1; + + /* Dependent on the page size, as that is the granularity of our allocator. */ + sz_array1 = pagesize / 2; + array1 = malloc(sz_array1 * sizeof(*array1)); + if (!array1) + return 2; + + for (idx = 0; idx < sz_array1; idx++) + array1[idx] = idx; + + sz_array2 = pagesize * 2; + array2 = calloc(sz_array2, sizeof(*array2)); + if (!array2) { + free(array1); + return 3; + } + + for (idx = 0; idx < sz_array2; idx++) { + if (array2[idx] != 0) { + free(array2); + return 4; + } + array2[idx] = idx + sz_array1; + } + + /* Resize array1 into array3 and append array2 at the end. */ + sz_array3 = sz_array1 + sz_array2; + array3 = realloc(array1, sz_array3 * sizeof(*array3)); + if (!array3) { + free(array2); + free(array1); + return 5; + } + memcpy(array3 + sz_array1, array2, sizeof(*array2) * sz_array2); + free(array2); + + /* The contents must be contiguous now. */ + for (idx = 0; idx < sz_array3; idx++) + if (array3[idx] != (int)idx) + return 6; + + free(array3); + return 0; +} + int run_stdlib(int min, int max) { int test; @@ -1637,6 +1735,22 @@ int run_stdlib(int min, int max) CASE_TEST(memchr_foobar6_o); EXPECT_STREQ(1, memchr("foobar", 'o', 6), "oobar"); break; CASE_TEST(memchr_foobar3_b); EXPECT_STRZR(1, memchr("foobar", 'b', 3)); break; CASE_TEST(time_types); EXPECT_ZR(is_nolibc, test_time_types()); break; + CASE_TEST(makedev); EXPECT_EQ(1, makedev(0x12, 0x34), 0x1234); break; + CASE_TEST(major); EXPECT_EQ(1, major(0x1234), 0x12); break; + CASE_TEST(minor); EXPECT_EQ(1, minor(0x1234), 0x34); break; + CASE_TEST(makedev_big); EXPECT_EQ(1, makedev(0x11223344, 0x55667788), 0x1122355667734488); break; + CASE_TEST(major_big); EXPECT_EQ(1, major(0x1122355667734488), 0x11223344); break; + CASE_TEST(minor_big); EXPECT_EQ(1, minor(0x1122355667734488), 0x55667788); break; + CASE_TEST(malloc); EXPECT_ZR(1, test_malloc()); break; + CASE_TEST(bswap_16); EXPECT_EQ(1, bswap_16(0x0123), 0x2301); break; + CASE_TEST(bswap_32); EXPECT_EQ(1, bswap_32(0x01234567), 0x67452301); break; + CASE_TEST(bswap_64); EXPECT_EQ(1, bswap_64(0x0123456789abcdef), 0xefcdab8967452301); break; + CASE_TEST(htobe16); EXPECT_EQ(1, htobe16(is_le ? 0x0123 : 0x2301), 0x2301); break; + CASE_TEST(htole16); EXPECT_EQ(1, htole16(is_le ? 0x0123 : 0x2301), 0x0123); break; + CASE_TEST(htobe32); EXPECT_EQ(1, htobe32(is_le ? 0x01234567 : 0x67452301), 0x67452301); break; + CASE_TEST(htole32); EXPECT_EQ(1, htole32(is_le ? 0x01234567 : 0x67452301), 0x01234567); break; + CASE_TEST(htobe64); EXPECT_EQ(1, htobe64(is_le ? 0x0123456789000000 : 0x8967452301), 0x8967452301); break; + CASE_TEST(htole64); EXPECT_EQ(1, htole64(is_le ? 0x0123456789 : 0x8967452301000000), 0x0123456789); break; case __LINE__: return ret; /* must be last */ @@ -1646,33 +1760,60 @@ int run_stdlib(int min, int max) return ret; } -#define EXPECT_VFPRINTF(c, expected, fmt, ...) \ - ret += expect_vfprintf(llen, c, expected, fmt, ##__VA_ARGS__) +#define EXPECT_VFPRINTF(cond, expected, fmt, ...) \ + do { if (!(cond)) result(llen, SKIPPED); else ret += expect_vfprintf(llen, expected, fmt, ##__VA_ARGS__); } while (0) -static int expect_vfprintf(int llen, int c, const char *expected, const char *fmt, ...) +#define VFPRINTF_LEN 25 +static int expect_vfprintf(int llen, const char *expected, const char *fmt, ...) { - char buf[100]; + char buf[VFPRINTF_LEN + 80]; + unsigned int cmp_len; va_list args; - ssize_t w; - int ret; + ssize_t written, expected_len; + /* Fill and terminate buf[] to check for overlong/absent writes */ + memset(buf, 0xa5, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = 0; va_start(args, fmt); - /* Only allow writing 21 bytes, to test truncation */ - w = vsnprintf(buf, 21, fmt, args); + /* Limit buffer length to test truncation */ + written = vsnprintf(buf, VFPRINTF_LEN + 1, fmt, args); va_end(args); - if (w != c) { - llen += printf(" written(%d) != %d", (int)w, c); + llen += printf(" \"%s\"", buf); + + expected_len = strlen(expected); + if (expected_len > VFPRINTF_LEN) { + /* Indicate truncated in test output */ + llen += printf("+"); + cmp_len = VFPRINTF_LEN; + } else { + cmp_len = expected_len; + } + + if (memcmp(expected, buf, cmp_len) || buf[cmp_len]) { + llen += printf(" should be \"%.*s\"", VFPRINTF_LEN, expected); result(llen, FAIL); return 1; } - llen += printf(" \"%s\" = \"%s\"", expected, buf); - ret = strncmp(expected, buf, c); + if (written != expected_len) { + llen += printf(" written(%d) != %d", (int)written, (int)expected_len); + result(llen, FAIL); + return 1; + } - result(llen, ret ? FAIL : OK); - return ret; + /* Check for any overwrites after the actual data. */ + while (++cmp_len < sizeof(buf) - 1) { + if ((unsigned char)buf[cmp_len] != 0xa5) { + llen += printf(" overwrote buf[%d] with 0x%x", cmp_len, buf[cmp_len]); + result(llen, FAIL); + return 1; + } + } + + result(llen, OK); + return 0; } static int test_scanf(void) @@ -1742,23 +1883,6 @@ static int test_scanf(void) return 0; } -int test_strerror(void) -{ - char buf[100]; - ssize_t ret; - - memset(buf, 'A', sizeof(buf)); - - errno = EINVAL; - ret = snprintf(buf, sizeof(buf), "%m"); - if (is_nolibc) { - if (ret < 6 || memcmp(buf, "errno=", 6)) - return 1; - } - - return 0; -} - static int test_printf_error(void) { int fd, ret, saved_errno; @@ -1781,6 +1905,29 @@ static int test_printf_error(void) return 0; } +int test_asprintf(void) +{ + char *str; + int ret; + + ret = asprintf(&str, "foo%s", "bar"); + if (ret == -1) + return 1; + + if (ret != 6) { + free(str); + return 2; + } + + if (memcmp(str, "foobar", 6) != 0) { + free(str); + return 3; + } + + free(str); + return 0; +} + static int run_printf(int min, int max) { int test; @@ -1793,24 +1940,58 @@ static int run_printf(int min, int max) * test numbers. */ switch (test + __LINE__ + 1) { - CASE_TEST(empty); EXPECT_VFPRINTF(0, "", ""); break; - CASE_TEST(simple); EXPECT_VFPRINTF(3, "foo", "foo"); break; - CASE_TEST(string); EXPECT_VFPRINTF(3, "foo", "%s", "foo"); break; - CASE_TEST(number); EXPECT_VFPRINTF(4, "1234", "%d", 1234); break; - CASE_TEST(negnumber); EXPECT_VFPRINTF(5, "-1234", "%d", -1234); break; - CASE_TEST(unsigned); EXPECT_VFPRINTF(5, "12345", "%u", 12345); break; - CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break; - CASE_TEST(hex); EXPECT_VFPRINTF(1, "f", "%x", 0xf); break; - CASE_TEST(pointer); EXPECT_VFPRINTF(3, "0x1", "%p", (void *) 0x1); break; - CASE_TEST(uintmax_t); EXPECT_VFPRINTF(20, "18446744073709551615", "%ju", 0xffffffffffffffffULL); break; - CASE_TEST(intmax_t); EXPECT_VFPRINTF(20, "-9223372036854775807", "%jd", 0x8000000000000001LL); break; - CASE_TEST(truncation); EXPECT_VFPRINTF(25, "01234567890123456789", "%s", "0123456789012345678901234"); break; - CASE_TEST(string_width); EXPECT_VFPRINTF(10, " 1", "%10s", "1"); break; - CASE_TEST(number_width); EXPECT_VFPRINTF(10, " 1", "%10d", 1); break; - CASE_TEST(width_trunc); EXPECT_VFPRINTF(25, " ", "%25d", 1); break; + CASE_TEST(empty); EXPECT_VFPRINTF(1, "", ""); break; + CASE_TEST(simple); EXPECT_VFPRINTF(1, "foo", "foo"); break; + CASE_TEST(string); EXPECT_VFPRINTF(1, "foo", "%s", "foo"); break; + CASE_TEST(number); EXPECT_VFPRINTF(1, "1234", "%d", 1234); break; + CASE_TEST(negnumber); EXPECT_VFPRINTF(1, "-1234", "%d", -1234); break; + CASE_TEST(num_sign); EXPECT_VFPRINTF(1, "| 1|+2|+3|+4|5|", "|% d|%+d|% +d|%+ d|%#d|", 1, 2, 3, 4, 5); break; + CASE_TEST(unsigned); EXPECT_VFPRINTF(1, "12345", "%u", 12345); break; + CASE_TEST(signed_max); EXPECT_VFPRINTF(1, "2147483647", "%i", ~0u >> 1); break; + CASE_TEST(signed_min); EXPECT_VFPRINTF(1, "-2147483648", "%i", (~0u >> 1) + 1); break; + CASE_TEST(unsigned_max); EXPECT_VFPRINTF(1, "4294967295", "%u", ~0u); break; + CASE_TEST(char); EXPECT_VFPRINTF(1, "|c|d| e|", "|%c|%.0c|%4c|", 'c', 'd', 'e'); break; + CASE_TEST(octal); EXPECT_VFPRINTF(1, "|17| 0033||", "|%o|%6.4o|%.0o|", 017, 033, 0); break; + CASE_TEST(octal_max); EXPECT_VFPRINTF(1, "1777777777777777777777", "%llo", ~0ULL); break; + CASE_TEST(octal_alt); EXPECT_VFPRINTF(1, "|0|01|02|034|0|0|", "|%#o|%#o|%#02o|%#02o|%#.0o|%0-#o|", 0, 1, 2, 034, 0, 0); break; + CASE_TEST(hex_nolibc); EXPECT_VFPRINTF(is_nolibc, "|f|d|", "|%x|%X|", 0xf, 0xd); break; + CASE_TEST(hex_libc); EXPECT_VFPRINTF(!is_nolibc, "|f|D|", "|%x|%X|", 0xf, 0xd); break; + CASE_TEST(hex_alt); EXPECT_VFPRINTF(1, "|0x1| 0x2| 0|", "|%#x|%#5x|%#5x|", 1, 2, 0); break; + CASE_TEST(hex_alt_prec); EXPECT_VFPRINTF(1, "| 0x02|0x03| 0x123|", "|%#5.2x|%#04x|%#6.2x|", 2, 3, 0x123); break; + CASE_TEST(hex_0_alt); EXPECT_VFPRINTF(1, "|0|0000| 00|", "|%#x|%#04x|%#5.2x|", 0, 0, 0); break; + CASE_TEST(pointer); EXPECT_VFPRINTF(1, "0x1", "%p", (void *) 0x1); break; + CASE_TEST(pointer_NULL); EXPECT_VFPRINTF(is_nolibc || is_glibc, "|(nil)|(nil)|", "|%p|%.4p|", (void *)0, (void *)0); break; + CASE_TEST(string_NULL); EXPECT_VFPRINTF(is_nolibc || is_glibc, "|(null)||(null)|", "|%s|%.5s|%.6s|", (void *)0, (void *)0, (void *)0); break; + CASE_TEST(percent); EXPECT_VFPRINTF(1, "a%d42%69%", "a%%d%d%%%d%%", 42, 69); break; + CASE_TEST(perc_qual); EXPECT_VFPRINTF(is_nolibc || is_glibc, "a%d2", "a%-14l%d%d", 2); break; + CASE_TEST(invalid); EXPECT_VFPRINTF(is_nolibc || is_glibc, "a%12yx3%y42%P", "a%12yx%d%y%d%P", 3, 42); break; + CASE_TEST(intmax_max); EXPECT_VFPRINTF(1, "9223372036854775807", "%lld", ~0ULL >> 1); break; + CASE_TEST(intmax_min); EXPECT_VFPRINTF(is_nolibc || is_glibc, "-9223372036854775808", "%Li", (~0ULL >> 1) + 1); break; + CASE_TEST(uintmax_max); EXPECT_VFPRINTF(1, "18446744073709551615", "%ju", ~0ULL); break; + CASE_TEST(truncation); EXPECT_VFPRINTF(1, "012345678901234567890123456789", "%s", "012345678901234567890123456789"); break; + CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); break; + CASE_TEST(string_trunc); EXPECT_VFPRINTF(1, " 12345", "%10.5s", "1234567890"); break; + CASE_TEST(string_var); EXPECT_VFPRINTF(1, "| ab|ef | ij|kl |", "|%*.*s|%*.*s|%*.*s|%*.*s|", 3, 2, "abcd", -3, 2, "efgh", 3, -1, "ij", -3, -1, "kl"); break; + CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); break; + CASE_TEST(number_left); EXPECT_VFPRINTF(1, "|-5 |", "|%-8d|", -5); break; + CASE_TEST(string_align); EXPECT_VFPRINTF(1, "|foo |", "|%-8s|", "foo"); break; + CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " 1", "%30d", 1); break; + CASE_TEST(width_tr_lft); EXPECT_VFPRINTF(1, "1 ", "%-30d", 1); break; + CASE_TEST(number_pad); EXPECT_VFPRINTF(1, "0000000005", "%010d", 5); break; + CASE_TEST(number_pad); EXPECT_VFPRINTF(1, "|0000000005|0x1234|", "|%010d|%#01x|", 5, 0x1234); break; + CASE_TEST(num_pad_neg); EXPECT_VFPRINTF(1, "-000000005", "%010d", -5); break; + CASE_TEST(num_pad_hex); EXPECT_VFPRINTF(1, "00fffffffb", "%010x", -5); break; + CASE_TEST(num_pad_trunc);EXPECT_VFPRINTF(is_nolibc, " 0000000000000000000000000000005", "%035d", 5); break; /* max 31 '0' can be added */ + CASE_TEST(num_p_tr_libc);EXPECT_VFPRINTF(!is_nolibc, "00000000000000000000000000000000005", "%035d", 5); break; + CASE_TEST(number_prec); EXPECT_VFPRINTF(1, " 00005", "%10.5d", 5); break; + CASE_TEST(num_prec_neg); EXPECT_VFPRINTF(1, " -00005", "%10.5d", -5); break; + CASE_TEST(number_var); EXPECT_VFPRINTF(1, "| -00005|5 |", "|%*.*d|%*.*d|", 10, 5, -5, -2, -10, 5); break; + CASE_TEST(num_0_prec_0); EXPECT_VFPRINTF(1, "|| |+||||", "|%.0d|% .0d|%+.0d|%.0u|%.0x|%#.0x|", 0, 0, 0, 0, 0, 0); break; + CASE_TEST(errno); errno = 22; EXPECT_VFPRINTF(is_nolibc, "errno=22", "%m"); break; + CASE_TEST(errno-neg); errno = -22; EXPECT_VFPRINTF(is_nolibc, "errno=-22 ", "%-12m"); break; CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; - CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break; CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break; + CASE_TEST(asprintf); EXPECT_ZR(1, test_asprintf()); break; case __LINE__: return ret; /* must be last */ /* note: do not set any defaults so as to permit holes above */ diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh index 3917cfb8fdc4..cd439096fdf3 100755 --- a/tools/testing/selftests/nolibc/run-tests.sh +++ b/tools/testing/selftests/nolibc/run-tests.sh @@ -7,7 +7,7 @@ set -e trap 'echo Aborting...' 'ERR' -crosstool_version=13.2.0 +crosstool_version=15.2.0 hostarch=x86_64 nproc=$(( $(nproc) + 2)) cache_dir="${XDG_CACHE_HOME:-"$HOME"/.cache}" |
