diff options
Diffstat (limited to 'lib/vsprintf.c')
| -rw-r--r-- | lib/vsprintf.c | 110 |
1 files changed, 72 insertions, 38 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index b235c96167d3..3a1e0843f9a2 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <stdarg.h> | 19 | #include <stdarg.h> |
| 20 | #include <linux/clk-provider.h> | ||
| 20 | #include <linux/module.h> /* for KSYM_SYMBOL_LEN */ | 21 | #include <linux/module.h> /* for KSYM_SYMBOL_LEN */ |
| 21 | #include <linux/types.h> | 22 | #include <linux/types.h> |
| 22 | #include <linux/string.h> | 23 | #include <linux/string.h> |
| @@ -340,11 +341,11 @@ int num_to_str(char *buf, int size, unsigned long long num) | |||
| 340 | return len; | 341 | return len; |
| 341 | } | 342 | } |
| 342 | 343 | ||
| 343 | #define ZEROPAD 1 /* pad with zero */ | 344 | #define SIGN 1 /* unsigned/signed, must be 1 */ |
| 344 | #define SIGN 2 /* unsigned/signed long */ | 345 | #define LEFT 2 /* left justified */ |
| 345 | #define PLUS 4 /* show plus */ | 346 | #define PLUS 4 /* show plus */ |
| 346 | #define SPACE 8 /* space if plus */ | 347 | #define SPACE 8 /* space if plus */ |
| 347 | #define LEFT 16 /* left justified */ | 348 | #define ZEROPAD 16 /* pad with zero, must be 16 == '0' - ' ' */ |
| 348 | #define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */ | 349 | #define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */ |
| 349 | #define SPECIAL 64 /* prefix hex with "0x", octal with "0" */ | 350 | #define SPECIAL 64 /* prefix hex with "0x", octal with "0" */ |
| 350 | 351 | ||
| @@ -383,10 +384,7 @@ static noinline_for_stack | |||
| 383 | char *number(char *buf, char *end, unsigned long long num, | 384 | char *number(char *buf, char *end, unsigned long long num, |
| 384 | struct printf_spec spec) | 385 | struct printf_spec spec) |
| 385 | { | 386 | { |
| 386 | /* we are called with base 8, 10 or 16, only, thus don't need "G..." */ | 387 | char tmp[3 * sizeof(num)]; |
| 387 | static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ | ||
| 388 | |||
| 389 | char tmp[66]; | ||
| 390 | char sign; | 388 | char sign; |
| 391 | char locase; | 389 | char locase; |
| 392 | int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); | 390 | int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); |
| @@ -422,12 +420,7 @@ char *number(char *buf, char *end, unsigned long long num, | |||
| 422 | /* generate full string in tmp[], in reverse order */ | 420 | /* generate full string in tmp[], in reverse order */ |
| 423 | i = 0; | 421 | i = 0; |
| 424 | if (num < spec.base) | 422 | if (num < spec.base) |
| 425 | tmp[i++] = digits[num] | locase; | 423 | tmp[i++] = hex_asc_upper[num] | locase; |
| 426 | /* Generic code, for any base: | ||
| 427 | else do { | ||
| 428 | tmp[i++] = (digits[do_div(num,base)] | locase); | ||
| 429 | } while (num != 0); | ||
| 430 | */ | ||
| 431 | else if (spec.base != 10) { /* 8 or 16 */ | 424 | else if (spec.base != 10) { /* 8 or 16 */ |
| 432 | int mask = spec.base - 1; | 425 | int mask = spec.base - 1; |
| 433 | int shift = 3; | 426 | int shift = 3; |
| @@ -435,7 +428,7 @@ char *number(char *buf, char *end, unsigned long long num, | |||
| 435 | if (spec.base == 16) | 428 | if (spec.base == 16) |
| 436 | shift = 4; | 429 | shift = 4; |
| 437 | do { | 430 | do { |
| 438 | tmp[i++] = (digits[((unsigned char)num) & mask] | locase); | 431 | tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] | locase); |
| 439 | num >>= shift; | 432 | num >>= shift; |
| 440 | } while (num); | 433 | } while (num); |
| 441 | } else { /* base 10 */ | 434 | } else { /* base 10 */ |
| @@ -447,7 +440,7 @@ char *number(char *buf, char *end, unsigned long long num, | |||
| 447 | spec.precision = i; | 440 | spec.precision = i; |
| 448 | /* leading space padding */ | 441 | /* leading space padding */ |
| 449 | spec.field_width -= spec.precision; | 442 | spec.field_width -= spec.precision; |
| 450 | if (!(spec.flags & (ZEROPAD+LEFT))) { | 443 | if (!(spec.flags & (ZEROPAD | LEFT))) { |
| 451 | while (--spec.field_width >= 0) { | 444 | while (--spec.field_width >= 0) { |
| 452 | if (buf < end) | 445 | if (buf < end) |
| 453 | *buf = ' '; | 446 | *buf = ' '; |
| @@ -475,7 +468,8 @@ char *number(char *buf, char *end, unsigned long long num, | |||
| 475 | } | 468 | } |
| 476 | /* zero or space padding */ | 469 | /* zero or space padding */ |
| 477 | if (!(spec.flags & LEFT)) { | 470 | if (!(spec.flags & LEFT)) { |
| 478 | char c = (spec.flags & ZEROPAD) ? '0' : ' '; | 471 | char c = ' ' + (spec.flags & ZEROPAD); |
| 472 | BUILD_BUG_ON(' ' + ZEROPAD != '0'); | ||
| 479 | while (--spec.field_width >= 0) { | 473 | while (--spec.field_width >= 0) { |
| 480 | if (buf < end) | 474 | if (buf < end) |
| 481 | *buf = c; | 475 | *buf = c; |
| @@ -783,11 +777,19 @@ char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | |||
| 783 | if (spec.field_width > 0) | 777 | if (spec.field_width > 0) |
| 784 | len = min_t(int, spec.field_width, 64); | 778 | len = min_t(int, spec.field_width, 64); |
| 785 | 779 | ||
| 786 | for (i = 0; i < len && buf < end - 1; i++) { | 780 | for (i = 0; i < len; ++i) { |
| 787 | buf = hex_byte_pack(buf, addr[i]); | 781 | if (buf < end) |
| 782 | *buf = hex_asc_hi(addr[i]); | ||
| 783 | ++buf; | ||
| 784 | if (buf < end) | ||
| 785 | *buf = hex_asc_lo(addr[i]); | ||
| 786 | ++buf; | ||
| 788 | 787 | ||
| 789 | if (buf < end && separator && i != len - 1) | 788 | if (separator && i != len - 1) { |
| 790 | *buf++ = separator; | 789 | if (buf < end) |
| 790 | *buf = separator; | ||
| 791 | ++buf; | ||
| 792 | } | ||
| 791 | } | 793 | } |
| 792 | 794 | ||
| 793 | return buf; | 795 | return buf; |
| @@ -1233,8 +1235,12 @@ char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | |||
| 1233 | 1235 | ||
| 1234 | len = spec.field_width < 0 ? 1 : spec.field_width; | 1236 | len = spec.field_width < 0 ? 1 : spec.field_width; |
| 1235 | 1237 | ||
| 1236 | /* Ignore the error. We print as many characters as we can */ | 1238 | /* |
| 1237 | string_escape_mem(addr, len, &buf, end - buf, flags, NULL); | 1239 | * string_escape_mem() writes as many characters as it can to |
| 1240 | * the given buffer, and returns the total size of the output | ||
| 1241 | * had the buffer been big enough. | ||
| 1242 | */ | ||
| 1243 | buf += string_escape_mem(addr, len, buf, buf < end ? end - buf : 0, flags, NULL); | ||
| 1238 | 1244 | ||
| 1239 | return buf; | 1245 | return buf; |
| 1240 | } | 1246 | } |
| @@ -1322,6 +1328,30 @@ char *address_val(char *buf, char *end, const void *addr, | |||
| 1322 | return number(buf, end, num, spec); | 1328 | return number(buf, end, num, spec); |
| 1323 | } | 1329 | } |
| 1324 | 1330 | ||
| 1331 | static noinline_for_stack | ||
| 1332 | char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec, | ||
| 1333 | const char *fmt) | ||
| 1334 | { | ||
| 1335 | if (!IS_ENABLED(CONFIG_HAVE_CLK) || !clk) | ||
| 1336 | return string(buf, end, NULL, spec); | ||
| 1337 | |||
| 1338 | switch (fmt[1]) { | ||
| 1339 | case 'r': | ||
| 1340 | return number(buf, end, clk_get_rate(clk), spec); | ||
| 1341 | |||
| 1342 | case 'n': | ||
| 1343 | default: | ||
| 1344 | #ifdef CONFIG_COMMON_CLK | ||
| 1345 | return string(buf, end, __clk_get_name(clk), spec); | ||
| 1346 | #else | ||
| 1347 | spec.base = 16; | ||
| 1348 | spec.field_width = sizeof(unsigned long) * 2 + 2; | ||
| 1349 | spec.flags |= SPECIAL | SMALL | ZEROPAD; | ||
| 1350 | return number(buf, end, (unsigned long)clk, spec); | ||
| 1351 | #endif | ||
| 1352 | } | ||
| 1353 | } | ||
| 1354 | |||
| 1325 | int kptr_restrict __read_mostly; | 1355 | int kptr_restrict __read_mostly; |
| 1326 | 1356 | ||
| 1327 | /* | 1357 | /* |
| @@ -1404,6 +1434,11 @@ int kptr_restrict __read_mostly; | |||
| 1404 | * (default assumed to be phys_addr_t, passed by reference) | 1434 | * (default assumed to be phys_addr_t, passed by reference) |
| 1405 | * - 'd[234]' For a dentry name (optionally 2-4 last components) | 1435 | * - 'd[234]' For a dentry name (optionally 2-4 last components) |
| 1406 | * - 'D[234]' Same as 'd' but for a struct file | 1436 | * - 'D[234]' Same as 'd' but for a struct file |
| 1437 | * - 'C' For a clock, it prints the name (Common Clock Framework) or address | ||
| 1438 | * (legacy clock framework) of the clock | ||
| 1439 | * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address | ||
| 1440 | * (legacy clock framework) of the clock | ||
| 1441 | * - 'Cr' For a clock, it prints the current rate of the clock | ||
| 1407 | * | 1442 | * |
| 1408 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | 1443 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
| 1409 | * function pointers are really function descriptors, which contain a | 1444 | * function pointers are really function descriptors, which contain a |
| @@ -1548,6 +1583,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
| 1548 | return address_val(buf, end, ptr, spec, fmt); | 1583 | return address_val(buf, end, ptr, spec, fmt); |
| 1549 | case 'd': | 1584 | case 'd': |
| 1550 | return dentry_name(buf, end, ptr, spec, fmt); | 1585 | return dentry_name(buf, end, ptr, spec, fmt); |
| 1586 | case 'C': | ||
| 1587 | return clock(buf, end, ptr, spec, fmt); | ||
| 1551 | case 'D': | 1588 | case 'D': |
| 1552 | return dentry_name(buf, end, | 1589 | return dentry_name(buf, end, |
| 1553 | ((const struct file *)ptr)->f_path.dentry, | 1590 | ((const struct file *)ptr)->f_path.dentry, |
| @@ -1738,29 +1775,21 @@ qualifier: | |||
| 1738 | if (spec->qualifier == 'L') | 1775 | if (spec->qualifier == 'L') |
| 1739 | spec->type = FORMAT_TYPE_LONG_LONG; | 1776 | spec->type = FORMAT_TYPE_LONG_LONG; |
| 1740 | else if (spec->qualifier == 'l') { | 1777 | else if (spec->qualifier == 'l') { |
| 1741 | if (spec->flags & SIGN) | 1778 | BUILD_BUG_ON(FORMAT_TYPE_ULONG + SIGN != FORMAT_TYPE_LONG); |
| 1742 | spec->type = FORMAT_TYPE_LONG; | 1779 | spec->type = FORMAT_TYPE_ULONG + (spec->flags & SIGN); |
| 1743 | else | ||
| 1744 | spec->type = FORMAT_TYPE_ULONG; | ||
| 1745 | } else if (_tolower(spec->qualifier) == 'z') { | 1780 | } else if (_tolower(spec->qualifier) == 'z') { |
| 1746 | spec->type = FORMAT_TYPE_SIZE_T; | 1781 | spec->type = FORMAT_TYPE_SIZE_T; |
| 1747 | } else if (spec->qualifier == 't') { | 1782 | } else if (spec->qualifier == 't') { |
| 1748 | spec->type = FORMAT_TYPE_PTRDIFF; | 1783 | spec->type = FORMAT_TYPE_PTRDIFF; |
| 1749 | } else if (spec->qualifier == 'H') { | 1784 | } else if (spec->qualifier == 'H') { |
| 1750 | if (spec->flags & SIGN) | 1785 | BUILD_BUG_ON(FORMAT_TYPE_UBYTE + SIGN != FORMAT_TYPE_BYTE); |
| 1751 | spec->type = FORMAT_TYPE_BYTE; | 1786 | spec->type = FORMAT_TYPE_UBYTE + (spec->flags & SIGN); |
| 1752 | else | ||
| 1753 | spec->type = FORMAT_TYPE_UBYTE; | ||
| 1754 | } else if (spec->qualifier == 'h') { | 1787 | } else if (spec->qualifier == 'h') { |
| 1755 | if (spec->flags & SIGN) | 1788 | BUILD_BUG_ON(FORMAT_TYPE_USHORT + SIGN != FORMAT_TYPE_SHORT); |
| 1756 | spec->type = FORMAT_TYPE_SHORT; | 1789 | spec->type = FORMAT_TYPE_USHORT + (spec->flags & SIGN); |
| 1757 | else | ||
| 1758 | spec->type = FORMAT_TYPE_USHORT; | ||
| 1759 | } else { | 1790 | } else { |
| 1760 | if (spec->flags & SIGN) | 1791 | BUILD_BUG_ON(FORMAT_TYPE_UINT + SIGN != FORMAT_TYPE_INT); |
| 1761 | spec->type = FORMAT_TYPE_INT; | 1792 | spec->type = FORMAT_TYPE_UINT + (spec->flags & SIGN); |
| 1762 | else | ||
| 1763 | spec->type = FORMAT_TYPE_UINT; | ||
| 1764 | } | 1793 | } |
| 1765 | 1794 | ||
| 1766 | return ++fmt - start; | 1795 | return ++fmt - start; |
| @@ -1800,6 +1829,11 @@ qualifier: | |||
| 1800 | * %*pE[achnops] print an escaped buffer | 1829 | * %*pE[achnops] print an escaped buffer |
| 1801 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 | 1830 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 |
| 1802 | * bytes of the input) | 1831 | * bytes of the input) |
| 1832 | * %pC output the name (Common Clock Framework) or address (legacy clock | ||
| 1833 | * framework) of a clock | ||
| 1834 | * %pCn output the name (Common Clock Framework) or address (legacy clock | ||
| 1835 | * framework) of a clock | ||
| 1836 | * %pCr output the current rate of a clock | ||
| 1803 | * %n is ignored | 1837 | * %n is ignored |
| 1804 | * | 1838 | * |
| 1805 | * ** Please update Documentation/printk-formats.txt when making changes ** | 1839 | * ** Please update Documentation/printk-formats.txt when making changes ** |
