diff options
Diffstat (limited to 'lib/vsprintf.c')
| -rw-r--r-- | lib/vsprintf.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 7536acea135b..756ccafa9cec 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -408,6 +408,8 @@ enum format_type { | |||
| 408 | FORMAT_TYPE_LONG_LONG, | 408 | FORMAT_TYPE_LONG_LONG, |
| 409 | FORMAT_TYPE_ULONG, | 409 | FORMAT_TYPE_ULONG, |
| 410 | FORMAT_TYPE_LONG, | 410 | FORMAT_TYPE_LONG, |
| 411 | FORMAT_TYPE_UBYTE, | ||
| 412 | FORMAT_TYPE_BYTE, | ||
| 411 | FORMAT_TYPE_USHORT, | 413 | FORMAT_TYPE_USHORT, |
| 412 | FORMAT_TYPE_SHORT, | 414 | FORMAT_TYPE_SHORT, |
| 413 | FORMAT_TYPE_UINT, | 415 | FORMAT_TYPE_UINT, |
| @@ -573,12 +575,15 @@ static char *string(char *buf, char *end, char *s, struct printf_spec spec) | |||
| 573 | } | 575 | } |
| 574 | 576 | ||
| 575 | static char *symbol_string(char *buf, char *end, void *ptr, | 577 | static char *symbol_string(char *buf, char *end, void *ptr, |
| 576 | struct printf_spec spec) | 578 | struct printf_spec spec, char ext) |
| 577 | { | 579 | { |
| 578 | unsigned long value = (unsigned long) ptr; | 580 | unsigned long value = (unsigned long) ptr; |
| 579 | #ifdef CONFIG_KALLSYMS | 581 | #ifdef CONFIG_KALLSYMS |
| 580 | char sym[KSYM_SYMBOL_LEN]; | 582 | char sym[KSYM_SYMBOL_LEN]; |
| 581 | sprint_symbol(sym, value); | 583 | if (ext != 'f') |
| 584 | sprint_symbol(sym, value); | ||
| 585 | else | ||
| 586 | kallsyms_lookup(value, NULL, NULL, NULL, sym); | ||
| 582 | return string(buf, end, sym, spec); | 587 | return string(buf, end, sym, spec); |
| 583 | #else | 588 | #else |
| 584 | spec.field_width = 2*sizeof(void *); | 589 | spec.field_width = 2*sizeof(void *); |
| @@ -690,7 +695,8 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, | |||
| 690 | * | 695 | * |
| 691 | * Right now we handle: | 696 | * Right now we handle: |
| 692 | * | 697 | * |
| 693 | * - 'F' For symbolic function descriptor pointers | 698 | * - 'F' For symbolic function descriptor pointers with offset |
| 699 | * - 'f' For simple symbolic function names without offset | ||
| 694 | * - 'S' For symbolic direct pointers | 700 | * - 'S' For symbolic direct pointers |
| 695 | * - 'R' For a struct resource pointer, it prints the range of | 701 | * - 'R' For a struct resource pointer, it prints the range of |
| 696 | * addresses (not the name nor the flags) | 702 | * addresses (not the name nor the flags) |
| @@ -713,10 +719,11 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
| 713 | 719 | ||
| 714 | switch (*fmt) { | 720 | switch (*fmt) { |
| 715 | case 'F': | 721 | case 'F': |
| 722 | case 'f': | ||
| 716 | ptr = dereference_function_descriptor(ptr); | 723 | ptr = dereference_function_descriptor(ptr); |
| 717 | /* Fallthrough */ | 724 | /* Fallthrough */ |
| 718 | case 'S': | 725 | case 'S': |
| 719 | return symbol_string(buf, end, ptr, spec); | 726 | return symbol_string(buf, end, ptr, spec, *fmt); |
| 720 | case 'R': | 727 | case 'R': |
| 721 | return resource_string(buf, end, ptr, spec); | 728 | return resource_string(buf, end, ptr, spec); |
| 722 | case 'm': | 729 | case 'm': |
| @@ -853,11 +860,15 @@ qualifier: | |||
| 853 | spec->qualifier = -1; | 860 | spec->qualifier = -1; |
| 854 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || | 861 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || |
| 855 | *fmt == 'Z' || *fmt == 'z' || *fmt == 't') { | 862 | *fmt == 'Z' || *fmt == 'z' || *fmt == 't') { |
| 856 | spec->qualifier = *fmt; | 863 | spec->qualifier = *fmt++; |
| 857 | ++fmt; | 864 | if (unlikely(spec->qualifier == *fmt)) { |
| 858 | if (spec->qualifier == 'l' && *fmt == 'l') { | 865 | if (spec->qualifier == 'l') { |
| 859 | spec->qualifier = 'L'; | 866 | spec->qualifier = 'L'; |
| 860 | ++fmt; | 867 | ++fmt; |
| 868 | } else if (spec->qualifier == 'h') { | ||
| 869 | spec->qualifier = 'H'; | ||
| 870 | ++fmt; | ||
| 871 | } | ||
| 861 | } | 872 | } |
| 862 | } | 873 | } |
| 863 | 874 | ||
| @@ -919,6 +930,11 @@ qualifier: | |||
| 919 | spec->type = FORMAT_TYPE_SIZE_T; | 930 | spec->type = FORMAT_TYPE_SIZE_T; |
| 920 | } else if (spec->qualifier == 't') { | 931 | } else if (spec->qualifier == 't') { |
| 921 | spec->type = FORMAT_TYPE_PTRDIFF; | 932 | spec->type = FORMAT_TYPE_PTRDIFF; |
| 933 | } else if (spec->qualifier == 'H') { | ||
| 934 | if (spec->flags & SIGN) | ||
| 935 | spec->type = FORMAT_TYPE_BYTE; | ||
| 936 | else | ||
| 937 | spec->type = FORMAT_TYPE_UBYTE; | ||
| 922 | } else if (spec->qualifier == 'h') { | 938 | } else if (spec->qualifier == 'h') { |
| 923 | if (spec->flags & SIGN) | 939 | if (spec->flags & SIGN) |
| 924 | spec->type = FORMAT_TYPE_SHORT; | 940 | spec->type = FORMAT_TYPE_SHORT; |
| @@ -943,7 +959,8 @@ qualifier: | |||
| 943 | * | 959 | * |
| 944 | * This function follows C99 vsnprintf, but has some extensions: | 960 | * This function follows C99 vsnprintf, but has some extensions: |
| 945 | * %pS output the name of a text symbol | 961 | * %pS output the name of a text symbol |
| 946 | * %pF output the name of a function pointer | 962 | * %pF output the name of a function pointer with its offset |
| 963 | * %pf output the name of a function pointer without its offset | ||
| 947 | * %pR output the address range in a struct resource | 964 | * %pR output the address range in a struct resource |
| 948 | * | 965 | * |
| 949 | * The return value is the number of characters which would | 966 | * The return value is the number of characters which would |
| @@ -1087,6 +1104,12 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
| 1087 | case FORMAT_TYPE_PTRDIFF: | 1104 | case FORMAT_TYPE_PTRDIFF: |
| 1088 | num = va_arg(args, ptrdiff_t); | 1105 | num = va_arg(args, ptrdiff_t); |
| 1089 | break; | 1106 | break; |
| 1107 | case FORMAT_TYPE_UBYTE: | ||
| 1108 | num = (unsigned char) va_arg(args, int); | ||
| 1109 | break; | ||
| 1110 | case FORMAT_TYPE_BYTE: | ||
| 1111 | num = (signed char) va_arg(args, int); | ||
| 1112 | break; | ||
| 1090 | case FORMAT_TYPE_USHORT: | 1113 | case FORMAT_TYPE_USHORT: |
| 1091 | num = (unsigned short) va_arg(args, int); | 1114 | num = (unsigned short) va_arg(args, int); |
| 1092 | break; | 1115 | break; |
| @@ -1363,6 +1386,10 @@ do { \ | |||
| 1363 | case FORMAT_TYPE_PTRDIFF: | 1386 | case FORMAT_TYPE_PTRDIFF: |
| 1364 | save_arg(ptrdiff_t); | 1387 | save_arg(ptrdiff_t); |
| 1365 | break; | 1388 | break; |
| 1389 | case FORMAT_TYPE_UBYTE: | ||
| 1390 | case FORMAT_TYPE_BYTE: | ||
| 1391 | save_arg(char); | ||
| 1392 | break; | ||
| 1366 | case FORMAT_TYPE_USHORT: | 1393 | case FORMAT_TYPE_USHORT: |
| 1367 | case FORMAT_TYPE_SHORT: | 1394 | case FORMAT_TYPE_SHORT: |
| 1368 | save_arg(short); | 1395 | save_arg(short); |
| @@ -1391,7 +1418,8 @@ EXPORT_SYMBOL_GPL(vbin_printf); | |||
| 1391 | * | 1418 | * |
| 1392 | * The format follows C99 vsnprintf, but has some extensions: | 1419 | * The format follows C99 vsnprintf, but has some extensions: |
| 1393 | * %pS output the name of a text symbol | 1420 | * %pS output the name of a text symbol |
| 1394 | * %pF output the name of a function pointer | 1421 | * %pF output the name of a function pointer with its offset |
| 1422 | * %pf output the name of a function pointer without its offset | ||
| 1395 | * %pR output the address range in a struct resource | 1423 | * %pR output the address range in a struct resource |
| 1396 | * %n is ignored | 1424 | * %n is ignored |
| 1397 | * | 1425 | * |
| @@ -1538,6 +1566,12 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | |||
| 1538 | case FORMAT_TYPE_PTRDIFF: | 1566 | case FORMAT_TYPE_PTRDIFF: |
| 1539 | num = get_arg(ptrdiff_t); | 1567 | num = get_arg(ptrdiff_t); |
| 1540 | break; | 1568 | break; |
| 1569 | case FORMAT_TYPE_UBYTE: | ||
| 1570 | num = get_arg(unsigned char); | ||
| 1571 | break; | ||
| 1572 | case FORMAT_TYPE_BYTE: | ||
| 1573 | num = get_arg(signed char); | ||
| 1574 | break; | ||
| 1541 | case FORMAT_TYPE_USHORT: | 1575 | case FORMAT_TYPE_USHORT: |
| 1542 | num = get_arg(unsigned short); | 1576 | num = get_arg(unsigned short); |
| 1543 | break; | 1577 | break; |
