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 *mac_address_string(char *buf, char *end, u8 *addr,
659 struct printf_spec spec, const char *fmt)
660{
661 char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
662 char *p = mac_addr;
663 int i;
664 char separator;
665
666 if (fmt[1] == 'F') {
667 separator = '-';
668 } else {
669 separator = ':';
670 }
671
672 for (i = 0; i < 6; i++) {
673 p = hex_byte_pack(p, addr[i]);
674 if (fmt[0] == 'M' && i != 5)
675 *p++ = separator;
676 }
677 *p = '\0';
678
679 return string(buf, end, mac_addr, spec);
680}
681
682static noinline_for_stack
683char *ip4_string(char *p, const u8 *addr, const char *fmt)
684{
685 int i;
686 bool leading_zeros = (fmt[0] == 'i');
687 int index;
688 int step;
689
690 switch (fmt[2]) {
691 case 'h':
692#ifdef __BIG_ENDIAN
693 index = 0;
694 step = 1;
695#else
696 index = 3;
697 step = -1;
698#endif
699 break;
700 case 'l':
701 index = 3;
702 step = -1;
703 break;
704 case 'n':
705 case 'b':
706 default:
707 index = 0;
708 step = 1;
709 break;
710 }
711 for (i = 0; i < 4; i++) {
712 char temp[3];
713 int digits = put_dec_trunc8(temp, addr[index]) - temp;
714 if (leading_zeros) {
715 if (digits < 3)
716 *p++ = '0';
717 if (digits < 2)
718 *p++ = '0';
719 }
720
721 while (digits--)
722 *p++ = temp[digits];
723 if (i < 3)
724 *p++ = '.';
725 index += step;
726 }
727 *p = '\0';
728
729 return p;
730}
731
732static noinline_for_stack
733char *ip6_compressed_string(char *p, const char *addr)
734{
735 int i, j, range;
736 unsigned char zerolength[8];
737 int longest = 1;
738 int colonpos = -1;
739 u16 word;
740 u8 hi, lo;
741 bool needcolon = false;
742 bool useIPv4;
743 struct in6_addr in6;
744
745 memcpy(&in6, addr, sizeof(struct in6_addr));
746
747 useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
748
749 memset(zerolength, 0, sizeof(zerolength));
750
751 if (useIPv4)
752 range = 6;
753 else
754 range = 8;
755
756
757 for (i = 0; i < range; i++) {
758 for (j = i; j < range; j++) {
759 if (in6.s6_addr16[j] != 0)
760 break;
761 zerolength[i]++;
762 }
763 }
764 for (i = 0; i < range; i++) {
765 if (zerolength[i] > longest) {
766 longest = zerolength[i];
767 colonpos = i;
768 }
769 }
770 if (longest == 1)
771 colonpos = -1;
772
773
774 for (i = 0; i < range; i++) {
775 if (i == colonpos) {
776 if (needcolon || i == 0)
777 *p++ = ':';
778 *p++ = ':';
779 needcolon = false;
780 i += longest - 1;
781 continue;
782 }
783 if (needcolon) {
784 *p++ = ':';
785 needcolon = false;
786 }
787
788 word = ntohs(in6.s6_addr16[i]);
789 hi = word >> 8;
790 lo = word & 0xff;
791 if (hi) {
792 if (hi > 0x0f)
793 p = hex_byte_pack(p, hi);
794 else
795 *p++ = hex_asc_lo(hi);
796 p = hex_byte_pack(p, lo);
797 }
798 else if (lo > 0x0f)
799 p = hex_byte_pack(p, lo);
800 else
801 *p++ = hex_asc_lo(lo);
802 needcolon = true;
803 }
804
805 if (useIPv4) {
806 if (needcolon)
807 *p++ = ':';
808 p = ip4_string(p, &in6.s6_addr[12], "I4");
809 }
810 *p = '\0';
811
812 return p;
813}
814
815static noinline_for_stack
816char *ip6_string(char *p, const char *addr, const char *fmt)
817{
818 int i;
819
820 for (i = 0; i < 8; i++) {
821 p = hex_byte_pack(p, *addr++);
822 p = hex_byte_pack(p, *addr++);
823 if (fmt[0] == 'I' && i != 7)
824 *p++ = ':';
825 }
826 *p = '\0';
827
828 return p;
829}
830
831static noinline_for_stack
832char *ip6_addr_string(char *buf, char *end, const u8 *addr,
833 struct printf_spec spec, const char *fmt)
834{
835 char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
836
837 if (fmt[0] == 'I' && fmt[2] == 'c')
838 ip6_compressed_string(ip6_addr, addr);
839 else
840 ip6_string(ip6_addr, addr, fmt);
841
842 return string(buf, end, ip6_addr, spec);
843}
844
845static noinline_for_stack
846char *ip4_addr_string(char *buf, char *end, const u8 *addr,
847 struct printf_spec spec, const char *fmt)
848{
849 char ip4_addr[sizeof("255.255.255.255")];
850
851 ip4_string(ip4_addr, addr, fmt);
852
853 return string(buf, end, ip4_addr, spec);
854}
855
856static noinline_for_stack
857char *uuid_string(char *buf, char *end, const u8 *addr,
858 struct printf_spec spec, const char *fmt)
859{
860 char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
861 char *p = uuid;
862 int i;
863 static const u8 be[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
864 static const u8 le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
865 const u8 *index = be;
866 bool uc = false;
867
868 switch (*(++fmt)) {
869 case 'L':
870 uc = true;
871 case 'l':
872 index = le;
873 break;
874 case 'B':
875 uc = true;
876 break;
877 }
878
879 for (i = 0; i < 16; i++) {
880 p = hex_byte_pack(p, addr[index[i]]);
881 switch (i) {
882 case 3:
883 case 5:
884 case 7:
885 case 9:
886 *p++ = '-';
887 break;
888 }
889 }
890
891 *p = 0;
892
893 if (uc) {
894 p = uuid;
895 do {
896 *p = toupper(*p);
897 } while (*(++p));
898 }
899
900 return string(buf, end, uuid, spec);
901}
902
903static
904char *netdev_feature_string(char *buf, char *end, const u8 *addr,
905 struct printf_spec spec)
906{
907 spec.flags |= SPECIAL | SMALL | ZEROPAD;
908 if (spec.field_width == -1)
909 spec.field_width = 2 + 2 * sizeof(netdev_features_t);
910 spec.base = 16;
911
912 return number(buf, end, *(const netdev_features_t *)addr, spec);
913}
914
915int kptr_restrict __read_mostly;
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968static noinline_for_stack
969char *pointer(const char *fmt, char *buf, char *end, void *ptr,
970 struct printf_spec spec)
971{
972 int default_width = 2 * sizeof(void *) + (spec.flags & SPECIAL ? 2 : 0);
973
974 if (!ptr && *fmt != 'K') {
975
976
977
978
979 if (spec.field_width == -1)
980 spec.field_width = default_width;
981 return string(buf, end, "(null)", spec);
982 }
983
984 switch (*fmt) {
985 case 'F':
986 case 'f':
987 ptr = dereference_function_descriptor(ptr);
988
989 case 'S':
990 case 's':
991 case 'B':
992 return symbol_string(buf, end, ptr, spec, *fmt);
993 case 'R':
994 case 'r':
995 return resource_string(buf, end, ptr, spec, fmt);
996 case 'M':
997 case 'm':
998
999 return mac_address_string(buf, end, ptr, spec, fmt);
1000 case 'I':
1001
1002
1003
1004
1005 case 'i':
1006
1007
1008
1009 switch (fmt[1]) {
1010 case '6':
1011 return ip6_addr_string(buf, end, ptr, spec, fmt);
1012 case '4':
1013 return ip4_addr_string(buf, end, ptr, spec, fmt);
1014 }
1015 break;
1016 case 'U':
1017 return uuid_string(buf, end, ptr, spec, fmt);
1018 case 'V':
1019 {
1020 va_list va;
1021
1022 va_copy(va, *((struct va_format *)ptr)->va);
1023 buf += vsnprintf(buf, end > buf ? end - buf : 0,
1024 ((struct va_format *)ptr)->fmt, va);
1025 va_end(va);
1026 return buf;
1027 }
1028 case 'K':
1029
1030
1031
1032
1033 if (kptr_restrict && (in_irq() || in_serving_softirq() ||
1034 in_nmi())) {
1035 if (spec.field_width == -1)
1036 spec.field_width = default_width;
1037 return string(buf, end, "pK-error", spec);
1038 }
1039 if (!((kptr_restrict == 0) ||
1040 (kptr_restrict == 1 &&
1041 has_capability_noaudit(current, CAP_SYSLOG))))
1042 ptr = NULL;
1043 break;
1044 case 'N':
1045 switch (fmt[1]) {
1046 case 'F':
1047 return netdev_feature_string(buf, end, ptr, spec);
1048 }
1049 break;
1050 }
1051 spec.flags |= SMALL;
1052 if (spec.field_width == -1) {
1053 spec.field_width = default_width;
1054 spec.flags |= ZEROPAD;
1055 }
1056 spec.base = 16;
1057
1058 return number(buf, end, (unsigned long) ptr, spec);
1059}
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081static noinline_for_stack
1082int format_decode(const char *fmt, struct printf_spec *spec)
1083{
1084 const char *start = fmt;
1085
1086
1087 if (spec->type == FORMAT_TYPE_WIDTH) {
1088 if (spec->field_width < 0) {
1089 spec->field_width = -spec->field_width;
1090 spec->flags |= LEFT;
1091 }
1092 spec->type = FORMAT_TYPE_NONE;
1093 goto precision;
1094 }
1095
1096
1097 if (spec->type == FORMAT_TYPE_PRECISION) {
1098 if (spec->precision < 0)
1099 spec->precision = 0;
1100
1101 spec->type = FORMAT_TYPE_NONE;
1102 goto qualifier;
1103 }
1104
1105
1106 spec->type = FORMAT_TYPE_NONE;
1107
1108 for (; *fmt ; ++fmt) {
1109 if (*fmt == '%')
1110 break;
1111 }
1112
1113
1114 if (fmt != start || !*fmt)
1115 return fmt - start;
1116
1117
1118 spec->flags = 0;
1119
1120 while (1) {
1121 bool found = true;
1122
1123 ++fmt;
1124
1125 switch (*fmt) {
1126 case '-': spec->flags |= LEFT; break;
1127 case '+': spec->flags |= PLUS; break;
1128 case ' ': spec->flags |= SPACE; break;
1129 case '#': spec->flags |= SPECIAL; break;
1130 case '0': spec->flags |= ZEROPAD; break;
1131 default: found = false;
1132 }
1133
1134 if (!found)
1135 break;
1136 }
1137
1138
1139 spec->field_width = -1;
1140
1141 if (isdigit(*fmt))
1142 spec->field_width = skip_atoi(&fmt);
1143 else if (*fmt == '*') {
1144
1145 spec->type = FORMAT_TYPE_WIDTH;
1146 return ++fmt - start;
1147 }
1148
1149precision:
1150
1151 spec->precision = -1;
1152 if (*fmt == '.') {
1153 ++fmt;
1154 if (isdigit(*fmt)) {
1155 spec->precision = skip_atoi(&fmt);
1156 if (spec->precision < 0)
1157 spec->precision = 0;
1158 } else if (*fmt == '*') {
1159
1160 spec->type = FORMAT_TYPE_PRECISION;
1161 return ++fmt - start;
1162 }
1163 }
1164
1165qualifier:
1166
1167 spec->qualifier = -1;
1168 if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
1169 _tolower(*fmt) == 'z' || *fmt == 't') {
1170 spec->qualifier = *fmt++;
1171 if (unlikely(spec->qualifier == *fmt)) {
1172 if (spec->qualifier == 'l') {
1173 spec->qualifier = 'L';
1174 ++fmt;
1175 } else if (spec->qualifier == 'h') {
1176 spec->qualifier = 'H';
1177 ++fmt;
1178 }
1179 }
1180 }
1181
1182
1183 spec->base = 10;
1184 switch (*fmt) {
1185 case 'c':
1186 spec->type = FORMAT_TYPE_CHAR;
1187 return ++fmt - start;
1188
1189 case 's':
1190 spec->type = FORMAT_TYPE_STR;
1191 return ++fmt - start;
1192
1193 case 'p':
1194 spec->type = FORMAT_TYPE_PTR;
1195 return fmt - start;
1196
1197
1198 case 'n':
1199 spec->type = FORMAT_TYPE_NRCHARS;
1200 return ++fmt - start;
1201
1202 case '%':
1203 spec->type = FORMAT_TYPE_PERCENT_CHAR;
1204 return ++fmt - start;
1205
1206
1207 case 'o':
1208 spec->base = 8;
1209 break;
1210
1211 case 'x':
1212 spec->flags |= SMALL;
1213
1214 case 'X':
1215 spec->base = 16;
1216 break;
1217
1218 case 'd':
1219 case 'i':
1220 spec->flags |= SIGN;
1221 case 'u':
1222 break;
1223
1224 default:
1225 spec->type = FORMAT_TYPE_INVALID;
1226 return fmt - start;
1227 }
1228
1229 if (spec->qualifier == 'L')
1230 spec->type = FORMAT_TYPE_LONG_LONG;
1231 else if (spec->qualifier == 'l') {
1232 if (spec->flags & SIGN)
1233 spec->type = FORMAT_TYPE_LONG;
1234 else
1235 spec->type = FORMAT_TYPE_ULONG;
1236 } else if (_tolower(spec->qualifier) == 'z') {
1237 spec->type = FORMAT_TYPE_SIZE_T;
1238 } else if (spec->qualifier == 't') {
1239 spec->type = FORMAT_TYPE_PTRDIFF;
1240 } else if (spec->qualifier == 'H') {
1241 if (spec->flags & SIGN)
1242 spec->type = FORMAT_TYPE_BYTE;
1243 else
1244 spec->type = FORMAT_TYPE_UBYTE;
1245 } else if (spec->qualifier == 'h') {
1246 if (spec->flags & SIGN)
1247 spec->type = FORMAT_TYPE_SHORT;
1248 else
1249 spec->type = FORMAT_TYPE_USHORT;
1250 } else {
1251 if (spec->flags & SIGN)
1252 spec->type = FORMAT_TYPE_INT;
1253 else
1254 spec->type = FORMAT_TYPE_UINT;
1255 }
1256
1257 return ++fmt - start;
1258}
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
1297{
1298 unsigned long long num;
1299 char *str, *end;
1300 struct printf_spec spec = {0};
1301
1302
1303
1304 if (WARN_ON_ONCE((int) size < 0))
1305 return 0;
1306
1307 str = buf;
1308 end = buf + size;
1309
1310
1311 if (end < buf) {
1312 end = ((void *)-1);
1313 size = end - buf;
1314 }
1315
1316 while (*fmt) {
1317 const char *old_fmt = fmt;
1318 int read = format_decode(fmt, &spec);
1319
1320 fmt += read;
1321
1322 switch (spec.type) {
1323 case FORMAT_TYPE_NONE: {
1324 int copy = read;
1325 if (str < end) {
1326 if (copy > end - str)
1327 copy = end - str;
1328 memcpy(str, old_fmt, copy);
1329 }
1330 str += read;
1331 break;
1332 }
1333
1334 case FORMAT_TYPE_WIDTH:
1335 spec.field_width = va_arg(args, int);
1336 break;
1337
1338 case FORMAT_TYPE_PRECISION:
1339 spec.precision = va_arg(args, int);
1340 break;
1341
1342 case FORMAT_TYPE_CHAR: {
1343 char c;
1344
1345 if (!(spec.flags & LEFT)) {
1346 while (--spec.field_width > 0) {
1347 if (str < end)
1348 *str = ' ';
1349 ++str;
1350
1351 }
1352 }
1353 c = (unsigned char) va_arg(args, int);
1354 if (str < end)
1355 *str = c;
1356 ++str;
1357 while (--spec.field_width > 0) {
1358 if (str < end)
1359 *str = ' ';
1360 ++str;
1361 }
1362 break;
1363 }
1364
1365 case FORMAT_TYPE_STR:
1366 str = string(str, end, va_arg(args, char *), spec);
1367 break;
1368
1369 case FORMAT_TYPE_PTR:
1370 str = pointer(fmt+1, str, end, va_arg(args, void *),
1371 spec);
1372 while (isalnum(*fmt))
1373 fmt++;
1374 break;
1375
1376 case FORMAT_TYPE_PERCENT_CHAR:
1377 if (str < end)
1378 *str = '%';
1379 ++str;
1380 break;
1381
1382 case FORMAT_TYPE_INVALID:
1383 if (str < end)
1384 *str = '%';
1385 ++str;
1386 break;
1387
1388 case FORMAT_TYPE_NRCHARS: {
1389 u8 qualifier = spec.qualifier;
1390
1391 if (qualifier == 'l') {
1392 long *ip = va_arg(args, long *);
1393 *ip = (str - buf);
1394 } else if (_tolower(qualifier) == 'z') {
1395 size_t *ip = va_arg(args, size_t *);
1396 *ip = (str - buf);
1397 } else {
1398 int *ip = va_arg(args, int *);
1399 *ip = (str - buf);
1400 }
1401 break;
1402 }
1403
1404 default:
1405 switch (spec.type) {
1406 case FORMAT_TYPE_LONG_LONG:
1407 num = va_arg(args, long long);
1408 break;
1409 case FORMAT_TYPE_ULONG:
1410 num = va_arg(args, unsigned long);
1411 break;
1412 case FORMAT_TYPE_LONG:
1413 num = va_arg(args, long);
1414 break;
1415 case FORMAT_TYPE_SIZE_T:
1416 num = va_arg(args, size_t);
1417 break;
1418 case FORMAT_TYPE_PTRDIFF:
1419 num = va_arg(args, ptrdiff_t);
1420 break;
1421 case FORMAT_TYPE_UBYTE:
1422 num = (unsigned char) va_arg(args, int);
1423 break;
1424 case FORMAT_TYPE_BYTE:
1425 num = (signed char) va_arg(args, int);
1426 break;
1427 case FORMAT_TYPE_USHORT:
1428 num = (unsigned short) va_arg(args, int);
1429 break;
1430 case FORMAT_TYPE_SHORT:
1431 num = (short) va_arg(args, int);
1432 break;
1433 case FORMAT_TYPE_INT:
1434 num = (int) va_arg(args, int);
1435 break;
1436 default:
1437 num = va_arg(args, unsigned int);
1438 }
1439
1440 str = number(str, end, num, spec);
1441 }
1442 }
1443
1444 if (size > 0) {
1445 if (str < end)
1446 *str = '\0';
1447 else
1448 end[-1] = '\0';
1449 }
1450
1451
1452 return str-buf;
1453
1454}
1455EXPORT_SYMBOL(vsnprintf);
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
1473{
1474 int i;
1475
1476 i = vsnprintf(buf, size, fmt, args);
1477
1478 if (likely(i < size))
1479 return i;
1480 if (size != 0)
1481 return size - 1;
1482 return 0;
1483}
1484EXPORT_SYMBOL(vscnprintf);
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500int snprintf(char *buf, size_t size, const char *fmt, ...)
1501{
1502 va_list args;
1503 int i;
1504
1505 va_start(args, fmt);
1506 i = vsnprintf(buf, size, fmt, args);
1507 va_end(args);
1508
1509 return i;
1510}
1511EXPORT_SYMBOL(snprintf);
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524int scnprintf(char *buf, size_t size, const char *fmt, ...)
1525{
1526 va_list args;
1527 int i;
1528
1529 va_start(args, fmt);
1530 i = vscnprintf(buf, size, fmt, args);
1531 va_end(args);
1532
1533 return i;
1534}
1535EXPORT_SYMBOL(scnprintf);
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551int vsprintf(char *buf, const char *fmt, va_list args)
1552{
1553 return vsnprintf(buf, INT_MAX, fmt, args);
1554}
1555EXPORT_SYMBOL(vsprintf);
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569int sprintf(char *buf, const char *fmt, ...)
1570{
1571 va_list args;
1572 int i;
1573
1574 va_start(args, fmt);
1575 i = vsnprintf(buf, INT_MAX, fmt, args);
1576 va_end(args);
1577
1578 return i;
1579}
1580EXPORT_SYMBOL(sprintf);
1581
1582#ifdef CONFIG_BINARY_PRINTF
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
1607{
1608 struct printf_spec spec = {0};
1609 char *str, *end;
1610
1611 str = (char *)bin_buf;
1612 end = (char *)(bin_buf + size);
1613
1614#define save_arg(type) \
1615do { \
1616 if (sizeof(type) == 8) { \
1617 unsigned long long value; \
1618 str = PTR_ALIGN(str, sizeof(u32)); \
1619 value = va_arg(args, unsigned long long); \
1620 if (str + sizeof(type) <= end) { \
1621 *(u32 *)str = *(u32 *)&value; \
1622 *(u32 *)(str + 4) = *((u32 *)&value + 1); \
1623 } \
1624 } else { \
1625 unsigned long value; \
1626 str = PTR_ALIGN(str, sizeof(type)); \
1627 value = va_arg(args, int); \
1628 if (str + sizeof(type) <= end) \
1629 *(typeof(type) *)str = (type)value; \
1630 } \
1631 str += sizeof(type); \
1632} while (0)
1633
1634 while (*fmt) {
1635 int read = format_decode(fmt, &spec);
1636
1637 fmt += read;
1638
1639 switch (spec.type) {
1640 case FORMAT_TYPE_NONE:
1641 case FORMAT_TYPE_INVALID:
1642 case FORMAT_TYPE_PERCENT_CHAR:
1643 break;
1644
1645 case FORMAT_TYPE_WIDTH:
1646 case FORMAT_TYPE_PRECISION:
1647 save_arg(int);
1648 break;
1649
1650 case FORMAT_TYPE_CHAR:
1651 save_arg(char);
1652 break;
1653
1654 case FORMAT_TYPE_STR: {
1655 const char *save_str = va_arg(args, char *);
1656 size_t len;
1657
1658 if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
1659 || (unsigned long)save_str < PAGE_SIZE)
1660 save_str = "(null)";
1661 len = strlen(save_str) + 1;
1662 if (str + len < end)
1663 memcpy(str, save_str, len);
1664 str += len;
1665 break;
1666 }
1667
1668 case FORMAT_TYPE_PTR:
1669 save_arg(void *);
1670
1671 while (isalnum(*fmt))
1672 fmt++;
1673 break;
1674
1675 case FORMAT_TYPE_NRCHARS: {
1676
1677 u8 qualifier = spec.qualifier;
1678 void *skip_arg;
1679 if (qualifier == 'l')
1680 skip_arg = va_arg(args, long *);
1681 else if (_tolower(qualifier) == 'z')
1682 skip_arg = va_arg(args, size_t *);
1683 else
1684 skip_arg = va_arg(args, int *);
1685 break;
1686 }
1687
1688 default:
1689 switch (spec.type) {
1690
1691 case FORMAT_TYPE_LONG_LONG:
1692 save_arg(long long);
1693 break;
1694 case FORMAT_TYPE_ULONG:
1695 case FORMAT_TYPE_LONG:
1696 save_arg(unsigned long);
1697 break;
1698 case FORMAT_TYPE_SIZE_T:
1699 save_arg(size_t);
1700 break;
1701 case FORMAT_TYPE_PTRDIFF:
1702 save_arg(ptrdiff_t);
1703 break;
1704 case FORMAT_TYPE_UBYTE:
1705 case FORMAT_TYPE_BYTE:
1706 save_arg(char);
1707 break;
1708 case FORMAT_TYPE_USHORT:
1709 case FORMAT_TYPE_SHORT:
1710 save_arg(short);
1711 break;
1712 default:
1713 save_arg(int);
1714 }
1715 }
1716 }
1717
1718 return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
1719#undef save_arg
1720}
1721EXPORT_SYMBOL_GPL(vbin_printf);
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
1746{
1747 struct printf_spec spec = {0};
1748 char *str, *end;
1749 const char *args = (const char *)bin_buf;
1750
1751 if (WARN_ON_ONCE((int) size < 0))
1752 return 0;
1753
1754 str = buf;
1755 end = buf + size;
1756
1757#define get_arg(type) \
1758({ \
1759 typeof(type) value; \
1760 if (sizeof(type) == 8) { \
1761 args = PTR_ALIGN(args, sizeof(u32)); \
1762 *(u32 *)&value = *(u32 *)args; \
1763 *((u32 *)&value + 1) = *(u32 *)(args + 4); \
1764 } else { \
1765 args = PTR_ALIGN(args, sizeof(type)); \
1766 value = *(typeof(type) *)args; \
1767 } \
1768 args += sizeof(type); \
1769 value; \
1770})
1771
1772
1773 if (end < buf) {
1774 end = ((void *)-1);
1775 size = end - buf;
1776 }
1777
1778 while (*fmt) {
1779 const char *old_fmt = fmt;
1780 int read = format_decode(fmt, &spec);
1781
1782 fmt += read;
1783
1784 switch (spec.type) {
1785 case FORMAT_TYPE_NONE: {
1786 int copy = read;
1787 if (str < end) {
1788 if (copy > end - str)
1789 copy = end - str;
1790 memcpy(str, old_fmt, copy);
1791 }
1792 str += read;
1793 break;
1794 }
1795
1796 case FORMAT_TYPE_WIDTH:
1797 spec.field_width = get_arg(int);
1798 break;
1799
1800 case FORMAT_TYPE_PRECISION:
1801 spec.precision = get_arg(int);
1802 break;
1803
1804 case FORMAT_TYPE_CHAR: {
1805 char c;
1806
1807 if (!(spec.flags & LEFT)) {
1808 while (--spec.field_width > 0) {
1809 if (str < end)
1810 *str = ' ';
1811 ++str;
1812 }
1813 }
1814 c = (unsigned char) get_arg(char);
1815 if (str < end)
1816 *str = c;
1817 ++str;
1818 while (--spec.field_width > 0) {
1819 if (str < end)
1820 *str = ' ';
1821 ++str;
1822 }
1823 break;
1824 }
1825
1826 case FORMAT_TYPE_STR: {
1827 const char *str_arg = args;
1828 args += strlen(str_arg) + 1;
1829 str = string(str, end, (char *)str_arg, spec);
1830 break;
1831 }
1832
1833 case FORMAT_TYPE_PTR:
1834 str = pointer(fmt+1, str, end, get_arg(void *), spec);
1835 while (isalnum(*fmt))
1836 fmt++;
1837 break;
1838
1839 case FORMAT_TYPE_PERCENT_CHAR:
1840 case FORMAT_TYPE_INVALID:
1841 if (str < end)
1842 *str = '%';
1843 ++str;
1844 break;
1845
1846 case FORMAT_TYPE_NRCHARS:
1847
1848 break;
1849
1850 default: {
1851 unsigned long long num;
1852
1853 switch (spec.type) {
1854
1855 case FORMAT_TYPE_LONG_LONG:
1856 num = get_arg(long long);
1857 break;
1858 case FORMAT_TYPE_ULONG:
1859 case FORMAT_TYPE_LONG:
1860 num = get_arg(unsigned long);
1861 break;
1862 case FORMAT_TYPE_SIZE_T:
1863 num = get_arg(size_t);
1864 break;
1865 case FORMAT_TYPE_PTRDIFF:
1866 num = get_arg(ptrdiff_t);
1867 break;
1868 case FORMAT_TYPE_UBYTE:
1869 num = get_arg(unsigned char);
1870 break;
1871 case FORMAT_TYPE_BYTE:
1872 num = get_arg(signed char);
1873 break;
1874 case FORMAT_TYPE_USHORT:
1875 num = get_arg(unsigned short);
1876 break;
1877 case FORMAT_TYPE_SHORT:
1878 num = get_arg(short);
1879 break;
1880 case FORMAT_TYPE_UINT:
1881 num = get_arg(unsigned int);
1882 break;
1883 default:
1884 num = get_arg(int);
1885 }
1886
1887 str = number(str, end, num, spec);
1888 }
1889 }
1890 }
1891
1892 if (size > 0) {
1893 if (str < end)
1894 *str = '\0';
1895 else
1896 end[-1] = '\0';
1897 }
1898
1899#undef get_arg
1900
1901
1902 return str - buf;
1903}
1904EXPORT_SYMBOL_GPL(bstr_printf);
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
1917{
1918 va_list args;
1919 int ret;
1920
1921 va_start(args, fmt);
1922 ret = vbin_printf(bin_buf, size, fmt, args);
1923 va_end(args);
1924
1925 return ret;
1926}
1927EXPORT_SYMBOL_GPL(bprintf);
1928
1929#endif
1930
1931
1932
1933
1934
1935
1936
1937int vsscanf(const char *buf, const char *fmt, va_list args)
1938{
1939 const char *str = buf;
1940 char *next;
1941 char digit;
1942 int num = 0;
1943 u8 qualifier;
1944 u8 base;
1945 s16 field_width;
1946 bool is_sign;
1947
1948 while (*fmt && *str) {
1949
1950
1951
1952
1953 if (isspace(*fmt)) {
1954 fmt = skip_spaces(++fmt);
1955 str = skip_spaces(str);
1956 }
1957
1958
1959 if (*fmt != '%' && *fmt) {
1960 if (*fmt++ != *str++)
1961 break;
1962 continue;
1963 }
1964
1965 if (!*fmt)
1966 break;
1967 ++fmt;
1968
1969
1970
1971
1972 if (*fmt == '*') {
1973 while (!isspace(*fmt) && *fmt != '%' && *fmt)
1974 fmt++;
1975 while (!isspace(*str) && *str)
1976 str++;
1977 continue;
1978 }
1979
1980
1981 field_width = -1;
1982 if (isdigit(*fmt))
1983 field_width = skip_atoi(&fmt);
1984
1985
1986 qualifier = -1;
1987 if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
1988 _tolower(*fmt) == 'z') {
1989 qualifier = *fmt++;
1990 if (unlikely(qualifier == *fmt)) {
1991 if (qualifier == 'h') {
1992 qualifier = 'H';
1993 fmt++;
1994 } else if (qualifier == 'l') {
1995 qualifier = 'L';
1996 fmt++;
1997 }
1998 }
1999 }
2000
2001 if (!*fmt || !*str)
2002 break;
2003
2004 base = 10;
2005 is_sign = 0;
2006
2007 switch (*fmt++) {
2008 case 'c':
2009 {
2010 char *s = (char *)va_arg(args, char*);
2011 if (field_width == -1)
2012 field_width = 1;
2013 do {
2014 *s++ = *str++;
2015 } while (--field_width > 0 && *str);
2016 num++;
2017 }
2018 continue;
2019 case 's':
2020 {
2021 char *s = (char *)va_arg(args, char *);
2022 if (field_width == -1)
2023 field_width = SHRT_MAX;
2024
2025 str = skip_spaces(str);
2026
2027
2028 while (*str && !isspace(*str) && field_width--)
2029 *s++ = *str++;
2030 *s = '\0';
2031 num++;
2032 }
2033 continue;
2034 case 'n':
2035
2036 {
2037 int *i = (int *)va_arg(args, int*);
2038 *i = str - buf;
2039 }
2040 continue;
2041 case 'o':
2042 base = 8;
2043 break;
2044 case 'x':
2045 case 'X':
2046 base = 16;
2047 break;
2048 case 'i':
2049 base = 0;
2050 case 'd':
2051 is_sign = 1;
2052 case 'u':
2053 break;
2054 case '%':
2055
2056 if (*str++ != '%')
2057 return num;
2058 continue;
2059 default:
2060
2061 return num;
2062 }
2063
2064
2065
2066
2067 str = skip_spaces(str);
2068
2069 digit = *str;
2070 if (is_sign && digit == '-')
2071 digit = *(str + 1);
2072
2073 if (!digit
2074 || (base == 16 && !isxdigit(digit))
2075 || (base == 10 && !isdigit(digit))
2076 || (base == 8 && (!isdigit(digit) || digit > '7'))
2077 || (base == 0 && !isdigit(digit)))
2078 break;
2079
2080 switch (qualifier) {
2081 case 'H':
2082 if (is_sign) {
2083 signed char *s = (signed char *)va_arg(args, signed char *);
2084 *s = (signed char)simple_strtol(str, &next, base);
2085 } else {
2086 unsigned char *s = (unsigned char *)va_arg(args, unsigned char *);
2087 *s = (unsigned char)simple_strtoul(str, &next, base);
2088 }
2089 break;
2090 case 'h':
2091 if (is_sign) {
2092 short *s = (short *)va_arg(args, short *);
2093 *s = (short)simple_strtol(str, &next, base);
2094 } else {
2095 unsigned short *s = (unsigned short *)va_arg(args, unsigned short *);
2096 *s = (unsigned short)simple_strtoul(str, &next, base);
2097 }
2098 break;
2099 case 'l':
2100 if (is_sign) {
2101 long *l = (long *)va_arg(args, long *);
2102 *l = simple_strtol(str, &next, base);
2103 } else {
2104 unsigned long *l = (unsigned long *)va_arg(args, unsigned long *);
2105 *l = simple_strtoul(str, &next, base);
2106 }
2107 break;
2108 case 'L':
2109 if (is_sign) {
2110 long long *l = (long long *)va_arg(args, long long *);
2111 *l = simple_strtoll(str, &next, base);
2112 } else {
2113 unsigned long long *l = (unsigned long long *)va_arg(args, unsigned long long *);
2114 *l = simple_strtoull(str, &next, base);
2115 }
2116 break;
2117 case 'Z':
2118 case 'z':
2119 {
2120 size_t *s = (size_t *)va_arg(args, size_t *);
2121 *s = (size_t)simple_strtoul(str, &next, base);
2122 }
2123 break;
2124 default:
2125 if (is_sign) {
2126 int *i = (int *)va_arg(args, int *);
2127 *i = (int)simple_strtol(str, &next, base);
2128 } else {
2129 unsigned int *i = (unsigned int *)va_arg(args, unsigned int*);
2130 *i = (unsigned int)simple_strtoul(str, &next, base);
2131 }
2132 break;
2133 }
2134 num++;
2135
2136 if (!next)
2137 break;
2138 str = next;
2139 }
2140
2141
2142
2143
2144
2145
2146 if (*fmt == '%' && *(fmt + 1) == 'n') {
2147 int *p = (int *)va_arg(args, int *);
2148 *p = str - buf;
2149 }
2150
2151 return num;
2152}
2153EXPORT_SYMBOL(vsscanf);
2154
2155
2156
2157
2158
2159
2160
2161int sscanf(const char *buf, const char *fmt, ...)
2162{
2163 va_list args;
2164 int i;
2165
2166 va_start(args, fmt);
2167 i = vsscanf(buf, fmt, args);
2168 va_end(args);
2169
2170 return i;
2171}
2172EXPORT_SYMBOL(sscanf);
2173