Commit Graph

457 Commits

Author SHA1 Message Date
Thomas Weißschuh
638b481613 tools/nolibc: cast default values of program_invocation_name
With -Wwrite-strings the plain assignment triggers a warning as a
'const char *' is assigned to a 'char *', removing the const qualifier.

Casting the const away is fine, as there is no valid modification that
can be done to an empty string anyways.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260525-nolibc-write-strings-v2-1-ab5cc16c7b23@weissschuh.net
2026-05-26 21:06:12 +02:00
Thomas Weißschuh
835fa43a4d tools/nolibc: add ftruncate()
On architectures with 32-bit longs, call the compat syscall
__NR_ftruncate64. As off_t is 64-bit it must be split into 2 registers.
Unlike llseek() which passes the high and low parts in explicitly named
arguments, the order here is endian independent.

Some architectures (arm, mips, ppc) require this pair of registers to
be aligned to an even register, so add custom _sys_ftruncate64()
wrappers for those.

A test case for ftruncate is added which validates negative length or
invalid fd return the appropriate error, and checks the length is
correct on success.

Co-developed-by: Jordan Richards <jordanrichards@google.com>
Signed-off-by: Jordan Richards <jordanrichards@google.com>
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Reviewed-by: Daniel Palmer <daniel@thingy.jp>
Link: https://patch.msgid.link/20260521-nolibc-ftruncate-v1-3-5384a83b2402@weissschuh.net
2026-05-24 23:58:04 +02:00
Daniel Palmer
acbbec1519 tools/nolibc: add a helper to split a 64-bit argument into 32-bit halves
On 32-bit architectures some system calls require a single 64-bit
argument to be passed as two 32-bit halves.

Add a helper to easily split such arguments. This works on little and
bit endian.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260521-nolibc-ftruncate-v1-2-5384a83b2402@weissschuh.net
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-05-24 23:57:59 +02:00
Daniel Palmer
b882d807fa tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
We are using the getrandom syscall to get a random seed for the
stack protector canary but we are calling it with no flags which means
it'll block until there is some real randomness to return.

This means that if the crng is not ready yet program startup will
block and if you are unlucky that could be for a long time and
look like the program has crashed.

Even if the call to getrandom does not yield any random data,
we will still initialize the canary.

Fixes: 7188d4637e ("tools/nolibc: add support for stack protector")
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260522090726.726985-1-daniel@thingy.jp
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-05-24 23:52:58 +02:00
Daniel Palmer
136ca91411 tools/nolibc: getopt: Fix potential out of bounds access
Running clang-tidy on a program that uses getopt() from nolibc
this warning appears:

