diff options
author | Petr Mladek <pmladek@suse.com> | 2018-06-05 07:38:48 -0400 |
---|---|---|
committer | Petr Mladek <pmladek@suse.com> | 2018-06-05 07:38:48 -0400 |
commit | bcf8677bc621e0e3b6ed67668d6bd72908fdec2c (patch) | |
tree | ab847decbab3e94bd15ab260218afd2749a3f1f5 /lib/vsprintf.c | |
parent | 554755be08fba31c74f66b82a485e5513205af84 (diff) | |
parent | cdb7e52d960a59f30de853f5dd85574432d6bb50 (diff) |
Merge branch 'for-4.18-vsprintf-cleanup' into for-4.18
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r-- | lib/vsprintf.c | 130 |
1 files changed, 53 insertions, 77 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index d7a708f82559..7649ef4ed7d0 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -693,6 +693,22 @@ char *symbol_string(char *buf, char *end, void *ptr, | |||
693 | #endif | 693 | #endif |
694 | } | 694 | } |
695 | 695 | ||
696 | static const struct printf_spec default_str_spec = { | ||
697 | .field_width = -1, | ||
698 | .precision = -1, | ||
699 | }; | ||
700 | |||
701 | static const struct printf_spec default_flag_spec = { | ||
702 | .base = 16, | ||
703 | .precision = -1, | ||
704 | .flags = SPECIAL | SMALL, | ||
705 | }; | ||
706 | |||
707 | static const struct printf_spec default_dec_spec = { | ||
708 | .base = 10, | ||
709 | .precision = -1, | ||
710 | }; | ||
711 | |||
696 | static noinline_for_stack | 712 | static noinline_for_stack |
697 | char *resource_string(char *buf, char *end, struct resource *res, | 713 | char *resource_string(char *buf, char *end, struct resource *res, |
698 | struct printf_spec spec, const char *fmt) | 714 | struct printf_spec spec, const char *fmt) |
@@ -722,21 +738,11 @@ char *resource_string(char *buf, char *end, struct resource *res, | |||
722 | .precision = -1, | 738 | .precision = -1, |
723 | .flags = SMALL | ZEROPAD, | 739 | .flags = SMALL | ZEROPAD, |
724 | }; | 740 | }; |
725 | static const struct printf_spec dec_spec = { | ||
726 | .base = 10, | ||
727 | .precision = -1, | ||
728 | .flags = 0, | ||
729 | }; | ||
730 | static const struct printf_spec str_spec = { | 741 | static const struct printf_spec str_spec = { |
731 | .field_width = -1, | 742 | .field_width = -1, |
732 | .precision = 10, | 743 | .precision = 10, |
733 | .flags = LEFT, | 744 | .flags = LEFT, |
734 | }; | 745 | }; |
735 | static const struct printf_spec flag_spec = { | ||
736 | .base = 16, | ||
737 | .precision = -1, | ||
738 | .flags = SPECIAL | SMALL, | ||
739 | }; | ||
740 | 746 | ||
741 | /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) | 747 | /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) |
742 | * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ | 748 | * 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, | |||
760 | specp = &mem_spec; | 766 | specp = &mem_spec; |
761 | } else if (res->flags & IORESOURCE_IRQ) { | 767 | } else if (res->flags & IORESOURCE_IRQ) { |
762 | p = string(p, pend, "irq ", str_spec); | 768 | p = string(p, pend, "irq ", str_spec); |
763 | specp = &dec_spec; | 769 | specp = &default_dec_spec; |
764 | } else if (res->flags & IORESOURCE_DMA) { | 770 | } else if (res->flags & IORESOURCE_DMA) { |
765 | p = string(p, pend, "dma ", str_spec); | 771 | p = string(p, pend, "dma ", str_spec); |
766 | specp = &dec_spec; | 772 | specp = &default_dec_spec; |
767 | } else if (res->flags & IORESOURCE_BUS) { | 773 | } else if (res->flags & IORESOURCE_BUS) { |
768 | p = string(p, pend, "bus ", str_spec); | 774 | p = string(p, pend, "bus ", str_spec); |
769 | specp = &bus_spec; | 775 | specp = &bus_spec; |
@@ -793,7 +799,7 @@ char *resource_string(char *buf, char *end, struct resource *res, | |||
793 | p = string(p, pend, " disabled", str_spec); | 799 | p = string(p, pend, " disabled", str_spec); |
794 | } else { | 800 | } else { |
795 | p = string(p, pend, " flags ", str_spec); | 801 | p = string(p, pend, " flags ", str_spec); |
796 | p = number(p, pend, res->flags, flag_spec); | 802 | p = number(p, pend, res->flags, default_flag_spec); |
797 | } | 803 | } |
798 | *p++ = ']'; | 804 | *p++ = ']'; |
799 | *p = '\0'; | 805 | *p = '\0'; |
@@ -903,9 +909,6 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, | |||
903 | int cur, rbot, rtop; | 909 | int cur, rbot, rtop; |
904 | bool first = true; | 910 | bool first = true; |
905 | 911 | ||
906 | /* reused to print numbers */ | ||
907 | spec = (struct printf_spec){ .base = 10 }; | ||
908 | |||
909 | rbot = cur = find_first_bit(bitmap, nr_bits); | 912 | rbot = cur = find_first_bit(bitmap, nr_bits); |
910 | while (cur < nr_bits) { | 913 | while (cur < nr_bits) { |
911 | rtop = cur; | 914 | rtop = cur; |
@@ -920,13 +923,13 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, | |||
920 | } | 923 | } |
921 | first = false; | 924 | first = false; |
922 | 925 | ||
923 | buf = number(buf, end, rbot, spec); | 926 | buf = number(buf, end, rbot, default_dec_spec); |
924 | if (rbot < rtop) { | 927 | if (rbot < rtop) { |
925 | if (buf < end) | 928 | if (buf < end) |
926 | *buf = '-'; | 929 | *buf = '-'; |
927 | buf++; | 930 | buf++; |
928 | 931 | ||
929 | buf = number(buf, end, rtop, spec); | 932 | buf = number(buf, end, rtop, default_dec_spec); |
930 | } | 933 | } |
931 | 934 | ||
932 | rbot = cur; | 935 | rbot = cur; |
@@ -1344,11 +1347,9 @@ char *uuid_string(char *buf, char *end, const u8 *addr, | |||
1344 | return string(buf, end, uuid, spec); | 1347 | return string(buf, end, uuid, spec); |
1345 | } | 1348 | } |
1346 | 1349 | ||
1347 | int kptr_restrict __read_mostly; | ||
1348 | |||
1349 | static noinline_for_stack | 1350 | static noinline_for_stack |
1350 | char *restricted_pointer(char *buf, char *end, const void *ptr, | 1351 | char *pointer_string(char *buf, char *end, const void *ptr, |
1351 | struct printf_spec spec) | 1352 | struct printf_spec spec) |
1352 | { | 1353 | { |
1353 | spec.base = 16; | 1354 | spec.base = 16; |
1354 | spec.flags |= SMALL; | 1355 | spec.flags |= SMALL; |
@@ -1357,6 +1358,15 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, | |||
1357 | spec.flags |= ZEROPAD; | 1358 | spec.flags |= ZEROPAD; |
1358 | } | 1359 | } |
1359 | 1360 | ||
1361 | return number(buf, end, (unsigned long int)ptr, spec); | ||
1362 | } | ||
1363 | |||
1364 | int kptr_restrict __read_mostly; | ||
1365 | |||
1366 | static noinline_for_stack | ||
1367 | char *restricted_pointer(char *buf, char *end, const void *ptr, | ||
1368 | struct printf_spec spec) | ||
1369 | { | ||
1360 | switch (kptr_restrict) { | 1370 | switch (kptr_restrict) { |
1361 | case 0: | 1371 | case 0: |
1362 | /* Always print %pK values */ | 1372 | /* Always print %pK values */ |
@@ -1368,8 +1378,11 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, | |||
1368 | * kptr_restrict==1 cannot be used in IRQ context | 1378 | * kptr_restrict==1 cannot be used in IRQ context |
1369 | * because its test for CAP_SYSLOG would be meaningless. | 1379 | * because its test for CAP_SYSLOG would be meaningless. |
1370 | */ | 1380 | */ |
1371 | if (in_irq() || in_serving_softirq() || in_nmi()) | 1381 | if (in_irq() || in_serving_softirq() || in_nmi()) { |
1382 | if (spec.field_width == -1) | ||
1383 | spec.field_width = 2 * sizeof(ptr); | ||
1372 | return string(buf, end, "pK-error", spec); | 1384 | return string(buf, end, "pK-error", spec); |
1385 | } | ||
1373 | 1386 | ||
1374 | /* | 1387 | /* |
1375 | * Only print the real pointer value if the current | 1388 | * Only print the real pointer value if the current |
@@ -1394,7 +1407,7 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, | |||
1394 | break; | 1407 | break; |
1395 | } | 1408 | } |
1396 | 1409 | ||
1397 | return number(buf, end, (unsigned long)ptr, spec); | 1410 | return pointer_string(buf, end, ptr, spec); |
1398 | } | 1411 | } |
1399 | 1412 | ||
1400 | static noinline_for_stack | 1413 | static noinline_for_stack |
@@ -1464,23 +1477,13 @@ char *format_flags(char *buf, char *end, unsigned long flags, | |||
1464 | const struct trace_print_flags *names) | 1477 | const struct trace_print_flags *names) |
1465 | { | 1478 | { |
1466 | unsigned long mask; | 1479 | unsigned long mask; |
1467 | const struct printf_spec strspec = { | ||
1468 | .field_width = -1, | ||
1469 | .precision = -1, | ||
1470 | }; | ||
1471 | const struct printf_spec numspec = { | ||
1472 | .flags = SPECIAL|SMALL, | ||
1473 | .field_width = -1, | ||
1474 | .precision = -1, | ||
1475 | .base = 16, | ||
1476 | }; | ||
1477 | 1480 | ||
1478 | for ( ; flags && names->name; names++) { | 1481 | for ( ; flags && names->name; names++) { |
1479 | mask = names->mask; | 1482 | mask = names->mask; |
1480 | if ((flags & mask) != mask) | 1483 | if ((flags & mask) != mask) |
1481 | continue; | 1484 | continue; |
1482 | 1485 | ||
1483 | buf = string(buf, end, names->name, strspec); | 1486 | buf = string(buf, end, names->name, default_str_spec); |
1484 | 1487 | ||
1485 | flags &= ~mask; | 1488 | flags &= ~mask; |
1486 | if (flags) { | 1489 | if (flags) { |
@@ -1491,7 +1494,7 @@ char *format_flags(char *buf, char *end, unsigned long flags, | |||
1491 | } | 1494 | } |
1492 | 1495 | ||
1493 | if (flags) | 1496 | if (flags) |
1494 | buf = number(buf, end, flags, numspec); | 1497 | buf = number(buf, end, flags, default_flag_spec); |
1495 | 1498 | ||
1496 | return buf; | 1499 | return buf; |
1497 | } | 1500 | } |
@@ -1538,22 +1541,18 @@ char *device_node_gen_full_name(const struct device_node *np, char *buf, char *e | |||
1538 | { | 1541 | { |
1539 | int depth; | 1542 | int depth; |
1540 | const struct device_node *parent = np->parent; | 1543 | const struct device_node *parent = np->parent; |
1541 | static const struct printf_spec strspec = { | ||
1542 | .field_width = -1, | ||
1543 | .precision = -1, | ||
1544 | }; | ||
1545 | 1544 | ||
1546 | /* special case for root node */ | 1545 | /* special case for root node */ |
1547 | if (!parent) | 1546 | if (!parent) |
1548 | return string(buf, end, "/", strspec); | 1547 | return string(buf, end, "/", default_str_spec); |
1549 | 1548 | ||
1550 | for (depth = 0; parent->parent; depth++) | 1549 | for (depth = 0; parent->parent; depth++) |
1551 | parent = parent->parent; | 1550 | parent = parent->parent; |
1552 | 1551 | ||
1553 | for ( ; depth >= 0; depth--) { | 1552 | for ( ; depth >= 0; depth--) { |
1554 | buf = string(buf, end, "/", strspec); | 1553 | buf = string(buf, end, "/", default_str_spec); |
1555 | buf = string(buf, end, device_node_name_for_depth(np, depth), | 1554 | buf = string(buf, end, device_node_name_for_depth(np, depth), |
1556 | strspec); | 1555 | default_str_spec); |
1557 | } | 1556 | } |
1558 | return buf; | 1557 | return buf; |
1559 | } | 1558 | } |
@@ -1645,20 +1644,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, | |||
1645 | return widen_string(buf, buf - buf_start, end, spec); | 1644 | return widen_string(buf, buf - buf_start, end, spec); |
1646 | } | 1645 | } |
1647 | 1646 | ||
1648 | static noinline_for_stack | ||
1649 | char *pointer_string(char *buf, char *end, const void *ptr, | ||
1650 | struct printf_spec spec) | ||
1651 | { | ||
1652 | spec.base = 16; | ||
1653 | spec.flags |= SMALL; | ||
1654 | if (spec.field_width == -1) { | ||
1655 | spec.field_width = 2 * sizeof(ptr); | ||
1656 | spec.flags |= ZEROPAD; | ||
1657 | } | ||
1658 | |||
1659 | return number(buf, end, (unsigned long int)ptr, spec); | ||
1660 | } | ||
1661 | |||
1662 | static bool have_filled_random_ptr_key __read_mostly; | 1647 | static bool have_filled_random_ptr_key __read_mostly; |
1663 | static siphash_key_t ptr_key __read_mostly; | 1648 | static siphash_key_t ptr_key __read_mostly; |
1664 | 1649 | ||
@@ -1696,13 +1681,13 @@ early_initcall(initialize_ptr_random); | |||
1696 | /* Maps a pointer to a 32 bit unique identifier. */ | 1681 | /* Maps a pointer to a 32 bit unique identifier. */ |
1697 | static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | 1682 | static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) |
1698 | { | 1683 | { |
1684 | const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)"; | ||
1699 | unsigned long hashval; | 1685 | unsigned long hashval; |
1700 | const int default_width = 2 * sizeof(ptr); | ||
1701 | 1686 | ||
1702 | if (unlikely(!have_filled_random_ptr_key)) { | 1687 | if (unlikely(!have_filled_random_ptr_key)) { |
1703 | spec.field_width = default_width; | 1688 | spec.field_width = 2 * sizeof(ptr); |
1704 | /* string length must be less than default_width */ | 1689 | /* string length must be less than default_width */ |
1705 | return string(buf, end, "(ptrval)", spec); | 1690 | return string(buf, end, str, spec); |
1706 | } | 1691 | } |
1707 | 1692 | ||
1708 | #ifdef CONFIG_64BIT | 1693 | #ifdef CONFIG_64BIT |
@@ -1715,15 +1700,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | |||
1715 | #else | 1700 | #else |
1716 | hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); | 1701 | hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); |
1717 | #endif | 1702 | #endif |
1718 | 1703 | return pointer_string(buf, end, (const void *)hashval, spec); | |
1719 | spec.flags |= SMALL; | ||
1720 | if (spec.field_width == -1) { | ||
1721 | spec.field_width = default_width; | ||
1722 | spec.flags |= ZEROPAD; | ||
1723 | } | ||
1724 | spec.base = 16; | ||
1725 | |||
1726 | return number(buf, end, hashval, spec); | ||
1727 | } | 1704 | } |
1728 | 1705 | ||
1729 | /* | 1706 | /* |
@@ -1736,10 +1713,10 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | |||
1736 | * | 1713 | * |
1737 | * Right now we handle: | 1714 | * Right now we handle: |
1738 | * | 1715 | * |
1739 | * - 'F' For symbolic function descriptor pointers with offset | 1716 | * - 'S' For symbolic direct pointers (or function descriptors) with offset |
1740 | * - 'f' For simple symbolic function names without offset | 1717 | * - 's' For symbolic direct pointers (or function descriptors) without offset |
1741 | * - 'S' For symbolic direct pointers with offset | 1718 | * - 'F' Same as 'S' |
1742 | * - 's' For symbolic direct pointers without offset | 1719 | * - 'f' Same as 's' |
1743 | * - '[FfSs]R' as above with __builtin_extract_return_addr() translation | 1720 | * - '[FfSs]R' as above with __builtin_extract_return_addr() translation |
1744 | * - 'B' For backtraced symbolic direct pointers with offset | 1721 | * - 'B' For backtraced symbolic direct pointers with offset |
1745 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] | 1722 | * - '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) | |||
1836 | * ** When making changes please also update: | 1813 | * ** When making changes please also update: |
1837 | * Documentation/core-api/printk-formats.rst | 1814 | * Documentation/core-api/printk-formats.rst |
1838 | * | 1815 | * |
1839 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | ||
1840 | * function pointers are really function descriptors, which contain a | ||
1841 | * pointer to the real address. | ||
1842 | * | ||
1843 | * Note: The default behaviour (unadorned %p) is to hash the address, | 1816 | * Note: The default behaviour (unadorned %p) is to hash the address, |
1844 | * rendering it useful as a unique identifier. | 1817 | * rendering it useful as a unique identifier. |
1845 | */ | 1818 | */ |
@@ -2115,6 +2088,7 @@ qualifier: | |||
2115 | 2088 | ||
2116 | case 'x': | 2089 | case 'x': |
2117 | spec->flags |= SMALL; | 2090 | spec->flags |= SMALL; |
2091 | /* fall through */ | ||
2118 | 2092 | ||
2119 | case 'X': | 2093 | case 'X': |
2120 | spec->base = 16; | 2094 | spec->base = 16; |
@@ -3069,8 +3043,10 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
3069 | break; | 3043 | break; |
3070 | case 'i': | 3044 | case 'i': |
3071 | base = 0; | 3045 | base = 0; |
3046 | /* fall through */ | ||
3072 | case 'd': | 3047 | case 'd': |
3073 | is_sign = true; | 3048 | is_sign = true; |
3049 | /* fall through */ | ||
3074 | case 'u': | 3050 | case 'u': |
3075 | break; | 3051 | break; |
3076 | case '%': | 3052 | case '%': |