printk: don't print incorrect 64-bit integers
printk is supposed to be very lean, but should at least not print garbage values. Now when a 64-bit integral value is passed in to be printed, 'ERR' will be reported if it doesn't fit in 32-bits instead of truncating it. The printk documentation was slightly out of date, this has been updated. Fixes: #7179 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
12836d9280
commit
970758408b
3 changed files with 52 additions and 15 deletions
|
@ -33,8 +33,11 @@ extern "C" {
|
||||||
* - character: \%c
|
* - character: \%c
|
||||||
* - percent: \%\%
|
* - percent: \%\%
|
||||||
*
|
*
|
||||||
* No other conversion specification capabilities are supported, such as flags,
|
* Field width (with or without leading zeroes) are supported.
|
||||||
* field width, precision, or length attributes.
|
* Length attributes such as 'h' and 'l' are supported. However,
|
||||||
|
* integral values with %lld and %lli are only printed if they fit in 32 bits,
|
||||||
|
* otherwise 'ERR' is printed. Full 64-bit values may be printed with %llx.
|
||||||
|
* Flags and precision attributes are not supported.
|
||||||
*
|
*
|
||||||
* @param fmt Format string.
|
* @param fmt Format string.
|
||||||
* @param ... Optional list of format arguments.
|
* @param ... Optional list of format arguments.
|
||||||
|
|
|
@ -82,6 +82,13 @@ void *__printk_get_hook(void)
|
||||||
return _char_out;
|
return _char_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_err(out_func_t out, void *ctx)
|
||||||
|
{
|
||||||
|
out('E', ctx);
|
||||||
|
out('R', ctx);
|
||||||
|
out('R', ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Printk internals
|
* @brief Printk internals
|
||||||
*
|
*
|
||||||
|
@ -141,11 +148,25 @@ void _vprintk(out_func_t out, void *ctx, const char *fmt, va_list ap)
|
||||||
goto still_might_format;
|
goto still_might_format;
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i': {
|
case 'i': {
|
||||||
long d;
|
s32_t d;
|
||||||
if (long_ctr < 2) {
|
|
||||||
d = va_arg(ap, long);
|
if (long_ctr == 0) {
|
||||||
|
d = va_arg(ap, int);
|
||||||
|
} else if (long_ctr == 1) {
|
||||||
|
long ld = va_arg(ap, long);
|
||||||
|
if (ld > INT32_MAX || ld < INT32_MIN) {
|
||||||
|
print_err(out, ctx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d = (s32_t)ld;
|
||||||
} else {
|
} else {
|
||||||
d = (long)va_arg(ap, long long);
|
long long lld = va_arg(ap, long long);
|
||||||
|
if (lld > INT32_MAX ||
|
||||||
|
lld < INT32_MIN) {
|
||||||
|
print_err(out, ctx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d = (s32_t)lld;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d < 0) {
|
if (d < 0) {
|
||||||
|
@ -158,14 +179,27 @@ void _vprintk(out_func_t out, void *ctx, const char *fmt, va_list ap)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'u': {
|
case 'u': {
|
||||||
unsigned long u;
|
u32_t u;
|
||||||
|
|
||||||
if (long_ctr < 2) {
|
if (long_ctr == 0) {
|
||||||
u = va_arg(ap, unsigned long);
|
u = va_arg(ap, unsigned int);
|
||||||
} else {
|
} else if (long_ctr == 1) {
|
||||||
u = (unsigned long)va_arg(ap,
|
long lu = va_arg(ap, unsigned long);
|
||||||
unsigned long long);
|
if (lu > INT32_MAX) {
|
||||||
|
print_err(out, ctx);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
u = (u32_t)lu;
|
||||||
|
} else {
|
||||||
|
unsigned long long llu =
|
||||||
|
va_arg(ap, unsigned long long);
|
||||||
|
if (llu > INT32_MAX) {
|
||||||
|
print_err(out, ctx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
u = (u32_t)llu;
|
||||||
|
}
|
||||||
|
|
||||||
_printk_dec_ulong(out, ctx, u, padding,
|
_printk_dec_ulong(out, ctx, u, padding,
|
||||||
min_width);
|
min_width);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -25,7 +25,7 @@ char *expected = "22 113 10000 32768 40000 22\n"
|
||||||
"42 42 42 42\n"
|
"42 42 42 42\n"
|
||||||
"42 42 0042 00000042\n"
|
"42 42 0042 00000042\n"
|
||||||
"255 42 abcdef 0x0000002a 42\n"
|
"255 42 abcdef 0x0000002a 42\n"
|
||||||
"-1 4294967295 ffffffffffffffff\n"
|
"ERR -1 ERR ffffffffffffffff\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ void test_printk(void)
|
||||||
printk("%u %2u %4u %8u\n", 42, 42, 42, 42);
|
printk("%u %2u %4u %8u\n", 42, 42, 42, 42);
|
||||||
printk("%u %02u %04u %08u\n", 42, 42, 42, 42);
|
printk("%u %02u %04u %08u\n", 42, 42, 42, 42);
|
||||||
printk("%-8u%-6d%-4x%-2p%8d\n", 0xFF, 42, 0xABCDEF, (char *)42, 42);
|
printk("%-8u%-6d%-4x%-2p%8d\n", 0xFF, 42, 0xABCDEF, (char *)42, 42);
|
||||||
printk("%lld %llu %llx\n", -1LL, -1ULL, -1ULL);
|
printk("%lld %lld %llu %llx\n", 0xFFFFFFFFFULL, -1LL, -1ULL, -1ULL);
|
||||||
|
|
||||||
ram_console[pos] = '\0';
|
ram_console[pos] = '\0';
|
||||||
zassert_true((strcmp(ram_console, expected) == 0), "printk failed");
|
zassert_true((strcmp(ram_console, expected) == 0), "printk failed");
|
||||||
|
@ -117,8 +117,8 @@ void test_printk(void)
|
||||||
"%-8u%-6d%-4x%-2p%8d\n",
|
"%-8u%-6d%-4x%-2p%8d\n",
|
||||||
0xFF, 42, 0xABCDEF, (char *)42, 42);
|
0xFF, 42, 0xABCDEF, (char *)42, 42);
|
||||||
count += snprintk(ram_console + count, sizeof(ram_console) - count,
|
count += snprintk(ram_console + count, sizeof(ram_console) - count,
|
||||||
"%lld %llu %llx\n",
|
"%lld %lld %llu %llx\n",
|
||||||
-1LL, -1ULL, -1ULL);
|
0xFFFFFFFFFULL, -1LL, -1ULL, -1ULL);
|
||||||
ram_console[count] = '\0';
|
ram_console[count] = '\0';
|
||||||
zassert_true((strcmp(ram_console, expected) == 0), "snprintk failed");
|
zassert_true((strcmp(ram_console, expected) == 0), "snprintk failed");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue