diff options
Diffstat (limited to 'lib/vsprintf.c')
| -rw-r--r-- | lib/vsprintf.c | 133 |
1 files changed, 53 insertions, 80 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 23920c5ff728..a48aaa79d352 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -703,6 +703,22 @@ char *symbol_string(char *buf, char *end, void *ptr, | |||
| 703 | #endif | 703 | #endif |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | static const struct printf_spec default_str_spec = { | ||
| 707 | .field_width = -1, | ||
| 708 | .precision = -1, | ||
| 709 | }; | ||
| 710 | |||
| 711 | static const struct printf_spec default_flag_spec = { | ||
| 712 | .base = 16, | ||
| 713 | .precision = -1, | ||
| 714 | .flags = SPECIAL | SMALL, | ||
| 715 | }; | ||
| 716 | |||
| 717 | static const struct printf_spec default_dec_spec = { | ||
| 718 | .base = 10, | ||
| 719 | .precision = -1, | ||
| 720 | }; | ||
| 721 | |||
| 706 | static noinline_for_stack | 722 | static noinline_for_stack |
| 707 | char *resource_string(char *buf, char *end, struct resource *res, | 723 | char *resource_string(char *buf, char *end, struct resource *res, |
| 708 | struct printf_spec spec, const char *fmt) | 724 | struct printf_spec spec, const char *fmt) |
| @@ -732,21 +748,11 @@ char *resource_string(char *buf, char *end, struct resource *res, | |||
| 732 | .precision = -1, | 748 | .precision = -1, |
| 733 | .flags = SMALL | ZEROPAD, | 749 | .flags = SMALL | ZEROPAD, |
| 734 | }; | 750 | }; |
| 735 | static const struct printf_spec dec_spec = { | ||
| 736 | .base = 10, | ||
| 737 | .precision = -1, | ||
| 738 | .flags = 0, | ||
| 739 | }; | ||
| 740 | static const struct printf_spec str_spec = { | 751 | static const struct printf_spec str_spec = { |
| 741 | .field_width = -1, | 752 | .field_width = -1, |
| 742 | .precision = 10, | 753 | .precision = 10, |
| 743 | .flags = LEFT, | 754 | .flags = LEFT, |
| 744 | }; | 755 | }; |
| 745 | static const struct printf_spec flag_spec = { | ||
| 746 | .base = 16, | ||
| 747 | .precision = -1, | ||
| 748 | .flags = SPECIAL | SMALL, | ||
| 749 | }; | ||
| 750 | 756 | ||
| 751 | /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) | 757 | /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) |
| 752 | * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ | 758 | * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ |
| @@ -770,10 +776,10 @@ char *resource_string(char *buf, char *end, struct resource *res, | |||
| 770 | specp = &mem_spec; | 776 | specp = &mem_spec; |
| 771 | } else if (res->flags & IORESOURCE_IRQ) { | 777 | } else if (res->flags & IORESOURCE_IRQ) { |
| 772 | p = string(p, pend, "irq ", str_spec); | 778 | p = string(p, pend, "irq ", str_spec); |
| 773 | specp = &dec_spec; | 779 | specp = &default_dec_spec; |
| 774 | } else if (res->flags & IORESOURCE_DMA) { | 780 | } else if (res->flags & IORESOURCE_DMA) { |
| 775 | p = string(p, pend, "dma ", str_spec); | 781 | p = string(p, pend, "dma ", str_spec); |
| 776 | specp = &dec_spec; | 782 | specp = &default_dec_spec; |
| 777 | } else if (res->flags & IORESOURCE_BUS) { | 783 | } else if (res->flags & IORESOURCE_BUS) { |
| 778 | p = string(p, pend, "bus ", str_spec); | 784 | p = string(p, pend, "bus ", str_spec); |
| 779 | specp = &bus_spec; | 785 | specp = &bus_spec; |
| @@ -803,7 +809,7 @@ char *resource_string(char *buf, char *end, struct resource *res, | |||
| 803 | p = string(p, pend, " disabled", str_spec); | 809 | p = string(p, pend, " disabled", str_spec); |
| 804 | } else { | 810 | } else { |
| 805 | p = string(p, pend, " flags ", str_spec); | 811 | p = string(p, pend, " flags ", str_spec); |
| 806 | p = number(p, pend, res->flags, flag_spec); | 812 | p = number(p, pend, res->flags, default_flag_spec); |
| 807 | } | 813 | } |
| 808 | *p++ = ']'; | 814 | *p++ = ']'; |
| 809 | *p = '\0'; | 815 | *p = '\0'; |
| @@ -913,9 +919,6 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, | |||
| 913 | int cur, rbot, rtop; | 919 | int cur, rbot, rtop; |
| 914 | bool first = true; | 920 | bool first = true; |
| 915 | 921 | ||
| 916 | /* reused to print numbers */ | ||
| 917 | spec = (struct printf_spec){ .base = 10 }; | ||
| 918 | |||
| 919 | rbot = cur = find_first_bit(bitmap, nr_bits); | 922 | rbot = cur = find_first_bit(bitmap, nr_bits); |
| 920 | while (cur < nr_bits) { | 923 | while (cur < nr_bits) { |
| 921 | rtop = cur; | 924 | rtop = cur; |
| @@ -930,13 +933,13 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, | |||
| 930 | } | 933 | } |
| 931 | first = false; | 934 | first = false; |
| 932 | 935 | ||
| 933 | buf = number(buf, end, rbot, spec); | 936 | buf = number(buf, end, rbot, default_dec_spec); |
| 934 | if (rbot < rtop) { | 937 | if (rbot < rtop) { |
| 935 | if (buf < end) | 938 | if (buf < end) |
| 936 | *buf = '-'; | 939 | *buf = '-'; |
| 937 | buf++; | 940 | buf++; |
| 938 | 941 | ||
| 939 | buf = number(buf, end, rtop, spec); | 942 | buf = number(buf, end, rtop, default_dec_spec); |
| 940 | } | 943 | } |
| 941 | 944 | ||
| 942 | rbot = cur; | 945 | rbot = cur; |
| @@ -1354,11 +1357,9 @@ char *uuid_string(char *buf, char *end, const u8 *addr, | |||
| 1354 | return string(buf, end, uuid, spec); | 1357 | return string(buf, end, uuid, spec); |
| 1355 | } | 1358 | } |
| 1356 | 1359 | ||
| 1357 | int kptr_restrict __read_mostly; | ||
| 1358 | |||
| 1359 | static noinline_for_stack | 1360 | static noinline_for_stack |
| 1360 | char *restricted_pointer(char *buf, char *end, const void *ptr, | 1361 | char *pointer_string(char *buf, char *end, const void *ptr, |
| 1361 | struct printf_spec spec) | 1362 | struct printf_spec spec) |
| 1362 | { | 1363 | { |
| 1363 | spec.base = 16; | 1364 | spec.base = 16; |
| 1364 | spec.flags |= SMALL; | 1365 | spec.flags |= SMALL; |
| @@ -1367,6 +1368,15 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, | |||
| 1367 | spec.flags |= ZEROPAD; | 1368 | spec.flags |= ZEROPAD; |
| 1368 | } | 1369 | } |
| 1369 | 1370 | ||
| 1371 | return number(buf, end, (unsigned long int)ptr, spec); | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | int kptr_restrict __read_mostly; | ||
| 1375 | |||
| 1376 | static noinline_for_stack | ||
| 1377 | char *restricted_pointer(char *buf, char *end, const void *ptr, | ||
| 1378 | struct printf_spec spec) | ||
| 1379 | { | ||
| 1370 | switch (kptr_restrict) { | 1380 | switch (kptr_restrict) { |
| 1371 | case 0: | 1381 | case 0: |
| 1372 | /* Always print %pK values */ | 1382 | /* Always print %pK values */ |
| @@ -1378,8 +1388,11 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, | |||
| 1378 | * kptr_restrict==1 cannot be used in IRQ context | 1388 | * kptr_restrict==1 cannot be used in IRQ context |
| 1379 | * because its test for CAP_SYSLOG would be meaningless. | 1389 | * because its test for CAP_SYSLOG would be meaningless. |
| 1380 | */ | 1390 | */ |
| 1381 | if (in_irq() || in_serving_softirq() || in_nmi()) | 1391 | if (in_irq() || in_serving_softirq() || in_nmi()) { |
| 1392 | if (spec.field_width == -1) | ||
| 1393 | spec.field_width = 2 * sizeof(ptr); | ||
| 1382 | return string(buf, end, "pK-error", spec); | 1394 | return string(buf, end, "pK-error", spec); |
| 1395 | } | ||
| 1383 | 1396 | ||
| 1384 | /* | 1397 | /* |
| 1385 | * Only print the real pointer value if the current | 1398 | * Only print the real pointer value if the current |
| @@ -1404,7 +1417,7 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, | |||
| 1404 | break; | 1417 | break; |
| 1405 | } | 1418 | } |
| 1406 | 1419 | ||
| 1407 | return number(buf, end, (unsigned long)ptr, spec); | 1420 | return pointer_string(buf, end, ptr, spec); |
| 1408 | } | 1421 | } |
| 1409 | 1422 | ||
| 1410 | static noinline_for_stack | 1423 | static noinline_for_stack |
| @@ -1456,9 +1469,6 @@ char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec, | |||
| 1456 | return string(buf, end, NULL, spec); | 1469 | return string(buf, end, NULL, spec); |
| 1457 | 1470 | ||
| 1458 | switch (fmt[1]) { | 1471 | switch (fmt[1]) { |
| 1459 | case 'r': | ||
| 1460 | return number(buf, end, clk_get_rate(clk), spec); | ||
| 1461 | |||
| 1462 | case 'n': | 1472 | case 'n': |
| 1463 | default: | 1473 | default: |
| 1464 | #ifdef CONFIG_COMMON_CLK | 1474 | #ifdef CONFIG_COMMON_CLK |
| @@ -1474,23 +1484,13 @@ char *format_flags(char *buf, char *end, unsigned long flags, | |||
| 1474 | const struct trace_print_flags *names) | 1484 | const struct trace_print_flags *names) |
| 1475 | { | 1485 | { |
| 1476 | unsigned long mask; | 1486 | unsigned long mask; |
| 1477 | const struct printf_spec strspec = { | ||
| 1478 | .field_width = -1, | ||
| 1479 | .precision = -1, | ||
| 1480 | }; | ||
| 1481 | const struct printf_spec numspec = { | ||
| 1482 | .flags = SPECIAL|SMALL, | ||
| 1483 | .field_width = -1, | ||
| 1484 | .precision = -1, | ||
| 1485 | .base = 16, | ||
| 1486 | }; | ||
| 1487 | 1487 | ||
| 1488 | for ( ; flags && names->name; names++) { | 1488 | for ( ; flags && names->name; names++) { |
| 1489 | mask = names->mask; | 1489 | mask = names->mask; |
| 1490 | if ((flags & mask) != mask) | 1490 | if ((flags & mask) != mask) |
| 1491 | continue; | 1491 | continue; |
| 1492 | 1492 | ||
| 1493 | buf = string(buf, end, names->name, strspec); | 1493 | buf = string(buf, end, names->name, default_str_spec); |
| 1494 | 1494 | ||
| 1495 | flags &= ~mask; | 1495 | flags &= ~mask; |
| 1496 | if (flags) { | 1496 | if (flags) { |
| @@ -1501,7 +1501,7 @@ char *format_flags(char *buf, char *end, unsigned long flags, | |||
| 1501 | } | 1501 | } |
| 1502 | 1502 | ||
| 1503 | if (flags) | 1503 | if (flags) |
| 1504 | buf = number(buf, end, flags, numspec); | 1504 | buf = number(buf, end, flags, default_flag_spec); |
| 1505 | 1505 | ||
| 1506 | return buf; | 1506 | return buf; |
| 1507 | } | 1507 | } |
| @@ -1548,22 +1548,18 @@ char *device_node_gen_full_name(const struct device_node *np, char *buf, char *e | |||
| 1548 | { | 1548 | { |
| 1549 | int depth; | 1549 | int depth; |
| 1550 | const struct device_node *parent = np->parent; | 1550 | const struct device_node *parent = np->parent; |
| 1551 | static const struct printf_spec strspec = { | ||
| 1552 | .field_width = -1, | ||
| 1553 | .precision = -1, | ||
| 1554 | }; | ||
| 1555 | 1551 | ||
| 1556 | /* special case for root node */ | 1552 | /* special case for root node */ |
| 1557 | if (!parent) | 1553 | if (!parent) |
| 1558 | return string(buf, end, "/", strspec); | 1554 | return string(buf, end, "/", default_str_spec); |
| 1559 | 1555 | ||
| 1560 | for (depth = 0; parent->parent; depth++) | 1556 | for (depth = 0; parent->parent; depth++) |
| 1561 | parent = parent->parent; | 1557 | parent = parent->parent; |
| 1562 | 1558 | ||
| 1563 | for ( ; depth >= 0; depth--) { | 1559 | for ( ; depth >= 0; depth--) { |
| 1564 | buf = string(buf, end, "/", strspec); | 1560 | buf = string(buf, end, "/", default_str_spec); |
| 1565 | buf = string(buf, end, device_node_name_for_depth(np, depth), | 1561 | buf = string(buf, end, device_node_name_for_depth(np, depth), |
| 1566 | strspec); | 1562 | default_str_spec); |
| 1567 | } | 1563 | } |
| 1568 | return buf; | 1564 | return buf; |
| 1569 | } | 1565 | } |
| @@ -1655,20 +1651,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, | |||
| 1655 | return widen_string(buf, buf - buf_start, end, spec); | 1651 | return widen_string(buf, buf - buf_start, end, spec); |
| 1656 | } | 1652 | } |
| 1657 | 1653 | ||
| 1658 | static noinline_for_stack | ||
| 1659 | char *pointer_string(char *buf, char *end, const void *ptr, | ||
| 1660 | struct printf_spec spec) | ||
| 1661 | { | ||
| 1662 | spec.base = 16; | ||
| 1663 | spec.flags |= SMALL; | ||
| 1664 | if (spec.field_width == -1) { | ||
| 1665 | spec.field_width = 2 * sizeof(ptr); | ||
| 1666 | spec.flags |= ZEROPAD; | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | return number(buf, end, (unsigned long int)ptr, spec); | ||
| 1670 | } | ||
| 1671 | |||
| 1672 | static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key); | 1654 | static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key); |
| 1673 | static siphash_key_t ptr_key __read_mostly; | 1655 | static siphash_key_t ptr_key __read_mostly; |
| 1674 | 1656 | ||
| @@ -1710,13 +1692,13 @@ early_initcall(initialize_ptr_random); | |||
| 1710 | /* Maps a pointer to a 32 bit unique identifier. */ | 1692 | /* Maps a pointer to a 32 bit unique identifier. */ |
| 1711 | static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | 1693 | static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) |
| 1712 | { | 1694 | { |
| 1695 | const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)"; | ||
| 1713 | unsigned long hashval; | 1696 | unsigned long hashval; |
| 1714 | const int default_width = 2 * sizeof(ptr); | ||
| 1715 | 1697 | ||
| 1716 | if (static_branch_unlikely(¬_filled_random_ptr_key)) { | 1698 | if (static_branch_unlikely(¬_filled_random_ptr_key)) { |
| 1717 | spec.field_width = default_width; | 1699 | spec.field_width = 2 * sizeof(ptr); |
| 1718 | /* string length must be less than default_width */ | 1700 | /* string length must be less than default_width */ |
| 1719 | return string(buf, end, "(ptrval)", spec); | 1701 | return string(buf, end, str, spec); |
| 1720 | } | 1702 | } |
| 1721 | 1703 | ||
| 1722 | #ifdef CONFIG_64BIT | 1704 | #ifdef CONFIG_64BIT |
| @@ -1729,15 +1711,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | |||
| 1729 | #else | 1711 | #else |
| 1730 | hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); | 1712 | hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); |
| 1731 | #endif | 1713 | #endif |
| 1732 | 1714 | return pointer_string(buf, end, (const void *)hashval, spec); | |
| 1733 | spec.flags |= SMALL; | ||
| 1734 | if (spec.field_width == -1) { | ||
| 1735 | spec.field_width = default_width; | ||
| 1736 | spec.flags |= ZEROPAD; | ||
| 1737 | } | ||
| 1738 | spec.base = 16; | ||
| 1739 | |||
| 1740 | return number(buf, end, hashval, spec); | ||
| 1741 | } | 1715 | } |
| 1742 | 1716 | ||
| 1743 | /* | 1717 | /* |
| @@ -1750,10 +1724,10 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | |||
| 1750 | * | 1724 | * |
| 1751 | * Right now we handle: | 1725 | * Right now we handle: |
| 1752 | * | 1726 | * |
| 1753 | * - 'F' For symbolic function descriptor pointers with offset | 1727 | * - 'S' For symbolic direct pointers (or function descriptors) with offset |
| 1754 | * - 'f' For simple symbolic function names without offset | 1728 | * - 's' For symbolic direct pointers (or function descriptors) without offset |
| 1755 | * - 'S' For symbolic direct pointers with offset | 1729 | * - 'F' Same as 'S' |
| 1756 | * - 's' For symbolic direct pointers without offset | 1730 | * - 'f' Same as 's' |
| 1757 | * - '[FfSs]R' as above with __builtin_extract_return_addr() translation | 1731 | * - '[FfSs]R' as above with __builtin_extract_return_addr() translation |
| 1758 | * - 'B' For backtraced symbolic direct pointers with offset | 1732 | * - 'B' For backtraced symbolic direct pointers with offset |
| 1759 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] | 1733 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
| @@ -1850,10 +1824,6 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | |||
| 1850 | * ** When making changes please also update: | 1824 | * ** When making changes please also update: |
| 1851 | * Documentation/core-api/printk-formats.rst | 1825 | * Documentation/core-api/printk-formats.rst |
| 1852 | * | 1826 | * |
| 1853 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | ||
| 1854 | * function pointers are really function descriptors, which contain a | ||
| 1855 | * pointer to the real address. | ||
| 1856 | * | ||
| 1857 | * Note: The default behaviour (unadorned %p) is to hash the address, | 1827 | * Note: The default behaviour (unadorned %p) is to hash the address, |
| 1858 | * rendering it useful as a unique identifier. | 1828 | * rendering it useful as a unique identifier. |
| 1859 | */ | 1829 | */ |
| @@ -2129,6 +2099,7 @@ qualifier: | |||
| 2129 | 2099 | ||
| 2130 | case 'x': | 2100 | case 'x': |
| 2131 | spec->flags |= SMALL; | 2101 | spec->flags |= SMALL; |
| 2102 | /* fall through */ | ||
| 2132 | 2103 | ||
| 2133 | case 'X': | 2104 | case 'X': |
| 2134 | spec->base = 16; | 2105 | spec->base = 16; |
| @@ -3087,8 +3058,10 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
| 3087 | break; | 3058 | break; |
| 3088 | case 'i': | 3059 | case 'i': |
| 3089 | base = 0; | 3060 | base = 0; |
| 3061 | /* fall through */ | ||
| 3090 | case 'd': | 3062 | case 'd': |
| 3091 | is_sign = true; | 3063 | is_sign = true; |
| 3064 | /* fall through */ | ||
| 3092 | case 'u': | 3065 | case 'u': |
| 3093 | break; | 3066 | break; |
| 3094 | case '%': | 3067 | case '%': |
