1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <stdarg.h>
20#include <linux/module.h>
21#include <linux/types.h>
22#include <linux/string.h>
23#include <linux/ctype.h>
24#include <linux/kernel.h>
25#include <linux/kallsyms.h>
26#include <linux/uaccess.h>
27#include <linux/ioport.h>
28#include <net/addrconf.h>
29
30#include <asm/page.h>
31#include <asm/div64.h>
32#include <asm/sections.h>
33
34#include "kstrtox.h"
35
36
37
38
39
40
41
42unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
43{
44 unsigned long long result;
45 unsigned int rv;
46
47 cp = _parse_integer_fixup_radix(cp, &base);
48 rv = _parse_integer(cp, base, &result);
49
50 cp += (rv & ~KSTRTOX_OVERFLOW);
51
52 if (endp)
53 *endp = (char *)cp;
54
55 return result;
56}
57EXPORT_SYMBOL(simple_strtoull);
58
59
60
61
62
63
64
65unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
66{
67 return simple_strtoull(cp, endp, base);
68}
69EXPORT_SYMBOL(simple_strtoul);
70
71
72
73
74
75
76
77long simple_strtol(const char *cp, char **endp, unsigned int base)
78{
79 if (*cp == '-')
80 return -simple_strtoul(cp + 1, endp, base);
81
82 return simple_strtoul(cp, endp, base);
83}
84EXPORT_SYMBOL(simple_strtol);
85
86
87
88
89
90
91
92long long simple_strtoll(const char *cp, char **endp, unsigned int base)
93{
94 if (*cp == '-')
95 return -simple_strtoull(cp + 1, endp, base);
96
97 return simple_strtoull(cp, endp, base);
98}
99EXPORT_SYMBOL(simple_strtoll);
100
101static noinline_for_stack
102int skip_atoi(const char **s)
103{
104 int i = 0;
105
106 while (isdigit(**s))
107 i = i*10 + *((*s)++) - '0';
108
109 return i;
110}
111
112
113
114
115
116
117
118
119#if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64
120
121static noinline_for_stack
122char *put_dec_full9(char *buf, unsigned q)
123{
124 unsigned r;
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 r = (q * (uint64_t)0x1999999a) >> 32;
146 *buf++ = (q - 10 * r) + '0';
147 q = (r * (uint64_t)0x1999999a) >> 32;
148 *buf++ = (r - 10 * q) + '0';
149 r = (q * (uint64_t)0x1999999a) >> 32;
150 *buf++ = (q - 10 * r) + '0';
151 q = (r * (uint64_t)0x1999999a) >> 32;
152 *buf++ = (r - 10 * q) + '0';
153 r = (q * (uint64_t)0x1999999a) >> 32;
154 *buf++ = (q - 10 * r) + '0';
155
156 q = (r * 0x199a) >> 16;
157 *buf++ = (r - 10 * q) + '0';
158 r = (q * 0xcd) >> 11;
159 *buf++ = (q - 10 * r) + '0';
160 q = (r * 0xcd) >> 11;
161 *buf++ = (r - 10 * q) + '0';
162 *buf++ = q + '0';
163 return buf;
164}
165#endif
166
167
168
169
170
171static noinline_for_stack
172char *put_dec_trunc8(char *buf, unsigned r)
173{
174 unsigned q;
175
176
177 q = (r * (uint64_t)0x1999999a) >> 32;
178 *buf++ = (r - 10 * q) + '0';
179 if (q == 0)
180 return buf;
181 r = (q * (uint64_t)0x1999999a) >> 32;
182 *buf++ = (q - 10 * r) + '0';
183 if (r == 0)
184 return buf;
185 q = (r * (uint64_t)0x1999999a) >> 32;
186 *buf++ = (r - 10 * q) + '0';
187 if (q == 0)
188 return buf;
189 r = (q * (uint64_t)0x1999999a) >> 32;
190 *buf++ = (q - 10 * r) + '0';
191 if (r == 0)
192 return buf;
193 q = (r * 0x199a) >> 16;
194 *buf++ = (r - 10 * q) + '0';
195 if (q == 0)
196 return buf;
197 r = (q * 0xcd) >> 11;
198 *buf++ = (q - 10 * r) + '0';
199 if (r == 0)
200 return buf;
201 q = (r * 0xcd) >> 11;
202 *buf++ = (r - 10 * q) + '0';
203 if (q == 0)
204 return buf;
205 *buf++ = q + '0';
206 return buf;
207}
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226#if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64
227
228
229
230static
231char *put_dec(char *buf, unsigned long long n)
232{
233 if (n >= 100*1000*1000) {
234 while (n >= 1000*1000*1000)
235 buf = put_dec_full9(buf, do_div(n, 1000*1000*1000));
236 if (n >= 100*1000*1000)
237 return put_dec_full9(buf, n);
238 }
239 return put_dec_trunc8(buf, n);
240}
241
242#else
243
244
245
246static noinline_for_stack
247char *put_dec_full4(char *buf, unsigned q)
248{
249 unsigned r;
250 r = (q * 0xcccd) >> 19;
251 *buf++ = (q - 10 * r) + '0';
252 q = (r * 0x199a) >> 16;
253 *buf++ = (r - 10 * q) + '0';
254 r = (q * 0xcd) >> 11;
255 *buf++ = (q - 10 * r) + '0';
256 *buf++ = r + '0';
257 return buf;
258}
259
260
261
262
263
264
265static
266char *put_dec(char *buf, unsigned long long n)
267{
268 uint32_t d3, d2, d1, q, h;
269
270 if (n < 100*1000*1000)
271 return put_dec_trunc8(buf, n);
272
273 d1 = ((uint32_t)n >> 16);
274 h = (n >> 32);
275 d2 = (h ) & 0xffff;
276 d3 = (h >> 16);
277
278 q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff);
279
280 buf = put_dec_full4(buf, q % 10000);
281 q = q / 10000;
282
283 d1 = q + 7671 * d3 + 9496 * d2 + 6 * d1;
284 buf = put_dec_full4(buf, d1 % 10000);
285 q = d1 / 10000;
286
287 d2 = q + 4749 * d3 + 42 * d2;
288 buf = put_dec_full4(buf, d2 % 10000);
289 q = d2 / 10000;
290
291 d3 = q + 281 * d3;
292 if (!d3)
293 goto done;
294 buf = put_dec_full4(buf, d3 % 10000);
295 q = d3 / 10000;
296 if (!q)
297 goto done;
298 buf = put_dec_full4(buf, q);
299 done:
300 while (buf[-1] == '0')
301 --buf;
302
303 return buf;
304}
305
306#endif
307
308
309
310
311
312
313
314int num_to_str(char *buf, int size, unsigned long long num)
315{
316 char tmp[sizeof(num) * 3];
317 int idx, len;
318
319
320 if (num <= 9) {
321 tmp[0] = '0' + num;
322 len = 1;
323 } else {
324 len = put_dec(tmp, num) - tmp;
325 }
326
327 if (len > size)
328 return 0;
329 for (idx = 0; idx < len; ++idx)
330 buf[idx] = tmp[len - idx - 1];
331 return len;
332}
333
334#define ZEROPAD 1
335#define SIGN 2
336#define PLUS 4
337#define SPACE 8
338#define LEFT 16
339#define SMALL 32
340#define SPECIAL 64
341
342enum format_type {
343 FORMAT_TYPE_NONE,
344 FORMAT_TYPE_WIDTH,
345 FORMAT_TYPE_PRECISION,
346 FORMAT_TYPE_CHAR,
347 FORMAT_TYPE_STR,
348 FORMAT_TYPE_PTR,
349 FORMAT_TYPE_PERCENT_CHAR,
350 FORMAT_TYPE_INVALID,
351 FORMAT_TYPE_LONG_LONG,
352 FORMAT_TYPE_ULONG,
353 FORMAT_TYPE_LONG,
354 FORMAT_TYPE_UBYTE,
355 FORMAT_TYPE_BYTE,
356 FORMAT_TYPE_USHORT,
357 FORMAT_TYPE_SHORT,
358 FORMAT_TYPE_UINT,
359 FORMAT_TYPE_INT,
360 FORMAT_TYPE_NRCHARS,
361 FORMAT_TYPE_SIZE_T,
362 FORMAT_TYPE_PTRDIFF
363};
364
365struct printf_spec {
366 u8 type;
367 u8 flags;
368 u8 base;
369 u8 qualifier;
370 s16 field_width;
371 s16 precision;
372};
373
374static noinline_for_stack
375char *number(char *buf, char *end, unsigned long long num,
376 struct printf_spec spec)
377{
378
379 static const char digits[16] = "0123456789ABCDEF";
380
381 char tmp[66];
382 char sign;
383 char locase;
384 int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
385 int i;
386 bool is_zero = num == 0LL;
387
388
389
390 locase = (spec.flags & SMALL);
391 if (spec.flags & LEFT)
392 spec.flags &= ~ZEROPAD;
393 sign = 0;
394 if (spec.flags & SIGN) {
395 if ((signed long long)num < 0) {
396 sign = '-';
397 num = -(signed long long)num;
398 spec.field_width--;
399 } else if (spec.flags & PLUS) {
400 sign = '+';
401 spec.field_width--;
402 } else if (spec.flags & SPACE) {
403 sign = ' ';
404 spec.field_width--;
405 }
406 }
407 if (need_pfx) {
408 if (spec.base == 16)
409 spec.field_width -= 2;
410 else if (!is_zero)
411 spec.field_width--;
412 }
413
414
415 i = 0;
416 if (num < spec.base)
417 tmp[i++] = digits[num] | locase;
418
419
420
421
422
423 else if (spec.base != 10) {
424 int mask = spec.base - 1;
425 int shift = 3;
426
427 if (spec.base == 16)
428 shift = 4;
429 do {
430 tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
431 num >>= shift;
432 } while (num);
433 } else {
434 i = put_dec(tmp, num) - tmp;
435 }
436
437
438 if (i > spec.precision)
439 spec.precision = i;
440
441 spec.field_width -= spec.precision;
442 if (!(spec.flags & (ZEROPAD+LEFT))) {
443 while (--spec.field_width >= 0) {
444 if (buf < end)
445 *buf = ' ';
446 ++buf;
447 }
448 }
449
450 if (sign) {
451 if (buf < end)
452 *buf = sign;
453 ++buf;
454 }
455
456 if (need_pfx) {
457 if (spec.base == 16 || !is_zero) {
458 if (buf < end)
459 *buf = '0';
460 ++buf;
461 }
462 if (spec.base == 16) {
463 if (buf < end)
464 *buf = ('X' | locase);
465 ++buf;
466 }
467 }
468
469 if (!(spec.flags & LEFT)) {
470 char c = (spec.flags & ZEROPAD) ? '0' : ' ';
471 while (--spec.field_width >= 0) {
472 if (buf < end)
473 *buf = c;
474 ++buf;
475 }
476 }
477
478 while (i <= --spec.precision) {
479 if (buf < end)
480 *buf = '0';
481 ++buf;
482 }
483
484 while (--i >= 0) {
485 if (buf < end)
486 *buf = tmp[i];
487 ++buf;
488 }
489
490 while (--spec.field_width >= 0) {
491 if (buf < end)
492 *buf = ' ';
493 ++buf;
494 }
495
496 return buf;
497}
498
499static noinline_for_stack
500char *string(char *buf, char *end, const char *s, struct printf_spec spec)
501{
502 int len, i;
503
504 if ((unsigned long)s < PAGE_SIZE)
505 s = "(null)";
506
507 len = strnlen(s, spec.precision);
508
509 if (!(spec.flags & LEFT)) {
510 while (len < spec.field_width--) {
511 if (buf < end)
512 *buf = ' ';
513 ++buf;
514 }
515 }
516 for (i = 0; i < len; ++i) {
517 if (buf < end)
518 *buf = *s;
519 ++buf; ++s;
520 }
521 while (len < spec.field_width--) {
522 if (buf < end)
523 *buf = ' ';
524 ++buf;
525 }
526
527 return buf;
528}
529
530static noinline_for_stack
531char *symbol_string(char *buf, char *end, void *ptr,
532 struct printf_spec spec, char ext)
533{
534 unsigned long value = (unsigned long) ptr;
535#ifdef CONFIG_KALLSYMS
536 char sym[KSYM_SYMBOL_LEN];
537 if (ext == 'B')
538 sprint_backtrace(sym, value);
539 else if (ext != 'f' && ext != 's')
540 sprint_symbol(sym, value);
541 else
542 sprint_symbol_no_offset(sym, value);
543
544 return string(buf, end, sym, spec);
545#else
546 spec.field_width = 2 * sizeof(void *);
547 spec.flags |= SPECIAL | SMALL | ZEROPAD;
548 spec.base = 16;
549
550 return number(buf, end, value, spec);
551#endif
552}
553
554static noinline_for_stack
555char *resource_string(char *buf, char *end, struct resource *res,
556 struct printf_spec spec, const char *fmt)
557{
558#ifndef IO_RSRC_PRINTK_SIZE
559#define IO_RSRC_PRINTK_SIZE 6
560#endif
561
562#ifndef MEM_RSRC_PRINTK_SIZE
563#define MEM_RSRC_PRINTK_SIZE 10
564#endif
565 static const struct printf_spec io_spec = {
566 .base = 16,
567 .field_width = IO_RSRC_PRINTK_SIZE,
568 .precision = -1,
569 .flags = SPECIAL | SMALL | ZEROPAD,
570 };
571 static const struct printf_spec mem_spec = {
572 .base = 16,
573 .field_width = MEM_RSRC_PRINTK_SIZE,
574 .precision = -1,
575 .flags = SPECIAL | SMALL | ZEROPAD,
576 };
577 static const struct printf_spec bus_spec = {
578 .base = 16,
579 .field_width = 2,
580 .precision = -1,
581 .flags = SMALL | ZEROPAD,
582 };
583 static const struct printf_spec dec_spec = {
584 .base = 10,
585 .precision = -1,
586 .flags = 0,
587 };
588 static const struct printf_spec str_spec = {
589 .field_width = -1,
590 .precision = 10,
591 .flags = LEFT,
592 };
593 static const struct printf_spec flag_spec = {
594 .base = 16,
595 .precision = -1,
596 .flags = SPECIAL | SMALL,
597 };
598
599
600
601#define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4)
602#define FLAG_BUF_SIZE (2 * sizeof(res->flags))
603#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]")
604#define RAW_BUF_SIZE sizeof("[mem - flags 0x]")
605 char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
606 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
607
608 char *p = sym, *pend = sym + sizeof(sym);
609 int decode = (fmt[0] == 'R') ? 1 : 0;
610 const struct printf_spec *specp;
611
612 *p++ = '[';
613 if (res->flags & IORESOURCE_IO) {
614 p = string(p, pend, "io ", str_spec);
615 specp = &io_spec;
616 } else if (res->flags & IORESOURCE_MEM) {
617 p = string(p, pend, "mem ", str_spec);
618 specp = &mem_spec;
619 } else if (res->flags & IORESOURCE_IRQ) {
620 p = string(p, pend, "irq ", str_spec);
621 specp = &dec_spec;
622 } else if (res->flags & IORESOURCE_DMA) {
623 p = string(p, pend, "dma ", str_spec);
624 specp = &dec_spec;
625 } else if (res->flags & IORESOURCE_BUS) {
626 p = string(p, pend, "bus ", str_spec);
627 specp = &bus_spec;
628 } else {
629 p = string(p, pend, "??? ", str_spec);
630 specp = &mem_spec;
631 decode = 0;
632 }
633 p = number(p, pend, res->start, *specp);
634 if (res->start != res->end) {
635 *p++ = '-';
636 p = number(p, pend, res->end, *specp);
637 }
638 if (decode) {
639 if (res->flags & IORESOURCE_MEM_64)
640 p = string(p, pend, " 64bit", str_spec);
641 if (res->flags & IORESOURCE_PREFETCH)
642 p = string(p, pend, " pref", str_spec);
643 if (res->flags & IORESOURCE_WINDOW)
644 p = string(p, pend, " window", str_spec);
645 if (res->flags & IORESOURCE_DISABLED)
646 p = string(p, pend, " disabled", str_spec);
647 } else {
648 p = string(p, pend, " flags ", str_spec);
649 p = number(p, pend, res->flags, flag_spec);
650 }
651 *p++ = ']';
652 *p = '\0';
653
654 return string(buf, end, sym, spec);
655}
656
657static noinline_for_stack
658char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
659 const char *fmt)
660{
661 int i, len = 1;
662
663 char separator;
664
665 if (spec.field_width == 0)
666
667 return buf;
668
669 if (ZERO_OR_NULL_PTR(addr))
670
671 return string(buf, end, NULL, spec);
672
673 switch (fmt[1]) {
674 case 'C':
675 separator = ':';
676 break;
677 case 'D':
678 separator = '-';
679 break;
680 case 'N':
681 separator = 0;
682 break;
683 default:
684 separator = ' ';
685 break;
686 }
687
688 if (spec.field_width > 0)
689 len = min_t(int, spec.field_width, 64);
690
691 for (i = 0; i < len && buf < end - 1; i++) {
692 buf = hex_byte_pack(buf, addr[i]);
693
694 if (buf < end && separator && i != len - 1)
695 *buf++ = separator;
696 }
697
698 return buf;
699}
700
701static noinline_for_stack
702char *mac_address_string(char *buf, char *end, u8 *addr,
703 struct printf_spec spec, const char *fmt)
704{
705 char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
706 char *p = mac_addr;
707 int i;
708 char separator;
709 bool reversed = false;
710
711 switch (fmt[1]) {
712 case 'F':
713 separator = '-';
714 break;
715
716 case 'R':
717 reversed = true;
718
719
720 default:
721 separator = ':';
722 break;
723 }
724
725 for (i = 0; i < 6; i++) {
726 if (reversed)
727 p = hex_byte_pack(p, addr[5 - i]);
728 else
729 p = hex_byte_pack(p, addr[i]);
730
731 if (fmt[0] == 'M' && i != 5)
732 *p++ = separator;
733 }
734 *p = '\0';
735
736 return string(buf, end, mac_addr, spec);
737}
738
739static noinline_for_stack
740char *ip4_string(char *p, const u8 *addr, const char *fmt)
741{
742 int i;
743 bool leading_zeros = (fmt[0] == 'i');
744 int index;
745 int step;
746
747 switch (fmt[2]) {
748 case 'h':
749#ifdef __BIG_ENDIAN
750 index = 0;
751 step = 1;
752#else
753 index = 3;
754 step = -1;
755#endif
756 break;
757 case 'l':
758 index = 3;
759 step = -1;
760 break;
761 case 'n':
762 case 'b':
763 default:
764 index = 0;
765 step = 1;
766 break;
767 }
768 for (i = 0; i < 4; i++) {
769 char temp[3];
770 int digits = put_dec_trunc8(temp, addr[index]) - temp;
771 if (leading_zeros) {
772 if (digits < 3)
773 *p++ = '0';
774 if (digits < 2)
775 *p++ = '0';
776 }
777
778 while (digits--)
779 *p++ = temp[digits];
780 if (i < 3)
781 *p++ = '.';
782 index += step;
783 }
784 *p = '\0';
785
786 return p;
787}
788
789static noinline_for_stack
790char *ip6_compressed_string(char *p, const char *addr)
791{
792 int i, j, range;
793 unsigned char zerolength[8];
794 int longest = 1;
795 int colonpos = -1;
796 u16 word;
797 u8 hi, lo;
798 bool needcolon = false;
799 bool useIPv4;
800 struct in6_addr in6;
801
802 memcpy(&in6, addr, sizeof(struct in6_addr));
803
804 useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
805
806 memset(zerolength, 0, sizeof(zerolength));
807
808 if (useIPv4)
809 range = 6;
810 else
811 range = 8;
812
813
814 for (i = 0; i < range; i++) {
815 for (j = i; j < range; j++) {
816 if (in6.s6_addr16[j] != 0)
817 break;
818 zerolength[i]++;
819 }
820 }
821 for (i = 0; i < range; i++) {
822 if (zerolength[i] > longest) {
823 longest = zerolength[i];
824 colonpos = i;
825 }
826 }
827 if (longest == 1)
828 colonpos = -1;
829
830
831 for (i = 0; i < range; i++) {
832 if (i == colonpos) {
833 if (needcolon || i == 0)
834 *p++ = ':';
835 *p++ = ':';
836 needcolon = false;
837 i += longest - 1;
838 continue;
839 }
840 if (needcolon) {
841 *p++ = ':';
842 needcolon = false;
843 }
844
845 word = ntohs(in6.s6_addr16[i]);
846 hi = word >> 8;
847 lo = word & 0xff;
848 if (hi) {
849 if (hi > 0x0f)
850 p = hex_byte_pack(p, hi);
851 else
852 *p++ = hex_asc_lo(hi);
853 p = hex_byte_pack(p, lo);
854 }
855 else if (lo > 0x0f)
856 p = hex_byte_pack(p, lo);
857 else
858 *p++ = hex_asc_lo(lo);
859 needcolon = true;
860 }
861
862 if (useIPv4) {
863 if (needcolon)
864 *p++ = ':';
865 p = ip4_string(p, &in6.s6_addr[12], "I4");
866 }
867 *p = '\0';
868
869 return p;
870}
871
872static noinline_for_stack
873char *ip6_string(char *p, const char *addr, const char *fmt)
874{
875 int i;
876
877 for (i = 0; i < 8; i++) {
878 p = hex_byte_pack(p, *addr++);
879 p = hex_byte_pack(p, *addr++);
880 if (fmt[0] == 'I' && i != 7)
881 *p++ = ':';
882 }
883 *p = '\0';
884
885 return p;
886}
887
888static noinline_for_stack
889char *ip6_addr_string(char *buf, char *end, const u8 *addr,
890 struct printf_spec spec, const char *fmt)
891{
892 char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
893
894 if (fmt[0] == 'I' && fmt[2] == 'c')
895 ip6_compressed_string(ip6_addr, addr);
896 else
897 ip6_string(ip6_addr, addr, fmt);
898
899 return string(buf, end, ip6_addr, spec);
900}
901
902static noinline_for_stack
903char *ip4_addr_string(char *buf, char *end, const u8 *addr,
904 struct printf_spec spec, const char *fmt)
905{
906 char ip4_addr[sizeof("255.255.255.255")];
907
908 ip4_string(ip4_addr, addr, fmt);
909
910 return string(buf, end, ip4_addr, spec);
911}
912
913static noinline_for_stack
914char *uuid_string(char *buf, char *end, const u8 *addr,
915 struct printf_spec spec, const char *fmt)
916{
917 char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
918 char *p = uuid;
919 int i;
920 static const u8 be[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
921 static const u8 le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
922 const u8 *index = be;
923 bool uc = false;
924
925 switch (*(++fmt)) {
926 case 'L':
927 uc = true;
928 case 'l':
929 index = le;
930 break;
931 case 'B':
932 uc = true;
933 break;
934 }
935
936 for (i = 0; i < 16; i++) {
937 p = hex_byte_pack(p, addr[index[i]]);
938 switch (i) {
939 case 3:
940 case 5:
941 case 7:
942 case 9:
943 *p++ = '-';
944 break;
945 }
946 }
947
948 *p = 0;
949
950 if (uc) {
951 p = uuid;
952 do {
953 *p = toupper(*p);
954 } while (*(++p));
955 }
956
957 return string(buf, end, uuid, spec);
958}
959
960static
961char *netdev_feature_string(char *buf, char *end, const u8 *addr,
962 struct printf_spec spec)
963{
964 spec.flags |= SPECIAL | SMALL | ZEROPAD;
965 if (spec.field_width == -1)
966 spec.field_width = 2 + 2 * sizeof(netdev_features_t);
967 spec.base = 16;
968
969 return number(buf, end, *(const netdev_features_t *)addr, spec);
970}
971
972int kptr_restrict __read_mostly;
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033static noinline_for_stack
1034char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1035 struct printf_spec spec)
1036{
1037 int default_width = 2 * sizeof(void *) + (spec.flags & SPECIAL ? 2 : 0);
1038
1039 if (!ptr && *fmt != 'K') {
1040
1041
1042
1043
1044 if (spec.field_width == -1)
1045 spec.field_width = default_width;
1046 return string(buf, end, "(null)", spec);
1047 }
1048
1049 switch (*fmt) {
1050 case 'F':
1051 case 'f':
1052 ptr = dereference_function_descriptor(ptr);
1053
1054 case 'S':
1055 case 's':
1056 case 'B':
1057 return symbol_string(buf, end, ptr, spec, *fmt);
1058 case 'R':
1059 case 'r':
1060 return resource_string(buf, end, ptr, spec, fmt);
1061 case 'h':
1062 return hex_string(buf, end, ptr, spec, fmt);
1063 case 'M':
1064 case 'm':
1065
1066
1067 return mac_address_string(buf, end, ptr, spec, fmt);
1068 case 'I':
1069
1070
1071
1072
1073 case 'i':
1074
1075
1076
1077 switch (fmt[1]) {
1078 case '6':
1079 return ip6_addr_string(buf, end, ptr, spec, fmt);
1080 case '4':
1081 return ip4_addr_string(buf, end, ptr, spec, fmt);
1082 }
1083 break;
1084 case 'U':
1085 return uuid_string(buf, end, ptr, spec, fmt);
1086 case 'V':
1087 {
1088 va_list va;
1089
1090 va_copy(va, *((struct va_format *)ptr)->va);
1091 buf += vsnprintf(buf, end > buf ? end - buf : 0,
1092 ((struct va_format *)ptr)->fmt, va);
1093 va_end(va);
1094 return buf;
1095 }
1096 case 'K':
1097
1098
1099
1100
1101 if (kptr_restrict && (in_irq() || in_serving_softirq() ||
1102 in_nmi())) {
1103 if (spec.field_width == -1)
1104 spec.field_width = default_width;
1105 return string(buf, end, "pK-error", spec);
1106 }
1107 if (!((kptr_restrict == 0) ||
1108 (kptr_restrict == 1 &&
1109 has_capability_noaudit(current, CAP_SYSLOG))))
1110 ptr = NULL;
1111 break;
1112 case 'N':
1113 switch (fmt[1]) {
1114 case 'F':
1115 return netdev_feature_string(buf, end, ptr, spec);
1116 }
1117 break;
1118 }
1119 spec.flags |= SMALL;
1120 if (spec.field_width == -1) {
1121 spec.field_width = default_width;
1122 spec.flags |= ZEROPAD;
1123 }
1124 spec.base = 16;
1125
1126 return number(buf, end, (unsigned long) ptr, spec);
1127}
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149static noinline_for_stack
1150int format_decode(const char *fmt, struct printf_spec *spec)
1151{
1152 const char *start = fmt;
1153
1154
1155 if (spec->type == FORMAT_TYPE_WIDTH) {
1156 if (spec->field_width < 0) {
1157 spec->field_width = -spec->field_width;
1158 spec->flags |= LEFT;
1159 }
1160 spec->type = FORMAT_TYPE_NONE;
1161 goto precision;
1162 }
1163
1164
1165 if (spec->type == FORMAT_TYPE_PRECISION) {
1166 if (spec->precision < 0)
1167 spec->precision = 0;
1168
1169 spec->type = FORMAT_TYPE_NONE;
1170 goto qualifier;
1171 }
1172
1173
1174 spec->type = FORMAT_TYPE_NONE;
1175
1176 for (; *fmt ; ++fmt) {
1177 if (*fmt == '%')
1178 break;
1179 }
1180
1181
1182 if (fmt != start || !*fmt)
1183 return fmt - start;
1184
1185
1186 spec->flags = 0;
1187
1188 while (1) {
1189 bool found = true;
1190
1191 ++fmt;
1192
1193 switch (*fmt) {
1194 case '-': spec->flags |= LEFT; break;
1195 case '+': spec->flags |= PLUS; break;
1196 case ' ': spec->flags |= SPACE; break;
1197 case '#': spec->flags |= SPECIAL; break;
1198 case '0': spec->flags |= ZEROPAD; break;
1199 default: found = false;
1200 }
1201
1202 if (!found)
1203 break;
1204 }
1205
1206
1207 spec->field_width = -1;
1208
1209 if (isdigit(*fmt))
1210 spec->field_width = skip_atoi(&fmt);
1211 else if (*fmt == '*') {
1212
1213 spec->type = FORMAT_TYPE_WIDTH;
1214 return ++fmt - start;
1215 }
1216
1217precision:
1218
1219 spec->precision = -1;
1220 if (*fmt == '.') {
1221 ++fmt;
1222 if (isdigit(*fmt)) {
1223 spec->precision = skip_atoi(&fmt);
1224 if (spec->precision < 0)
1225 spec->precision = 0;
1226 } else if (*fmt == '*') {
1227
1228 spec->type = FORMAT_TYPE_PRECISION;
1229 return ++fmt - start;
1230 }
1231 }
1232
1233qualifier:
1234
1235 spec->qualifier = -1;
1236 if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
1237 _tolower(*fmt) == 'z' || *fmt == 't') {
1238 spec->qualifier = *fmt++;
1239 if (unlikely(spec->qualifier == *fmt)) {
1240 if (spec->qualifier == 'l') {
1241 spec->qualifier = 'L';
1242 ++fmt;
1243 } else if (spec->qualifier == 'h') {
1244 spec->qualifier = 'H';
1245 ++fmt;
1246 }
1247 }
1248 }
1249
1250
1251 spec->base = 10;
1252 switch (*fmt) {
1253 case 'c':
1254 spec->type = FORMAT_TYPE_CHAR;
1255 return ++fmt - start;
1256
1257 case 's':
1258 spec->type = FORMAT_TYPE_STR;
1259 return ++fmt - start;
1260
1261 case 'p':
1262 spec->type = FORMAT_TYPE_PTR;
1263 return fmt - start;
1264
1265
1266 case 'n':
1267 spec->type = FORMAT_TYPE_NRCHARS;
1268 return ++fmt - start;
1269
1270 case '%':
1271 spec->type = FORMAT_TYPE_PERCENT_CHAR;
1272 return ++fmt - start;
1273
1274
1275 case 'o':
1276 spec->base = 8;
1277 break;
1278
1279 case 'x':
1280 spec->flags |= SMALL;
1281
1282 case 'X':
1283 spec->base = 16;
1284 break;
1285
1286 case 'd':
1287 case 'i':
1288 spec->flags |= SIGN;
1289 case 'u':
1290 break;
1291
1292 default:
1293 spec->type = FORMAT_TYPE_INVALID;
1294 return fmt - start;
1295 }
1296
1297 if (spec->qualifier == 'L')
1298 spec->type = FORMAT_TYPE_LONG_LONG;
1299 else if (spec->qualifier == 'l') {
1300 if (spec->flags & SIGN)
1301 spec->type = FORMAT_TYPE_LONG;
1302 else
1303 spec->type = FORMAT_TYPE_ULONG;
1304 } else if (_tolower(spec->qualifier) == 'z') {
1305 spec->type = FORMAT_TYPE_SIZE_T;
1306 } else if (spec->qualifier == 't') {
1307 spec->type = FORMAT_TYPE_PTRDIFF;
1308 } else if (spec->qualifier == 'H') {
1309 if (spec->flags & SIGN)
1310 spec->type = FORMAT_TYPE_BYTE;
1311 else
1312 spec->type = FORMAT_TYPE_UBYTE;
1313 } else if (spec->qualifier == 'h') {
1314 if (spec->flags & SIGN)
1315 spec->type = FORMAT_TYPE_SHORT;
1316 else
1317 spec->type = FORMAT_TYPE_USHORT;
1318 } else {
1319 if (spec->flags & SIGN)
1320 spec->type = FORMAT_TYPE_INT;
1321 else
1322 spec->type = FORMAT_TYPE_UINT;
1323 }
1324
1325 return ++fmt - start;
1326}
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
1369{
1370 unsigned long long num;
1371 char *str, *end;
1372 struct printf_spec spec = {0};
1373
1374
1375
1376 if (WARN_ON_ONCE((int) size < 0))
1377 return 0;
1378
1379 str = buf;
1380 end = buf + size;
1381
1382
1383 if (end < buf) {
1384 end = ((void *)-1);
1385 size = end - buf;
1386 }
1387
1388 while (*fmt) {
1389 const char *old_fmt = fmt;
1390 int read = format_decode(fmt, &spec);
1391
1392 fmt += read;
1393
1394 switch (spec.type) {
1395 case FORMAT_TYPE_NONE: {
1396 int copy = read;
1397 if (str < end) {
1398 if (copy > end - str)
1399 copy = end - str;
1400 memcpy(str, old_fmt, copy);
1401 }
1402 str += read;
1403 break;
1404 }
1405
1406 case FORMAT_TYPE_WIDTH:
1407 spec.field_width = va_arg(args, int);
1408 break;
1409
1410 case FORMAT_TYPE_PRECISION:
1411 spec.precision = va_arg(args, int);
1412 break;
1413
1414 case FORMAT_TYPE_CHAR: {
1415 char c;
1416
1417 if (!(spec.flags & LEFT)) {
1418 while (--spec.field_width > 0) {
1419 if (str < end)
1420 *str = ' ';
1421 ++str;
1422
1423 }
1424 }
1425 c = (unsigned char) va_arg(args, int);
1426 if (str < end)
1427 *str = c;
1428 ++str;
1429 while (--spec.field_width > 0) {
1430 if (str < end)
1431 *str = ' ';
1432 ++str;
1433 }
1434 break;
1435 }
1436
1437 case FORMAT_TYPE_STR:
1438 str = string(str, end, va_arg(args, char *), spec);
1439 break;
1440
1441 case FORMAT_TYPE_PTR:
1442 str = pointer(fmt+1, str, end, va_arg(args, void *),
1443 spec);
1444 while (isalnum(*fmt))
1445 fmt++;
1446 break;
1447
1448 case FORMAT_TYPE_PERCENT_CHAR:
1449 if (str < end)
1450 *str = '%';
1451 ++str;
1452 break;
1453
1454 case FORMAT_TYPE_INVALID:
1455 if (str < end)
1456 *str = '%';
1457 ++str;
1458 break;
1459
1460 case FORMAT_TYPE_NRCHARS: {
1461 u8 qualifier = spec.qualifier;
1462
1463 if (qualifier == 'l') {
1464 long *ip = va_arg(args, long *);
1465 *ip = (str - buf);
1466 } else if (_tolower(qualifier) == 'z') {
1467 size_t *ip = va_arg(args, size_t *);
1468 *ip = (str - buf);
1469 } else {
1470 int *ip = va_arg(args, int *);
1471 *ip = (str - buf);
1472 }
1473 break;
1474 }
1475
1476 default:
1477 switch (spec.type) {
1478 case FORMAT_TYPE_LONG_LONG:
1479 num = va_arg(args, long long);
1480 break;
1481 case FORMAT_TYPE_ULONG:
1482 num = va_arg(args, unsigned long);
1483 break;
1484 case FORMAT_TYPE_LONG:
1485 num = va_arg(args, long);
1486 break;
1487 case FORMAT_TYPE_SIZE_T:
1488 num = va_arg(args, size_t);
1489 break;
1490 case FORMAT_TYPE_PTRDIFF:
1491 num = va_arg(args, ptrdiff_t);
1492 break;
1493 case FORMAT_TYPE_UBYTE:
1494 num = (unsigned char) va_arg(args, int);
1495 break;
1496 case FORMAT_TYPE_BYTE:
1497 num = (signed char) va_arg(args, int);
1498 break;
1499 case FORMAT_TYPE_USHORT:
1500 num = (unsigned short) va_arg(args, int);
1501 break;
1502 case FORMAT_TYPE_SHORT:
1503 num = (short) va_arg(args, int);
1504 break;
1505 case FORMAT_TYPE_INT:
1506 num = (int) va_arg(args, int);
1507 break;
1508 default:
1509 num = va_arg(args, unsigned int);
1510 }
1511
1512 str = number(str, end, num, spec);
1513 }
1514 }
1515
1516 if (size > 0) {
1517 if (str < end)
1518 *str = '\0';
1519 else
1520 end[-1] = '\0';
1521 }
1522
1523
1524 return str-buf;
1525
1526}
1527EXPORT_SYMBOL(vsnprintf);
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
1545{
1546 int i;
1547
1548 i = vsnprintf(buf, size, fmt, args);
1549
1550 if (likely(i < size))
1551 return i;
1552 if (size != 0)
1553 return size - 1;
1554 return 0;
1555}
1556EXPORT_SYMBOL(vscnprintf);
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572int snprintf(char *buf, size_t size, const char *fmt, ...)
1573{
1574 va_list args;
1575 int i;
1576
1577 va_start(args, fmt);
1578 i = vsnprintf(buf, size, fmt, args);
1579 va_end(args);
1580
1581 return i;
1582}
1583EXPORT_SYMBOL(snprintf);
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596int scnprintf(char *buf, size_t size, const char *fmt, ...)
1597{
1598 va_list args;
1599 int i;
1600
1601 va_start(args, fmt);
1602 i = vscnprintf(buf, size, fmt, args);
1603 va_end(args);
1604
1605 return i;
1606}
1607EXPORT_SYMBOL(scnprintf);
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623int vsprintf(char *buf, const char *fmt, va_list args)
1624{
1625 return vsnprintf(buf, INT_MAX, fmt, args);
1626}
1627EXPORT_SYMBOL(vsprintf);
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641int sprintf(char *buf, const char *fmt, ...)
1642{
1643 va_list args;
1644 int i;
1645
1646 va_start(args, fmt);
1647 i = vsnprintf(buf, INT_MAX, fmt, args);
1648 va_end(args);
1649
1650 return i;
1651}
1652EXPORT_SYMBOL(sprintf);
1653
1654#ifdef CONFIG_BINARY_PRINTF
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
1679{
1680 struct printf_spec spec = {0};
1681 char *str, *end;
1682
1683 str = (char *)bin_buf;
1684 end = (char *)(bin_buf + size);
1685
1686#define save_arg(type) \
1687do { \
1688 if (sizeof(type) == 8) { \
1689 unsigned long long value; \
1690 str = PTR_ALIGN(str, sizeof(u32)); \
1691 value = va_arg(args, unsigned long long); \
1692 if (str + sizeof(type) <= end) { \
1693 *(u32 *)str = *(u32 *)&value; \
1694 *(u32 *)(str + 4) = *((u32 *)&value + 1); \
1695 } \
1696 } else { \
1697 unsigned long value; \
1698 str = PTR_ALIGN(str, sizeof(type)); \
1699 value = va_arg(args, int); \
1700 if (str + sizeof(type) <= end) \
1701 *(typeof(type) *)str = (type)value; \
1702 } \
1703 str += sizeof(type); \
1704} while (0)
1705
1706 while (*fmt) {
1707 int read = format_decode(fmt, &spec);
1708
1709 fmt += read;
1710
1711 switch (spec.type) {
1712 case FORMAT_TYPE_NONE:
1713 case FORMAT_TYPE_INVALID:
1714 case FORMAT_TYPE_PERCENT_CHAR:
1715 break;
1716
1717 case FORMAT_TYPE_WIDTH:
1718 case FORMAT_TYPE_PRECISION:
1719 save_arg(int);
1720 break;
1721
1722 case FORMAT_TYPE_CHAR:
1723 save_arg(char);
1724 break;
1725
1726 case FORMAT_TYPE_STR: {
1727 const char *save_str = va_arg(args, char *);
1728 size_t len;
1729
1730 if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
1731 || (unsigned long)save_str < PAGE_SIZE)
1732 save_str = "(null)";
1733 len = strlen(save_str) + 1;
1734 if (str + len < end)
1735 memcpy(str, save_str, len);
1736 str += len;
1737 break;
1738 }
1739
1740 case FORMAT_TYPE_PTR:
1741 save_arg(void *);
1742
1743 while (isalnum(*fmt))
1744 fmt++;
1745 break;
1746
1747 case FORMAT_TYPE_NRCHARS: {
1748
1749 u8 qualifier = spec.qualifier;
1750 void *skip_arg;
1751 if (qualifier == 'l')
1752 skip_arg = va_arg(args, long *);
1753 else if (_tolower(qualifier) == 'z')
1754 skip_arg = va_arg(args, size_t *);
1755 else
1756 skip_arg = va_arg(args, int *);
1757 break;
1758 }
1759
1760 default:
1761 switch (spec.type) {
1762
1763 case FORMAT_TYPE_LONG_LONG:
1764 save_arg(long long);
1765 break;
1766 case FORMAT_TYPE_ULONG:
1767 case FORMAT_TYPE_LONG:
1768 save_arg(unsigned long);
1769 break;
1770 case FORMAT_TYPE_SIZE_T:
1771 save_arg(size_t);
1772 break;
1773 case FORMAT_TYPE_PTRDIFF:
1774 save_arg(ptrdiff_t);
1775 break;
1776 case FORMAT_TYPE_UBYTE:
1777 case FORMAT_TYPE_BYTE:
1778 save_arg(char);
1779 break;
1780 case FORMAT_TYPE_USHORT:
1781 case FORMAT_TYPE_SHORT:
1782 save_arg(short);
1783 break;
1784 default:
1785 save_arg(int);
1786 }
1787 }
1788 }
1789
1790 return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
1791#undef save_arg
1792}
1793EXPORT_SYMBOL_GPL(vbin_printf);
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
1818{
1819 struct printf_spec spec = {0};
1820 char *str, *end;
1821 const char *args = (const char *)bin_buf;
1822
1823 if (WARN_ON_ONCE((int) size < 0))
1824 return 0;
1825
1826 str = buf;
1827 end = buf + size;
1828
1829#define get_arg(type) \
1830({ \
1831 typeof(type) value; \
1832 if (sizeof(type) == 8) { \
1833 args = PTR_ALIGN(args, sizeof(u32)); \
1834 *(u32 *)&value = *(u32 *)args; \
1835 *((u32 *)&value + 1) = *(u32 *)(args + 4); \
1836 } else { \
1837 args = PTR_ALIGN(args, sizeof(type)); \
1838 value = *(typeof(type) *)args; \
1839 } \
1840 args += sizeof(type); \
1841 value; \
1842})
1843
1844
1845 if (end < buf) {
1846 end = ((void *)-1);
1847 size = end - buf;
1848 }
1849
1850 while (*fmt) {
1851 const char *old_fmt = fmt;
1852 int read = format_decode(fmt, &spec);
1853
1854 fmt += read;
1855
1856 switch (spec.type) {
1857 case FORMAT_TYPE_NONE: {
1858 int copy = read;
1859 if (str < end) {
1860 if (copy > end - str)
1861 copy = end - str;
1862 memcpy(str, old_fmt, copy);
1863 }
1864 str += read;
1865 break;
1866 }
1867
1868 case FORMAT_TYPE_WIDTH:
1869 spec.field_width = get_arg(int);
1870 break;
1871
1872 case FORMAT_TYPE_PRECISION:
1873 spec.precision = get_arg(int);
1874 break;
1875
1876 case FORMAT_TYPE_CHAR: {
1877 char c;
1878
1879 if (!(spec.flags & LEFT)) {
1880 while (--spec.field_width > 0) {
1881 if (str < end)
1882 *str = ' ';
1883 ++str;
1884 }
1885 }
1886 c = (unsigned char) get_arg(char);
1887 if (str < end)
1888 *str = c;
1889 ++str;
1890 while (--spec.field_width > 0) {
1891 if (str < end)
1892 *str = ' ';
1893 ++str;
1894 }
1895 break;
1896 }
1897
1898 case FORMAT_TYPE_STR: {
1899 const char *str_arg = args;
1900 args += strlen(str_arg) + 1;
1901 str = string(str, end, (char *)str_arg, spec);
1902 break;
1903 }
1904
1905 case FORMAT_TYPE_PTR:
1906 str = pointer(fmt+1, str, end, get_arg(void *), spec);
1907 while (isalnum(*fmt))
1908 fmt++;
1909 break;
1910
1911 case FORMAT_TYPE_PERCENT_CHAR:
1912 case FORMAT_TYPE_INVALID:
1913 if (str < end)
1914 *str = '%';
1915 ++str;
1916 break;
1917
1918 case FORMAT_TYPE_NRCHARS:
1919
1920 break;
1921
1922 default: {
1923 unsigned long long num;
1924
1925 switch (spec.type) {
1926
1927 case FORMAT_TYPE_LONG_LONG:
1928 num = get_arg(long long);
1929 break;
1930 case FORMAT_TYPE_ULONG:
1931 case FORMAT_TYPE_LONG:
1932 num = get_arg(unsigned long);
1933 break;
1934 case FORMAT_TYPE_SIZE_T:
1935 num = get_arg(size_t);
1936 break;
1937 case FORMAT_TYPE_PTRDIFF:
1938 num = get_arg(ptrdiff_t);
1939 break;
1940 case FORMAT_TYPE_UBYTE:
1941 num = get_arg(unsigned char);
1942 break;
1943 case FORMAT_TYPE_BYTE:
1944 num = get_arg(signed char);
1945 break;
1946 case FORMAT_TYPE_USHORT:
1947 num = get_arg(unsigned short);
1948 break;
1949 case FORMAT_TYPE_SHORT:
1950 num = get_arg(short);
1951 break;
1952 case FORMAT_TYPE_UINT:
1953 num = get_arg(unsigned int);
1954 break;
1955 default:
1956 num = get_arg(int);
1957 }
1958
1959 str = number(str, end, num, spec);
1960 }
1961 }
1962 }
1963
1964 if (size > 0) {
1965 if (str < end)
1966 *str = '\0';
1967 else
1968 end[-1] = '\0';
1969 }
1970
1971#undef get_arg
1972
1973
1974 return str - buf;
1975}
1976EXPORT_SYMBOL_GPL(bstr_printf);
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
1989{
1990 va_list args;
1991 int ret;
1992
1993 va_start(args, fmt);
1994 ret = vbin_printf(bin_buf, size, fmt, args);
1995 va_end(args);
1996
1997 return ret;
1998}
1999EXPORT_SYMBOL_GPL(bprintf);
2000
2001#endif
2002
2003
2004
2005
2006
2007
2008
2009int vsscanf(const char *buf, const char *fmt, va_list args)
2010{
2011 const char *str = buf;
2012 char *next;
2013 char digit;
2014 int num = 0;
2015 u8 qualifier;
2016 u8 base;
2017 s16 field_width;
2018 bool is_sign;
2019
2020 while (*fmt && *str) {
2021
2022
2023
2024
2025 if (isspace(*fmt)) {
2026 fmt = skip_spaces(++fmt);
2027 str = skip_spaces(str);
2028 }
2029
2030
2031 if (*fmt != '%' && *fmt) {
2032 if (*fmt++ != *str++)
2033 break;
2034 continue;
2035 }
2036
2037 if (!*fmt)
2038 break;
2039 ++fmt;
2040
2041
2042
2043
2044 if (*fmt == '*') {
2045 while (!isspace(*fmt) && *fmt != '%' && *fmt)
2046 fmt++;
2047 while (!isspace(*str) && *str)
2048 str++;
2049 continue;
2050 }
2051
2052
2053 field_width = -1;
2054 if (isdigit(*fmt))
2055 field_width = skip_atoi(&fmt);
2056
2057
2058 qualifier = -1;
2059 if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
2060 _tolower(*fmt) == 'z') {
2061 qualifier = *fmt++;
2062 if (unlikely(qualifier == *fmt)) {
2063 if (qualifier == 'h') {
2064 qualifier = 'H';
2065 fmt++;
2066 } else if (qualifier == 'l') {
2067 qualifier = 'L';
2068 fmt++;
2069 }
2070 }
2071 }
2072
2073 if (!*fmt || !*str)
2074 break;
2075
2076 base = 10;
2077 is_sign = 0;
2078
2079 switch (*fmt++) {
2080 case 'c':
2081 {
2082 char *s = (char *)va_arg(args, char*);
2083 if (field_width == -1)
2084 field_width = 1;
2085 do {
2086 *s++ = *str++;
2087 } while (--field_width > 0 && *str);
2088 num++;
2089 }
2090 continue;
2091 case 's':
2092 {
2093 char *s = (char *)va_arg(args, char *);
2094 if (field_width == -1)
2095 field_width = SHRT_MAX;
2096
2097 str = skip_spaces(str);
2098
2099
2100 while (*str && !isspace(*str) && field_width--)
2101 *s++ = *str++;
2102 *s = '\0';
2103 num++;
2104 }
2105 continue;
2106 case 'n':
2107
2108 {
2109 int *i = (int *)va_arg(args, int*);
2110 *i = str - buf;
2111 }
2112 continue;
2113 case 'o':
2114 base = 8;
2115 break;
2116 case 'x':
2117 case 'X':
2118 base = 16;
2119 break;
2120 case 'i':
2121 base = 0;
2122 case 'd':
2123 is_sign = 1;
2124 case 'u':
2125 break;
2126 case '%':
2127
2128 if (*str++ != '%')
2129 return num;
2130 continue;
2131 default:
2132
2133 return num;
2134 }
2135
2136
2137
2138
2139 str = skip_spaces(str);
2140
2141 digit = *str;
2142 if (is_sign && digit == '-')
2143 digit = *(str + 1);
2144
2145 if (!digit
2146 || (base == 16 && !isxdigit(digit))
2147 || (base == 10 && !isdigit(digit))
2148 || (base == 8 && (!isdigit(digit) || digit > '7'))
2149 || (base == 0 && !isdigit(digit)))
2150 break;
2151
2152 switch (qualifier) {
2153 case 'H':
2154 if (is_sign) {
2155 signed char *s = (signed char *)va_arg(args, signed char *);
2156 *s = (signed char)simple_strtol(str, &next, base);
2157 } else {
2158 unsigned char *s = (unsigned char *)va_arg(args, unsigned char *);
2159 *s = (unsigned char)simple_strtoul(str, &next, base);
2160 }
2161 break;
2162 case 'h':
2163 if (is_sign) {
2164 short *s = (short *)va_arg(args, short *);
2165 *s = (short)simple_strtol(str, &next, base);
2166 } else {
2167 unsigned short *s = (unsigned short *)va_arg(args, unsigned short *);
2168 *s = (unsigned short)simple_strtoul(str, &next, base);
2169 }
2170 break;
2171 case 'l':
2172 if (is_sign) {
2173 long *l = (long *)va_arg(args, long *);
2174 *l = simple_strtol(str, &next, base);
2175 } else {
2176 unsigned long *l = (unsigned long *)va_arg(args, unsigned long *);
2177 *l = simple_strtoul(str, &next, base);
2178 }
2179 break;
2180 case 'L':
2181 if (is_sign) {
2182 long long *l = (long long *)va_arg(args, long long *);
2183 *l = simple_strtoll(str, &next, base);
2184 } else {
2185 unsigned long long *l = (unsigned long long *)va_arg(args, unsigned long long *);
2186 *l = simple_strtoull(str, &next, base);
2187 }
2188 break;
2189 case 'Z':
2190 case 'z':
2191 {
2192 size_t *s = (size_t *)va_arg(args, size_t *);
2193 *s = (size_t)simple_strtoul(str, &next, base);
2194 }
2195 break;
2196 default:
2197 if (is_sign) {
2198 int *i = (int *)va_arg(args, int *);
2199 *i = (int)simple_strtol(str, &next, base);
2200 } else {
2201 unsigned int *i = (unsigned int *)va_arg(args, unsigned int*);
2202 *i = (unsigned int)simple_strtoul(str, &next, base);
2203 }
2204 break;
2205 }
2206 num++;
2207
2208 if (!next)
2209 break;
2210 str = next;
2211 }
2212
2213
2214
2215
2216
2217
2218 if (*fmt == '%' && *(fmt + 1) == 'n') {
2219 int *p = (int *)va_arg(args, int *);
2220 *p = str - buf;
2221 }
2222
2223 return num;
2224}
2225EXPORT_SYMBOL(vsscanf);
2226
2227
2228
2229
2230
2231
2232
2233int sscanf(const char *buf, const char *fmt, ...)
2234{
2235 va_list args;
2236 int i;
2237
2238 va_start(args, fmt);
2239 i = vsscanf(buf, fmt, args);
2240 va_end(args);
2241
2242 return i;
2243}
2244EXPORT_SYMBOL(sscanf);
2245