[ipxe-devel] [PATCH] Format HTTP Range with unsigned long long

Michael Brown mcb30 at ipxe.org
Wed May 24 15:29:23 UTC 2017


On 24/05/17 14:27, Linus Lüssing wrote:
> Thanks for the patch. I had tried this approach unsuccessfully
> before writing my initial mail. It seems that the custom
> snprintf() implementation provided by core/vsprintf.c does not
> support the "u" format option yet.

That is correct.  To keep the code size down, vsprintf.c has code only 
for printing signed decimals (and unsigned hex).

> Maybe another issue, but I'm also confused about the type_sizes[]
> array in vsprintf.c, I don't think that a size_t is necessarilly
> greater or equal to a "long long", is it?

It doesn't have to be.  The type_sizes[] array is designed to minimise 
the size of the code that parses the printf format length modifiers: the 
layout allows us to increment for every "l" modifier and decrement for 
every "h" modifier.  A "z" modifier just resets to a known point within 
the array.

In theory an invalid format specifier such as "%llllllld" could break 
this code but we never use a format specifier constructed from user 
input (enforced by building with -Werror and all of the available 
-Wformat warnings), so in practice the safety of this optimisation is 
enforced by the compiler.

We exclude support for unsigned long long decimals in vsprintf.c to 
avoid unconditionally dragging in the 64-bit division code 
(__udivmoddi4.o etc) into every build.  This will prevent %lld (or %llu) 
from working as expected in a 32-bit build: the 64-bit parameter will be 
consumed from the va_args list but will be truncated to a long when it 
is passed to format_decimal().

We could plausibly extend format_decimal() to handle unsigned longs (%lu 
or %zu) by factoring out the negation code.  This would probably be a 
smaller overall size impact than dragging in the 64-bit division code.

Michael



More information about the ipxe-devel mailing list