<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/lib/vsprintf.c, branch v6.14</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v6.14</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v6.14'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2025-01-13T16:23:28Z</updated>
<entry>
<title>vsnprintf: fix the number base for non-numeric formats</title>
<updated>2025-01-13T16:23:28Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2025-01-13T16:23:28Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ecdc475e0707c98c2a89da8d0024b3ea2924ef9b'/>
<id>urn:sha1:ecdc475e0707c98c2a89da8d0024b3ea2924ef9b</id>
<content type='text'>
Commit 8d4826cc8a8a ("vsnprintf: collapse the number format state into
one single state") changed the format specification decoding to be a bit
more straightforward but in the process ended up also resetting the
number base to zero for formats that aren't clearly numerical.

Now, the number base obviously doesn't matter for something like '%s',
so this wasn't all that obvious.  But some of our specialized pointer
extension formatting (ie, things like "print out IPv6 address") did up
depending on the default base-10 setting, and when they then tried to
print out numbers in "base zero", things didn't work out so well.

Most pointer formatting (including things like the default raw hex value
conversion) didn't have this issue, because they used helpers that
explicitly set the base.

Reported-and-tested-by: kernel test robot &lt;oliver.sang@intel.com&gt;
Closes: https://lore.kernel.org/oe-lkp/202501131352.e226f995-lkp@intel.com
Fixes: 8d4826cc8a8a ("vsnprintf: collapse the number format state into one single state")
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsnprintf: fix up kerneldoc for argument name changes</title>
<updated>2025-01-06T14:31:11Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2025-01-06T14:31:11Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=fa47906ff358a5865b7be2356a5a1d1e58dd17d8'/>
<id>urn:sha1:fa47906ff358a5865b7be2356a5a1d1e58dd17d8</id>
<content type='text'>
Stephen Rothwell reports that I missed fixing up the documentation when
the argument names changed in commit 938df695e98d ("vsprintf: associate
the format state with the format pointer"), resulting in htmldoc
warnings like

  lib/vsprintf.c:2760: warning: Function parameter or struct member 'fmt_str' not described in 'vsnprintf'
  lib/vsprintf.c:2760: warning: Excess function parameter 'fmt' description in 'vsnprintf'
  ...

which I didn't notice because the doc build takes longer than the whole
"real" kernel build for me, so I never bother (and judging by the other
warnings, pretty much nobody else does either).

I guess the bigger issues won't be fixed until the doc build is much
faster (narrator: "That isn's in the cards") but at least linux-next
finds the new cases.

Reported-by: Stephen Rothwell &lt;sfr@canb.auug.org.au&gt;
Fixes: 938df695e98d ("vsprintf: associate the format state with the format pointer")
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsprintf: don't make the 'binary' version pack small integer arguments</title>
<updated>2024-12-23T19:52:34Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2024-12-23T19:34:32Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=4c538044ee2d11299cc57ac1e92d343e1e83b847'/>
<id>urn:sha1:4c538044ee2d11299cc57ac1e92d343e1e83b847</id>
<content type='text'>
The strange vbin_printf / bstr_printf interface used to save one- and
two-byte printf numerical arguments into their packed format.

That's more than a bit strange since the argument buffer is supposed to
be an array of 'u32' words, and it's also very different from how the
source of the data (varargs) work - which always do the normal integer
type conversions, so 'char' and 'short' are always passed as int-sized
anyway.

This odd packing causes extra code complexity, and it really isn't worth
it, since the space savings are simply not there: it only happens for
formats like '%hd' (short) and '%hhd' (char), which are very rare
indeed.

In fact, the only other user of this interface seems to be the bpf
helper code (bpf_bprintf_prepare()), and Alexei points out that that
case doesn't support those truncated integer formatting options at all
in the first place.

As a result, bpf_bprintf_prepare() doesn't need any changes for this,
and TRACE_BPRINT uses 'vbin_printf()' -&gt; 'bstr_printf()' for the
formatting and hopefully doesn't expose the odd packing any other way
(knock wood).

Link: https://lore.kernel.org/all/CAADnVQJy65oOubjxM-378O3wDfhuwg8TGa9hc-cTv6NmmUSykQ@mail.gmail.com/
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsnprintf: collapse the number format state into one single state</title>
<updated>2024-12-23T19:18:36Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2024-12-19T21:52:53Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=8d4826cc8a8aca01a3b5e95438dfc0eb3bd589ab'/>
<id>urn:sha1:8d4826cc8a8aca01a3b5e95438dfc0eb3bd589ab</id>
<content type='text'>
We'll squirrel away the size of the number in 'struct fmt' instead.

We have two fairly separate state structures: the 'decode state' is in
'struct fmt', while the 'printout format' is in 'printf_spec'.  Both
structures are small enough to pass around in registers even across
function boundaries (ie two words), even on 32-bit machines.

The goal here is to avoid the case statements on the format states,
which generate either deep conditionals or jump tables, while also
keeping the state size manageable.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsnprintf: mark the indirect width and precision cases unlikely</title>
<updated>2024-12-23T19:18:35Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2024-12-19T19:42:15Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=2b76e39fca4739a75c9a4f96f3471af6b1c18d9e'/>
<id>urn:sha1:2b76e39fca4739a75c9a4f96f3471af6b1c18d9e</id>
<content type='text'>
Make the format_decode() code generation easier to look at by getting
the strange and unlikely cases out of line.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsnprintf: inline skip_atoi() again</title>
<updated>2024-12-23T19:18:35Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2024-12-19T19:37:07Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=f372b2256acbfbbf703cfdfae3d02c5a6c0e1679'/>
<id>urn:sha1:f372b2256acbfbbf703cfdfae3d02c5a6c0e1679</id>
<content type='text'>
At some point skip_atoi() had been marked 'noinline_for_stack', but it
turns out that this is now a pessimization, and not inlining it actually
results in a stack frame in format decoding due to the call and thus
hurts stack usage rather than helping.

With the simplistic atoi function inlined, the format decoding now needs
no frame at all.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsprintf: deal with format specifiers with a lookup table</title>
<updated>2024-12-23T19:18:35Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2024-12-19T18:55:56Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=614d13462daef9bf6ac735744b5835a18cbfd19c'/>
<id>urn:sha1:614d13462daef9bf6ac735744b5835a18cbfd19c</id>
<content type='text'>
We did the flags as an array earlier, they had simpler rules.  The final
format specifiers are a bit more complex since they have more fields to
deal with, and we want to handle the length modifiers at the same time.
But like the flags, we're better off just making it a data-driven table
rather than some case statement.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsprintf: deal with format flags with a simple lookup table</title>
<updated>2024-12-23T19:18:35Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2024-12-19T18:02:45Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=312f48b2e27f0f8ede4260e024352fdad225d1c5'/>
<id>urn:sha1:312f48b2e27f0f8ede4260e024352fdad225d1c5</id>
<content type='text'>
Rather than a case statement, just look up the printf format flags
(justification, zero-padding etc) using a small table.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsprintf: associate the format state with the format pointer</title>
<updated>2024-12-23T19:18:35Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2024-12-16T23:44:10Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=938df695e98db7e0df540cce3b12da8c382955b4'/>
<id>urn:sha1:938df695e98db7e0df540cce3b12da8c382955b4</id>
<content type='text'>
The vsnprintf() code is written as a state machine as it walks the
format pointer, but for various historical reasons the state is oddly
named and was encoded as the 'type' field in the 'struct printf_spec'.

That naming came from the fact that the states used to not just encode
the state of the state machine, but also the various integer types that
would then be printed out.

Let's make the state machine more obvious, and actually call it 'state',
and associate it with the format pointer itself, rather than the
'printf_spec' that contains the currently decoded formatting specs.

This also removes the bit packing from printf_spec, which makes it much
easier on the compiler.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vsprintf: fix calling convention for format_decode()</title>
<updated>2024-12-23T19:18:35Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2024-12-16T23:37:06Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=9e0e6d8a3268e805e061ae8b22f14e37b157102a'/>
<id>urn:sha1:9e0e6d8a3268e805e061ae8b22f14e37b157102a</id>
<content type='text'>
Every single caller wants to know what the next format location is, but
instead the function returned the length of the processed part and so
every single return statement in the format_decode() function was
instead subtracting the start of the format string.

The callers that that did want to know the length (in addition to the
end of the format processing) already had to save off the start of the
format string anyway.  So this was all just doing extra processing both
on the caller and callee sides.

Just change the calling convention to return the end of the format
processing, making everything simpler (and preparing for yet more
simplification to come).

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
</feed>