getopt.h:80:6: warning: Out of bound access to memory after the end of the string literal [clang-analyzer-security.ArrayBound]
80 |         if (optstring[i] == ':') {

This looks like a very unlikely case that an argument
inside of argv is being changed between getopt() calls.

Adding a check for d becoming 0 in the guard after the loop
stops getopt() getting far enough to access beyond the end
of the array and seems to correct the issue.

Fixes: bae3cd708e ("tools/nolibc: add getopt()")
Assisted-by: Claude:claude-4.6-sonnet # reproducer
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
Link: https://patch.msgid.link/20260520111931.1027758-1-daniel@thingy.jp
[Thomas: clean up commit message a bit]
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-05-20 18:43:17 +02:00
Thomas Weißschuh
219d120c19 tools/nolibc: always pass mode to open syscall
When O_TMPFILE is set, the open mode needs to be passed to the kernel as
per the documentation. Currently this is not done.
Instead of checking for O_TMPFILE explicitly and making the conditionals
more complex, just always pass the mode to the kernel. If no value was
passed the mode will be garbage, but the kernel will ignore it anyways.

Fixes: a7604ba149 ("tools/nolibc/sys: make open() take a vararg on the 3rd argument")
Suggested-by: Willy Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/lkml/afRfjdovT6pNtwtP@1wt.eu/
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260514-nolibc-open-tmpfile-v2-3-b4c6c5efa266@weissschuh.net
2026-05-14 17:41:14 +02:00
Thomas Weißschuh
a8856027e2 tools/nolibc: split open mode handling into a macro
This logic is duplicated and some upcoming extensions would require even
more duplicated logic.

Move it into a macro to avoid the duplication and allow cleaner changes.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260514-nolibc-open-tmpfile-v2-2-b4c6c5efa266@weissschuh.net
2026-05-14 17:41:09 +02:00
Thomas Weißschuh
ced7994fc8 tools/nolibc: split implicit open flags into a macro
This logic is duplicated and its current form will be in the way of some
upcoming simplificiations.

Move it into a macro to avoid the duplication and enable some cleanups.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260514-nolibc-open-tmpfile-v2-1-b4c6c5efa266@weissschuh.net
2026-05-14 17:41:02 +02:00
Thomas Weißschuh
d4fe68aea3 tools/nolibc: add support for 32-bit parisc
Extend nolibc to target the 32-bit parisc architecture.
64-bit is not yet supported.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch/msgid.link/20260428-nolibc-hppa-v5-2-d843d573111a@weissschuh.net
2026-05-03 16:39:54 +02:00
Thomas Weißschuh
97d6655082 tools/nolibc: add support for OpenRISC / or1k
Add support for OpenRISC / or1k to nolibc.

_start() uses the same wrapper construct as in arch-sh.h.
libgcc is necessary as OpenRISC is missing 64-bit multiplication.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Stafford Horne <shorne@gmail.com>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260429-nolibc-openrisc-v2-1-8d7d7a2f3fec@weissschuh.net
2026-05-03 16:34:58 +02:00
Thomas Weißschuh
ce7677458e tools/nolibc: open files with O_LARGEFILE
nolibc can natively handle large files. Tell this to the kernel by
always using O_LARGEFILE when opening files. This is also how other
libcs do it.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260418-nolibc-largefile-v1-6-b91f0775bac3@weissschuh.net
2026-04-27 20:09:12 +02:00
Thomas Weißschuh
02937a241c tools/nolibc: handle 64-bit system call arguments on MIPS N32
The N32 system call ABI expects 64-bit values directly in registers.
This does not work on nolibc currently, as a 'long' is only 32 bits
wide. Switch the system call wrappers to use 'long long' instead which
can handle 64-bit values on N32. As on N64 'long' and 'long long' are
the same, this does not change the behavior there.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260418-nolibc-largefile-v1-5-b91f0775bac3@weissschuh.net
2026-04-27 20:09:07 +02:00
Thomas Weißschuh
7070421c9f tools/nolibc: handle 64-bit system call arguments on x32
The x32 system call ABI expects 64-bit values directly in registers.
This does not work on nolibc currently, as a 'long' is only 32 bits
wide. Switch the system call wrappers to use 'long long' instead which
can handle 64-bit values on x32. As on x86_64 'long' and 'long long' are
the same, this does not change the behavior there.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260418-nolibc-largefile-v1-4-b91f0775bac3@weissschuh.net
2026-04-27 20:09:00 +02:00
Thomas Weißschuh
c503c3deb9 tools/nolibc: cast pointers returned from system calls through integers
Currently all system call wrappers return 'long' integers which can be
directly cast to 'void *' if the returned value is actually a pointer.
An upcoming change will change the system call wrappers to sometimes
return 'long long' which can not be cast to a pointer directly.

Add explicit cast through 'long' to prepare for this.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260418-nolibc-largefile-v1-3-b91f0775bac3@weissschuh.net
2026-04-27 20:08:54 +02:00
Thomas Weißschuh
32db83195f tools/nolibc: add __nolibc_arg_to_reg()
In the architecture specific system call glue, all arguments are
currently casted to 'long' to fit into registers. This works for
pointers as 'long' has the same size as pointers.
However the system call registers for X32 and MIPS N32 need to be
'long long' to work correctly for 64-bit values expected by the system
call ABI. Casting a pointer to a 'long long' will produce a compiler
warning while casting 64-bit integers to 'long' will truncate those.

Add a helper which can be used to correctly cast both pointers and
integers into 'long long' registers. Cast the pointers through
'unsigned' to avoid any sign extensions.

Both builtins have been available since at least GCC 3 and clang 3.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260418-nolibc-largefile-v1-2-b91f0775bac3@weissschuh.net
2026-04-27 20:08:48 +02:00
Thomas Weißschuh
f38a0bb745 tools/nolibc: also handle _llseek system call
On some architectures the llseek system call contains a leading
underscore. Treat it the same way as llseek and prefer it over the
plain lseek system call as is necessary for 64-bit offset handling.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260418-nolibc-largefile-v1-1-b91f0775bac3@weissschuh.net
2026-04-27 19:45:25 +02:00
Thomas Weißschuh
7ffb6e99c3 tools/nolibc: add creat()
creat() is a simple wrapper around open().

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260419-nolibc-open-mode-v1-2-8dc5a960daa7@weissschuh.net
2026-04-27 19:25:30 +02:00
Daniel Palmer
5b1528c33b tools/nolibc: Don't use stack protector before setting it up
The stack protector is configured in _start_c() so we shouldn't
use it before then.

Add __nolibc_no_stack_protector to _start_c() to avoid the compiler
generating stack protector code for _start_c() and thus using it
before its configured.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
Link: https://patch.msgid.link/20260425111315.3191461-3-daniel@thingy.jp
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-04-27 19:09:26 +02:00
Daniel Palmer
9adc1c33a1 tools/nolibc: Rename __no_stack_protector to __nolibc_no_stack_protector
To avoid polluting the namespace rename __no_stack_protector to
__nolibc_no_stack_protector so its now within the nolibc umbrella.

Suggested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
Link: https://patch.msgid.link/20260425111315.3191461-2-daniel@thingy.jp
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-04-27 18:14:47 +02:00
Thomas Weißschuh
4c6826ee7d tools/nolibc: avoid call to wcslen() in _start_c() inserted by clang
Clang may convert the loop to find _auxv into a call to wcslen() which
is missing on nolibc. -fsanitize needs to be disabled for this to
happen.

Use the same pattern as in the nolibc strlen() implementation to avoid
the function call generation.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260418-nolibc-wcslen-v1-1-671271b8ea63@weissschuh.net
2026-04-27 18:13:27 +02:00
Thomas Weißschuh
e635b0459a tools/nolibc: make __nolibc_enosys() a compile time error
Functions which are known at compile-time to result in ENOSYS can be
surprising to the user. For example using old UAPI headers might mean
that stat() will always fail although the kernel would have the system
call available at runtime. Nowadays __nolibc_enosys() should never be
called for normal applications.

Switch the silent ENOSYS return into a compile-time error, so the user
is aware about the issue. Prefer the 'error' attribute as it provides
the best diagnostics. If the users defines NOLIBC_COMPILE_TIME_ENOSYS
the old, silent fallback is kept.

Also add a test which validates that the error can be optimized away.

Reported-by: Willy Tarreau <w@1wt.eu>
Closes: https://lore.kernel.org/lkml/acizRIq2xrFUNHNS@1wt.eu/
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260404-nolibc-enosys-v1-1-e0aba47bdee4@weissschuh.net
2026-04-27 09:00:52 +02:00
Thomas Weißschuh
80e5de852e tools/nolibc: add alloca()
Add the wide-used alloca() function. As it is highly machine and
compiler dependent, just defer to the compiler builtin. This has
been available since GCC 4 and clang 3.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260409-nolibc-alloca-v1-1-ed02f68dfaf9@weissschuh.net
2026-04-27 09:00:50 +02:00
Thomas Weißschuh
f94da2b42b tools/nolibc: add assert() and assert.h
Add the standard assert() macro from the assert.h header.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260409-nolibc-assert-v1-1-42da8b367e23@weissschuh.net
2026-04-27 09:00:49 +02:00
Thomas Weißschuh
3495279d05 tools/nolibc: support UBSAN on gcc
The UBSAN implementation in gcc requires a slightly different function
attribute to skip instrumentation.

Extend __nolibc_no_sanitize_undefined to also handle gcc.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20260408-nolibc-gcc-15-v1-2-330d0c40f894@weissschuh.net
2026-04-09 23:25:40 +02:00
Thomas Weißschuh
08ab958072 tools/nolibc: create __nolibc_no_sanitize_ubsan
The logic to disable UBSAN will become a bit more complicated.
Move it out into compiler.h, so crt.h stays readable.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20260408-nolibc-gcc-15-v1-1-330d0c40f894@weissschuh.net
2026-04-09 23:25:35 +02:00
Thomas Weißschuh
ce834c9cb9 tools/nolibc: add byteorder conversions
Add some standard functions to convert between different byte orders.
Conveniently the UAPI headers provide all the necessary functionality.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260405-nolibc-bswap-v1-1-f7699ca9cee0@weissschuh.net
2026-04-07 09:27:25 +02:00
Thomas Weißschuh
2eb64b936d tools/nolibc: add the _syscall() macro
The standard syscall() function or macro uses the libc return value
convention. Errors returned from the kernel as negative values are
stored in errno and -1 is returned. Users who want to avoid using
errno don't have a way to call raw syscalls and check the returned
error.

Add a new macro _syscall() which works like the standard syscall()
but passes through the return value from the kernel unchanged.
The naming scheme and return values match the named _sys_foo()
system call wrappers already part of nolibc.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260405-nolibc-syscall-v1-3-e5b12bc63211@weissschuh.net
2026-04-07 09:27:07 +02:00
Thomas Weißschuh
022bbb5a41 tools/nolibc: move the call to __sysret() into syscall()
__sysret() transforms the return value from the kernel into the libc
return value convention. There is no reason for it to be called in the
middle of the internals of the syscall() implementation macros.

Move the call up, directly into syscall(), to make the code simpler.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260405-nolibc-syscall-v1-2-e5b12bc63211@weissschuh.net
2026-04-07 09:27:02 +02:00
Thomas Weißschuh
3f5059f01d tools/nolibc: rename the internal macros used in syscall()
These macros are the internal implementation of syscall().
They can not be used by users. Align them with the standard naming
scheme for internal symbols.

The current name also prevents the addition of an application-usable
_syscall() symbol.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260405-nolibc-syscall-v1-1-e5b12bc63211@weissschuh.net
2026-04-07 09:26:57 +02:00
Thomas Weißschuh
1e3c374e9f tools/nolibc: check for overflow in calloc() without divisions
On some architectures without native division instructions
the division can generate calls into libgcc/compiler-rt.
This library might not be available, so its use should be avoided.

Use the compiler builtin to check for overflows without needing a
division. The builtin has been available since GCC 3 and clang 3.8.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260404-nolibc-asprintf-v2-1-17d2d0df9763@weissschuh.net
2026-04-06 19:46:52 +02:00
Thomas Weißschuh
12496aad10 tools/nolibc: add support for asprintf()
Add support for dynamically allocating formatted strings through
asprintf() and vasprintf().

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260401-nolibc-asprintf-v1-3-46292313439f@weissschuh.net
2026-04-06 19:46:51 +02:00
Thomas Weißschuh
fd2e9f8200 tools/nolibc: use __builtin_offsetof()
The current custom implementation of offsetof() fails UBSAN:
runtime error: member access within null pointer of type 'struct ...'
This means that all its users, including container_of(), free() and
realloc(), fail.

Use __builtin_offsetof() instead which does not have this issue and
has been available since GCC 4 and clang 3.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260401-nolibc-asprintf-v1-1-46292313439f@weissschuh.net
2026-04-04 10:48:14 +02:00
Thomas Weißschuh
867fb336a6 tools/nolibc: use makedev() in fstatat()
fstatat() contains two open-coded copies of makedev() to handle minor
numbers >= 256. Now that the regular makedev() handles both large minor
and major numbers correctly use the common function.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260404-nolibc-makedev-v2-6-456a429bf60c@weissschuh.net
2026-04-04 10:29:07 +02:00
Thomas Weißschuh
572246dcdd tools/nolibc: handle all major and minor numbers in makedev() and friends
Remove the limitation of only handling small major and minor numbers.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260404-nolibc-makedev-v2-5-456a429bf60c@weissschuh.net
2026-04-04 10:29:02 +02:00
Thomas Weißschuh
df4ef52c1d tools/nolibc: make dev_t 64 bits wide
statx() returns both 32-bit minor and major numbers. For both of them to
fit into the 'dev_t' in 'struct stat', that needs to be 64 bits wide.

The other uses of 'dev_t' in nolibc are makedev() and friends and
mknod(). makedev() and friends are going to be adapted in an upcoming
commit and mknod() will silently truncate 'dev_t' to 'unsigned int' in
the kernel, similar to other libcs.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260404-nolibc-makedev-v2-4-456a429bf60c@weissschuh.net
2026-04-04 10:28:57 +02:00
Thomas Weißschuh
70091eada3 tools/nolibc: move the logic of makedev() and friends into functions
Functions make it easier to keep the input and output types straight and
avoid duplicate evaluations of their arguments.

Also these functions will become a bit more complex to handle full
64-bit 'dev_t' which is easier to read in a function.

Still stay compatible with code which expects these to be macros.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260404-nolibc-makedev-v2-3-456a429bf60c@weissschuh.net
2026-04-04 10:28:50 +02:00
Thomas Weißschuh
7933969e1f tools/nolibc: explicitly list architecture headers
Relying on $(wildcard) is brittle and non-deterministic.

similar to all the other headers.
Switch the list of architecture headers to an explicit list,

Link: https://patch.msgid.link/20260401-nolibc-cleanup-v1-4-bcf4c9f5c1be@weissschuh.net
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-04-02 17:11:53 +02:00
Thomas Weißschuh
b972b37cb6 tools/nolibc: drop superfluous definition of Q
Q is already defined by tools/scripts/Makefile.include which is included
at the top of tools/include/nolibc/Makefile.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20260401-nolibc-cleanup-v1-3-bcf4c9f5c1be@weissschuh.net
2026-04-02 17:11:48 +02:00
Thomas Weißschuh
010d03d0e8 tools/nolibc: drop superfluous invocation of mkdir
The call to 'mkdir -p $(OUTPUT)sysroot/include' will also create the
sysroot directory.

Drop the unnecessary explicit invocation of mkdir.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20260401-nolibc-cleanup-v1-2-bcf4c9f5c1be@weissschuh.net
2026-04-02 17:11:42 +02:00
Thomas Weißschuh
5bf4b30ed4 tools/nolibc: drop superfluous invocation of 'make headers'
The headers_install target of the toplevel Makefile will already make
sure that the headers are up-to-date.

Drop the superfluous explicit invocation.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20260401-nolibc-cleanup-v1-1-bcf4c9f5c1be@weissschuh.net
2026-04-02 17:11:37 +02:00
David Laight
1dff9ac2c8 tools/nolibc/printf: Support negative variable width and precision
For (eg) "%*.*s" treat a negative field width as a request to left align
the output (the same as the '-' flag), and a negative precision to
request the default precision.

Set the default precision to -1 (not INT_MAX) and add explicit checks
to the string handling for negative values (makes the tet unsigned).

For numeric output check for 'precision >= 0' instead of testing
_NOLIBC_PF_FLAGS_CONTAIN(flags, '.').
This needs an inverted test, some extra goto and removes an indentation.
The changed conditionals fix printf("%0-#o", 0) - but '0' and '-' shouldn't
both be specified.

Signed-off-by: David Laight <david.laight.linux@gmail.com>
Link: https://patch.msgid.link/20260323112247.3196-1-david.laight.linux@gmail.com
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-04-01 18:02:37 +02:00
Thomas Weißschuh
6285f0881e tools/nolibc: rename sys_foo() functions to _sys_foo()
The sys_foo() naming scheme used by the syscall wrappers may collide
with application symbols. Especially as 'sys_' is an obvious naming
scheme an application may choose for its own custom systemcall wrappers.

Avoid these conflicts by using an leading underscore which moves the
names into the implementation's namespace. This naming scheme was chosen
over a '__nolibc_' prefix, as these functions are not an implementation
detail but a documented interface meant to be used by applications.

While this may break some existing users, adapting them should be
straightforward. Given that nolibc is most-likely vendored, no
unexpected breakage should happen. No in-tree users are affected.

These conflicts happen when compiling some of the kernel selftests
with nolibc.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260319-nolibc-namespacing-v1-1-33c22eaddb5e@weissschuh.net
2026-03-22 11:03:59 +01:00
Thomas Weißschuh
3eb97c4cbd tools/nolibc: avoid -Wundef warning for __STDC_VERSION__
With -std=c89 the macro __STDC_VERSION__ is not defined.
While undefined identifiers in '#if' directives are assumed to be '0',
with -Wundef a warning is emitted.

Avoid the warning by explicitly falling back to '0' if __STDC_VERSION__
is not provided by the preprocessor.

Fixes: 37219aa5b1 ("tools/nolibc: add __nolibc_static_assert()")
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260318-nolibc-wundef-v1-1-fcb7f9ac7298@weissschuh.net
2026-03-22 11:03:58 +01:00
Thomas Weißschuh
9da0f529c0 tools/nolibc: add err.h
Add a few convenient helpers to print error and warning messages.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260318-nolibc-err-h-v4-2-08247a694bd9@weissschuh.net
2026-03-22 10:40:37 +01:00
Thomas Weißschuh
b74be92274 tools/nolibc: add support for program_invocation_{,short_}name
Add support for the GNU extensions 'program_invocation_name' and
'program_invocation_short_name'. These are useful to print error
messages, which by convention include the program name.

As these are global variables which take up memory even if not used,
similar to 'errno', gate them behind NOLIBC_IGNORE_ERRNO.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260318-nolibc-err-h-v4-1-08247a694bd9@weissschuh.net
2026-03-22 10:40:30 +01:00
Thomas Weißschuh
e83b07dc8c tools/nolibc: MIPS: fix clobbers of 'lo' and 'hi' registers on different ISAs
All MIPS ISAs before r6 use the 'lo' and 'hi' special registers.
These are clobbered by system calls and need to be marked as such to
avoid miscompilations. Currently nolibc ties the clobbers to the ABI.
But this is wrong and leads to ISA<->ABI combinations which are not
handled correctly, leading to compiler errors or miscompilations.

Handle all different combinations of ABI and ISA.

Fixes: a6a2a8a429 ("tools/nolibc: MIPS: add support for N64 and N32 ABIs")
Fixes: 66b6f755ad ("rcutorture: Import a copy of nolibc")
Suggested-by: Maciej W. Rozycki <macro@orcam.me.uk>
Link: https://lore.kernel.org/lkml/alpine.DEB.2.21.2603141744240.55200@angie.orcam.me.uk/
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Link: https://patch.msgid.link/20260317-nolibc-mips-clobber-v2-1-5b9a97761a9e@linutronix.de
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-03-20 17:58:26 +01:00
David Laight
248c7cf60c tools/nolibc/printf: Add support for octal output
Octal output isn't often used, but adding it costs very little.

Supporting "%#o" is mildly annoying, it has to add a leading '0' if
there isn't one present. In simple cases this is the same as adding a sign
of '0' - but that adds an extra '0' in a few places.
So you need 3 tests, %o, # and no leading '0' (which can only be checked
after the zero pad for precision).
If all the test are deferred until after zero padding then too many values
are 'live' across the call to _nolibc_u64toa_base() and get spilled to stack.
Hence the check that ignores the 'sign' if it is the same as the first
character of the output string.

