Branch data Line data Source code
1 : : /*
2 : : * linux/lib/vsprintf.c
3 : : *
4 : : * Copyright (C) 1991, 1992 Linus Torvalds
5 : : */
6 : :
7 : : /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
8 : : /*
9 : : * Wirzenius wrote this portably, Torvalds fucked it up :-)
10 : : */
11 : :
12 : : /*
13 : : * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
14 : : * - changed to provide snprintf and vsnprintf functions
15 : : * So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
16 : : * - scnprintf and vscnprintf
17 : : */
18 : :
19 : : #include <stdarg.h>
20 : : #include <linux/module.h> /* for KSYM_SYMBOL_LEN */
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/math64.h>
27 : : #include <linux/uaccess.h>
28 : : #include <linux/ioport.h>
29 : : #include <linux/dcache.h>
30 : : #include <linux/cred.h>
31 : : #include <net/addrconf.h>
32 : :
33 : : #include <asm/page.h> /* for PAGE_SIZE */
34 : : #include <asm/sections.h> /* for dereference_function_descriptor() */
35 : :
36 : : #include "kstrtox.h"
37 : :
38 : : /**
39 : : * simple_strtoull - convert a string to an unsigned long long
40 : : * @cp: The start of the string
41 : : * @endp: A pointer to the end of the parsed string will be placed here
42 : : * @base: The number base to use
43 : : *
44 : : * This function is obsolete. Please use kstrtoull instead.
45 : : */
46 : 0 : unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
47 : : {
48 : : unsigned long long result;
49 : : unsigned int rv;
50 : :
51 : 211 : cp = _parse_integer_fixup_radix(cp, &base);
52 : 211 : rv = _parse_integer(cp, base, &result);
53 : : /* FIXME */
54 : 211 : cp += (rv & ~KSTRTOX_OVERFLOW);
55 : :
56 [ + - ]: 211 : if (endp)
57 : 211 : *endp = (char *)cp;
58 : :
59 : 0 : return result;
60 : : }
61 : : EXPORT_SYMBOL(simple_strtoull);
62 : :
63 : : /**
64 : : * simple_strtoul - convert a string to an unsigned long
65 : : * @cp: The start of the string
66 : : * @endp: A pointer to the end of the parsed string will be placed here
67 : : * @base: The number base to use
68 : : *
69 : : * This function is obsolete. Please use kstrtoul instead.
70 : : */
71 : 0 : unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
72 : : {
73 : 209 : return simple_strtoull(cp, endp, base);
74 : : }
75 : : EXPORT_SYMBOL(simple_strtoul);
76 : :
77 : : /**
78 : : * simple_strtol - convert a string to a signed long
79 : : * @cp: The start of the string
80 : : * @endp: A pointer to the end of the parsed string will be placed here
81 : : * @base: The number base to use
82 : : *
83 : : * This function is obsolete. Please use kstrtol instead.
84 : : */
85 : 0 : long simple_strtol(const char *cp, char **endp, unsigned int base)
86 : : {
87 [ # # ]: 0 : if (*cp == '-')
88 : 0 : return -simple_strtoul(cp + 1, endp, base);
89 : :
90 : 0 : return simple_strtoul(cp, endp, base);
91 : : }
92 : : EXPORT_SYMBOL(simple_strtol);
93 : :
94 : : /**
95 : : * simple_strtoll - convert a string to a signed long long
96 : : * @cp: The start of the string
97 : : * @endp: A pointer to the end of the parsed string will be placed here
98 : : * @base: The number base to use
99 : : *
100 : : * This function is obsolete. Please use kstrtoll instead.
101 : : */
102 : 0 : long long simple_strtoll(const char *cp, char **endp, unsigned int base)
103 : : {
104 [ # # ]: 0 : if (*cp == '-')
105 : 0 : return -simple_strtoull(cp + 1, endp, base);
106 : :
107 : 0 : return simple_strtoull(cp, endp, base);
108 : : }
109 : : EXPORT_SYMBOL(simple_strtoll);
110 : :
111 : : static noinline_for_stack
112 : 0 : int skip_atoi(const char **s)
113 : : {
114 : : int i = 0;
115 : :
116 [ + + ]: 9997279 : while (isdigit(**s))
117 : 5006825 : i = i*10 + *((*s)++) - '0';
118 : :
119 : 4990454 : return i;
120 : : }
121 : :
122 : : /* Decimal conversion is by far the most typical, and is used
123 : : * for /proc and /sys data. This directly impacts e.g. top performance
124 : : * with many processes running. We optimize it for speed
125 : : * using ideas described at <http://www.cs.uiowa.edu/~jones/bcd/divide.html>
126 : : * (with permission from the author, Douglas W. Jones).
127 : : */
128 : :
129 : : #if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64
130 : : /* Formats correctly any integer in [0, 999999999] */
131 : : static noinline_for_stack
132 : : char *put_dec_full9(char *buf, unsigned q)
133 : : {
134 : : unsigned r;
135 : :
136 : : /*
137 : : * Possible ways to approx. divide by 10
138 : : * (x * 0x1999999a) >> 32 x < 1073741829 (multiply must be 64-bit)
139 : : * (x * 0xcccd) >> 19 x < 81920 (x < 262149 when 64-bit mul)
140 : : * (x * 0x6667) >> 18 x < 43699
141 : : * (x * 0x3334) >> 17 x < 16389
142 : : * (x * 0x199a) >> 16 x < 16389
143 : : * (x * 0x0ccd) >> 15 x < 16389
144 : : * (x * 0x0667) >> 14 x < 2739
145 : : * (x * 0x0334) >> 13 x < 1029
146 : : * (x * 0x019a) >> 12 x < 1029
147 : : * (x * 0x00cd) >> 11 x < 1029 shorter code than * 0x67 (on i386)
148 : : * (x * 0x0067) >> 10 x < 179
149 : : * (x * 0x0034) >> 9 x < 69 same
150 : : * (x * 0x001a) >> 8 x < 69 same
151 : : * (x * 0x000d) >> 7 x < 69 same, shortest code (on i386)
152 : : * (x * 0x0007) >> 6 x < 19
153 : : * See <http://www.cs.uiowa.edu/~jones/bcd/divide.html>
154 : : */
155 : : r = (q * (uint64_t)0x1999999a) >> 32;
156 : : *buf++ = (q - 10 * r) + '0'; /* 1 */
157 : : q = (r * (uint64_t)0x1999999a) >> 32;
158 : : *buf++ = (r - 10 * q) + '0'; /* 2 */
159 : : r = (q * (uint64_t)0x1999999a) >> 32;
160 : : *buf++ = (q - 10 * r) + '0'; /* 3 */
161 : : q = (r * (uint64_t)0x1999999a) >> 32;
162 : : *buf++ = (r - 10 * q) + '0'; /* 4 */
163 : : r = (q * (uint64_t)0x1999999a) >> 32;
164 : : *buf++ = (q - 10 * r) + '0'; /* 5 */
165 : : /* Now value is under 10000, can avoid 64-bit multiply */
166 : : q = (r * 0x199a) >> 16;
167 : : *buf++ = (r - 10 * q) + '0'; /* 6 */
168 : : r = (q * 0xcd) >> 11;
169 : : *buf++ = (q - 10 * r) + '0'; /* 7 */
170 : : q = (r * 0xcd) >> 11;
171 : : *buf++ = (r - 10 * q) + '0'; /* 8 */
172 : : *buf++ = q + '0'; /* 9 */
173 : : return buf;
174 : : }
175 : : #endif
176 : :
177 : : /* Similar to above but do not pad with zeros.
178 : : * Code can be easily arranged to print 9 digits too, but our callers
179 : : * always call put_dec_full9() instead when the number has 9 decimal digits.
180 : : */
181 : : static noinline_for_stack
182 : 0 : char *put_dec_trunc8(char *buf, unsigned r)
183 : : {
184 : : unsigned q;
185 : :
186 : : /* Copy of previous function's body with added early returns */
187 [ + + ]: 8272037 : while (r >= 10000) {
188 : 4329945 : q = r + '0';
189 : 4329945 : r = (r * (uint64_t)0x1999999a) >> 32;
190 : 4329945 : *buf++ = q - 10*r;
191 : : }
192 : :
193 : 3942092 : q = (r * 0x199a) >> 16; /* r <= 9999 */
194 : 3942092 : *buf++ = (r - 10 * q) + '0';
195 [ + + ]: 3942092 : if (q == 0)
196 : : return buf;
197 : 3941913 : r = (q * 0xcd) >> 11; /* q <= 999 */
198 : 3941913 : *buf++ = (q - 10 * r) + '0';
199 [ + + ]: 3941913 : if (r == 0)
200 : : return buf;
201 : 3783583 : q = (r * 0xcd) >> 11; /* r <= 99 */
202 : 3783583 : *buf++ = (r - 10 * q) + '0';
203 [ + + ]: 3783583 : if (q == 0)
204 : : return buf;
205 : 3551703 : *buf++ = q + '0'; /* q <= 9 */
206 : 3551703 : return buf;
207 : : }
208 : :
209 : : /* There are two algorithms to print larger numbers.
210 : : * One is generic: divide by 1000000000 and repeatedly print
211 : : * groups of (up to) 9 digits. It's conceptually simple,
212 : : * but requires a (unsigned long long) / 1000000000 division.
213 : : *
214 : : * Second algorithm splits 64-bit unsigned long long into 16-bit chunks,
215 : : * manipulates them cleverly and generates groups of 4 decimal digits.
216 : : * It so happens that it does NOT require long long division.
217 : : *
218 : : * If long is > 32 bits, division of 64-bit values is relatively easy,
219 : : * and we will use the first algorithm.
220 : : * If long long is > 64 bits (strange architecture with VERY large long long),
221 : : * second algorithm can't be used, and we again use the first one.
222 : : *
223 : : * Else (if long is 32 bits and long long is 64 bits) we use second one.
224 : : */
225 : :
226 : : #if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64
227 : :
228 : : /* First algorithm: generic */
229 : :
230 : : static
231 : : char *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 : : /* Second algorithm: valid only for 64-bit long longs */
245 : :
246 : : /* See comment in put_dec_full9 for choice of constants */
247 : : static noinline_for_stack
248 : 0 : void put_dec_full4(char *buf, unsigned q)
249 : : {
250 : : unsigned r;
251 : 550545 : r = (q * 0xccd) >> 15;
252 : 550545 : buf[0] = (q - 10 * r) + '0';
253 : 550545 : q = (r * 0xcd) >> 11;
254 : 550545 : buf[1] = (r - 10 * q) + '0';
255 : 550545 : r = (q * 0xcd) >> 11;
256 : 550545 : buf[2] = (q - 10 * r) + '0';
257 : 550545 : buf[3] = r + '0';
258 : 550545 : }
259 : :
260 : : /*
261 : : * Call put_dec_full4 on x % 10000, return x / 10000.
262 : : * The approximation x/10000 == (x * 0x346DC5D7) >> 43
263 : : * holds for all x < 1,128,869,999. The largest value this
264 : : * helper will ever be asked to convert is 1,125,520,955.
265 : : * (d1 in the put_dec code, assuming n is all-ones).
266 : : */
267 : : static
268 : : unsigned put_dec_helper4(char *buf, unsigned x)
269 : : {
270 : 550571 : uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43;
271 : :
272 : 183521 : put_dec_full4(buf, x - q * 10000);
273 : : return q;
274 : : }
275 : :
276 : : /* Based on code by Douglas W. Jones found at
277 : : * <http://www.cs.uiowa.edu/~jones/bcd/decimal.html#sixtyfour>
278 : : * (with permission from the author).
279 : : * Performs no 64-bit division and hence should be fast on 32-bit machines.
280 : : */
281 : : static
282 : 0 : char *put_dec(char *buf, unsigned long long n)
283 : : {
284 : : uint32_t d3, d2, d1, q, h;
285 : :
286 [ + + ]: 4125363 : if (n < 100*1000*1000)
287 : 3941842 : return put_dec_trunc8(buf, n);
288 : :
289 : 183521 : d1 = ((uint32_t)n >> 16); /* implicit "& 0xffff" */
290 : 183521 : h = (n >> 32);
291 : 183521 : d2 = (h ) & 0xffff;
292 : 183521 : d3 = (h >> 16); /* implicit "& 0xffff" */
293 : :
294 : 183521 : q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff);
295 : : q = put_dec_helper4(buf, q);
296 : :
297 : 183526 : q += 7671 * d3 + 9496 * d2 + 6 * d1;
298 : 183526 : q = put_dec_helper4(buf+4, q);
299 : :
300 : 183524 : q += 4749 * d3 + 42 * d2;
301 : 183524 : q = put_dec_helper4(buf+8, q);
302 : :
303 : 183526 : q += 281 * d3;
304 : 183526 : buf += 12;
305 [ + + ]: 183526 : if (q)
306 : 89 : buf = put_dec_trunc8(buf, q);
307 [ + ]: 542796 : else while (buf[-1] == '0')
308 : 359359 : --buf;
309 : :
310 : 183524 : return buf;
311 : : }
312 : :
313 : : #endif
314 : :
315 : : /*
316 : : * Convert passed number to decimal string.
317 : : * Returns the length of string. On buffer overflow, returns 0.
318 : : *
319 : : * If speed is not important, use snprintf(). It's easy to read the code.
320 : : */
321 : 0 : int num_to_str(char *buf, int size, unsigned long long num)
322 : : {
323 : : char tmp[sizeof(num) * 3];
324 : : int idx, len;
325 : :
326 : : /* put_dec() may work incorrectly for num = 0 (generate "", not "0") */
327 [ - + ]: 369418 : if (num <= 9) {
328 : 0 : tmp[0] = '0' + num;
329 : : len = 1;
330 : : } else {
331 : 369418 : len = put_dec(tmp, num) - tmp;
332 : : }
333 : :
334 [ + - ]: 369405 : if (len > size)
335 : : return 0;
336 [ + ]: 2711834 : for (idx = 0; idx < len; ++idx)
337 : 2342429 : buf[idx] = tmp[len - idx - 1];
338 : : return len;
339 : : }
340 : :
341 : : #define ZEROPAD 1 /* pad with zero */
342 : : #define SIGN 2 /* unsigned/signed long */
343 : : #define PLUS 4 /* show plus */
344 : : #define SPACE 8 /* space if plus */
345 : : #define LEFT 16 /* left justified */
346 : : #define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */
347 : : #define SPECIAL 64 /* prefix hex with "0x", octal with "0" */
348 : :
349 : : enum format_type {
350 : : FORMAT_TYPE_NONE, /* Just a string part */
351 : : FORMAT_TYPE_WIDTH,
352 : : FORMAT_TYPE_PRECISION,
353 : : FORMAT_TYPE_CHAR,
354 : : FORMAT_TYPE_STR,
355 : : FORMAT_TYPE_PTR,
356 : : FORMAT_TYPE_PERCENT_CHAR,
357 : : FORMAT_TYPE_INVALID,
358 : : FORMAT_TYPE_LONG_LONG,
359 : : FORMAT_TYPE_ULONG,
360 : : FORMAT_TYPE_LONG,
361 : : FORMAT_TYPE_UBYTE,
362 : : FORMAT_TYPE_BYTE,
363 : : FORMAT_TYPE_USHORT,
364 : : FORMAT_TYPE_SHORT,
365 : : FORMAT_TYPE_UINT,
366 : : FORMAT_TYPE_INT,
367 : : FORMAT_TYPE_NRCHARS,
368 : : FORMAT_TYPE_SIZE_T,
369 : : FORMAT_TYPE_PTRDIFF
370 : : };
371 : :
372 : : struct printf_spec {
373 : : u8 type; /* format_type enum */
374 : : u8 flags; /* flags to number() */
375 : : u8 base; /* number base, 8, 10 or 16 only */
376 : : u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */
377 : : s16 field_width; /* width of output field */
378 : : s16 precision; /* # of digits/chars */
379 : : };
380 : :
381 : : static noinline_for_stack
382 : 11127147 : char *number(char *buf, char *end, unsigned long long num,
383 : : struct printf_spec spec)
384 : : {
385 : : /* we are called with base 8, 10 or 16, only, thus don't need "G..." */
386 : : static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
387 : :
388 : : char tmp[66];
389 : : char sign;
390 : : char locase;
391 [ + + ][ + + ]: 11127147 : int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
392 : : int i;
393 : 11127147 : bool is_zero = num == 0LL;
394 : :
395 : : /* locase = 0 or 0x20. ORing digits or letters with 'locase'
396 : : * produces same digits or (maybe lowercased) letters */
397 : 11127147 : locase = (spec.flags & SMALL);
398 [ + + ]: 11127147 : if (spec.flags & LEFT)
399 : 5095 : spec.flags &= ~ZEROPAD;
400 : : sign = 0;
401 [ + + ]: 11127147 : if (spec.flags & SIGN) {
402 [ + + ]: 2789927 : if ((signed long long)num < 0) {
403 : : sign = '-';
404 : 529 : num = -(signed long long)num;
405 : 529 : spec.field_width--;
406 [ - + ]: 2789398 : } else if (spec.flags & PLUS) {
407 : : sign = '+';
408 : 0 : spec.field_width--;
409 [ - + ]: 2789398 : } else if (spec.flags & SPACE) {
410 : : sign = ' ';
411 : 0 : spec.field_width--;
412 : : }
413 : : }
414 [ + + ]: 11127147 : if (need_pfx) {
415 [ + + ]: 425 : if (spec.base == 16)
416 : 206 : spec.field_width -= 2;
417 [ + - ]: 219 : else if (!is_zero)
418 : 219 : spec.field_width--;
419 : : }
420 : :
421 : : /* generate full string in tmp[], in reverse order */
422 : : i = 0;
423 [ + + ]: 11127147 : if (num < spec.base)
424 : 5401489 : tmp[i++] = digits[num] | locase;
425 : : /* Generic code, for any base:
426 : : else do {
427 : : tmp[i++] = (digits[do_div(num,base)] | locase);
428 : : } while (num != 0);
429 : : */
430 [ + + ]: 5725658 : else if (spec.base != 10) { /* 8 or 16 */
431 : 1969723 : int mask = spec.base - 1;
432 : : int shift = 3;
433 : :
434 [ + + ]: 1969723 : if (spec.base == 16)
435 : : shift = 4;
436 : : do {
437 : 15165498 : tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
438 : 15165498 : num >>= shift;
439 [ + + ]: 15165498 : } while (num);
440 : : } else { /* base 10 */
441 : 3755935 : i = put_dec(tmp, num) - tmp;
442 : : }
443 : :
444 : : /* printing 100 using %2d gives "100", not "00" */
445 [ + ]: 11127146 : if (i > spec.precision)
446 : 11127161 : spec.precision = i;
447 : : /* leading space padding */
448 : 11127146 : spec.field_width -= spec.precision;
449 [ + + ]: 11127146 : if (!(spec.flags & (ZEROPAD+LEFT))) {
450 [ + + ]: 8005891 : while (--spec.field_width >= 0) {
451 [ + + ]: 1550689 : if (buf < end)
452 : 1547580 : *buf = ' ';
453 : 1550689 : ++buf;
454 : : }
455 : : }
456 : : /* sign */
457 [ + + ]: 11127146 : if (sign) {
458 [ + - ]: 529 : if (buf < end)
459 : 529 : *buf = sign;
460 : 529 : ++buf;
461 : : }
462 : : /* "0x" / "0" prefix */
463 [ + + ]: 11127146 : if (need_pfx) {
464 [ + + ][ + - ]: 425 : if (spec.base == 16 || !is_zero) {
465 [ + - ]: 425 : if (buf < end)
466 : 425 : *buf = '0';
467 : 425 : ++buf;
468 : : }
469 [ + + ]: 425 : if (spec.base == 16) {
470 [ + - ]: 206 : if (buf < end)
471 : 206 : *buf = ('X' | locase);
472 : 206 : ++buf;
473 : : }
474 : : }
475 : : /* zero or space padding */
476 [ + + ]: 11127146 : if (!(spec.flags & LEFT)) {
477 [ + + ]: 11122051 : char c = (spec.flags & ZEROPAD) ? '0' : ' ';
478 [ + + ]: 19881431 : while (--spec.field_width >= 0) {
479 [ + + ]: 8754285 : if (buf < end)
480 : 8753827 : *buf = c;
481 : 8754285 : ++buf;
482 : : }
483 : : }
484 : : /* hmm even more zero padding? */
485 [ - + ]: 11127146 : while (i <= --spec.precision) {
486 [ # # ]: 0 : if (buf < end)
487 : 0 : *buf = '0';
488 : 0 : ++buf;
489 : : }
490 : : /* actual digits of result */
491 [ + + ]: 50743350 : while (--i >= 0) {
492 [ + + ]: 39616204 : if (buf < end)
493 : 39597936 : *buf = tmp[i];
494 : 39616204 : ++buf;
495 : : }
496 : : /* trailing space padding */
497 [ + + ]: 11181934 : while (--spec.field_width >= 0) {
498 [ + - ]: 54788 : if (buf < end)
499 : 54788 : *buf = ' ';
500 : 54788 : ++buf;
501 : : }
502 : :
503 : 11127146 : return buf;
504 : : }
505 : :
506 : : static noinline_for_stack
507 : 1727680 : char *string(char *buf, char *end, const char *s, struct printf_spec spec)
508 : : {
509 : : int len, i;
510 : :
511 [ - + ]: 1727680 : if ((unsigned long)s < PAGE_SIZE)
512 : : s = "(null)";
513 : :
514 : 1727680 : len = strnlen(s, spec.precision);
515 : :
516 [ + + ]: 3455405 : if (!(spec.flags & LEFT)) {
517 [ + + ]: 5678311 : while (len < spec.field_width--) {
518 [ + - ]: 2222906 : if (buf < end)
519 : 2222906 : *buf = ' ';
520 : 2222906 : ++buf;
521 : : }
522 : : }
523 [ + + ]: 8849909 : for (i = 0; i < len; ++i) {
524 [ + + ]: 5394504 : if (buf < end)
525 : 5393426 : *buf = *s;
526 : 5394504 : ++buf; ++s;
527 : : }
528 [ + + ]: 1861609 : while (len < spec.field_width--) {
529 [ + - ]: 133884 : if (buf < end)
530 : 133884 : *buf = ' ';
531 : 133884 : ++buf;
532 : : }
533 : :
534 : 1727725 : return buf;
535 : : }
536 : :
537 : 0 : static void widen(char *buf, char *end, unsigned len, unsigned spaces)
538 : : {
539 : : size_t size;
540 [ # # ]: 0 : if (buf >= end) /* nowhere to put anything */
541 : : return;
542 : 0 : size = end - buf;
543 [ # # ]: 0 : if (size <= spaces) {
544 [ # # ]: 0 : memset(buf, ' ', size);
545 : : return;
546 : : }
547 [ # # ]: 0 : if (len) {
548 [ # # ]: 0 : if (len > size - spaces)
549 : : len = size - spaces;
550 : 0 : memmove(buf + spaces, buf, len);
551 : : }
552 [ # # ]: 0 : memset(buf, ' ', spaces);
553 : : }
554 : :
555 : : static noinline_for_stack
556 : 0 : char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_spec spec,
557 : : const char *fmt)
558 : : {
559 : : const char *array[4], *s;
560 : : const struct dentry *p;
561 : : int depth;
562 : : int i, n;
563 : :
564 [ # # ]: 0 : switch (fmt[1]) {
565 : : case '2': case '3': case '4':
566 : 0 : depth = fmt[1] - '0';
567 : : break;
568 : : default:
569 : : depth = 1;
570 : : }
571 : :
572 : : rcu_read_lock();
573 [ # # ]: 0 : for (i = 0; i < depth; i++, d = p) {
574 : 0 : p = ACCESS_ONCE(d->d_parent);
575 : 0 : array[i] = ACCESS_ONCE(d->d_name.name);
576 [ # # ]: 0 : if (p == d) {
577 [ # # ]: 0 : if (i)
578 : 0 : array[i] = "";
579 : 0 : i++;
580 : : break;
581 : : }
582 : : }
583 : 0 : s = array[--i];
584 [ # # ]: 0 : for (n = 0; n != spec.precision; n++, buf++) {
585 : 0 : char c = *s++;
586 [ # # ]: 0 : if (!c) {
587 [ # # ]: 0 : if (!i)
588 : : break;
589 : : c = '/';
590 : 0 : s = array[--i];
591 : : }
592 [ # # ]: 0 : if (buf < end)
593 : 0 : *buf = c;
594 : : }
595 : : rcu_read_unlock();
596 [ # # ]: 0 : if (n < spec.field_width) {
597 : : /* we want to pad the sucker */
598 : 0 : unsigned spaces = spec.field_width - n;
599 [ # # ]: 0 : if (!(spec.flags & LEFT)) {
600 : 0 : widen(buf - n, end, n, spaces);
601 : 0 : return buf + spaces;
602 : : }
603 [ # # ]: 0 : while (spaces--) {
604 [ # # ]: 0 : if (buf < end)
605 : 0 : *buf = ' ';
606 : 0 : ++buf;
607 : : }
608 : : }
609 : : return buf;
610 : : }
611 : :
612 : : static noinline_for_stack
613 : 109 : char *symbol_string(char *buf, char *end, void *ptr,
614 : 109 : struct printf_spec spec, const char *fmt)
615 : : {
616 : : unsigned long value;
617 : : #ifdef CONFIG_KALLSYMS
618 : : char sym[KSYM_SYMBOL_LEN];
619 : : #endif
620 : :
621 [ - + ]: 109 : if (fmt[1] == 'R')
622 : 0 : ptr = __builtin_extract_return_addr(ptr);
623 : 109 : value = (unsigned long)ptr;
624 : :
625 : : #ifdef CONFIG_KALLSYMS
626 [ - + ]: 218 : if (*fmt == 'B')
627 : 0 : sprint_backtrace(sym, value);
628 [ + + ]: 109 : else if (*fmt != 'f' && *fmt != 's')
629 : 105 : sprint_symbol(sym, value);
630 : : else
631 : 4 : sprint_symbol_no_offset(sym, value);
632 : :
633 : 109 : return string(buf, end, sym, spec);
634 : : #else
635 : : spec.field_width = 2 * sizeof(void *);
636 : : spec.flags |= SPECIAL | SMALL | ZEROPAD;
637 : : spec.base = 16;
638 : :
639 : : return number(buf, end, value, spec);
640 : : #endif
641 : : }
642 : :
643 : : static noinline_for_stack
644 : 0 : char *resource_string(char *buf, char *end, struct resource *res,
645 : 0 : struct printf_spec spec, const char *fmt)
646 : : {
647 : : #ifndef IO_RSRC_PRINTK_SIZE
648 : : #define IO_RSRC_PRINTK_SIZE 6
649 : : #endif
650 : :
651 : : #ifndef MEM_RSRC_PRINTK_SIZE
652 : : #define MEM_RSRC_PRINTK_SIZE 10
653 : : #endif
654 : : static const struct printf_spec io_spec = {
655 : : .base = 16,
656 : : .field_width = IO_RSRC_PRINTK_SIZE,
657 : : .precision = -1,
658 : : .flags = SPECIAL | SMALL | ZEROPAD,
659 : : };
660 : : static const struct printf_spec mem_spec = {
661 : : .base = 16,
662 : : .field_width = MEM_RSRC_PRINTK_SIZE,
663 : : .precision = -1,
664 : : .flags = SPECIAL | SMALL | ZEROPAD,
665 : : };
666 : : static const struct printf_spec bus_spec = {
667 : : .base = 16,
668 : : .field_width = 2,
669 : : .precision = -1,
670 : : .flags = SMALL | ZEROPAD,
671 : : };
672 : : static const struct printf_spec dec_spec = {
673 : : .base = 10,
674 : : .precision = -1,
675 : : .flags = 0,
676 : : };
677 : : static const struct printf_spec str_spec = {
678 : : .field_width = -1,
679 : : .precision = 10,
680 : : .flags = LEFT,
681 : : };
682 : : static const struct printf_spec flag_spec = {
683 : : .base = 16,
684 : : .precision = -1,
685 : : .flags = SPECIAL | SMALL,
686 : : };
687 : :
688 : : /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
689 : : * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
690 : : #define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4)
691 : : #define FLAG_BUF_SIZE (2 * sizeof(res->flags))
692 : : #define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]")
693 : : #define RAW_BUF_SIZE sizeof("[mem - flags 0x]")
694 : 0 : char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
695 : : 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
696 : :
697 : 0 : char *p = sym, *pend = sym + sizeof(sym);
698 : 0 : int decode = (fmt[0] == 'R') ? 1 : 0;
699 : : const struct printf_spec *specp;
700 : :
701 : 0 : *p++ = '[';
702 [ # # ]: 0 : if (res->flags & IORESOURCE_IO) {
703 : 0 : p = string(p, pend, "io ", str_spec);
704 : : specp = &io_spec;
705 [ # # ]: 0 : } else if (res->flags & IORESOURCE_MEM) {
706 : 0 : p = string(p, pend, "mem ", str_spec);
707 : : specp = &mem_spec;
708 [ # # ]: 0 : } else if (res->flags & IORESOURCE_IRQ) {
709 : 0 : p = string(p, pend, "irq ", str_spec);
710 : : specp = &dec_spec;
711 [ # # ]: 0 : } else if (res->flags & IORESOURCE_DMA) {
712 : 0 : p = string(p, pend, "dma ", str_spec);
713 : : specp = &dec_spec;
714 [ # # ]: 0 : } else if (res->flags & IORESOURCE_BUS) {
715 : 0 : p = string(p, pend, "bus ", str_spec);
716 : : specp = &bus_spec;
717 : : } else {
718 : 0 : p = string(p, pend, "??? ", str_spec);
719 : : specp = &mem_spec;
720 : : decode = 0;
721 : : }
722 : 0 : p = number(p, pend, res->start, *specp);
723 [ # # ]: 0 : if (res->start != res->end) {
724 : 0 : *p++ = '-';
725 : 0 : p = number(p, pend, res->end, *specp);
726 : : }
727 [ # # ]: 0 : if (decode) {
728 [ # # ]: 0 : if (res->flags & IORESOURCE_MEM_64)
729 : 0 : p = string(p, pend, " 64bit", str_spec);
730 [ # # ]: 0 : if (res->flags & IORESOURCE_PREFETCH)
731 : 0 : p = string(p, pend, " pref", str_spec);
732 [ # # ]: 0 : if (res->flags & IORESOURCE_WINDOW)
733 : 0 : p = string(p, pend, " window", str_spec);
734 [ # # ]: 0 : if (res->flags & IORESOURCE_DISABLED)
735 : 0 : p = string(p, pend, " disabled", str_spec);
736 : : } else {
737 : 0 : p = string(p, pend, " flags ", str_spec);
738 : 0 : p = number(p, pend, res->flags, flag_spec);
739 : : }
740 : 0 : *p++ = ']';
741 : 0 : *p = '\0';
742 : :
743 : 0 : return string(buf, end, sym, spec);
744 : : }
745 : :
746 : : static noinline_for_stack
747 : 0 : char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
748 : : const char *fmt)
749 : : {
750 : : int i, len = 1; /* if we pass '%ph[CDN]', field width remains
751 : : negative value, fallback to the default */
752 : : char separator;
753 : :
754 [ # # ]: 0 : if (spec.field_width == 0)
755 : : /* nothing to print */
756 : : return buf;
757 : :
758 [ # # ]: 0 : if (ZERO_OR_NULL_PTR(addr))
759 : : /* NULL pointer */
760 : 0 : return string(buf, end, NULL, spec);
761 : :
762 [ # # ]: 0 : switch (fmt[1]) {
763 : : case 'C':
764 : : separator = ':';
765 : : break;
766 : : case 'D':
767 : : separator = '-';
768 : : break;
769 : : case 'N':
770 : : separator = 0;
771 : : break;
772 : : default:
773 : : separator = ' ';
774 : : break;
775 : : }
776 : :
777 [ # # ]: 0 : if (spec.field_width > 0)
778 : 0 : len = min_t(int, spec.field_width, 64);
779 : :
780 [ # # ][ # # ]: 0 : for (i = 0; i < len && buf < end - 1; i++) {
781 : 0 : buf = hex_byte_pack(buf, addr[i]);
782 : :
783 [ # # ][ # # ]: 0 : if (buf < end && separator && i != len - 1)
784 : 0 : *buf++ = separator;
785 : : }
786 : :
787 : : return buf;
788 : : }
789 : :
790 : : static noinline_for_stack
791 : 0 : char *mac_address_string(char *buf, char *end, u8 *addr,
792 : 0 : struct printf_spec spec, const char *fmt)
793 : : {
794 : : char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
795 : : char *p = mac_addr;
796 : : int i;
797 : : char separator;
798 : : bool reversed = false;
799 : :
800 [ # # # ]: 0 : switch (fmt[1]) {
801 : : case 'F':
802 : : separator = '-';
803 : : break;
804 : :
805 : : case 'R':
806 : : reversed = true;
807 : : /* fall through */
808 : :
809 : : default:
810 : : separator = ':';
811 : : break;
812 : : }
813 : :
814 [ # # ]: 0 : for (i = 0; i < 6; i++) {
815 [ # # ]: 0 : if (reversed)
816 : 0 : p = hex_byte_pack(p, addr[5 - i]);
817 : : else
818 : 0 : p = hex_byte_pack(p, addr[i]);
819 : :
820 [ # # ][ # # ]: 0 : if (fmt[0] == 'M' && i != 5)
821 : 0 : *p++ = separator;
822 : : }
823 : 0 : *p = '\0';
824 : :
825 : 0 : return string(buf, end, mac_addr, spec);
826 : : }
827 : :
828 : : static noinline_for_stack
829 : 0 : char *ip4_string(char *p, const u8 *addr, const char *fmt)
830 : : {
831 : : int i;
832 : 42 : bool leading_zeros = (fmt[0] == 'i');
833 : : int index;
834 : : int step;
835 : :
836 [ + - ]: 42 : switch (fmt[2]) {
837 : : case 'h':
838 : : #ifdef __BIG_ENDIAN
839 : : index = 0;
840 : : step = 1;
841 : : #else
842 : : index = 3;
843 : : step = -1;
844 : : #endif
845 : : break;
846 : : case 'l':
847 : : index = 3;
848 : : step = -1;
849 : : break;
850 : : case 'n':
851 : : case 'b':
852 : : default:
853 : : index = 0;
854 : : step = 1;
855 : 42 : break;
856 : : }
857 [ + + ]: 210 : for (i = 0; i < 4; i++) {
858 : : char temp[3]; /* hold each IP quad in reverse order */
859 : 168 : int digits = put_dec_trunc8(temp, addr[index]) - temp;
860 [ - + ]: 210 : if (leading_zeros) {
861 [ # # ]: 0 : if (digits < 3)
862 : 0 : *p++ = '0';
863 [ # # ]: 0 : if (digits < 2)
864 : 210 : *p++ = '0';
865 : : }
866 : : /* reverse the digits in the quad */
867 [ + + ]: 415 : while (digits--)
868 : 247 : *p++ = temp[digits];
869 [ + + ]: 168 : if (i < 3)
870 : 126 : *p++ = '.';
871 : 168 : index += step;
872 : : }
873 : 42 : *p = '\0';
874 : :
875 : 42 : return p;
876 : : }
877 : :
878 : : static noinline_for_stack
879 : 0 : char *ip6_compressed_string(char *p, const char *addr)
880 : : {
881 : : int i, j, range;
882 : : unsigned char zerolength[8];
883 : : int longest = 1;
884 : : int colonpos = -1;
885 : : u16 word;
886 : : u8 hi, lo;
887 : : bool needcolon = false;
888 : : bool useIPv4;
889 : : struct in6_addr in6;
890 : :
891 : 0 : memcpy(&in6, addr, sizeof(struct in6_addr));
892 : :
893 [ # # ][ # # ]: 0 : useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
894 : :
895 : 0 : memset(zerolength, 0, sizeof(zerolength));
896 : :
897 [ # # ]: 0 : if (useIPv4)
898 : : range = 6;
899 : : else
900 : : range = 8;
901 : :
902 : : /* find position of longest 0 run */
903 [ # # ]: 0 : for (i = 0; i < range; i++) {
904 [ # # ]: 0 : for (j = i; j < range; j++) {
905 [ # # ]: 0 : if (in6.s6_addr16[j] != 0)
906 : : break;
907 : 0 : zerolength[i]++;
908 : : }
909 : : }
910 [ # # ]: 0 : for (i = 0; i < range; i++) {
911 [ # # ]: 0 : if (zerolength[i] > longest) {
912 : : longest = zerolength[i];
913 : : colonpos = i;
914 : : }
915 : : }
916 [ # # ]: 0 : if (longest == 1) /* don't compress a single 0 */
917 : : colonpos = -1;
918 : :
919 : : /* emit address */
920 [ # # ]: 0 : for (i = 0; i < range; i++) {
921 [ # # ]: 0 : if (i == colonpos) {
922 [ # # ]: 0 : if (needcolon || i == 0)
923 : 0 : *p++ = ':';
924 : 0 : *p++ = ':';
925 : : needcolon = false;
926 : 0 : i += longest - 1;
927 : 0 : continue;
928 : : }
929 [ # # ]: 0 : if (needcolon) {
930 : 0 : *p++ = ':';
931 : : needcolon = false;
932 : : }
933 : : /* hex u16 without leading 0s */
934 [ # # ]: 0 : word = ntohs(in6.s6_addr16[i]);
935 : 0 : hi = word >> 8;
936 : 0 : lo = word & 0xff;
937 [ # # ]: 0 : if (hi) {
938 [ # # ]: 0 : if (hi > 0x0f)
939 : 0 : p = hex_byte_pack(p, hi);
940 : : else
941 : 0 : *p++ = hex_asc_lo(hi);
942 : 0 : p = hex_byte_pack(p, lo);
943 : : }
944 [ # # ]: 0 : else if (lo > 0x0f)
945 : 0 : p = hex_byte_pack(p, lo);
946 : : else
947 : 0 : *p++ = hex_asc_lo(lo);
948 : : needcolon = true;
949 : : }
950 : :
951 [ # # ]: 0 : if (useIPv4) {
952 [ # # ]: 0 : if (needcolon)
953 : 0 : *p++ = ':';
954 : 0 : p = ip4_string(p, &in6.s6_addr[12], "I4");
955 : : }
956 : 0 : *p = '\0';
957 : :
958 : 0 : return p;
959 : : }
960 : :
961 : : static noinline_for_stack
962 : 0 : char *ip6_string(char *p, const char *addr, const char *fmt)
963 : : {
964 : : int i;
965 : :
966 [ + + ]: 153 : for (i = 0; i < 8; i++) {
967 : 136 : p = hex_byte_pack(p, *addr++);
968 : 272 : p = hex_byte_pack(p, *addr++);
969 [ - + ][ # # ]: 136 : if (fmt[0] == 'I' && i != 7)
970 : 0 : *p++ = ':';
971 : : }
972 : 17 : *p = '\0';
973 : :
974 : 17 : return p;
975 : : }
976 : :
977 : : static noinline_for_stack
978 : 17 : char *ip6_addr_string(char *buf, char *end, const u8 *addr,
979 : 17 : struct printf_spec spec, const char *fmt)
980 : : {
981 : : char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
982 : :
983 [ - + ][ # # ]: 17 : if (fmt[0] == 'I' && fmt[2] == 'c')
984 : 0 : ip6_compressed_string(ip6_addr, addr);
985 : : else
986 : 17 : ip6_string(ip6_addr, addr, fmt);
987 : :
988 : 17 : return string(buf, end, ip6_addr, spec);
989 : : }
990 : :
991 : : static noinline_for_stack
992 : 42 : char *ip4_addr_string(char *buf, char *end, const u8 *addr,
993 : 42 : struct printf_spec spec, const char *fmt)
994 : : {
995 : : char ip4_addr[sizeof("255.255.255.255")];
996 : :
997 : 42 : ip4_string(ip4_addr, addr, fmt);
998 : :
999 : 42 : return string(buf, end, ip4_addr, spec);
1000 : : }
1001 : :
1002 : : static noinline_for_stack
1003 : 0 : char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa,
1004 : : struct printf_spec spec, const char *fmt)
1005 : : {
1006 : : bool have_p = false, have_s = false, have_f = false, have_c = false;
1007 : : char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") +
1008 : : sizeof(":12345") + sizeof("/123456789") +
1009 : : sizeof("%1234567890")];
1010 : : char *p = ip6_addr, *pend = ip6_addr + sizeof(ip6_addr);
1011 : 0 : const u8 *addr = (const u8 *) &sa->sin6_addr;
1012 : 0 : char fmt6[2] = { fmt[0], '6' };
1013 : : u8 off = 0;
1014 : :
1015 : 0 : fmt++;
1016 [ # # ]: 0 : while (isalpha(*++fmt)) {
1017 [ # # # # : 0 : switch (*fmt) {
# ]
1018 : : case 'p':
1019 : : have_p = true;
1020 : : break;
1021 : : case 'f':
1022 : : have_f = true;
1023 : : break;
1024 : : case 's':
1025 : : have_s = true;
1026 : : break;
1027 : : case 'c':
1028 : : have_c = true;
1029 : : break;
1030 : : }
1031 : : }
1032 : :
1033 [ # # ][ # # ]: 0 : if (have_p || have_s || have_f) {
1034 : 0 : *p = '[';
1035 : : off = 1;
1036 : : }
1037 : :
1038 [ # # ][ # # ]: 0 : if (fmt6[0] == 'I' && have_c)
1039 : 0 : p = ip6_compressed_string(ip6_addr + off, addr);
1040 : : else
1041 : 0 : p = ip6_string(ip6_addr + off, addr, fmt6);
1042 : :
1043 [ # # ][ # # ]: 0 : if (have_p || have_s || have_f)
1044 : 0 : *p++ = ']';
1045 : :
1046 [ # # ]: 0 : if (have_p) {
1047 : 0 : *p++ = ':';
1048 [ # # ]: 0 : p = number(p, pend, ntohs(sa->sin6_port), spec);
1049 : : }
1050 [ # # ]: 0 : if (have_f) {
1051 : 0 : *p++ = '/';
1052 [ # # ]: 0 : p = number(p, pend, ntohl(sa->sin6_flowinfo &
1053 : : IPV6_FLOWINFO_MASK), spec);
1054 : : }
1055 [ # # ]: 0 : if (have_s) {
1056 : 0 : *p++ = '%';
1057 : 0 : p = number(p, pend, sa->sin6_scope_id, spec);
1058 : : }
1059 : 0 : *p = '\0';
1060 : :
1061 : 0 : return string(buf, end, ip6_addr, spec);
1062 : : }
1063 : :
1064 : : static noinline_for_stack
1065 : 0 : char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa,
1066 : 0 : struct printf_spec spec, const char *fmt)
1067 : : {
1068 : : bool have_p = false;
1069 : : char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")];
1070 : : char *pend = ip4_addr + sizeof(ip4_addr);
1071 : 0 : const u8 *addr = (const u8 *) &sa->sin_addr.s_addr;
1072 : 0 : char fmt4[3] = { fmt[0], '4', 0 };
1073 : :
1074 [ # # ][ # # ]: 0 : fmt++;
[ # # ]
1075 [ # # ]: 0 : while (isalpha(*++fmt)) {
1076 : : switch (*fmt) {
1077 : : case 'p':
1078 : : have_p = true;
1079 : : break;
1080 : : case 'h':
1081 : : case 'l':
1082 : : case 'n':
1083 : : case 'b':
1084 : 0 : fmt4[2] = *fmt;
1085 : : break;
1086 : : }
1087 : : }
1088 : :
1089 : 0 : p = ip4_string(ip4_addr, addr, fmt4);
1090 [ # # ]: 0 : if (have_p) {
1091 : 0 : *p++ = ':';
1092 [ # # ]: 0 : p = number(p, pend, ntohs(sa->sin_port), spec);
1093 : : }
1094 : 0 : *p = '\0';
1095 : :
1096 : 0 : return string(buf, end, ip4_addr, spec);
1097 : : }
1098 : :
1099 : : static noinline_for_stack
1100 : 4 : char *uuid_string(char *buf, char *end, const u8 *addr,
1101 : 0 : struct printf_spec spec, const char *fmt)
1102 : : {
1103 : : char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
1104 : : char *p = uuid;
1105 : : int i;
1106 : : static const u8 be[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
1107 : : static const u8 le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
1108 : : const u8 *index = be;
1109 : : bool uc = false;
1110 : :
1111 [ - - - + ]: 4 : switch (*(++fmt)) {
1112 : : case 'L':
1113 : : uc = true; /* fall-through */
1114 : : case 'l':
1115 : : index = le;
1116 : : break;
1117 : : case 'B':
1118 : : uc = true;
1119 : : break;
1120 : : }
1121 : :
1122 [ + + ]: 68 : for (i = 0; i < 16; i++) {
1123 [ + + ][ + + ]: 64 : p = hex_byte_pack(p, addr[index[i]]);
1124 : : switch (i) {
1125 : : case 3:
1126 : : case 5:
1127 : : case 7:
1128 : : case 9:
1129 : 16 : *p++ = '-';
1130 : : break;
1131 : : }
1132 : : }
1133 : :
1134 : 4 : *p = 0;
1135 : :
1136 [ - + ]: 4 : if (uc) {
1137 : : p = uuid;
1138 : : do {
1139 : 0 : *p = toupper(*p);
1140 [ # # ]: 0 : } while (*(++p));
1141 : : }
1142 : :
1143 : 4 : return string(buf, end, uuid, spec);
1144 : : }
1145 : :
1146 : : static
1147 : 0 : char *netdev_feature_string(char *buf, char *end, const u8 *addr,
1148 : 0 : struct printf_spec spec)
1149 : : {
1150 : 0 : spec.flags |= SPECIAL | SMALL | ZEROPAD;
1151 [ # # ]: 0 : if (spec.field_width == -1)
1152 : : spec.field_width = 2 + 2 * sizeof(netdev_features_t);
1153 : : spec.base = 16;
1154 : :
1155 : 0 : return number(buf, end, *(const netdev_features_t *)addr, spec);
1156 : : }
1157 : :
1158 : : int kptr_restrict __read_mostly;
1159 : :
1160 : : /*
1161 : : * Show a '%p' thing. A kernel extension is that the '%p' is followed
1162 : : * by an extra set of alphanumeric characters that are extended format
1163 : : * specifiers.
1164 : : *
1165 : : * Right now we handle:
1166 : : *
1167 : : * - 'F' For symbolic function descriptor pointers with offset
1168 : : * - 'f' For simple symbolic function names without offset
1169 : : * - 'S' For symbolic direct pointers with offset
1170 : : * - 's' For symbolic direct pointers without offset
1171 : : * - '[FfSs]R' as above with __builtin_extract_return_addr() translation
1172 : : * - 'B' For backtraced symbolic direct pointers with offset
1173 : : * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
1174 : : * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
1175 : : * - 'M' For a 6-byte MAC address, it prints the address in the
1176 : : * usual colon-separated hex notation
1177 : : * - 'm' For a 6-byte MAC address, it prints the hex address without colons
1178 : : * - 'MF' For a 6-byte MAC FDDI address, it prints the address
1179 : : * with a dash-separated hex notation
1180 : : * - '[mM]R' For a 6-byte MAC address, Reverse order (Bluetooth)
1181 : : * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
1182 : : * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
1183 : : * IPv6 uses colon separated network-order 16 bit hex with leading 0's
1184 : : * [S][pfs]
1185 : : * Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
1186 : : * [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
1187 : : * - 'i' [46] for 'raw' IPv4/IPv6 addresses
1188 : : * IPv6 omits the colons (01020304...0f)
1189 : : * IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
1190 : : * [S][pfs]
1191 : : * Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
1192 : : * [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
1193 : : * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order
1194 : : * - 'I[6S]c' for IPv6 addresses printed as specified by
1195 : : * http://tools.ietf.org/html/rfc5952
1196 : : * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
1197 : : * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
1198 : : * Options for %pU are:
1199 : : * b big endian lower case hex (default)
1200 : : * B big endian UPPER case hex
1201 : : * l little endian lower case hex
1202 : : * L little endian UPPER case hex
1203 : : * big endian output byte order is:
1204 : : * [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
1205 : : * little endian output byte order is:
1206 : : * [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
1207 : : * - 'V' For a struct va_format which contains a format string * and va_list *,
1208 : : * call vsnprintf(->format, *->va_list).
1209 : : * Implements a "recursive vsnprintf".
1210 : : * Do not use this feature without some mechanism to verify the
1211 : : * correctness of the format string and va_list arguments.
1212 : : * - 'K' For a kernel pointer that should be hidden from unprivileged users
1213 : : * - 'NF' For a netdev_features_t
1214 : : * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with
1215 : : * a certain separator (' ' by default):
1216 : : * C colon
1217 : : * D dash
1218 : : * N no separator
1219 : : * The maximum supported length is 64 bytes of the input. Consider
1220 : : * to use print_hex_dump() for the larger input.
1221 : : * - 'a' For a phys_addr_t type and its derivative types (passed by reference)
1222 : : * - 'd[234]' For a dentry name (optionally 2-4 last components)
1223 : : * - 'D[234]' Same as 'd' but for a struct file
1224 : : *
1225 : : * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
1226 : : * function pointers are really function descriptors, which contain a
1227 : : * pointer to the real address.
1228 : : */
1229 : : static noinline_for_stack
1230 : 44570 : char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1231 : : struct printf_spec spec)
1232 : : {
1233 [ + - ]: 44570 : int default_width = 2 * sizeof(void *) + (spec.flags & SPECIAL ? 2 : 0);
1234 : :
1235 [ - + ][ # # ]: 44570 : if (!ptr && *fmt != 'K') {
1236 : : /*
1237 : : * Print (null) with the same width as a pointer so it makes
1238 : : * tabular output look nice.
1239 : : */
1240 [ # # ]: 0 : if (spec.field_width == -1)
1241 : 0 : spec.field_width = default_width;
1242 : 0 : return string(buf, end, "(null)", spec);
1243 : : }
1244 : :
1245 [ + - - - : 44570 : switch (*fmt) {
+ + + + -
- - - - ]
1246 : : case 'F':
1247 : : case 'f':
1248 : : ptr = dereference_function_descriptor(ptr);
1249 : : /* Fallthrough */
1250 : : case 'S':
1251 : : case 's':
1252 : : case 'B':
1253 : 109 : return symbol_string(buf, end, ptr, spec, fmt);
1254 : : case 'R':
1255 : : case 'r':
1256 : 0 : return resource_string(buf, end, ptr, spec, fmt);
1257 : : case 'h':
1258 : 0 : return hex_string(buf, end, ptr, spec, fmt);
1259 : : case 'M': /* Colon separated: 00:01:02:03:04:05 */
1260 : : case 'm': /* Contiguous: 000102030405 */
1261 : : /* [mM]F (FDDI) */
1262 : : /* [mM]R (Reverse order; Bluetooth) */
1263 : 0 : return mac_address_string(buf, end, ptr, spec, fmt);
1264 : : case 'I': /* Formatted IP supported
1265 : : * 4: 1.2.3.4
1266 : : * 6: 0001:0203:...:0708
1267 : : * 6c: 1::708 or 1::1.2.3.4
1268 : : */
1269 : : case 'i': /* Contiguous:
1270 : : * 4: 001.002.003.004
1271 : : * 6: 000102...0f
1272 : : */
1273 [ + + - - ]: 59 : switch (fmt[1]) {
1274 : : case '6':
1275 : 17 : return ip6_addr_string(buf, end, ptr, spec, fmt);
1276 : : case '4':
1277 : 42 : return ip4_addr_string(buf, end, ptr, spec, fmt);
1278 : : case 'S': {
1279 : : const union {
1280 : : struct sockaddr raw;
1281 : : struct sockaddr_in v4;
1282 : : struct sockaddr_in6 v6;
1283 : : } *sa = ptr;
1284 : :
1285 [ # # # ]: 0 : switch (sa->raw.sa_family) {
1286 : : case AF_INET:
1287 : 0 : return ip4_addr_string_sa(buf, end, &sa->v4, spec, fmt);
1288 : : case AF_INET6:
1289 : 0 : return ip6_addr_string_sa(buf, end, &sa->v6, spec, fmt);
1290 : : default:
1291 : 0 : return string(buf, end, "(invalid address)", spec);
1292 : : }}
1293 : : }
1294 : : break;
1295 : : case 'U':
1296 : 4 : return uuid_string(buf, end, ptr, spec, fmt);
1297 : : case 'V':
1298 : : {
1299 : : va_list va;
1300 : :
1301 : 57 : va_copy(va, *((struct va_format *)ptr)->va);
1302 [ + - ]: 57 : buf += vsnprintf(buf, end > buf ? end - buf : 0,
1303 : : ((struct va_format *)ptr)->fmt, va);
1304 : 57 : va_end(va);
1305 : : return buf;
1306 : : }
1307 : : case 'K':
1308 : : /*
1309 : : * %pK cannot be used in IRQ context because its test
1310 : : * for CAP_SYSLOG would be meaningless.
1311 : : */
1312 [ + - ][ + - ]: 44341 : if (kptr_restrict && (in_irq() || in_serving_softirq() ||
[ + - ][ - + ]
1313 : 44341 : in_nmi())) {
1314 [ - ]: 0 : if (spec.field_width == -1)
1315 : 0 : spec.field_width = default_width;
1316 : 0 : return string(buf, end, "pK-error", spec);
1317 : : }
1318 : :
1319 [ + - - ]: 44341 : switch (kptr_restrict) {
1320 : : case 0:
1321 : : /* Always print %pK values */
1322 : : break;
1323 : : case 1: {
1324 : : /*
1325 : : * Only print the real pointer value if the current
1326 : : * process has CAP_SYSLOG and is running with the
1327 : : * same credentials it started with. This is because
1328 : : * access to files is checked at open() time, but %pK
1329 : : * checks permission at read() time. We don't want to
1330 : : * leak pointer values if a binary opens a file using
1331 : : * %pK and then elevates privileges before reading it.
1332 : : */
1333 : 44341 : const struct cred *cred = current_cred();
1334 : :
1335 [ + - ][ + - ]: 44341 : if (!has_capability_noaudit(current, CAP_SYSLOG) ||
1336 [ - + ]: 44341 : !uid_eq(cred->euid, cred->uid) ||
1337 : 44341 : !gid_eq(cred->egid, cred->gid))
1338 : : ptr = NULL;
1339 : : break;
1340 : : }
1341 : : case 2:
1342 : : default:
1343 : : /* Always print 0's for %pK */
1344 : : ptr = NULL;
1345 : : break;
1346 : : }
1347 : : break;
1348 : :
1349 : : case 'N':
1350 [ # # ]: 0 : switch (fmt[1]) {
1351 : : case 'F':
1352 : 0 : return netdev_feature_string(buf, end, ptr, spec);
1353 : : }
1354 : : break;
1355 : : case 'a':
1356 : 0 : spec.flags |= SPECIAL | SMALL | ZEROPAD;
1357 : : spec.field_width = sizeof(phys_addr_t) * 2 + 2;
1358 : : spec.base = 16;
1359 : 0 : return number(buf, end,
1360 : 0 : (unsigned long long) *((phys_addr_t *)ptr), spec);
1361 : : case 'd':
1362 : 0 : return dentry_name(buf, end, ptr, spec, fmt);
1363 : : case 'D':
1364 : 0 : return dentry_name(buf, end,
1365 : 0 : ((const struct file *)ptr)->f_path.dentry,
1366 : : spec, fmt);
1367 : : }
1368 : 44341 : spec.flags |= SMALL;
1369 [ + - ]: 44341 : if (spec.field_width == -1) {
1370 : 44341 : spec.field_width = default_width;
1371 : 44341 : spec.flags |= ZEROPAD;
1372 : : }
1373 : : spec.base = 16;
1374 : :
1375 : 44341 : return number(buf, end, (unsigned long) ptr, spec);
1376 : : }
1377 : :
1378 : : /*
1379 : : * Helper function to decode printf style format.
1380 : : * Each call decode a token from the format and return the
1381 : : * number of characters read (or likely the delta where it wants
1382 : : * to go on the next call).
1383 : : * The decoded token is returned through the parameters
1384 : : *
1385 : : * 'h', 'l', or 'L' for integer fields
1386 : : * 'z' support added 23/7/1999 S.H.
1387 : : * 'z' changed to 'Z' --davidm 1/25/99
1388 : : * 't' added for ptrdiff_t
1389 : : *
1390 : : * @fmt: the format string
1391 : : * @type of the token returned
1392 : : * @flags: various flags such as +, -, # tokens..
1393 : : * @field_width: overwritten width
1394 : : * @base: base of the number (octal, hex, ...)
1395 : : * @precision: precision of a number
1396 : : * @qualifier: qualifier of a number (long, size_t, ...)
1397 : : */
1398 : : static noinline_for_stack
1399 : 0 : int format_decode(const char *fmt, struct printf_spec *spec)
1400 : : {
1401 : 25925822 : const char *start = fmt;
1402 : :
1403 : : /* we finished early by reading the field width */
1404 [ + + ]: 25925822 : if (spec->type == FORMAT_TYPE_WIDTH) {
1405 [ - + ]: 900351 : if (spec->field_width < 0) {
1406 : 0 : spec->field_width = -spec->field_width;
1407 : 0 : spec->flags |= LEFT;
1408 : : }
1409 : 900351 : spec->type = FORMAT_TYPE_NONE;
1410 : 900351 : goto precision;
1411 : : }
1412 : :
1413 : : /* we finished early by reading the precision */
1414 [ + + ]: 25025471 : if (spec->type == FORMAT_TYPE_PRECISION) {
1415 [ - + ]: 6 : if (spec->precision < 0)
1416 : 0 : spec->precision = 0;
1417 : :
1418 : 6 : spec->type = FORMAT_TYPE_NONE;
1419 : 6 : goto qualifier;
1420 : : }
1421 : :
1422 : : /* By default */
1423 : 25025465 : spec->type = FORMAT_TYPE_NONE;
1424 : :
1425 [ + + ]: 43405178 : for (; *fmt ; ++fmt) {
1426 [ + + ]: 41828262 : if (*fmt == '%')
1427 : : break;
1428 : : }
1429 : :
1430 : : /* Return the current non-format string */
1431 [ + + ][ + ]: 25025465 : if (fmt != start || !*fmt)
1432 : 8525490 : return fmt - start;
1433 : :
1434 : : /* Process flags */
1435 : 16499975 : spec->flags = 0;
1436 : :
1437 : : while (1) { /* this also skips first '%' */
1438 : : bool found = true;
1439 : :
1440 : 21143872 : ++fmt;
1441 : :
1442 [ + - - + : 21143872 : switch (*fmt) {
+ + ]
1443 : 20949 : case '-': spec->flags |= LEFT; break;
1444 : 0 : case '+': spec->flags |= PLUS; break;
1445 : 0 : case ' ': spec->flags |= SPACE; break;
1446 : 425 : case '#': spec->flags |= SPECIAL; break;
1447 : 4622523 : case '0': spec->flags |= ZEROPAD; break;
1448 : : default: found = false;
1449 : : }
1450 : :
1451 [ + + ]: 21143872 : if (!found)
1452 : : break;
1453 : : }
1454 : :
1455 : : /* get field width */
1456 : 16499975 : spec->field_width = -1;
1457 : :
1458 [ + + ]: 16499975 : if (isdigit(*fmt))
1459 : 4990102 : spec->field_width = skip_atoi(&fmt);
1460 [ + + ]: 11509873 : else if (*fmt == '*') {
1461 : : /* it's the next argument */
1462 : 900438 : spec->type = FORMAT_TYPE_WIDTH;
1463 : 900438 : return ++fmt - start;
1464 : : }
1465 : :
1466 : : precision:
1467 : : /* get the precision */
1468 : 16499887 : spec->precision = -1;
1469 [ + + ]: 16499887 : if (*fmt == '.') {
1470 : 359 : ++fmt;
1471 [ + + ]: 359 : if (isdigit(*fmt)) {
1472 : 353 : spec->precision = skip_atoi(&fmt);
1473 [ - + ]: 353 : if (spec->precision < 0)
1474 : 0 : spec->precision = 0;
1475 [ + - ]: 6 : } else if (*fmt == '*') {
1476 : : /* it's the next argument */
1477 : 6 : spec->type = FORMAT_TYPE_PRECISION;
1478 : 6 : return ++fmt - start;
1479 : : }
1480 : : }
1481 : :
1482 : : qualifier:
1483 : : /* get the conversion qualifier */
1484 : 16499887 : spec->qualifier = -1;
1485 [ + + ][ + + ]: 16499887 : if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
[ + + ]
1486 [ + ]: 12339709 : _tolower(*fmt) == 'z' || *fmt == 't') {
1487 : 4160147 : spec->qualifier = *fmt++;
1488 [ + + ]: 4160147 : if (unlikely(spec->qualifier == *fmt)) {
1489 [ + - ]: 1026724 : if (spec->qualifier == 'l') {
1490 : 1026724 : spec->qualifier = 'L';
1491 : 1026724 : ++fmt;
1492 [ # # ]: 0 : } else if (spec->qualifier == 'h') {
1493 : 0 : spec->qualifier = 'H';
1494 : 0 : ++fmt;
1495 : : }
1496 : : }
1497 : : }
1498 : :
1499 : : /* default base */
1500 : 16499887 : spec->base = 10;
1501 [ + + + - : 16499887 : switch (*fmt) {
- + + + +
- + ]
1502 : : case 'c':
1503 : 3645036 : spec->type = FORMAT_TYPE_CHAR;
1504 : 3645036 : return ++fmt - start;
1505 : :
1506 : : case 's':
1507 : 1727470 : spec->type = FORMAT_TYPE_STR;
1508 : 1727470 : return ++fmt - start;
1509 : :
1510 : : case 'p':
1511 : 44570 : spec->type = FORMAT_TYPE_PTR;
1512 : 44570 : return fmt - start;
1513 : : /* skip alnum */
1514 : :
1515 : : case 'n':
1516 : 0 : spec->type = FORMAT_TYPE_NRCHARS;
1517 : 0 : return ++fmt - start;
1518 : :
1519 : : case '%':
1520 : 0 : spec->type = FORMAT_TYPE_PERCENT_CHAR;
1521 : 0 : return ++fmt - start;
1522 : :
1523 : : /* integer number formats - set up the flags and "break" */
1524 : : case 'o':
1525 : 342 : spec->base = 8;
1526 : 342 : break;
1527 : :
1528 : : case 'x':
1529 : 6695028 : spec->flags |= SMALL;
1530 : :
1531 : : case 'X':
1532 : 6697527 : spec->base = 16;
1533 : 6697527 : break;
1534 : :
1535 : : case 'd':
1536 : : case 'i':
1537 : 2789922 : spec->flags |= SIGN;
1538 : : case 'u':
1539 : : break;
1540 : :
1541 : : default:
1542 : 0 : spec->type = FORMAT_TYPE_INVALID;
1543 : 0 : return fmt - start;
1544 : : }
1545 : :
1546 [ + + ]: 11082811 : if (spec->qualifier == 'L')
1547 : 1027711 : spec->type = FORMAT_TYPE_LONG_LONG;
1548 [ + + ]: 10055100 : else if (spec->qualifier == 'l') {
1549 [ + + ]: 3132013 : if (spec->flags & SIGN)
1550 : 1099 : spec->type = FORMAT_TYPE_LONG;
1551 : : else
1552 : 3130914 : spec->type = FORMAT_TYPE_ULONG;
1553 [ + + ]: 6923087 : } else if (_tolower(spec->qualifier) == 'z') {
1554 : 2 : spec->type = FORMAT_TYPE_SIZE_T;
1555 [ - + ]: 6923085 : } else if (spec->qualifier == 't') {
1556 : 0 : spec->type = FORMAT_TYPE_PTRDIFF;
1557 [ - + ]: 6923085 : } else if (spec->qualifier == 'H') {
1558 [ # # ]: 0 : if (spec->flags & SIGN)
1559 : 0 : spec->type = FORMAT_TYPE_BYTE;
1560 : : else
1561 : 0 : spec->type = FORMAT_TYPE_UBYTE;
1562 [ + + ]: 6923085 : } else if (spec->qualifier == 'h') {
1563 [ + + ]: 388 : if (spec->flags & SIGN)
1564 : 89 : spec->type = FORMAT_TYPE_SHORT;
1565 : : else
1566 : 299 : spec->type = FORMAT_TYPE_USHORT;
1567 : : } else {
1568 [ + + ]: 6922697 : if (spec->flags & SIGN)
1569 : 2787838 : spec->type = FORMAT_TYPE_INT;
1570 : : else
1571 : 4134859 : spec->type = FORMAT_TYPE_UINT;
1572 : : }
1573 : :
1574 : 11082811 : return ++fmt - start;
1575 : : }
1576 : :
1577 : : /**
1578 : : * vsnprintf - Format a string and place it in a buffer
1579 : : * @buf: The buffer to place the result into
1580 : : * @size: The size of the buffer, including the trailing null space
1581 : : * @fmt: The format string to use
1582 : : * @args: Arguments for the format string
1583 : : *
1584 : : * This function follows C99 vsnprintf, but has some extensions:
1585 : : * %pS output the name of a text symbol with offset
1586 : : * %ps output the name of a text symbol without offset
1587 : : * %pF output the name of a function pointer with its offset
1588 : : * %pf output the name of a function pointer without its offset
1589 : : * %pB output the name of a backtrace symbol with its offset
1590 : : * %pR output the address range in a struct resource with decoded flags
1591 : : * %pr output the address range in a struct resource with raw flags
1592 : : * %pM output a 6-byte MAC address with colons
1593 : : * %pMR output a 6-byte MAC address with colons in reversed order
1594 : : * %pMF output a 6-byte MAC address with dashes
1595 : : * %pm output a 6-byte MAC address without colons
1596 : : * %pmR output a 6-byte MAC address without colons in reversed order
1597 : : * %pI4 print an IPv4 address without leading zeros
1598 : : * %pi4 print an IPv4 address with leading zeros
1599 : : * %pI6 print an IPv6 address with colons
1600 : : * %pi6 print an IPv6 address without colons
1601 : : * %pI6c print an IPv6 address as specified by RFC 5952
1602 : : * %pIS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address
1603 : : * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address
1604 : : * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
1605 : : * case.
1606 : : * %*ph[CDN] a variable-length hex string with a separator (supports up to 64
1607 : : * bytes of the input)
1608 : : * %n is ignored
1609 : : *
1610 : : * ** Please update Documentation/printk-formats.txt when making changes **
1611 : : *
1612 : : * The return value is the number of characters which would
1613 : : * be generated for the given input, excluding the trailing
1614 : : * '\0', as per ISO C99. If you want to have the exact
1615 : : * number of characters written into @buf as return value
1616 : : * (not including the trailing '\0'), use vscnprintf(). If the
1617 : : * return is greater than or equal to @size, the resulting
1618 : : * string is truncated.
1619 : : *
1620 : : * If you're not already dealing with a va_list consider using snprintf().
1621 : : */
1622 : 0 : int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
1623 : : {
1624 : : unsigned long long num;
1625 : : char *str, *end;
1626 : 19980814 : struct printf_spec spec = {0};
1627 : :
1628 : : /* Reject out-of-range values early. Large positive sizes are
1629 : : used for unknown buffer sizes. */
1630 [ - + ][ # # ]: 7125925 : if (WARN_ON_ONCE((int) size < 0))
[ - + ][ + - ]
1631 : : return 0;
1632 : :
1633 : : str = buf;
1634 : 7125911 : end = buf + size;
1635 : :
1636 : : /* Make sure end is always >= buf */
1637 [ + + ]: 7125911 : if (end < buf) {
1638 : : end = ((void *)-1);
1639 : 7125911 : size = end - buf;
1640 : : }
1641 : :
1642 [ + + ]: 33051099 : while (*fmt) {
1643 : : const char *old_fmt = fmt;
1644 : 25925165 : int read = format_decode(fmt, &spec);
1645 : :
1646 : 25925809 : fmt += read;
1647 : :
1648 [ + + + + : 25925809 : switch (spec.type) {
+ + - - -
+ ]
1649 : : case FORMAT_TYPE_NONE: {
1650 : : int copy = read;
1651 [ + + ]: 8525440 : if (str < end) {
1652 [ - + ]: 8516545 : if (copy > end - str)
1653 : : copy = end - str;
1654 : 8516545 : memcpy(str, old_fmt, copy);
1655 : : }
1656 : 8525440 : str += read;
1657 : 8525440 : break;
1658 : : }
1659 : :
1660 : : case FORMAT_TYPE_WIDTH:
1661 : 900438 : spec.field_width = va_arg(args, int);
1662 : 900438 : break;
1663 : :
1664 : : case FORMAT_TYPE_PRECISION:
1665 : 6 : spec.precision = va_arg(args, int);
1666 : 6 : break;
1667 : :
1668 : : case FORMAT_TYPE_CHAR: {
1669 : : char c;
1670 : :
1671 [ + - ]: 3645036 : if (!(spec.flags & LEFT)) {
1672 [ + + ]: 3645302 : while (--spec.field_width > 0) {
1673 [ + - ]: 266 : if (str < end)
1674 : 266 : *str = ' ';
1675 : 266 : ++str;
1676 : :
1677 : : }
1678 : : }
1679 : 3645036 : c = (unsigned char) va_arg(args, int);
1680 [ + - ]: 3645036 : if (str < end)
1681 : 3645036 : *str = c;
1682 : 3645036 : ++str;
1683 [ - + ]: 3645036 : while (--spec.field_width > 0) {
1684 [ # # ]: 0 : if (str < end)
1685 : 0 : *str = ' ';
1686 : 0 : ++str;
1687 : : }
1688 : : break;
1689 : : }
1690 : :
1691 : : case FORMAT_TYPE_STR:
1692 : 1727482 : str = string(str, end, va_arg(args, char *), spec);
1693 : 1727547 : break;
1694 : :
1695 : : case FORMAT_TYPE_PTR:
1696 : 44570 : str = pointer(fmt+1, str, end, va_arg(args, void *),
1697 : : spec);
1698 [ + + ]: 133769 : while (isalnum(*fmt))
1699 : 89199 : fmt++;
1700 : : break;
1701 : :
1702 : : case FORMAT_TYPE_PERCENT_CHAR:
1703 [ # # ]: 0 : if (str < end)
1704 : 0 : *str = '%';
1705 : 0 : ++str;
1706 : 0 : break;
1707 : :
1708 : : case FORMAT_TYPE_INVALID:
1709 [ # # ]: 0 : if (str < end)
1710 : 0 : *str = '%';
1711 : 0 : ++str;
1712 : 0 : break;
1713 : :
1714 : : case FORMAT_TYPE_NRCHARS: {
1715 : : /*
1716 : : * Since %n poses a greater security risk than
1717 : : * utility, ignore %n and skip its argument.
1718 : : */
1719 : : void *skip_arg;
1720 : :
1721 [ # # ][ # # ]: 0 : WARN_ONCE(1, "Please remove ignored %%n in '%s'\n",
1722 : : old_fmt);
1723 : :
1724 : 0 : skip_arg = va_arg(args, void *);
1725 : 0 : break;
1726 : : }
1727 : :
1728 : : default:
1729 [ + + + + : 11082837 : switch (spec.type) {
- - - + +
+ + ]
1730 : : case FORMAT_TYPE_LONG_LONG:
1731 : 1027744 : num = va_arg(args, long long);
1732 : 1027744 : break;
1733 : : case FORMAT_TYPE_ULONG:
1734 : 3130914 : num = va_arg(args, unsigned long);
1735 : 3130914 : break;
1736 : : case FORMAT_TYPE_LONG:
1737 : 1099 : num = va_arg(args, long);
1738 : 1099 : break;
1739 : : case FORMAT_TYPE_SIZE_T:
1740 [ + - ]: 2 : if (spec.flags & SIGN)
1741 : 2 : num = va_arg(args, ssize_t);
1742 : : else
1743 : 0 : num = va_arg(args, size_t);
1744 : : break;
1745 : : case FORMAT_TYPE_PTRDIFF:
1746 : 0 : num = va_arg(args, ptrdiff_t);
1747 : 0 : break;
1748 : : case FORMAT_TYPE_UBYTE:
1749 : 0 : num = (unsigned char) va_arg(args, int);
1750 : 0 : break;
1751 : : case FORMAT_TYPE_BYTE:
1752 : 0 : num = (signed char) va_arg(args, int);
1753 : 0 : break;
1754 : : case FORMAT_TYPE_USHORT:
1755 : 299 : num = (unsigned short) va_arg(args, int);
1756 : 299 : break;
1757 : : case FORMAT_TYPE_SHORT:
1758 : 89 : num = (short) va_arg(args, int);
1759 : 89 : break;
1760 : : case FORMAT_TYPE_INT:
1761 : 2787831 : num = (int) va_arg(args, int);
1762 : 2787831 : break;
1763 : : default:
1764 : 4134859 : num = va_arg(args, unsigned int);
1765 : : }
1766 : :
1767 : 25925874 : str = number(str, end, num, spec);
1768 : : }
1769 : : }
1770 : :
1771 [ + + ]: 7125934 : if (size > 0) {
1772 [ + + ]: 7121286 : if (str < end)
1773 : 7121284 : *str = '\0';
1774 : : else
1775 : 2 : end[-1] = '\0';
1776 : : }
1777 : :
1778 : : /* the trailing null byte doesn't count towards the total */
1779 : 7125934 : return str-buf;
1780 : :
1781 : : }
1782 : : EXPORT_SYMBOL(vsnprintf);
1783 : :
1784 : : /**
1785 : : * vscnprintf - Format a string and place it in a buffer
1786 : : * @buf: The buffer to place the result into
1787 : : * @size: The size of the buffer, including the trailing null space
1788 : : * @fmt: The format string to use
1789 : : * @args: Arguments for the format string
1790 : : *
1791 : : * The return value is the number of characters which have been written into
1792 : : * the @buf not including the trailing '\0'. If @size is == 0 the function
1793 : : * returns 0.
1794 : : *
1795 : : * If you're not already dealing with a va_list consider using scnprintf().
1796 : : *
1797 : : * See the vsnprintf() documentation for format string extensions over C99.
1798 : : */
1799 : 0 : int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
1800 : : {
1801 : : int i;
1802 : :
1803 : 54000 : i = vsnprintf(buf, size, fmt, args);
1804 : :
1805 [ - + ]: 54000 : if (likely(i < size))
1806 : : return i;
1807 [ # # ]: 0 : if (size != 0)
1808 : 0 : return size - 1;
1809 : : return 0;
1810 : : }
1811 : : EXPORT_SYMBOL(vscnprintf);
1812 : :
1813 : : /**
1814 : : * snprintf - Format a string and place it in a buffer
1815 : : * @buf: The buffer to place the result into
1816 : : * @size: The size of the buffer, including the trailing null space
1817 : : * @fmt: The format string to use
1818 : : * @...: Arguments for the format string
1819 : : *
1820 : : * The return value is the number of characters which would be
1821 : : * generated for the given input, excluding the trailing null,
1822 : : * as per ISO C99. If the return is greater than or equal to
1823 : : * @size, the resulting string is truncated.
1824 : : *
1825 : : * See the vsnprintf() documentation for format string extensions over C99.
1826 : : */
1827 : 0 : int snprintf(char *buf, size_t size, const char *fmt, ...)
1828 : : {
1829 : : va_list args;
1830 : : int i;
1831 : :
1832 : 2285993 : va_start(args, fmt);
1833 : 2285993 : i = vsnprintf(buf, size, fmt, args);
1834 : 2285993 : va_end(args);
1835 : :
1836 : 2285993 : return i;
1837 : : }
1838 : : EXPORT_SYMBOL(snprintf);
1839 : :
1840 : : /**
1841 : : * scnprintf - Format a string and place it in a buffer
1842 : : * @buf: The buffer to place the result into
1843 : : * @size: The size of the buffer, including the trailing null space
1844 : : * @fmt: The format string to use
1845 : : * @...: Arguments for the format string
1846 : : *
1847 : : * The return value is the number of characters written into @buf not including
1848 : : * the trailing '\0'. If @size is == 0 the function returns 0.
1849 : : */
1850 : :
1851 : 0 : int scnprintf(char *buf, size_t size, const char *fmt, ...)
1852 : : {
1853 : : va_list args;
1854 : : int i;
1855 : :
1856 : 52352 : va_start(args, fmt);
1857 : 52352 : i = vscnprintf(buf, size, fmt, args);
1858 : 52351 : va_end(args);
1859 : :
1860 : 52351 : return i;
1861 : : }
1862 : : EXPORT_SYMBOL(scnprintf);
1863 : :
1864 : : /**
1865 : : * vsprintf - Format a string and place it in a buffer
1866 : : * @buf: The buffer to place the result into
1867 : : * @fmt: The format string to use
1868 : : * @args: Arguments for the format string
1869 : : *
1870 : : * The function returns the number of characters written
1871 : : * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
1872 : : * buffer overflows.
1873 : : *
1874 : : * If you're not already dealing with a va_list consider using sprintf().
1875 : : *
1876 : : * See the vsnprintf() documentation for format string extensions over C99.
1877 : : */
1878 : 0 : int vsprintf(char *buf, const char *fmt, va_list args)
1879 : : {
1880 : 0 : return vsnprintf(buf, INT_MAX, fmt, args);
1881 : : }
1882 : : EXPORT_SYMBOL(vsprintf);
1883 : :
1884 : : /**
1885 : : * sprintf - Format a string and place it in a buffer
1886 : : * @buf: The buffer to place the result into
1887 : : * @fmt: The format string to use
1888 : : * @...: Arguments for the format string
1889 : : *
1890 : : * The function returns the number of characters written
1891 : : * into @buf. Use snprintf() or scnprintf() in order to avoid
1892 : : * buffer overflows.
1893 : : *
1894 : : * See the vsnprintf() documentation for format string extensions over C99.
1895 : : */
1896 : 0 : int sprintf(char *buf, const char *fmt, ...)
1897 : : {
1898 : : va_list args;
1899 : : int i;
1900 : :
1901 : 107688 : va_start(args, fmt);
1902 : 107688 : i = vsnprintf(buf, INT_MAX, fmt, args);
1903 : 107688 : va_end(args);
1904 : :
1905 : 107688 : return i;
1906 : : }
1907 : : EXPORT_SYMBOL(sprintf);
1908 : :
1909 : : #ifdef CONFIG_BINARY_PRINTF
1910 : : /*
1911 : : * bprintf service:
1912 : : * vbin_printf() - VA arguments to binary data
1913 : : * bstr_printf() - Binary data to text string
1914 : : */
1915 : :
1916 : : /**
1917 : : * vbin_printf - Parse a format string and place args' binary value in a buffer
1918 : : * @bin_buf: The buffer to place args' binary value
1919 : : * @size: The size of the buffer(by words(32bits), not characters)
1920 : : * @fmt: The format string to use
1921 : : * @args: Arguments for the format string
1922 : : *
1923 : : * The format follows C99 vsnprintf, except %n is ignored, and its argument
1924 : : * is skiped.
1925 : : *
1926 : : * The return value is the number of words(32bits) which would be generated for
1927 : : * the given input.
1928 : : *
1929 : : * NOTE:
1930 : : * If the return value is greater than @size, the resulting bin_buf is NOT
1931 : : * valid for bstr_printf().
1932 : : */
1933 : 0 : int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
1934 : : {
1935 : 0 : struct printf_spec spec = {0};
1936 : : char *str, *end;
1937 : :
1938 : : str = (char *)bin_buf;
1939 : 0 : end = (char *)(bin_buf + size);
1940 : :
1941 : : #define save_arg(type) \
1942 : : do { \
1943 : : if (sizeof(type) == 8) { \
1944 : : unsigned long long value; \
1945 : : str = PTR_ALIGN(str, sizeof(u32)); \
1946 : : value = va_arg(args, unsigned long long); \
1947 : : if (str + sizeof(type) <= end) { \
1948 : : *(u32 *)str = *(u32 *)&value; \
1949 : : *(u32 *)(str + 4) = *((u32 *)&value + 1); \
1950 : : } \
1951 : : } else { \
1952 : : unsigned long value; \
1953 : : str = PTR_ALIGN(str, sizeof(type)); \
1954 : : value = va_arg(args, int); \
1955 : : if (str + sizeof(type) <= end) \
1956 : : *(typeof(type) *)str = (type)value; \
1957 : : } \
1958 : : str += sizeof(type); \
1959 : : } while (0)
1960 : :
1961 [ # # ]: 0 : while (*fmt) {
1962 : 0 : int read = format_decode(fmt, &spec);
1963 : :
1964 : 0 : fmt += read;
1965 : :
1966 [ # # # # : 0 : switch (spec.type) {
# # # ]
1967 : : case FORMAT_TYPE_NONE:
1968 : : case FORMAT_TYPE_INVALID:
1969 : : case FORMAT_TYPE_PERCENT_CHAR:
1970 : : break;
1971 : :
1972 : : case FORMAT_TYPE_WIDTH:
1973 : : case FORMAT_TYPE_PRECISION:
1974 [ # # ]: 0 : save_arg(int);
1975 : 0 : break;
1976 : :
1977 : : case FORMAT_TYPE_CHAR:
1978 [ # # ]: 0 : save_arg(char);
1979 : 0 : break;
1980 : :
1981 : : case FORMAT_TYPE_STR: {
1982 : 0 : const char *save_str = va_arg(args, char *);
1983 : : size_t len;
1984 : :
1985 [ # # ]: 0 : if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
1986 : 0 : || (unsigned long)save_str < PAGE_SIZE)
1987 : : save_str = "(null)";
1988 : 0 : len = strlen(save_str) + 1;
1989 [ # # ]: 0 : if (str + len < end)
1990 : 0 : memcpy(str, save_str, len);
1991 : : str += len;
1992 : 0 : break;
1993 : : }
1994 : :
1995 : : case FORMAT_TYPE_PTR:
1996 [ # # ]: 0 : save_arg(void *);
1997 : : /* skip all alphanumeric pointer suffixes */
1998 [ # # ]: 0 : while (isalnum(*fmt))
1999 : 0 : fmt++;
2000 : : break;
2001 : :
2002 : : case FORMAT_TYPE_NRCHARS: {
2003 : : /* skip %n 's argument */
2004 : 0 : u8 qualifier = spec.qualifier;
2005 : : void *skip_arg;
2006 [ # # ]: 0 : if (qualifier == 'l')
2007 : 0 : skip_arg = va_arg(args, long *);
2008 [ # # ]: 0 : else if (_tolower(qualifier) == 'z')
2009 : 0 : skip_arg = va_arg(args, size_t *);
2010 : : else
2011 : 0 : skip_arg = va_arg(args, int *);
2012 : : break;
2013 : : }
2014 : :
2015 : : default:
2016 [ # # # # : 0 : switch (spec.type) {
# # # ]
2017 : :
2018 : : case FORMAT_TYPE_LONG_LONG:
2019 [ # # ]: 0 : save_arg(long long);
2020 : 0 : break;
2021 : : case FORMAT_TYPE_ULONG:
2022 : : case FORMAT_TYPE_LONG:
2023 [ # # ]: 0 : save_arg(unsigned long);
2024 : 0 : break;
2025 : : case FORMAT_TYPE_SIZE_T:
2026 [ # # ]: 0 : save_arg(size_t);
2027 : 0 : break;
2028 : : case FORMAT_TYPE_PTRDIFF:
2029 [ # # ]: 0 : save_arg(ptrdiff_t);
2030 : 0 : break;
2031 : : case FORMAT_TYPE_UBYTE:
2032 : : case FORMAT_TYPE_BYTE:
2033 [ # # ]: 0 : save_arg(char);
2034 : 0 : break;
2035 : : case FORMAT_TYPE_USHORT:
2036 : : case FORMAT_TYPE_SHORT:
2037 [ # # ]: 0 : save_arg(short);
2038 : 0 : break;
2039 : : default:
2040 [ # # ]: 0 : save_arg(int);
2041 : : }
2042 : : }
2043 : : }
2044 : :
2045 : 0 : return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
2046 : : #undef save_arg
2047 : : }
2048 : : EXPORT_SYMBOL_GPL(vbin_printf);
2049 : :
2050 : : /**
2051 : : * bstr_printf - Format a string from binary arguments and place it in a buffer
2052 : : * @buf: The buffer to place the result into
2053 : : * @size: The size of the buffer, including the trailing null space
2054 : : * @fmt: The format string to use
2055 : : * @bin_buf: Binary arguments for the format string
2056 : : *
2057 : : * This function like C99 vsnprintf, but the difference is that vsnprintf gets
2058 : : * arguments from stack, and bstr_printf gets arguments from @bin_buf which is
2059 : : * a binary buffer that generated by vbin_printf.
2060 : : *
2061 : : * The format follows C99 vsnprintf, but has some extensions:
2062 : : * see vsnprintf comment for details.
2063 : : *
2064 : : * The return value is the number of characters which would
2065 : : * be generated for the given input, excluding the trailing
2066 : : * '\0', as per ISO C99. If you want to have the exact
2067 : : * number of characters written into @buf as return value
2068 : : * (not including the trailing '\0'), use vscnprintf(). If the
2069 : : * return is greater than or equal to @size, the resulting
2070 : : * string is truncated.
2071 : : */
2072 : 0 : int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
2073 : : {
2074 : 0 : struct printf_spec spec = {0};
2075 : : char *str, *end;
2076 : : const char *args = (const char *)bin_buf;
2077 : :
2078 [ # # ][ # # ]: 0 : if (WARN_ON_ONCE((int) size < 0))
[ # # ][ # # ]
2079 : : return 0;
2080 : :
2081 : : str = buf;
2082 : 0 : end = buf + size;
2083 : :
2084 : : #define get_arg(type) \
2085 : : ({ \
2086 : : typeof(type) value; \
2087 : : if (sizeof(type) == 8) { \
2088 : : args = PTR_ALIGN(args, sizeof(u32)); \
2089 : : *(u32 *)&value = *(u32 *)args; \
2090 : : *((u32 *)&value + 1) = *(u32 *)(args + 4); \
2091 : : } else { \
2092 : : args = PTR_ALIGN(args, sizeof(type)); \
2093 : : value = *(typeof(type) *)args; \
2094 : : } \
2095 : : args += sizeof(type); \
2096 : : value; \
2097 : : })
2098 : :
2099 : : /* Make sure end is always >= buf */
2100 [ # # ]: 0 : if (end < buf) {
2101 : : end = ((void *)-1);
2102 : 0 : size = end - buf;
2103 : : }
2104 : :
2105 [ # # ]: 0 : while (*fmt) {
2106 : : const char *old_fmt = fmt;
2107 : 0 : int read = format_decode(fmt, &spec);
2108 : :
2109 : 0 : fmt += read;
2110 : :
2111 [ # # # # : 0 : switch (spec.type) {
# # # #
# ]
2112 : : case FORMAT_TYPE_NONE: {
2113 : : int copy = read;
2114 [ # # ]: 0 : if (str < end) {
2115 [ # # ]: 0 : if (copy > end - str)
2116 : : copy = end - str;
2117 : 0 : memcpy(str, old_fmt, copy);
2118 : : }
2119 : 0 : str += read;
2120 : 0 : break;
2121 : : }
2122 : :
2123 : : case FORMAT_TYPE_WIDTH:
2124 : 0 : spec.field_width = get_arg(int);
2125 : 0 : break;
2126 : :
2127 : : case FORMAT_TYPE_PRECISION:
2128 : 0 : spec.precision = get_arg(int);
2129 : 0 : break;
2130 : :
2131 : : case FORMAT_TYPE_CHAR: {
2132 : : char c;
2133 : :
2134 [ # # ]: 0 : if (!(spec.flags & LEFT)) {
2135 [ # # ]: 0 : while (--spec.field_width > 0) {
2136 [ # # ]: 0 : if (str < end)
2137 : 0 : *str = ' ';
2138 : 0 : ++str;
2139 : : }
2140 : : }
2141 : 0 : c = (unsigned char) get_arg(char);
2142 [ # # ]: 0 : if (str < end)
2143 : 0 : *str = c;
2144 : 0 : ++str;
2145 [ # # ]: 0 : while (--spec.field_width > 0) {
2146 [ # # ]: 0 : if (str < end)
2147 : 0 : *str = ' ';
2148 : 0 : ++str;
2149 : : }
2150 : : break;
2151 : : }
2152 : :
2153 : : case FORMAT_TYPE_STR: {
2154 : : const char *str_arg = args;
2155 : 0 : args += strlen(str_arg) + 1;
2156 : 0 : str = string(str, end, (char *)str_arg, spec);
2157 : 0 : break;
2158 : : }
2159 : :
2160 : : case FORMAT_TYPE_PTR:
2161 : 0 : str = pointer(fmt+1, str, end, get_arg(void *), spec);
2162 [ # # ]: 0 : while (isalnum(*fmt))
2163 : 0 : fmt++;
2164 : : break;
2165 : :
2166 : : case FORMAT_TYPE_PERCENT_CHAR:
2167 : : case FORMAT_TYPE_INVALID:
2168 [ # # ]: 0 : if (str < end)
2169 : 0 : *str = '%';
2170 : 0 : ++str;
2171 : 0 : break;
2172 : :
2173 : : case FORMAT_TYPE_NRCHARS:
2174 : : /* skip */
2175 : : break;
2176 : :
2177 : : default: {
2178 : : unsigned long long num;
2179 : :
2180 [ # # # # : 0 : switch (spec.type) {
# # # # #
# ]
2181 : :
2182 : : case FORMAT_TYPE_LONG_LONG:
2183 : 0 : num = get_arg(long long);
2184 : 0 : break;
2185 : : case FORMAT_TYPE_ULONG:
2186 : : case FORMAT_TYPE_LONG:
2187 : 0 : num = get_arg(unsigned long);
2188 : 0 : break;
2189 : : case FORMAT_TYPE_SIZE_T:
2190 : 0 : num = get_arg(size_t);
2191 : 0 : break;
2192 : : case FORMAT_TYPE_PTRDIFF:
2193 : 0 : num = get_arg(ptrdiff_t);
2194 : 0 : break;
2195 : : case FORMAT_TYPE_UBYTE:
2196 : 0 : num = get_arg(unsigned char);
2197 : 0 : break;
2198 : : case FORMAT_TYPE_BYTE:
2199 : 0 : num = get_arg(signed char);
2200 : 0 : break;
2201 : : case FORMAT_TYPE_USHORT:
2202 : 0 : num = get_arg(unsigned short);
2203 : 0 : break;
2204 : : case FORMAT_TYPE_SHORT:
2205 : 0 : num = get_arg(short);
2206 : 0 : break;
2207 : : case FORMAT_TYPE_UINT:
2208 : 0 : num = get_arg(unsigned int);
2209 : 0 : break;
2210 : : default:
2211 : 0 : num = get_arg(int);
2212 : : }
2213 : :
2214 : 0 : str = number(str, end, num, spec);
2215 : : } /* default: */
2216 : : } /* switch(spec.type) */
2217 : : } /* while(*fmt) */
2218 : :
2219 [ # # ]: 0 : if (size > 0) {
2220 [ # # ]: 0 : if (str < end)
2221 : 0 : *str = '\0';
2222 : : else
2223 : 0 : end[-1] = '\0';
2224 : : }
2225 : :
2226 : : #undef get_arg
2227 : :
2228 : : /* the trailing null byte doesn't count towards the total */
2229 : 0 : return str - buf;
2230 : : }
2231 : : EXPORT_SYMBOL_GPL(bstr_printf);
2232 : :
2233 : : /**
2234 : : * bprintf - Parse a format string and place args' binary value in a buffer
2235 : : * @bin_buf: The buffer to place args' binary value
2236 : : * @size: The size of the buffer(by words(32bits), not characters)
2237 : : * @fmt: The format string to use
2238 : : * @...: Arguments for the format string
2239 : : *
2240 : : * The function returns the number of words(u32) written
2241 : : * into @bin_buf.
2242 : : */
2243 : 0 : int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
2244 : : {
2245 : : va_list args;
2246 : : int ret;
2247 : :
2248 : 0 : va_start(args, fmt);
2249 : 0 : ret = vbin_printf(bin_buf, size, fmt, args);
2250 : 0 : va_end(args);
2251 : :
2252 : 0 : return ret;
2253 : : }
2254 : : EXPORT_SYMBOL_GPL(bprintf);
2255 : :
2256 : : #endif /* CONFIG_BINARY_PRINTF */
2257 : :
2258 : : /**
2259 : : * vsscanf - Unformat a buffer into a list of arguments
2260 : : * @buf: input buffer
2261 : : * @fmt: format of buffer
2262 : : * @args: arguments
2263 : : */
2264 : 0 : int vsscanf(const char *buf, const char *fmt, va_list args)
2265 : : {
2266 : : const char *str = buf;
2267 : : char *next;
2268 : : char digit;
2269 : : int num = 0;
2270 : : u8 qualifier;
2271 : : unsigned int base;
2272 : : union {
2273 : : long long s;
2274 : : unsigned long long u;
2275 : : } val;
2276 : : s16 field_width;
2277 : : bool is_sign;
2278 : :
2279 [ # # ]: 0 : while (*fmt) {
2280 : : /* skip any white space in format */
2281 : : /* white space in format matchs any amount of
2282 : : * white space, including none, in the input.
2283 : : */
2284 [ # # ]: 0 : if (isspace(*fmt)) {
2285 : 0 : fmt = skip_spaces(++fmt);
2286 : 0 : str = skip_spaces(str);
2287 : : }
2288 : :
2289 : : /* anything that is not a conversion must match exactly */
2290 [ # # ]: 0 : if (*fmt != '%' && *fmt) {
2291 [ # # ]: 0 : if (*fmt++ != *str++)
2292 : : break;
2293 : 0 : continue;
2294 : : }
2295 : :
2296 [ # # ]: 0 : if (!*fmt)
2297 : : break;
2298 : 0 : ++fmt;
2299 : :
2300 : : /* skip this conversion.
2301 : : * advance both strings to next white space
2302 : : */
2303 [ # # ]: 0 : if (*fmt == '*') {
2304 [ # # ]: 0 : if (!*str)
2305 : : break;
2306 [ # # ][ # # ]: 0 : while (!isspace(*fmt) && *fmt != '%' && *fmt)
[ # # ]
2307 : 0 : fmt++;
2308 [ # # ][ # # ]: 0 : while (!isspace(*str) && *str)
2309 : 0 : str++;
2310 : 0 : continue;
2311 : : }
2312 : :
2313 : : /* get field width */
2314 : : field_width = -1;
2315 [ # # ]: 0 : if (isdigit(*fmt)) {
2316 : 0 : field_width = skip_atoi(&fmt);
2317 [ # # ]: 0 : if (field_width <= 0)
2318 : : break;
2319 : : }
2320 : :
2321 : : /* get conversion qualifier */
2322 : : qualifier = -1;
2323 [ # # ][ # # ]: 0 : if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
[ # # ]
2324 : : _tolower(*fmt) == 'z') {
2325 : 0 : qualifier = *fmt++;
2326 [ # # ]: 0 : if (unlikely(qualifier == *fmt)) {
2327 [ # # ]: 0 : if (qualifier == 'h') {
2328 : : qualifier = 'H';
2329 : 0 : fmt++;
2330 [ # # ]: 0 : } else if (qualifier == 'l') {
2331 : : qualifier = 'L';
2332 : 0 : fmt++;
2333 : : }
2334 : : }
2335 : : }
2336 : :
2337 [ # # ]: 0 : if (!*fmt)
2338 : : break;
2339 : :
2340 [ # # ]: 0 : if (*fmt == 'n') {
2341 : : /* return number of characters read so far */
2342 : 0 : *va_arg(args, int *) = str - buf;
2343 : 0 : ++fmt;
2344 : 0 : continue;
2345 : : }
2346 : :
2347 [ # # ]: 0 : if (!*str)
2348 : : break;
2349 : :
2350 : 0 : base = 10;
2351 : : is_sign = 0;
2352 : :
2353 [ # # # # : 0 : switch (*fmt++) {
# # # #
# ]
2354 : : case 'c':
2355 : : {
2356 : 0 : char *s = (char *)va_arg(args, char*);
2357 [ # # ]: 0 : if (field_width == -1)
2358 : : field_width = 1;
2359 : : do {
2360 : 0 : *s++ = *str++;
2361 [ # # ][ # # ]: 0 : } while (--field_width > 0 && *str);
2362 : 0 : num++;
2363 : : }
2364 : 0 : continue;
2365 : : case 's':
2366 : : {
2367 : 0 : char *s = (char *)va_arg(args, char *);
2368 [ # # ]: 0 : if (field_width == -1)
2369 : : field_width = SHRT_MAX;
2370 : : /* first, skip leading white space in buffer */
2371 : 0 : str = skip_spaces(str);
2372 : :
2373 : : /* now copy until next white space */
2374 [ # # ][ # # ]: 0 : while (*str && !isspace(*str) && field_width--)
[ # # ]
2375 : 0 : *s++ = *str++;
2376 : 0 : *s = '\0';
2377 : 0 : num++;
2378 : : }
2379 : 0 : continue;
2380 : : case 'o':
2381 : 0 : base = 8;
2382 : 0 : break;
2383 : : case 'x':
2384 : : case 'X':
2385 : 0 : base = 16;
2386 : 0 : break;
2387 : : case 'i':
2388 : 0 : base = 0;
2389 : : case 'd':
2390 : : is_sign = 1;
2391 : : case 'u':
2392 : : break;
2393 : : case '%':
2394 : : /* looking for '%' in str */
2395 [ # # ]: 0 : if (*str++ != '%')
2396 : : return num;
2397 : 0 : continue;
2398 : : default:
2399 : : /* invalid format; stop here */
2400 : : return num;
2401 : : }
2402 : :
2403 : : /* have some sort of integer conversion.
2404 : : * first, skip white space in buffer.
2405 : : */
2406 : 0 : str = skip_spaces(str);
2407 : :
2408 : 0 : digit = *str;
2409 [ # # ]: 0 : if (is_sign && digit == '-')
2410 : 0 : digit = *(str + 1);
2411 : :
2412 [ # # ]: 0 : if (!digit
2413 [ # # ][ # # ]: 0 : || (base == 16 && !isxdigit(digit))
2414 [ # # ][ # # ]: 0 : || (base == 10 && !isdigit(digit))
2415 [ # # ][ # # ]: 0 : || (base == 8 && (!isdigit(digit) || digit > '7'))
[ # # ]
2416 [ # # ][ # # ]: 0 : || (base == 0 && !isdigit(digit)))
2417 : : break;
2418 : :
2419 [ # # ]: 0 : if (is_sign)
2420 : : val.s = qualifier != 'L' ?
2421 [ # # ]: 0 : simple_strtol(str, &next, base) :
2422 : : simple_strtoll(str, &next, base);
2423 : : else
2424 : 0 : val.u = qualifier != 'L' ?
2425 [ # # ]: 0 : simple_strtoul(str, &next, base) :
2426 : : simple_strtoull(str, &next, base);
2427 : :
2428 [ # # ][ # # ]: 0 : if (field_width > 0 && next - str > field_width) {
2429 [ # # ]: 0 : if (base == 0)
2430 : 0 : _parse_integer_fixup_radix(str, &base);
2431 [ # # ]: 0 : while (next - str > field_width) {
2432 [ # # ]: 0 : if (is_sign)
2433 : 0 : val.s = div_s64(val.s, base);
2434 : : else
2435 : 0 : val.u = div_u64(val.u, base);
2436 : 0 : --next;
2437 : : }
2438 : : }
2439 : :
2440 [ # # # # : 0 : switch (qualifier) {
# # ]
2441 : : case 'H': /* that's 'hh' in format */
2442 [ # # ]: 0 : if (is_sign)
2443 : 0 : *va_arg(args, signed char *) = val.s;
2444 : : else
2445 : 0 : *va_arg(args, unsigned char *) = val.u;
2446 : : break;
2447 : : case 'h':
2448 [ # # ]: 0 : if (is_sign)
2449 : 0 : *va_arg(args, short *) = val.s;
2450 : : else
2451 : 0 : *va_arg(args, unsigned short *) = val.u;
2452 : : break;
2453 : : case 'l':
2454 [ # # ]: 0 : if (is_sign)
2455 : 0 : *va_arg(args, long *) = val.s;
2456 : : else
2457 : 0 : *va_arg(args, unsigned long *) = val.u;
2458 : : break;
2459 : : case 'L':
2460 [ # # ]: 0 : if (is_sign)
2461 : 0 : *va_arg(args, long long *) = val.s;
2462 : : else
2463 : 0 : *va_arg(args, unsigned long long *) = val.u;
2464 : : break;
2465 : : case 'Z':
2466 : : case 'z':
2467 : 0 : *va_arg(args, size_t *) = val.u;
2468 : 0 : break;
2469 : : default:
2470 [ # # ]: 0 : if (is_sign)
2471 : 0 : *va_arg(args, int *) = val.s;
2472 : : else
2473 : 0 : *va_arg(args, unsigned int *) = val.u;
2474 : : break;
2475 : : }
2476 : 0 : num++;
2477 : :
2478 [ # # ]: 0 : if (!next)
2479 : : break;
2480 : : str = next;
2481 : : }
2482 : :
2483 : 0 : return num;
2484 : : }
2485 : : EXPORT_SYMBOL(vsscanf);
2486 : :
2487 : : /**
2488 : : * sscanf - Unformat a buffer into a list of arguments
2489 : : * @buf: input buffer
2490 : : * @fmt: formatting of buffer
2491 : : * @...: resulting arguments
2492 : : */
2493 : 0 : int sscanf(const char *buf, const char *fmt, ...)
2494 : : {
2495 : : va_list args;
2496 : : int i;
2497 : :
2498 : 0 : va_start(args, fmt);
2499 : 0 : i = vsscanf(buf, fmt, args);
2500 : 0 : va_end(args);
2501 : :
2502 : 0 : return i;
2503 : : }
2504 : : EXPORT_SYMBOL(sscanf);
|