Merge branch 'for-4.18-vsprintf-cleanup' into for-4.18
This commit is contained in:
commit
bcf8677bc6
|
@ -204,7 +204,7 @@ test_string(void)
|
||||||
#if BITS_PER_LONG == 64
|
#if BITS_PER_LONG == 64
|
||||||
|
|
||||||
#define PTR_WIDTH 16
|
#define PTR_WIDTH 16
|
||||||
#define PTR ((void *)0xffff0123456789ab)
|
#define PTR ((void *)0xffff0123456789abUL)
|
||||||
#define PTR_STR "ffff0123456789ab"
|
#define PTR_STR "ffff0123456789ab"
|
||||||
#define ZEROS "00000000" /* hex 32 zero bits */
|
#define ZEROS "00000000" /* hex 32 zero bits */
|
||||||
|
|
||||||
|
|
130
lib/vsprintf.c
130
lib/vsprintf.c
|
@ -693,6 +693,22 @@ char *symbol_string(char *buf, char *end, void *ptr,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct printf_spec default_str_spec = {
|
||||||
|
.field_width = -1,
|
||||||
|
.precision = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct printf_spec default_flag_spec = {
|
||||||
|
.base = 16,
|
||||||
|
.precision = -1,
|
||||||
|
.flags = SPECIAL | SMALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct printf_spec default_dec_spec = {
|
||||||
|
.base = 10,
|
||||||
|
.precision = -1,
|
||||||
|
};
|
||||||
|
|
||||||
static noinline_for_stack
|
static noinline_for_stack
|
||||||
char *resource_string(char *buf, char *end, struct resource *res,
|
char *resource_string(char *buf, char *end, struct resource *res,
|
||||||
struct printf_spec spec, const char *fmt)
|
struct printf_spec spec, const char *fmt)
|
||||||
|
@ -722,21 +738,11 @@ char *resource_string(char *buf, char *end, struct resource *res,
|
||||||
.precision = -1,
|
.precision = -1,
|
||||||
.flags = SMALL | ZEROPAD,
|
.flags = SMALL | ZEROPAD,
|
||||||
};
|
};
|
||||||
static const struct printf_spec dec_spec = {
|
|
||||||
.base = 10,
|
|
||||||
.precision = -1,
|
|
||||||
.flags = 0,
|
|
||||||
};
|
|
||||||
static const struct printf_spec str_spec = {
|
static const struct printf_spec str_spec = {
|
||||||
.field_width = -1,
|
.field_width = -1,
|
||||||
.precision = 10,
|
.precision = 10,
|
||||||
.flags = LEFT,
|
.flags = LEFT,
|
||||||
};
|
};
|
||||||
static const struct printf_spec flag_spec = {
|
|
||||||
.base = 16,
|
|
||||||
.precision = -1,
|
|
||||||
.flags = SPECIAL | SMALL,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
|
/* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
|
||||||
* 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
|
* 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
|
||||||
|
@ -760,10 +766,10 @@ char *resource_string(char *buf, char *end, struct resource *res,
|
||||||
specp = &mem_spec;
|
specp = &mem_spec;
|
||||||
} else if (res->flags & IORESOURCE_IRQ) {
|
} else if (res->flags & IORESOURCE_IRQ) {
|
||||||
p = string(p, pend, "irq ", str_spec);
|
p = string(p, pend, "irq ", str_spec);
|
||||||
specp = &dec_spec;
|
specp = &default_dec_spec;
|
||||||
} else if (res->flags & IORESOURCE_DMA) {
|
} else if (res->flags & IORESOURCE_DMA) {
|
||||||
p = string(p, pend, "dma ", str_spec);
|
p = string(p, pend, "dma ", str_spec);
|
||||||
specp = &dec_spec;
|
specp = &default_dec_spec;
|
||||||
} else if (res->flags & IORESOURCE_BUS) {
|
} else if (res->flags & IORESOURCE_BUS) {
|
||||||
p = string(p, pend, "bus ", str_spec);
|
p = string(p, pend, "bus ", str_spec);
|
||||||
specp = &bus_spec;
|
specp = &bus_spec;
|
||||||
|
@ -793,7 +799,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
|
||||||
p = string(p, pend, " disabled", str_spec);
|
p = string(p, pend, " disabled", str_spec);
|
||||||
} else {
|
} else {
|
||||||
p = string(p, pend, " flags ", str_spec);
|
p = string(p, pend, " flags ", str_spec);
|
||||||
p = number(p, pend, res->flags, flag_spec);
|
p = number(p, pend, res->flags, default_flag_spec);
|
||||||
}
|
}
|
||||||
*p++ = ']';
|
*p++ = ']';
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
@ -903,9 +909,6 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
|
||||||
int cur, rbot, rtop;
|
int cur, rbot, rtop;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
/* reused to print numbers */
|
|
||||||
spec = (struct printf_spec){ .base = 10 };
|
|
||||||
|
|
||||||
rbot = cur = find_first_bit(bitmap, nr_bits);
|
rbot = cur = find_first_bit(bitmap, nr_bits);
|
||||||
while (cur < nr_bits) {
|
while (cur < nr_bits) {
|
||||||
rtop = cur;
|
rtop = cur;
|
||||||
|
@ -920,13 +923,13 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
buf = number(buf, end, rbot, spec);
|
buf = number(buf, end, rbot, default_dec_spec);
|
||||||
if (rbot < rtop) {
|
if (rbot < rtop) {
|
||||||
if (buf < end)
|
if (buf < end)
|
||||||
*buf = '-';
|
*buf = '-';
|
||||||
buf++;
|
buf++;
|
||||||
|
|
||||||
buf = number(buf, end, rtop, spec);
|
buf = number(buf, end, rtop, default_dec_spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
rbot = cur;
|
rbot = cur;
|
||||||
|
@ -1344,11 +1347,9 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
|
||||||
return string(buf, end, uuid, spec);
|
return string(buf, end, uuid, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
int kptr_restrict __read_mostly;
|
|
||||||
|
|
||||||
static noinline_for_stack
|
static noinline_for_stack
|
||||||
char *restricted_pointer(char *buf, char *end, const void *ptr,
|
char *pointer_string(char *buf, char *end, const void *ptr,
|
||||||
struct printf_spec spec)
|
struct printf_spec spec)
|
||||||
{
|
{
|
||||||
spec.base = 16;
|
spec.base = 16;
|
||||||
spec.flags |= SMALL;
|
spec.flags |= SMALL;
|
||||||
|
@ -1357,6 +1358,15 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
|
||||||
spec.flags |= ZEROPAD;
|
spec.flags |= ZEROPAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return number(buf, end, (unsigned long int)ptr, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
int kptr_restrict __read_mostly;
|
||||||
|
|
||||||
|
static noinline_for_stack
|
||||||
|
char *restricted_pointer(char *buf, char *end, const void *ptr,
|
||||||
|
struct printf_spec spec)
|
||||||
|
{
|
||||||
switch (kptr_restrict) {
|
switch (kptr_restrict) {
|
||||||
case 0:
|
case 0:
|
||||||
/* Always print %pK values */
|
/* Always print %pK values */
|
||||||
|
@ -1368,8 +1378,11 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
|
||||||
* kptr_restrict==1 cannot be used in IRQ context
|
* kptr_restrict==1 cannot be used in IRQ context
|
||||||
* because its test for CAP_SYSLOG would be meaningless.
|
* because its test for CAP_SYSLOG would be meaningless.
|
||||||
*/
|
*/
|
||||||
if (in_irq() || in_serving_softirq() || in_nmi())
|
if (in_irq() || in_serving_softirq() || in_nmi()) {
|
||||||
|
if (spec.field_width == -1)
|
||||||
|
spec.field_width = 2 * sizeof(ptr);
|
||||||
return string(buf, end, "pK-error", spec);
|
return string(buf, end, "pK-error", spec);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only print the real pointer value if the current
|
* Only print the real pointer value if the current
|
||||||
|
@ -1394,7 +1407,7 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return number(buf, end, (unsigned long)ptr, spec);
|
return pointer_string(buf, end, ptr, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static noinline_for_stack
|
static noinline_for_stack
|
||||||
|
@ -1464,23 +1477,13 @@ char *format_flags(char *buf, char *end, unsigned long flags,
|
||||||
const struct trace_print_flags *names)
|
const struct trace_print_flags *names)
|
||||||
{
|
{
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
const struct printf_spec strspec = {
|
|
||||||
.field_width = -1,
|
|
||||||
.precision = -1,
|
|
||||||
};
|
|
||||||
const struct printf_spec numspec = {
|
|
||||||
.flags = SPECIAL|SMALL,
|
|
||||||
.field_width = -1,
|
|
||||||
.precision = -1,
|
|
||||||
.base = 16,
|
|
||||||
};
|
|
||||||
|
|
||||||
for ( ; flags && names->name; names++) {
|
for ( ; flags && names->name; names++) {
|
||||||
mask = names->mask;
|
mask = names->mask;
|
||||||
if ((flags & mask) != mask)
|
if ((flags & mask) != mask)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
buf = string(buf, end, names->name, strspec);
|
buf = string(buf, end, names->name, default_str_spec);
|
||||||
|
|
||||||
flags &= ~mask;
|
flags &= ~mask;
|
||||||
if (flags) {
|
if (flags) {
|
||||||
|
@ -1491,7 +1494,7 @@ char *format_flags(char *buf, char *end, unsigned long flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
buf = number(buf, end, flags, numspec);
|
buf = number(buf, end, flags, default_flag_spec);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -1538,22 +1541,18 @@ char *device_node_gen_full_name(const struct device_node *np, char *buf, char *e
|
||||||
{
|
{
|
||||||
int depth;
|
int depth;
|
||||||
const struct device_node *parent = np->parent;
|
const struct device_node *parent = np->parent;
|
||||||
static const struct printf_spec strspec = {
|
|
||||||
.field_width = -1,
|
|
||||||
.precision = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* special case for root node */
|
/* special case for root node */
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return string(buf, end, "/", strspec);
|
return string(buf, end, "/", default_str_spec);
|
||||||
|
|
||||||
for (depth = 0; parent->parent; depth++)
|
for (depth = 0; parent->parent; depth++)
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
|
|
||||||
for ( ; depth >= 0; depth--) {
|
for ( ; depth >= 0; depth--) {
|
||||||
buf = string(buf, end, "/", strspec);
|
buf = string(buf, end, "/", default_str_spec);
|
||||||
buf = string(buf, end, device_node_name_for_depth(np, depth),
|
buf = string(buf, end, device_node_name_for_depth(np, depth),
|
||||||
strspec);
|
default_str_spec);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -1645,20 +1644,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
|
||||||
return widen_string(buf, buf - buf_start, end, spec);
|
return widen_string(buf, buf - buf_start, end, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static noinline_for_stack
|
|
||||||
char *pointer_string(char *buf, char *end, const void *ptr,
|
|
||||||
struct printf_spec spec)
|
|
||||||
{
|
|
||||||
spec.base = 16;
|
|
||||||
spec.flags |= SMALL;
|
|
||||||
if (spec.field_width == -1) {
|
|
||||||
spec.field_width = 2 * sizeof(ptr);
|
|
||||||
spec.flags |= ZEROPAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
return number(buf, end, (unsigned long int)ptr, spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool have_filled_random_ptr_key __read_mostly;
|
static bool have_filled_random_ptr_key __read_mostly;
|
||||||
static siphash_key_t ptr_key __read_mostly;
|
static siphash_key_t ptr_key __read_mostly;
|
||||||
|
|
||||||
|
@ -1696,13 +1681,13 @@ early_initcall(initialize_ptr_random);
|
||||||
/* Maps a pointer to a 32 bit unique identifier. */
|
/* Maps a pointer to a 32 bit unique identifier. */
|
||||||
static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
||||||
{
|
{
|
||||||
|
const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)";
|
||||||
unsigned long hashval;
|
unsigned long hashval;
|
||||||
const int default_width = 2 * sizeof(ptr);
|
|
||||||
|
|
||||||
if (unlikely(!have_filled_random_ptr_key)) {
|
if (unlikely(!have_filled_random_ptr_key)) {
|
||||||
spec.field_width = default_width;
|
spec.field_width = 2 * sizeof(ptr);
|
||||||
/* string length must be less than default_width */
|
/* string length must be less than default_width */
|
||||||
return string(buf, end, "(ptrval)", spec);
|
return string(buf, end, str, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
|
@ -1715,15 +1700,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
||||||
#else
|
#else
|
||||||
hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key);
|
hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key);
|
||||||
#endif
|
#endif
|
||||||
|
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||||
spec.flags |= SMALL;
|
|
||||||
if (spec.field_width == -1) {
|
|
||||||
spec.field_width = default_width;
|
|
||||||
spec.flags |= ZEROPAD;
|
|
||||||
}
|
|
||||||
spec.base = 16;
|
|
||||||
|
|
||||||
return number(buf, end, hashval, spec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1736,10 +1713,10 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
||||||
*
|
*
|
||||||
* Right now we handle:
|
* Right now we handle:
|
||||||
*
|
*
|
||||||
* - 'F' For symbolic function descriptor pointers with offset
|
* - 'S' For symbolic direct pointers (or function descriptors) with offset
|
||||||
* - 'f' For simple symbolic function names without offset
|
* - 's' For symbolic direct pointers (or function descriptors) without offset
|
||||||
* - 'S' For symbolic direct pointers with offset
|
* - 'F' Same as 'S'
|
||||||
* - 's' For symbolic direct pointers without offset
|
* - 'f' Same as 's'
|
||||||
* - '[FfSs]R' as above with __builtin_extract_return_addr() translation
|
* - '[FfSs]R' as above with __builtin_extract_return_addr() translation
|
||||||
* - 'B' For backtraced symbolic direct pointers with offset
|
* - 'B' For backtraced symbolic direct pointers with offset
|
||||||
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
|
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
|
||||||
|
@ -1836,10 +1813,6 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
|
||||||
* ** When making changes please also update:
|
* ** When making changes please also update:
|
||||||
* Documentation/core-api/printk-formats.rst
|
* Documentation/core-api/printk-formats.rst
|
||||||
*
|
*
|
||||||
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64
|
|
||||||
* function pointers are really function descriptors, which contain a
|
|
||||||
* pointer to the real address.
|
|
||||||
*
|
|
||||||
* Note: The default behaviour (unadorned %p) is to hash the address,
|
* Note: The default behaviour (unadorned %p) is to hash the address,
|
||||||
* rendering it useful as a unique identifier.
|
* rendering it useful as a unique identifier.
|
||||||
*/
|
*/
|
||||||
|
@ -2115,6 +2088,7 @@ qualifier:
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
spec->flags |= SMALL;
|
spec->flags |= SMALL;
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
case 'X':
|
case 'X':
|
||||||
spec->base = 16;
|
spec->base = 16;
|
||||||
|
@ -3069,8 +3043,10 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
base = 0;
|
base = 0;
|
||||||
|
/* fall through */
|
||||||
case 'd':
|
case 'd':
|
||||||
is_sign = true;
|
is_sign = true;
|
||||||
|
/* fall through */
|
||||||
case 'u':
|
case 'u':
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
|
|
Loading…
Reference in New Issue