Add tests for octal output.

Signed-off-by: David Laight <david.laight.linux@gmail.com>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260308113742.12649-17-david.laight.linux@gmail.com
[Thomas: avoid a -Wsign-compare]
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-03-20 17:58:24 +01:00
David Laight
d3d3f64f8e tools/nolibc/printf: Add support for zero padding and field precision
Includes support for variable field widths (eg "%*.*d").

Zero padding is limited to 31 zero characters.
This is wider than the largest numeric field so shouldn't be a problem.

All the standard printf formats are now supported except octal
and floating point.

Add tests for new features

Signed-off-by: David Laight <david.laight.linux@gmail.com>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260308113742.12649-16-david.laight.linux@gmail.com
[Thomas: fixup testcases for musl libc]
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-03-20 17:58:10 +01:00
David Laight
b5f3f59cf4 tools/nolibc/printf: Add support for left aligning fields
Output the characters before or after the pad - writing the pad takes more code.

Include additional/changed tests

Signed-off-by: David Laight <david.laight.linux@gmail.com>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260308113742.12649-15-david.laight.linux@gmail.com
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-03-20 17:57:21 +01:00
David Laight
5eae5f1a01 tools/nolibc/printf: Special case 0 and add support for %#x
The output for %#x is almost the same as that for %p, both output in
hexadecimal with a leading "0x".
However for zero %#x should just output "0" (the same as decimal and ocal).
For %p match glibc and output "(nil)" rather than "0x0" or "0".

Add tests for "%#x", "% d", "%+d" and passing NULL to "%p".

Signed-off-by: David Laight <david.laight.linux@gmail.com>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260308113742.12649-14-david.laight.linux@gmail.com
[Thomas: fix up testcases for musl libc]
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
2026-03-20 17:57:08 +01:00