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