From: David Laight Date: Sun, 8 Mar 2026 11:37:35 +0000 (+0000) Subject: tools/nolibc/printf: Handle "%s" with the numeric formats X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b43be424343407661d5e7c79a3584a37b91a88bb;p=thirdparty%2Fkernel%2Flinux.git tools/nolibc/printf: Handle "%s" with the numeric formats Avoids the extra va_arg() call with is non-trivial on a lot of modern ABI. Signed-off-by: David Laight Acked-by: Willy Tarreau Link: https://patch.msgid.link/20260308113742.12649-11-david.laight.linux@gmail.com Signed-off-by: Thomas Weißschuh --- diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 7382b00707fb8..a377f164c70d9 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -412,13 +412,13 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list */ ch_flag = _NOLIBC_PF_FLAG(ch); if (((ch >= 'a' && ch <= 'z') || ch == 'X') && - _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p')) { - /* 'long' is needed for pointer conversions and ltz lengths. + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', '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', 'l', 't', 'z')) { + 'p', 's', 'l', 't', 'z')) { v = va_arg(args, unsigned long); signed_v = (long)v; } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, 'j', 'q')) { @@ -437,6 +437,14 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list goto do_output; } + if (ch == 's') { + /* "%s" - character string. */ + outstr = (const char *)(uintptr_t)v; + if (!outstr) + outstr = "(null)"; + goto do_strlen_output; + } + out = outbuf; if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i')) { @@ -465,13 +473,6 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list goto do_strlen_output; } - if (ch == 's') { - outstr = va_arg(args, char *); - if (!outstr) - outstr = "(null)"; - goto do_strlen_output; - } - if (ch == 'm') { #ifdef NOLIBC_IGNORE_ERRNO outstr = "unknown error";