aboutsummaryrefslogtreecommitdiffstats
path: root/lib/vsprintf.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-02-28 02:03:10 -0500
committerIngo Molnar <mingo@kernel.org>2015-02-28 02:03:10 -0500
commit5838d18955b52467f4b30486e62a31727b39998d (patch)
tree8aeb8412156bab93a6b39f2de4a8d6c912ddb31a /lib/vsprintf.c
parent579deee571a755c485ad702ef82c77a98a2ccc05 (diff)
parent895c8b7b4623d4f55e260e5dee2574b4f7113105 (diff)
Merge branch 'linus' into x86/urgent, to merge dependent patch
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r--lib/vsprintf.c106
1 files changed, 100 insertions, 6 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index ec337f64f52d..b235c96167d3 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -114,8 +114,9 @@ int skip_atoi(const char **s)
114{ 114{
115 int i = 0; 115 int i = 0;
116 116
117 while (isdigit(**s)) 117 do {
118 i = i*10 + *((*s)++) - '0'; 118 i = i*10 + *((*s)++) - '0';
119 } while (isdigit(**s));
119 120
120 return i; 121 return i;
121} 122}
@@ -793,6 +794,87 @@ char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
793} 794}
794 795
795static noinline_for_stack 796static noinline_for_stack
797char *bitmap_string(char *buf, char *end, unsigned long *bitmap,
798 struct printf_spec spec, const char *fmt)
799{
800 const int CHUNKSZ = 32;
801 int nr_bits = max_t(int, spec.field_width, 0);
802 int i, chunksz;
803 bool first = true;
804
805 /* reused to print numbers */
806 spec = (struct printf_spec){ .flags = SMALL | ZEROPAD, .base = 16 };
807
808 chunksz = nr_bits & (CHUNKSZ - 1);
809 if (chunksz == 0)
810 chunksz = CHUNKSZ;
811
812 i = ALIGN(nr_bits, CHUNKSZ) - CHUNKSZ;
813 for (; i >= 0; i -= CHUNKSZ) {
814 u32 chunkmask, val;
815 int word, bit;
816
817 chunkmask = ((1ULL << chunksz) - 1);
818 word = i / BITS_PER_LONG;
819 bit = i % BITS_PER_LONG;
820 val = (bitmap[word] >> bit) & chunkmask;
821
822 if (!first) {
823 if (buf < end)
824 *buf = ',';
825 buf++;
826 }
827 first = false;
828
829 spec.field_width = DIV_ROUND_UP(chunksz, 4);
830 buf = number(buf, end, val, spec);
831
832 chunksz = CHUNKSZ;
833 }
834 return buf;
835}
836
837static noinline_for_stack
838char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
839 struct printf_spec spec, const char *fmt)
840{
841 int nr_bits = max_t(int, spec.field_width, 0);
842 /* current bit is 'cur', most recently seen range is [rbot, rtop] */
843 int cur, rbot, rtop;
844 bool first = true;
845
846 /* reused to print numbers */
847 spec = (struct printf_spec){ .base = 10 };
848
849 rbot = cur = find_first_bit(bitmap, nr_bits);
850 while (cur < nr_bits) {
851 rtop = cur;
852 cur = find_next_bit(bitmap, nr_bits, cur + 1);
853 if (cur < nr_bits && cur <= rtop + 1)
854 continue;
855
856 if (!first) {
857 if (buf < end)
858 *buf = ',';
859 buf++;
860 }
861 first = false;
862
863 buf = number(buf, end, rbot, spec);
864 if (rbot < rtop) {
865 if (buf < end)
866 *buf = '-';
867 buf++;
868
869 buf = number(buf, end, rtop, spec);
870 }
871
872 rbot = cur;
873 }
874 return buf;
875}
876
877static noinline_for_stack
796char *mac_address_string(char *buf, char *end, u8 *addr, 878char *mac_address_string(char *buf, char *end, u8 *addr,
797 struct printf_spec spec, const char *fmt) 879 struct printf_spec spec, const char *fmt)
798{ 880{
@@ -1257,6 +1339,10 @@ int kptr_restrict __read_mostly;
1257 * - 'B' For backtraced symbolic direct pointers with offset 1339 * - 'B' For backtraced symbolic direct pointers with offset
1258 * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] 1340 * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
1259 * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] 1341 * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
1342 * - 'b[l]' For a bitmap, the number of bits is determined by the field
1343 * width which must be explicitly specified either as part of the
1344 * format string '%32b[l]' or through '%*b[l]', [l] selects
1345 * range-list format instead of hex format
1260 * - 'M' For a 6-byte MAC address, it prints the address in the 1346 * - 'M' For a 6-byte MAC address, it prints the address in the
1261 * usual colon-separated hex notation 1347 * usual colon-separated hex notation
1262 * - 'm' For a 6-byte MAC address, it prints the hex address without colons 1348 * - 'm' For a 6-byte MAC address, it prints the hex address without colons
@@ -1353,6 +1439,13 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1353 return resource_string(buf, end, ptr, spec, fmt); 1439 return resource_string(buf, end, ptr, spec, fmt);
1354 case 'h': 1440 case 'h':
1355 return hex_string(buf, end, ptr, spec, fmt); 1441 return hex_string(buf, end, ptr, spec, fmt);
1442 case 'b':
1443 switch (fmt[1]) {
1444 case 'l':
1445 return bitmap_list_string(buf, end, ptr, spec, fmt);
1446 default:
1447 return bitmap_string(buf, end, ptr, spec, fmt);
1448 }
1356 case 'M': /* Colon separated: 00:01:02:03:04:05 */ 1449 case 'M': /* Colon separated: 00:01:02:03:04:05 */
1357 case 'm': /* Contiguous: 000102030405 */ 1450 case 'm': /* Contiguous: 000102030405 */
1358 /* [mM]F (FDDI) */ 1451 /* [mM]F (FDDI) */
@@ -1604,8 +1697,7 @@ qualifier:
1604 1697
1605 case 'p': 1698 case 'p':
1606 spec->type = FORMAT_TYPE_PTR; 1699 spec->type = FORMAT_TYPE_PTR;
1607 return fmt - start; 1700 return ++fmt - start;
1608 /* skip alnum */
1609 1701
1610 case '%': 1702 case '%':
1611 spec->type = FORMAT_TYPE_PERCENT_CHAR; 1703 spec->type = FORMAT_TYPE_PERCENT_CHAR;
@@ -1689,6 +1781,8 @@ qualifier:
1689 * %pB output the name of a backtrace symbol with its offset 1781 * %pB output the name of a backtrace symbol with its offset
1690 * %pR output the address range in a struct resource with decoded flags 1782 * %pR output the address range in a struct resource with decoded flags
1691 * %pr output the address range in a struct resource with raw flags 1783 * %pr output the address range in a struct resource with raw flags
1784 * %pb output the bitmap with field width as the number of bits
1785 * %pbl output the bitmap as range list with field width as the number of bits
1692 * %pM output a 6-byte MAC address with colons 1786 * %pM output a 6-byte MAC address with colons
1693 * %pMR output a 6-byte MAC address with colons in reversed order 1787 * %pMR output a 6-byte MAC address with colons in reversed order
1694 * %pMF output a 6-byte MAC address with dashes 1788 * %pMF output a 6-byte MAC address with dashes
@@ -1728,7 +1822,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
1728 1822
1729 /* Reject out-of-range values early. Large positive sizes are 1823 /* Reject out-of-range values early. Large positive sizes are
1730 used for unknown buffer sizes. */ 1824 used for unknown buffer sizes. */
1731 if (WARN_ON_ONCE((int) size < 0)) 1825 if (WARN_ON_ONCE(size > INT_MAX))
1732 return 0; 1826 return 0;
1733 1827
1734 str = buf; 1828 str = buf;
@@ -1794,7 +1888,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
1794 break; 1888 break;
1795 1889
1796 case FORMAT_TYPE_PTR: 1890 case FORMAT_TYPE_PTR:
1797 str = pointer(fmt+1, str, end, va_arg(args, void *), 1891 str = pointer(fmt, str, end, va_arg(args, void *),
1798 spec); 1892 spec);
1799 while (isalnum(*fmt)) 1893 while (isalnum(*fmt))
1800 fmt++; 1894 fmt++;
@@ -2232,7 +2326,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
2232 } 2326 }
2233 2327
2234 case FORMAT_TYPE_PTR: 2328 case FORMAT_TYPE_PTR:
2235 str = pointer(fmt+1, str, end, get_arg(void *), spec); 2329 str = pointer(fmt, str, end, get_arg(void *), spec);
2236 while (isalnum(*fmt)) 2330 while (isalnum(*fmt))
2237 fmt++; 2331 fmt++;
2238 break; 2332 break;