LCOV - code coverage report
Current view: top level - lib - vsprintf.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 327 1214 26.9 %
Date: 2023-03-27 20:00:47 Functions: 24 74 32.4 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  *  linux/lib/vsprintf.c
       4             :  *
       5             :  *  Copyright (C) 1991, 1992  Linus Torvalds
       6             :  */
       7             : 
       8             : /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
       9             : /*
      10             :  * Wirzenius wrote this portably, Torvalds fucked it up :-)
      11             :  */
      12             : 
      13             : /*
      14             :  * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
      15             :  * - changed to provide snprintf and vsnprintf functions
      16             :  * So Feb  1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
      17             :  * - scnprintf and vscnprintf
      18             :  */
      19             : 
      20             : #include <linux/stdarg.h>
      21             : #include <linux/build_bug.h>
      22             : #include <linux/clk.h>
      23             : #include <linux/clk-provider.h>
      24             : #include <linux/errname.h>
      25             : #include <linux/module.h> /* for KSYM_SYMBOL_LEN */
      26             : #include <linux/types.h>
      27             : #include <linux/string.h>
      28             : #include <linux/ctype.h>
      29             : #include <linux/kernel.h>
      30             : #include <linux/kallsyms.h>
      31             : #include <linux/math64.h>
      32             : #include <linux/uaccess.h>
      33             : #include <linux/ioport.h>
      34             : #include <linux/dcache.h>
      35             : #include <linux/cred.h>
      36             : #include <linux/rtc.h>
      37             : #include <linux/time.h>
      38             : #include <linux/uuid.h>
      39             : #include <linux/of.h>
      40             : #include <net/addrconf.h>
      41             : #include <linux/siphash.h>
      42             : #include <linux/compiler.h>
      43             : #include <linux/property.h>
      44             : #include <linux/notifier.h>
      45             : #ifdef CONFIG_BLOCK
      46             : #include <linux/blkdev.h>
      47             : #endif
      48             : 
      49             : #include "../mm/internal.h"   /* For the trace_print_flags arrays */
      50             : 
      51             : #include <asm/page.h>             /* for PAGE_SIZE */
      52             : #include <asm/byteorder.h>        /* cpu_to_le16 */
      53             : #include <asm/unaligned.h>
      54             : 
      55             : #include <linux/string_helpers.h>
      56             : #include "kstrtox.h"
      57             : 
      58             : /* Disable pointer hashing if requested */
      59             : bool no_hash_pointers __ro_after_init;
      60             : EXPORT_SYMBOL_GPL(no_hash_pointers);
      61             : 
      62         152 : static noinline unsigned long long simple_strntoull(const char *startp, size_t max_chars, char **endp, unsigned int base)
      63             : {
      64             :         const char *cp;
      65         152 :         unsigned long long result = 0ULL;
      66             :         size_t prefix_chars;
      67             :         unsigned int rv;
      68             : 
      69         152 :         cp = _parse_integer_fixup_radix(startp, &base);
      70         152 :         prefix_chars = cp - startp;
      71         152 :         if (prefix_chars < max_chars) {
      72         152 :                 rv = _parse_integer_limit(cp, base, &result, max_chars - prefix_chars);
      73             :                 /* FIXME */
      74         152 :                 cp += (rv & ~KSTRTOX_OVERFLOW);
      75             :         } else {
      76             :                 /* Field too short for prefix + digit, skip over without converting */
      77           0 :                 cp = startp + max_chars;
      78             :         }
      79             : 
      80         152 :         if (endp)
      81         151 :                 *endp = (char *)cp;
      82             : 
      83         152 :         return result;
      84             : }
      85             : 
      86             : /**
      87             :  * simple_strtoull - convert a string to an unsigned long long
      88             :  * @cp: The start of the string
      89             :  * @endp: A pointer to the end of the parsed string will be placed here
      90             :  * @base: The number base to use
      91             :  *
      92             :  * This function has caveats. Please use kstrtoull instead.
      93             :  */
      94             : noinline
      95         152 : unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
      96             : {
      97         152 :         return simple_strntoull(cp, INT_MAX, endp, base);
      98             : }
      99             : EXPORT_SYMBOL(simple_strtoull);
     100             : 
     101             : /**
     102             :  * simple_strtoul - convert a string to an unsigned long
     103             :  * @cp: The start of the string
     104             :  * @endp: A pointer to the end of the parsed string will be placed here
     105             :  * @base: The number base to use
     106             :  *
     107             :  * This function has caveats. Please use kstrtoul instead.
     108             :  */
     109           1 : unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
     110             : {
     111         147 :         return simple_strtoull(cp, endp, base);
     112             : }
     113             : EXPORT_SYMBOL(simple_strtoul);
     114             : 
     115             : /**
     116             :  * simple_strtol - convert a string to a signed long
     117             :  * @cp: The start of the string
     118             :  * @endp: A pointer to the end of the parsed string will be placed here
     119             :  * @base: The number base to use
     120             :  *
     121             :  * This function has caveats. Please use kstrtol instead.
     122             :  */
     123         146 : long simple_strtol(const char *cp, char **endp, unsigned int base)
     124             : {
     125         146 :         if (*cp == '-')
     126           2 :                 return -simple_strtoul(cp + 1, endp, base);
     127             : 
     128         145 :         return simple_strtoul(cp, endp, base);
     129             : }
     130             : EXPORT_SYMBOL(simple_strtol);
     131             : 
     132           0 : static long long simple_strntoll(const char *cp, size_t max_chars, char **endp,
     133             :                                  unsigned int base)
     134             : {
     135             :         /*
     136             :          * simple_strntoull() safely handles receiving max_chars==0 in the
     137             :          * case cp[0] == '-' && max_chars == 1.
     138             :          * If max_chars == 0 we can drop through and pass it to simple_strntoull()
     139             :          * and the content of *cp is irrelevant.
     140             :          */
     141           0 :         if (*cp == '-' && max_chars > 0)
     142           0 :                 return -simple_strntoull(cp + 1, max_chars - 1, endp, base);
     143             : 
     144           0 :         return simple_strntoull(cp, max_chars, endp, base);
     145             : }
     146             : 
     147             : /**
     148             :  * simple_strtoll - convert a string to a signed long long
     149             :  * @cp: The start of the string
     150             :  * @endp: A pointer to the end of the parsed string will be placed here
     151             :  * @base: The number base to use
     152             :  *
     153             :  * This function has caveats. Please use kstrtoll instead.
     154             :  */
     155           0 : long long simple_strtoll(const char *cp, char **endp, unsigned int base)
     156             : {
     157           0 :         return simple_strntoll(cp, INT_MAX, endp, base);
     158             : }
     159             : EXPORT_SYMBOL(simple_strtoll);
     160             : 
     161             : static noinline_for_stack
     162         431 : int skip_atoi(const char **s)
     163             : {
     164         431 :         int i = 0;
     165             : 
     166             :         do {
     167         463 :                 i = i*10 + *((*s)++) - '0';
     168         926 :         } while (isdigit(**s));
     169             : 
     170         431 :         return i;
     171             : }
     172             : 
     173             : /*
     174             :  * Decimal conversion is by far the most typical, and is used for
     175             :  * /proc and /sys data. This directly impacts e.g. top performance
     176             :  * with many processes running. We optimize it for speed by emitting
     177             :  * two characters at a time, using a 200 byte lookup table. This
     178             :  * roughly halves the number of multiplications compared to computing
     179             :  * the digits one at a time. Implementation strongly inspired by the
     180             :  * previous version, which in turn used ideas described at
     181             :  * <http://www.cs.uiowa.edu/~jones/bcd/divide.html> (with permission
     182             :  * from the author, Douglas W. Jones).
     183             :  *
     184             :  * It turns out there is precisely one 26 bit fixed-point
     185             :  * approximation a of 64/100 for which x/100 == (x * (u64)a) >> 32
     186             :  * holds for all x in [0, 10^8-1], namely a = 0x28f5c29. The actual
     187             :  * range happens to be somewhat larger (x <= 1073741898), but that's
     188             :  * irrelevant for our purpose.
     189             :  *
     190             :  * For dividing a number in the range [10^4, 10^6-1] by 100, we still
     191             :  * need a 32x32->64 bit multiply, so we simply use the same constant.
     192             :  *
     193             :  * For dividing a number in the range [100, 10^4-1] by 100, there are
     194             :  * several options. The simplest is (x * 0x147b) >> 19, which is valid
     195             :  * for all x <= 43698.
     196             :  */
     197             : 
     198             : static const u16 decpair[100] = {
     199             : #define _(x) (__force u16) cpu_to_le16(((x % 10) | ((x / 10) << 8)) + 0x3030)
     200             :         _( 0), _( 1), _( 2), _( 3), _( 4), _( 5), _( 6), _( 7), _( 8), _( 9),
     201             :         _(10), _(11), _(12), _(13), _(14), _(15), _(16), _(17), _(18), _(19),
     202             :         _(20), _(21), _(22), _(23), _(24), _(25), _(26), _(27), _(28), _(29),
     203             :         _(30), _(31), _(32), _(33), _(34), _(35), _(36), _(37), _(38), _(39),
     204             :         _(40), _(41), _(42), _(43), _(44), _(45), _(46), _(47), _(48), _(49),
     205             :         _(50), _(51), _(52), _(53), _(54), _(55), _(56), _(57), _(58), _(59),
     206             :         _(60), _(61), _(62), _(63), _(64), _(65), _(66), _(67), _(68), _(69),
     207             :         _(70), _(71), _(72), _(73), _(74), _(75), _(76), _(77), _(78), _(79),
     208             :         _(80), _(81), _(82), _(83), _(84), _(85), _(86), _(87), _(88), _(89),
     209             :         _(90), _(91), _(92), _(93), _(94), _(95), _(96), _(97), _(98), _(99),
     210             : #undef _
     211             : };
     212             : 
     213             : /*
     214             :  * This will print a single '0' even if r == 0, since we would
     215             :  * immediately jump to out_r where two 0s would be written but only
     216             :  * one of them accounted for in buf. This is needed by ip4_string
     217             :  * below. All other callers pass a non-zero value of r.
     218             : */
     219             : static noinline_for_stack
     220        2422 : char *put_dec_trunc8(char *buf, unsigned r)
     221             : {
     222             :         unsigned q;
     223             : 
     224             :         /* 1 <= r < 10^8 */
     225        2422 :         if (r < 100)
     226             :                 goto out_r;
     227             : 
     228             :         /* 100 <= r < 10^8 */
     229        1485 :         q = (r * (u64)0x28f5c29) >> 32;
     230        1485 :         *((u16 *)buf) = decpair[r - 100*q];
     231        1485 :         buf += 2;
     232             : 
     233             :         /* 1 <= q < 10^6 */
     234        1485 :         if (q < 100)
     235             :                 goto out_q;
     236             : 
     237             :         /*  100 <= q < 10^6 */
     238          52 :         r = (q * (u64)0x28f5c29) >> 32;
     239          52 :         *((u16 *)buf) = decpair[q - 100*r];
     240          52 :         buf += 2;
     241             : 
     242             :         /* 1 <= r < 10^4 */
     243          52 :         if (r < 100)
     244             :                 goto out_r;
     245             : 
     246             :         /* 100 <= r < 10^4 */
     247          18 :         q = (r * 0x147b) >> 19;
     248          18 :         *((u16 *)buf) = decpair[r - 100*q];
     249          18 :         buf += 2;
     250             : out_q:
     251             :         /* 1 <= q < 100 */
     252             :         r = q;
     253             : out_r:
     254             :         /* 1 <= r < 100 */
     255        2422 :         *((u16 *)buf) = decpair[r];
     256        2422 :         buf += r < 10 ? 1 : 2;
     257        2422 :         return buf;
     258             : }
     259             : 
     260             : #if BITS_PER_LONG == 64 && BITS_PER_LONG_LONG == 64
     261             : static noinline_for_stack
     262           6 : char *put_dec_full8(char *buf, unsigned r)
     263             : {
     264             :         unsigned q;
     265             : 
     266             :         /* 0 <= r < 10^8 */
     267           6 :         q = (r * (u64)0x28f5c29) >> 32;
     268           6 :         *((u16 *)buf) = decpair[r - 100*q];
     269           6 :         buf += 2;
     270             : 
     271             :         /* 0 <= q < 10^6 */
     272           6 :         r = (q * (u64)0x28f5c29) >> 32;
     273           6 :         *((u16 *)buf) = decpair[q - 100*r];
     274           6 :         buf += 2;
     275             : 
     276             :         /* 0 <= r < 10^4 */
     277           6 :         q = (r * 0x147b) >> 19;
     278           6 :         *((u16 *)buf) = decpair[r - 100*q];
     279           6 :         buf += 2;
     280             : 
     281             :         /* 0 <= q < 100 */
     282           6 :         *((u16 *)buf) = decpair[q];
     283           6 :         buf += 2;
     284           6 :         return buf;
     285             : }
     286             : 
     287             : static noinline_for_stack
     288        2422 : char *put_dec(char *buf, unsigned long long n)
     289             : {
     290        2422 :         if (n >= 100*1000*1000)
     291           4 :                 buf = put_dec_full8(buf, do_div(n, 100*1000*1000));
     292             :         /* 1 <= n <= 1.6e11 */
     293        2422 :         if (n >= 100*1000*1000)
     294           2 :                 buf = put_dec_full8(buf, do_div(n, 100*1000*1000));
     295             :         /* 1 <= n < 1e8 */
     296        2422 :         return put_dec_trunc8(buf, n);
     297             : }
     298             : 
     299             : #elif BITS_PER_LONG == 32 && BITS_PER_LONG_LONG == 64
     300             : 
     301             : static void
     302             : put_dec_full4(char *buf, unsigned r)
     303             : {
     304             :         unsigned q;
     305             : 
     306             :         /* 0 <= r < 10^4 */
     307             :         q = (r * 0x147b) >> 19;
     308             :         *((u16 *)buf) = decpair[r - 100*q];
     309             :         buf += 2;
     310             :         /* 0 <= q < 100 */
     311             :         *((u16 *)buf) = decpair[q];
     312             : }
     313             : 
     314             : /*
     315             :  * Call put_dec_full4 on x % 10000, return x / 10000.
     316             :  * The approximation x/10000 == (x * 0x346DC5D7) >> 43
     317             :  * holds for all x < 1,128,869,999.  The largest value this
     318             :  * helper will ever be asked to convert is 1,125,520,955.
     319             :  * (second call in the put_dec code, assuming n is all-ones).
     320             :  */
     321             : static noinline_for_stack
     322             : unsigned put_dec_helper4(char *buf, unsigned x)
     323             : {
     324             :         uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43;
     325             : 
     326             :         put_dec_full4(buf, x - q * 10000);
     327             :         return q;
     328             : }
     329             : 
     330             : /* Based on code by Douglas W. Jones found at
     331             :  * <http://www.cs.uiowa.edu/~jones/bcd/decimal.html#sixtyfour>
     332             :  * (with permission from the author).
     333             :  * Performs no 64-bit division and hence should be fast on 32-bit machines.
     334             :  */
     335             : static
     336             : char *put_dec(char *buf, unsigned long long n)
     337             : {
     338             :         uint32_t d3, d2, d1, q, h;
     339             : 
     340             :         if (n < 100*1000*1000)
     341             :                 return put_dec_trunc8(buf, n);
     342             : 
     343             :         d1  = ((uint32_t)n >> 16); /* implicit "& 0xffff" */
     344             :         h   = (n >> 32);
     345             :         d2  = (h      ) & 0xffff;
     346             :         d3  = (h >> 16); /* implicit "& 0xffff" */
     347             : 
     348             :         /* n = 2^48 d3 + 2^32 d2 + 2^16 d1 + d0
     349             :              = 281_4749_7671_0656 d3 + 42_9496_7296 d2 + 6_5536 d1 + d0 */
     350             :         q   = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff);
     351             :         q = put_dec_helper4(buf, q);
     352             : 
     353             :         q += 7671 * d3 + 9496 * d2 + 6 * d1;
     354             :         q = put_dec_helper4(buf+4, q);
     355             : 
     356             :         q += 4749 * d3 + 42 * d2;
     357             :         q = put_dec_helper4(buf+8, q);
     358             : 
     359             :         q += 281 * d3;
     360             :         buf += 12;
     361             :         if (q)
     362             :                 buf = put_dec_trunc8(buf, q);
     363             :         else while (buf[-1] == '0')
     364             :                 --buf;
     365             : 
     366             :         return buf;
     367             : }
     368             : 
     369             : #endif
     370             : 
     371             : /*
     372             :  * Convert passed number to decimal string.
     373             :  * Returns the length of string.  On buffer overflow, returns 0.
     374             :  *
     375             :  * If speed is not important, use snprintf(). It's easy to read the code.
     376             :  */
     377           0 : int num_to_str(char *buf, int size, unsigned long long num, unsigned int width)
     378             : {
     379             :         /* put_dec requires 2-byte alignment of the buffer. */
     380             :         char tmp[sizeof(num) * 3] __aligned(2);
     381             :         int idx, len;
     382             : 
     383             :         /* put_dec() may work incorrectly for num = 0 (generate "", not "0") */
     384           0 :         if (num <= 9) {
     385           0 :                 tmp[0] = '0' + num;
     386           0 :                 len = 1;
     387             :         } else {
     388           0 :                 len = put_dec(tmp, num) - tmp;
     389             :         }
     390             : 
     391           0 :         if (len > size || width > size)
     392             :                 return 0;
     393             : 
     394           0 :         if (width > len) {
     395           0 :                 width = width - len;
     396           0 :                 for (idx = 0; idx < width; idx++)
     397           0 :                         buf[idx] = ' ';
     398             :         } else {
     399             :                 width = 0;
     400             :         }
     401             : 
     402           0 :         for (idx = 0; idx < len; ++idx)
     403           0 :                 buf[idx + width] = tmp[len - idx - 1];
     404             : 
     405           0 :         return len + width;
     406             : }
     407             : 
     408             : #define SIGN    1               /* unsigned/signed, must be 1 */
     409             : #define LEFT    2               /* left justified */
     410             : #define PLUS    4               /* show plus */
     411             : #define SPACE   8               /* space if plus */
     412             : #define ZEROPAD 16              /* pad with zero, must be 16 == '0' - ' ' */
     413             : #define SMALL   32              /* use lowercase in hex (must be 32 == 0x20) */
     414             : #define SPECIAL 64              /* prefix hex with "0x", octal with "0" */
     415             : 
     416             : static_assert(SIGN == 1);
     417             : static_assert(ZEROPAD == ('0' - ' '));
     418             : static_assert(SMALL == ('a' ^ 'A'));
     419             : 
     420             : enum format_type {
     421             :         FORMAT_TYPE_NONE, /* Just a string part */
     422             :         FORMAT_TYPE_WIDTH,
     423             :         FORMAT_TYPE_PRECISION,
     424             :         FORMAT_TYPE_CHAR,
     425             :         FORMAT_TYPE_STR,
     426             :         FORMAT_TYPE_PTR,
     427             :         FORMAT_TYPE_PERCENT_CHAR,
     428             :         FORMAT_TYPE_INVALID,
     429             :         FORMAT_TYPE_LONG_LONG,
     430             :         FORMAT_TYPE_ULONG,
     431             :         FORMAT_TYPE_LONG,
     432             :         FORMAT_TYPE_UBYTE,
     433             :         FORMAT_TYPE_BYTE,
     434             :         FORMAT_TYPE_USHORT,
     435             :         FORMAT_TYPE_SHORT,
     436             :         FORMAT_TYPE_UINT,
     437             :         FORMAT_TYPE_INT,
     438             :         FORMAT_TYPE_SIZE_T,
     439             :         FORMAT_TYPE_PTRDIFF
     440             : };
     441             : 
     442             : struct printf_spec {
     443             :         unsigned int    type:8;         /* format_type enum */
     444             :         signed int      field_width:24; /* width of output field */
     445             :         unsigned int    flags:8;        /* flags to number() */
     446             :         unsigned int    base:8;         /* number base, 8, 10 or 16 only */
     447             :         signed int      precision:16;   /* # of digits/chars */
     448             : } __packed;
     449             : static_assert(sizeof(struct printf_spec) == 8);
     450             : 
     451             : #define FIELD_WIDTH_MAX ((1 << 23) - 1)
     452             : #define PRECISION_MAX ((1 << 15) - 1)
     453             : 
     454             : static noinline_for_stack
     455        6011 : char *number(char *buf, char *end, unsigned long long num,
     456             :              struct printf_spec spec)
     457             : {
     458             :         /* put_dec requires 2-byte alignment of the buffer. */
     459             :         char tmp[3 * sizeof(num)] __aligned(2);
     460             :         char sign;
     461             :         char locase;
     462        6011 :         int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
     463             :         int i;
     464        6011 :         bool is_zero = num == 0LL;
     465        6011 :         int field_width = spec.field_width;
     466        6011 :         int precision = spec.precision;
     467             : 
     468             :         /* locase = 0 or 0x20. ORing digits or letters with 'locase'
     469             :          * produces same digits or (maybe lowercased) letters */
     470        6011 :         locase = (spec.flags & SMALL);
     471        6011 :         if (spec.flags & LEFT)
     472           0 :                 spec.flags &= ~ZEROPAD;
     473        6011 :         sign = 0;
     474        6011 :         if (spec.flags & SIGN) {
     475        1250 :                 if ((signed long long)num < 0) {
     476           6 :                         sign = '-';
     477           6 :                         num = -(signed long long)num;
     478           6 :                         field_width--;
     479        1244 :                 } else if (spec.flags & PLUS) {
     480          48 :                         sign = '+';
     481          48 :                         field_width--;
     482        1196 :                 } else if (spec.flags & SPACE) {
     483           0 :                         sign = ' ';
     484           0 :                         field_width--;
     485             :                 }
     486             :         }
     487        6011 :         if (need_pfx) {
     488         504 :                 if (spec.base == 16)
     489         496 :                         field_width -= 2;
     490           8 :                 else if (!is_zero)
     491           8 :                         field_width--;
     492             :         }
     493             : 
     494             :         /* generate full string in tmp[], in reverse order */
     495        6011 :         i = 0;
     496        6011 :         if (num < spec.base)
     497        2833 :                 tmp[i++] = hex_asc_upper[num] | locase;
     498        3178 :         else if (spec.base != 10) { /* 8 or 16 */
     499         756 :                 int mask = spec.base - 1;
     500         756 :                 int shift = 3;
     501             : 
     502         756 :                 if (spec.base == 16)
     503         748 :                         shift = 4;
     504             :                 do {
     505        3828 :                         tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] | locase);
     506        3828 :                         num >>= shift;
     507        3828 :                 } while (num);
     508             :         } else { /* base 10 */
     509        2422 :                 i = put_dec(tmp, num) - tmp;
     510             :         }
     511             : 
     512             :         /* printing 100 using %2d gives "100", not "00" */
     513        6011 :         if (i > precision)
     514        6011 :                 precision = i;
     515             :         /* leading space padding */
     516        6011 :         field_width -= precision;
     517        6011 :         if (!(spec.flags & (ZEROPAD | LEFT))) {
     518        5594 :                 while (--field_width >= 0) {
     519           4 :                         if (buf < end)
     520           2 :                                 *buf = ' ';
     521           4 :                         ++buf;
     522             :                 }
     523             :         }
     524             :         /* sign */
     525        6011 :         if (sign) {
     526          54 :                 if (buf < end)
     527          53 :                         *buf = sign;
     528          54 :                 ++buf;
     529             :         }
     530             :         /* "0x" / "0" prefix */
     531        6011 :         if (need_pfx) {
     532         504 :                 if (spec.base == 16 || !is_zero) {
     533         504 :                         if (buf < end)
     534         499 :                                 *buf = '0';
     535         504 :                         ++buf;
     536             :                 }
     537         504 :                 if (spec.base == 16) {
     538         496 :                         if (buf < end)
     539         490 :                                 *buf = ('X' | locase);
     540         496 :                         ++buf;
     541             :                 }
     542             :         }
     543             :         /* zero or space padding */
     544        6011 :         if (!(spec.flags & LEFT)) {
     545        6011 :                 char c = ' ' + (spec.flags & ZEROPAD);
     546             : 
     547       12607 :                 while (--field_width >= 0) {
     548         585 :                         if (buf < end)
     549         423 :                                 *buf = c;
     550         585 :                         ++buf;
     551             :                 }
     552             :         }
     553             :         /* hmm even more zero padding? */
     554        6011 :         while (i <= --precision) {
     555           0 :                 if (buf < end)
     556           0 :                         *buf = '0';
     557           0 :                 ++buf;
     558             :         }
     559             :         /* actual digits of result */
     560       19231 :         while (--i >= 0) {
     561       13220 :                 if (buf < end)
     562       11519 :                         *buf = tmp[i];
     563       13220 :                 ++buf;
     564             :         }
     565             :         /* trailing space padding */
     566        6011 :         while (--field_width >= 0) {
     567           0 :                 if (buf < end)
     568           0 :                         *buf = ' ';
     569           0 :                 ++buf;
     570             :         }
     571             : 
     572        6011 :         return buf;
     573             : }
     574             : 
     575             : static noinline_for_stack
     576           0 : char *special_hex_number(char *buf, char *end, unsigned long long num, int size)
     577             : {
     578             :         struct printf_spec spec;
     579             : 
     580           0 :         spec.type = FORMAT_TYPE_PTR;
     581           0 :         spec.field_width = 2 + 2 * size;        /* 0x + hex */
     582           0 :         spec.flags = SPECIAL | SMALL | ZEROPAD;
     583           0 :         spec.base = 16;
     584           0 :         spec.precision = -1;
     585             : 
     586           0 :         return number(buf, end, num, spec);
     587             : }
     588             : 
     589           0 : static void move_right(char *buf, char *end, unsigned len, unsigned spaces)
     590             : {
     591             :         size_t size;
     592           0 :         if (buf >= end)      /* nowhere to put anything */
     593             :                 return;
     594           0 :         size = end - buf;
     595           0 :         if (size <= spaces) {
     596           0 :                 memset(buf, ' ', size);
     597           0 :                 return;
     598             :         }
     599           0 :         if (len) {
     600           0 :                 if (len > size - spaces)
     601           0 :                         len = size - spaces;
     602           0 :                 memmove(buf + spaces, buf, len);
     603             :         }
     604           0 :         memset(buf, ' ', spaces);
     605             : }
     606             : 
     607             : /*
     608             :  * Handle field width padding for a string.
     609             :  * @buf: current buffer position
     610             :  * @n: length of string
     611             :  * @end: end of output buffer
     612             :  * @spec: for field width and flags
     613             :  * Returns: new buffer position after padding.
     614             :  */
     615             : static noinline_for_stack
     616        6714 : char *widen_string(char *buf, int n, char *end, struct printf_spec spec)
     617             : {
     618             :         unsigned spaces;
     619             : 
     620        6714 :         if (likely(n >= spec.field_width))
     621             :                 return buf;
     622             :         /* we want to pad the sucker */
     623           2 :         spaces = spec.field_width - n;
     624           2 :         if (!(spec.flags & LEFT)) {
     625           0 :                 move_right(buf - n, end, n, spaces);
     626           0 :                 return buf + spaces;
     627             :         }
     628           6 :         while (spaces--) {
     629           4 :                 if (buf < end)
     630           2 :                         *buf = ' ';
     631           4 :                 ++buf;
     632             :         }
     633             :         return buf;
     634             : }
     635             : 
     636             : /* Handle string from a well known address. */
     637        6714 : static char *string_nocheck(char *buf, char *end, const char *s,
     638             :                             struct printf_spec spec)
     639             : {
     640        6714 :         int len = 0;
     641        6714 :         int lim = spec.precision;
     642             : 
     643       82175 :         while (lim--) {
     644       75451 :                 char c = *s++;
     645       75451 :                 if (!c)
     646             :                         break;
     647       68747 :                 if (buf < end)
     648       51852 :                         *buf = c;
     649       68747 :                 ++buf;
     650       68747 :                 ++len;
     651             :         }
     652        6714 :         return widen_string(buf, len, end, spec);
     653             : }
     654             : 
     655           0 : static char *err_ptr(char *buf, char *end, void *ptr,
     656             :                      struct printf_spec spec)
     657             : {
     658           0 :         int err = PTR_ERR(ptr);
     659           0 :         const char *sym = errname(err);
     660             : 
     661           0 :         if (sym)
     662           0 :                 return string_nocheck(buf, end, sym, spec);
     663             : 
     664             :         /*
     665             :          * Somebody passed ERR_PTR(-1234) or some other non-existing
     666             :          * Efoo - or perhaps CONFIG_SYMBOLIC_ERRNAME=n. Fall back to
     667             :          * printing it as its decimal representation.
     668             :          */
     669           0 :         spec.flags |= SIGN;
     670           0 :         spec.base = 10;
     671           0 :         return number(buf, end, err, spec);
     672             : }
     673             : 
     674             : /* Be careful: error messages must fit into the given buffer. */
     675             : static char *error_string(char *buf, char *end, const char *s,
     676             :                           struct printf_spec spec)
     677             : {
     678             :         /*
     679             :          * Hard limit to avoid a completely insane messages. It actually
     680             :          * works pretty well because most error messages are in
     681             :          * the many pointer format modifiers.
     682             :          */
     683           4 :         if (spec.precision == -1)
     684           4 :                 spec.precision = 2 * sizeof(void *);
     685             : 
     686           4 :         return string_nocheck(buf, end, s, spec);
     687             : }
     688             : 
     689             : /*
     690             :  * Do not call any complex external code here. Nested printk()/vsprintf()
     691             :  * might cause infinite loops. Failures might break printk() and would
     692             :  * be hard to debug.
     693             :  */
     694             : static const char *check_pointer_msg(const void *ptr)
     695             : {
     696        6472 :         if (!ptr)
     697             :                 return "(null)";
     698             : 
     699        6468 :         if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr))
     700             :                 return "(efault)";
     701             : 
     702             :         return NULL;
     703             : }
     704             : 
     705        6472 : static int check_pointer(char **buf, char *end, const void *ptr,
     706             :                          struct printf_spec spec)
     707             : {
     708             :         const char *err_msg;
     709             : 
     710        6472 :         err_msg = check_pointer_msg(ptr);
     711        6472 :         if (err_msg) {
     712           8 :                 *buf = error_string(*buf, end, err_msg, spec);
     713           4 :                 return -EFAULT;
     714             :         }
     715             : 
     716             :         return 0;
     717             : }
     718             : 
     719             : static noinline_for_stack
     720        6472 : char *string(char *buf, char *end, const char *s,
     721             :              struct printf_spec spec)
     722             : {
     723        6472 :         if (check_pointer(&buf, end, s, spec))
     724           4 :                 return buf;
     725             : 
     726        6468 :         return string_nocheck(buf, end, s, spec);
     727             : }
     728             : 
     729             : static char *pointer_string(char *buf, char *end,
     730             :                             const void *ptr,
     731             :                             struct printf_spec spec)
     732             : {
     733           0 :         spec.base = 16;
     734           0 :         spec.flags |= SMALL;
     735           0 :         if (spec.field_width == -1) {
     736           0 :                 spec.field_width = 2 * sizeof(ptr);
     737           0 :                 spec.flags |= ZEROPAD;
     738             :         }
     739             : 
     740           0 :         return number(buf, end, (unsigned long int)ptr, spec);
     741             : }
     742             : 
     743             : /* Make pointers available for printing early in the boot sequence. */
     744             : static int debug_boot_weak_hash __ro_after_init;
     745             : 
     746           0 : static int __init debug_boot_weak_hash_enable(char *str)
     747             : {
     748           0 :         debug_boot_weak_hash = 1;
     749           0 :         pr_info("debug_boot_weak_hash enabled\n");
     750           0 :         return 0;
     751             : }
     752             : early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable);
     753             : 
     754             : static bool filled_random_ptr_key __read_mostly;
     755             : static siphash_key_t ptr_key __read_mostly;
     756             : 
     757           1 : static int fill_ptr_key(struct notifier_block *nb, unsigned long action, void *data)
     758             : {
     759           1 :         get_random_bytes(&ptr_key, sizeof(ptr_key));
     760             : 
     761             :         /* Pairs with smp_rmb() before reading ptr_key. */
     762           1 :         smp_wmb();
     763           1 :         WRITE_ONCE(filled_random_ptr_key, true);
     764           1 :         return NOTIFY_DONE;
     765             : }
     766             : 
     767           1 : static int __init vsprintf_init_hashval(void)
     768             : {
     769             :         static struct notifier_block fill_ptr_key_nb = { .notifier_call = fill_ptr_key };
     770           1 :         execute_with_initialized_rng(&fill_ptr_key_nb);
     771           1 :         return 0;
     772             : }
     773             : subsys_initcall(vsprintf_init_hashval)
     774             : 
     775             : /* Maps a pointer to a 32 bit unique identifier. */
     776             : static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
     777             : {
     778             :         unsigned long hashval;
     779             : 
     780           0 :         if (!READ_ONCE(filled_random_ptr_key))
     781             :                 return -EBUSY;
     782             : 
     783             :         /* Pairs with smp_wmb() after writing ptr_key. */
     784           0 :         smp_rmb();
     785             : 
     786             : #ifdef CONFIG_64BIT
     787           0 :         hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key);
     788             :         /*
     789             :          * Mask off the first 32 bits, this makes explicit that we have
     790             :          * modified the address (and 32 bits is plenty for a unique ID).
     791             :          */
     792           0 :         hashval = hashval & 0xffffffff;
     793             : #else
     794             :         hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key);
     795             : #endif
     796           0 :         *hashval_out = hashval;
     797             :         return 0;
     798             : }
     799             : 
     800           0 : int ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
     801             : {
     802           0 :         return __ptr_to_hashval(ptr, hashval_out);
     803             : }
     804             : 
     805           0 : static char *ptr_to_id(char *buf, char *end, const void *ptr,
     806             :                        struct printf_spec spec)
     807             : {
     808           0 :         const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)";
     809             :         unsigned long hashval;
     810             :         int ret;
     811             : 
     812             :         /*
     813             :          * Print the real pointer value for NULL and error pointers,
     814             :          * as they are not actual addresses.
     815             :          */
     816           0 :         if (IS_ERR_OR_NULL(ptr))
     817           0 :                 return pointer_string(buf, end, ptr, spec);
     818             : 
     819             :         /* When debugging early boot use non-cryptographically secure hash. */
     820           0 :         if (unlikely(debug_boot_weak_hash)) {
     821           0 :                 hashval = hash_long((unsigned long)ptr, 32);
     822           0 :                 return pointer_string(buf, end, (const void *)hashval, spec);
     823             :         }
     824             : 
     825           0 :         ret = __ptr_to_hashval(ptr, &hashval);
     826           0 :         if (ret) {
     827           0 :                 spec.field_width = 2 * sizeof(ptr);
     828             :                 /* string length must be less than default_width */
     829           0 :                 return error_string(buf, end, str, spec);
     830             :         }
     831             : 
     832           0 :         return pointer_string(buf, end, (const void *)hashval, spec);
     833             : }
     834             : 
     835           0 : static char *default_pointer(char *buf, char *end, const void *ptr,
     836             :                              struct printf_spec spec)
     837             : {
     838             :         /*
     839             :          * default is to _not_ leak addresses, so hash before printing,
     840             :          * unless no_hash_pointers is specified on the command line.
     841             :          */
     842           0 :         if (unlikely(no_hash_pointers))
     843           0 :                 return pointer_string(buf, end, ptr, spec);
     844             : 
     845           0 :         return ptr_to_id(buf, end, ptr, spec);
     846             : }
     847             : 
     848             : int kptr_restrict __read_mostly;
     849             : 
     850             : static noinline_for_stack
     851           0 : char *restricted_pointer(char *buf, char *end, const void *ptr,
     852             :                          struct printf_spec spec)
     853             : {
     854           0 :         switch (kptr_restrict) {
     855             :         case 0:
     856             :                 /* Handle as %p, hash and do _not_ leak addresses. */
     857           0 :                 return default_pointer(buf, end, ptr, spec);
     858             :         case 1: {
     859             :                 const struct cred *cred;
     860             : 
     861             :                 /*
     862             :                  * kptr_restrict==1 cannot be used in IRQ context
     863             :                  * because its test for CAP_SYSLOG would be meaningless.
     864             :                  */
     865           0 :                 if (in_hardirq() || in_serving_softirq() || in_nmi()) {
     866           0 :                         if (spec.field_width == -1)
     867           0 :                                 spec.field_width = 2 * sizeof(ptr);
     868           0 :                         return error_string(buf, end, "pK-error", spec);
     869             :                 }
     870             : 
     871             :                 /*
     872             :                  * Only print the real pointer value if the current
     873             :                  * process has CAP_SYSLOG and is running with the
     874             :                  * same credentials it started with. This is because
     875             :                  * access to files is checked at open() time, but %pK
     876             :                  * checks permission at read() time. We don't want to
     877             :                  * leak pointer values if a binary opens a file using
     878             :                  * %pK and then elevates privileges before reading it.
     879             :                  */
     880           0 :                 cred = current_cred();
     881           0 :                 if (!has_capability_noaudit(current, CAP_SYSLOG) ||
     882           0 :                     !uid_eq(cred->euid, cred->uid) ||
     883           0 :                     !gid_eq(cred->egid, cred->gid))
     884             :                         ptr = NULL;
     885             :                 break;
     886             :         }
     887             :         case 2:
     888             :         default:
     889             :                 /* Always print 0's for %pK */
     890             :                 ptr = NULL;
     891             :                 break;
     892             :         }
     893             : 
     894           0 :         return pointer_string(buf, end, ptr, spec);
     895             : }
     896             : 
     897             : static noinline_for_stack
     898           0 : char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_spec spec,
     899             :                   const char *fmt)
     900             : {
     901             :         const char *array[4], *s;
     902             :         const struct dentry *p;
     903             :         int depth;
     904             :         int i, n;
     905             : 
     906           0 :         switch (fmt[1]) {
     907             :                 case '2': case '3': case '4':
     908           0 :                         depth = fmt[1] - '0';
     909           0 :                         break;
     910             :                 default:
     911             :                         depth = 1;
     912             :         }
     913             : 
     914             :         rcu_read_lock();
     915           0 :         for (i = 0; i < depth; i++, d = p) {
     916           0 :                 if (check_pointer(&buf, end, d, spec)) {
     917             :                         rcu_read_unlock();
     918           0 :                         return buf;
     919             :                 }
     920             : 
     921           0 :                 p = READ_ONCE(d->d_parent);
     922           0 :                 array[i] = READ_ONCE(d->d_name.name);
     923           0 :                 if (p == d) {
     924           0 :                         if (i)
     925           0 :                                 array[i] = "";
     926           0 :                         i++;
     927           0 :                         break;
     928             :                 }
     929             :         }
     930           0 :         s = array[--i];
     931           0 :         for (n = 0; n != spec.precision; n++, buf++) {
     932           0 :                 char c = *s++;
     933           0 :                 if (!c) {
     934           0 :                         if (!i)
     935             :                                 break;
     936           0 :                         c = '/';
     937           0 :                         s = array[--i];
     938             :                 }
     939           0 :                 if (buf < end)
     940           0 :                         *buf = c;
     941             :         }
     942             :         rcu_read_unlock();
     943           0 :         return widen_string(buf, n, end, spec);
     944             : }
     945             : 
     946             : static noinline_for_stack
     947           0 : char *file_dentry_name(char *buf, char *end, const struct file *f,
     948             :                         struct printf_spec spec, const char *fmt)
     949             : {
     950           0 :         if (check_pointer(&buf, end, f, spec))
     951           0 :                 return buf;
     952             : 
     953           0 :         return dentry_name(buf, end, f->f_path.dentry, spec, fmt);
     954             : }
     955             : #ifdef CONFIG_BLOCK
     956             : static noinline_for_stack
     957           0 : char *bdev_name(char *buf, char *end, struct block_device *bdev,
     958             :                 struct printf_spec spec, const char *fmt)
     959             : {
     960             :         struct gendisk *hd;
     961             : 
     962           0 :         if (check_pointer(&buf, end, bdev, spec))
     963           0 :                 return buf;
     964             : 
     965           0 :         hd = bdev->bd_disk;
     966           0 :         buf = string(buf, end, hd->disk_name, spec);
     967           0 :         if (bdev->bd_partno) {
     968           0 :                 if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) {
     969           0 :                         if (buf < end)
     970           0 :                                 *buf = 'p';
     971           0 :                         buf++;
     972             :                 }
     973           0 :                 buf = number(buf, end, bdev->bd_partno, spec);
     974             :         }
     975           0 :         return buf;
     976             : }
     977             : #endif
     978             : 
     979             : static noinline_for_stack
     980         242 : char *symbol_string(char *buf, char *end, void *ptr,
     981             :                     struct printf_spec spec, const char *fmt)
     982             : {
     983             :         unsigned long value;
     984             : #ifdef CONFIG_KALLSYMS
     985             :         char sym[KSYM_SYMBOL_LEN];
     986             : #endif
     987             : 
     988         242 :         if (fmt[1] == 'R')
     989           0 :                 ptr = __builtin_extract_return_addr(ptr);
     990         242 :         value = (unsigned long)ptr;
     991             : 
     992             : #ifdef CONFIG_KALLSYMS
     993         242 :         if (*fmt == 'B' && fmt[1] == 'b')
     994           0 :                 sprint_backtrace_build_id(sym, value);
     995         242 :         else if (*fmt == 'B')
     996           0 :                 sprint_backtrace(sym, value);
     997         242 :         else if (*fmt == 'S' && (fmt[1] == 'b' || (fmt[1] == 'R' && fmt[2] == 'b')))
     998           0 :                 sprint_symbol_build_id(sym, value);
     999         242 :         else if (*fmt != 's')
    1000         242 :                 sprint_symbol(sym, value);
    1001             :         else
    1002           0 :                 sprint_symbol_no_offset(sym, value);
    1003             : 
    1004         242 :         return string_nocheck(buf, end, sym, spec);
    1005             : #else
    1006             :         return special_hex_number(buf, end, value, sizeof(void *));
    1007             : #endif
    1008             : }
    1009             : 
    1010             : static const struct printf_spec default_str_spec = {
    1011             :         .field_width = -1,
    1012             :         .precision = -1,
    1013             : };
    1014             : 
    1015             : static const struct printf_spec default_flag_spec = {
    1016             :         .base = 16,
    1017             :         .precision = -1,
    1018             :         .flags = SPECIAL | SMALL,
    1019             : };
    1020             : 
    1021             : static const struct printf_spec default_dec_spec = {
    1022             :         .base = 10,
    1023             :         .precision = -1,
    1024             : };
    1025             : 
    1026             : static const struct printf_spec default_dec02_spec = {
    1027             :         .base = 10,
    1028             :         .field_width = 2,
    1029             :         .precision = -1,
    1030             :         .flags = ZEROPAD,
    1031             : };
    1032             : 
    1033             : static const struct printf_spec default_dec04_spec = {
    1034             :         .base = 10,
    1035             :         .field_width = 4,
    1036             :         .precision = -1,
    1037             :         .flags = ZEROPAD,
    1038             : };
    1039             : 
    1040             : static noinline_for_stack
    1041           0 : char *resource_string(char *buf, char *end, struct resource *res,
    1042             :                       struct printf_spec spec, const char *fmt)
    1043             : {
    1044             : #ifndef IO_RSRC_PRINTK_SIZE
    1045             : #define IO_RSRC_PRINTK_SIZE     6
    1046             : #endif
    1047             : 
    1048             : #ifndef MEM_RSRC_PRINTK_SIZE
    1049             : #define MEM_RSRC_PRINTK_SIZE    10
    1050             : #endif
    1051             :         static const struct printf_spec io_spec = {
    1052             :                 .base = 16,
    1053             :                 .field_width = IO_RSRC_PRINTK_SIZE,
    1054             :                 .precision = -1,
    1055             :                 .flags = SPECIAL | SMALL | ZEROPAD,
    1056             :         };
    1057             :         static const struct printf_spec mem_spec = {
    1058             :                 .base = 16,
    1059             :                 .field_width = MEM_RSRC_PRINTK_SIZE,
    1060             :                 .precision = -1,
    1061             :                 .flags = SPECIAL | SMALL | ZEROPAD,
    1062             :         };
    1063             :         static const struct printf_spec bus_spec = {
    1064             :                 .base = 16,
    1065             :                 .field_width = 2,
    1066             :                 .precision = -1,
    1067             :                 .flags = SMALL | ZEROPAD,
    1068             :         };
    1069             :         static const struct printf_spec str_spec = {
    1070             :                 .field_width = -1,
    1071             :                 .precision = 10,
    1072             :                 .flags = LEFT,
    1073             :         };
    1074             : 
    1075             :         /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
    1076             :          * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
    1077             : #define RSRC_BUF_SIZE           ((2 * sizeof(resource_size_t)) + 4)
    1078             : #define FLAG_BUF_SIZE           (2 * sizeof(res->flags))
    1079             : #define DECODED_BUF_SIZE        sizeof("[mem - 64bit pref window disabled]")
    1080             : #define RAW_BUF_SIZE            sizeof("[mem - flags 0x]")
    1081             :         char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
    1082             :                      2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
    1083             : 
    1084           0 :         char *p = sym, *pend = sym + sizeof(sym);
    1085           0 :         int decode = (fmt[0] == 'R') ? 1 : 0;
    1086             :         const struct printf_spec *specp;
    1087             : 
    1088           0 :         if (check_pointer(&buf, end, res, spec))
    1089           0 :                 return buf;
    1090             : 
    1091           0 :         *p++ = '[';
    1092           0 :         if (res->flags & IORESOURCE_IO) {
    1093           0 :                 p = string_nocheck(p, pend, "io  ", str_spec);
    1094           0 :                 specp = &io_spec;
    1095           0 :         } else if (res->flags & IORESOURCE_MEM) {
    1096           0 :                 p = string_nocheck(p, pend, "mem ", str_spec);
    1097           0 :                 specp = &mem_spec;
    1098           0 :         } else if (res->flags & IORESOURCE_IRQ) {
    1099           0 :                 p = string_nocheck(p, pend, "irq ", str_spec);
    1100           0 :                 specp = &default_dec_spec;
    1101           0 :         } else if (res->flags & IORESOURCE_DMA) {
    1102           0 :                 p = string_nocheck(p, pend, "dma ", str_spec);
    1103           0 :                 specp = &default_dec_spec;
    1104           0 :         } else if (res->flags & IORESOURCE_BUS) {
    1105           0 :                 p = string_nocheck(p, pend, "bus ", str_spec);
    1106           0 :                 specp = &bus_spec;
    1107             :         } else {
    1108           0 :                 p = string_nocheck(p, pend, "??? ", str_spec);
    1109           0 :                 specp = &mem_spec;
    1110           0 :                 decode = 0;
    1111             :         }
    1112           0 :         if (decode && res->flags & IORESOURCE_UNSET) {
    1113           0 :                 p = string_nocheck(p, pend, "size ", str_spec);
    1114           0 :                 p = number(p, pend, resource_size(res), *specp);
    1115             :         } else {
    1116           0 :                 p = number(p, pend, res->start, *specp);
    1117           0 :                 if (res->start != res->end) {
    1118           0 :                         *p++ = '-';
    1119           0 :                         p = number(p, pend, res->end, *specp);
    1120             :                 }
    1121             :         }
    1122           0 :         if (decode) {
    1123           0 :                 if (res->flags & IORESOURCE_MEM_64)
    1124           0 :                         p = string_nocheck(p, pend, " 64bit", str_spec);
    1125           0 :                 if (res->flags & IORESOURCE_PREFETCH)
    1126           0 :                         p = string_nocheck(p, pend, " pref", str_spec);
    1127           0 :                 if (res->flags & IORESOURCE_WINDOW)
    1128           0 :                         p = string_nocheck(p, pend, " window", str_spec);
    1129           0 :                 if (res->flags & IORESOURCE_DISABLED)
    1130           0 :                         p = string_nocheck(p, pend, " disabled", str_spec);
    1131             :         } else {
    1132           0 :                 p = string_nocheck(p, pend, " flags ", str_spec);
    1133           0 :                 p = number(p, pend, res->flags, default_flag_spec);
    1134             :         }
    1135           0 :         *p++ = ']';
    1136           0 :         *p = '\0';
    1137             : 
    1138           0 :         return string_nocheck(buf, end, sym, spec);
    1139             : }
    1140             : 
    1141             : static noinline_for_stack
    1142           0 : char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
    1143             :                  const char *fmt)
    1144             : {
    1145           0 :         int i, len = 1;         /* if we pass '%ph[CDN]', field width remains
    1146             :                                    negative value, fallback to the default */
    1147             :         char separator;
    1148             : 
    1149           0 :         if (spec.field_width == 0)
    1150             :                 /* nothing to print */
    1151           0 :                 return buf;
    1152             : 
    1153           0 :         if (check_pointer(&buf, end, addr, spec))
    1154           0 :                 return buf;
    1155             : 
    1156           0 :         switch (fmt[1]) {
    1157             :         case 'C':
    1158             :                 separator = ':';
    1159             :                 break;
    1160             :         case 'D':
    1161             :                 separator = '-';
    1162             :                 break;
    1163             :         case 'N':
    1164             :                 separator = 0;
    1165             :                 break;
    1166             :         default:
    1167             :                 separator = ' ';
    1168             :                 break;
    1169             :         }
    1170             : 
    1171           0 :         if (spec.field_width > 0)
    1172           0 :                 len = min_t(int, spec.field_width, 64);
    1173             : 
    1174           0 :         for (i = 0; i < len; ++i) {
    1175           0 :                 if (buf < end)
    1176           0 :                         *buf = hex_asc_hi(addr[i]);
    1177           0 :                 ++buf;
    1178           0 :                 if (buf < end)
    1179           0 :                         *buf = hex_asc_lo(addr[i]);
    1180           0 :                 ++buf;
    1181             : 
    1182           0 :                 if (separator && i != len - 1) {
    1183           0 :                         if (buf < end)
    1184           0 :                                 *buf = separator;
    1185           0 :                         ++buf;
    1186             :                 }
    1187             :         }
    1188             : 
    1189           0 :         return buf;
    1190             : }
    1191             : 
    1192             : static noinline_for_stack
    1193           0 : char *bitmap_string(char *buf, char *end, const unsigned long *bitmap,
    1194             :                     struct printf_spec spec, const char *fmt)
    1195             : {
    1196           0 :         const int CHUNKSZ = 32;
    1197           0 :         int nr_bits = max_t(int, spec.field_width, 0);
    1198             :         int i, chunksz;
    1199           0 :         bool first = true;
    1200             : 
    1201           0 :         if (check_pointer(&buf, end, bitmap, spec))
    1202           0 :                 return buf;
    1203             : 
    1204             :         /* reused to print numbers */
    1205           0 :         spec = (struct printf_spec){ .flags = SMALL | ZEROPAD, .base = 16 };
    1206             : 
    1207           0 :         chunksz = nr_bits & (CHUNKSZ - 1);
    1208           0 :         if (chunksz == 0)
    1209           0 :                 chunksz = CHUNKSZ;
    1210             : 
    1211           0 :         i = ALIGN(nr_bits, CHUNKSZ) - CHUNKSZ;
    1212           0 :         for (; i >= 0; i -= CHUNKSZ) {
    1213             :                 u32 chunkmask, val;
    1214             :                 int word, bit;
    1215             : 
    1216           0 :                 chunkmask = ((1ULL << chunksz) - 1);
    1217           0 :                 word = i / BITS_PER_LONG;
    1218           0 :                 bit = i % BITS_PER_LONG;
    1219           0 :                 val = (bitmap[word] >> bit) & chunkmask;
    1220             : 
    1221           0 :                 if (!first) {
    1222           0 :                         if (buf < end)
    1223           0 :                                 *buf = ',';
    1224           0 :                         buf++;
    1225             :                 }
    1226           0 :                 first = false;
    1227             : 
    1228           0 :                 spec.field_width = DIV_ROUND_UP(chunksz, 4);
    1229           0 :                 buf = number(buf, end, val, spec);
    1230             : 
    1231           0 :                 chunksz = CHUNKSZ;
    1232             :         }
    1233           0 :         return buf;
    1234             : }
    1235             : 
    1236             : static noinline_for_stack
    1237           0 : char *bitmap_list_string(char *buf, char *end, const unsigned long *bitmap,
    1238             :                          struct printf_spec spec, const char *fmt)
    1239             : {
    1240           0 :         int nr_bits = max_t(int, spec.field_width, 0);
    1241           0 :         bool first = true;
    1242             :         int rbot, rtop;
    1243             : 
    1244           0 :         if (check_pointer(&buf, end, bitmap, spec))
    1245           0 :                 return buf;
    1246             : 
    1247           0 :         for_each_set_bitrange(rbot, rtop, bitmap, nr_bits) {
    1248           0 :                 if (!first) {
    1249           0 :                         if (buf < end)
    1250           0 :                                 *buf = ',';
    1251           0 :                         buf++;
    1252             :                 }
    1253           0 :                 first = false;
    1254             : 
    1255           0 :                 buf = number(buf, end, rbot, default_dec_spec);
    1256           0 :                 if (rtop == rbot + 1)
    1257           0 :                         continue;
    1258             : 
    1259           0 :                 if (buf < end)
    1260           0 :                         *buf = '-';
    1261           0 :                 buf = number(++buf, end, rtop - 1, default_dec_spec);
    1262             :         }
    1263           0 :         return buf;
    1264             : }
    1265             : 
    1266             : static noinline_for_stack
    1267           0 : char *mac_address_string(char *buf, char *end, u8 *addr,
    1268             :                          struct printf_spec spec, const char *fmt)
    1269             : {
    1270             :         char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
    1271           0 :         char *p = mac_addr;
    1272             :         int i;
    1273             :         char separator;
    1274           0 :         bool reversed = false;
    1275             : 
    1276           0 :         if (check_pointer(&buf, end, addr, spec))
    1277           0 :                 return buf;
    1278             : 
    1279           0 :         switch (fmt[1]) {
    1280             :         case 'F':
    1281             :                 separator = '-';
    1282             :                 break;
    1283             : 
    1284             :         case 'R':
    1285           0 :                 reversed = true;
    1286             :                 fallthrough;
    1287             : 
    1288             :         default:
    1289             :                 separator = ':';
    1290             :                 break;
    1291             :         }
    1292             : 
    1293           0 :         for (i = 0; i < 6; i++) {
    1294           0 :                 if (reversed)
    1295           0 :                         p = hex_byte_pack(p, addr[5 - i]);
    1296             :                 else
    1297           0 :                         p = hex_byte_pack(p, addr[i]);
    1298             : 
    1299           0 :                 if (fmt[0] == 'M' && i != 5)
    1300           0 :                         *p++ = separator;
    1301             :         }
    1302           0 :         *p = '\0';
    1303             : 
    1304           0 :         return string_nocheck(buf, end, mac_addr, spec);
    1305             : }
    1306             : 
    1307             : static noinline_for_stack
    1308           0 : char *ip4_string(char *p, const u8 *addr, const char *fmt)
    1309             : {
    1310             :         int i;
    1311           0 :         bool leading_zeros = (fmt[0] == 'i');
    1312             :         int index;
    1313             :         int step;
    1314             : 
    1315           0 :         switch (fmt[2]) {
    1316             :         case 'h':
    1317             : #ifdef __BIG_ENDIAN
    1318             :                 index = 0;
    1319             :                 step = 1;
    1320             : #else
    1321             :                 index = 3;
    1322             :                 step = -1;
    1323             : #endif
    1324             :                 break;
    1325             :         case 'l':
    1326             :                 index = 3;
    1327             :                 step = -1;
    1328             :                 break;
    1329             :         case 'n':
    1330             :         case 'b':
    1331             :         default:
    1332           0 :                 index = 0;
    1333           0 :                 step = 1;
    1334           0 :                 break;
    1335             :         }
    1336           0 :         for (i = 0; i < 4; i++) {
    1337             :                 char temp[4] __aligned(2);      /* hold each IP quad in reverse order */
    1338           0 :                 int digits = put_dec_trunc8(temp, addr[index]) - temp;
    1339           0 :                 if (leading_zeros) {
    1340           0 :                         if (digits < 3)
    1341           0 :                                 *p++ = '0';
    1342           0 :                         if (digits < 2)
    1343           0 :                                 *p++ = '0';
    1344             :                 }
    1345             :                 /* reverse the digits in the quad */
    1346           0 :                 while (digits--)
    1347           0 :                         *p++ = temp[digits];
    1348           0 :                 if (i < 3)
    1349           0 :                         *p++ = '.';
    1350           0 :                 index += step;
    1351             :         }
    1352           0 :         *p = '\0';
    1353             : 
    1354           0 :         return p;
    1355             : }
    1356             : 
    1357             : static noinline_for_stack
    1358           0 : char *ip6_compressed_string(char *p, const char *addr)
    1359             : {
    1360             :         int i, j, range;
    1361             :         unsigned char zerolength[8];
    1362           0 :         int longest = 1;
    1363           0 :         int colonpos = -1;
    1364             :         u16 word;
    1365             :         u8 hi, lo;
    1366           0 :         bool needcolon = false;
    1367             :         bool useIPv4;
    1368             :         struct in6_addr in6;
    1369             : 
    1370           0 :         memcpy(&in6, addr, sizeof(struct in6_addr));
    1371             : 
    1372           0 :         useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
    1373             : 
    1374           0 :         memset(zerolength, 0, sizeof(zerolength));
    1375             : 
    1376           0 :         if (useIPv4)
    1377             :                 range = 6;
    1378             :         else
    1379           0 :                 range = 8;
    1380             : 
    1381             :         /* find position of longest 0 run */
    1382           0 :         for (i = 0; i < range; i++) {
    1383           0 :                 for (j = i; j < range; j++) {
    1384           0 :                         if (in6.s6_addr16[j] != 0)
    1385             :                                 break;
    1386           0 :                         zerolength[i]++;
    1387             :                 }
    1388             :         }
    1389           0 :         for (i = 0; i < range; i++) {
    1390           0 :                 if (zerolength[i] > longest) {
    1391           0 :                         longest = zerolength[i];
    1392           0 :                         colonpos = i;
    1393             :                 }
    1394             :         }
    1395           0 :         if (longest == 1)               /* don't compress a single 0 */
    1396           0 :                 colonpos = -1;
    1397             : 
    1398             :         /* emit address */
    1399           0 :         for (i = 0; i < range; i++) {
    1400           0 :                 if (i == colonpos) {
    1401           0 :                         if (needcolon || i == 0)
    1402           0 :                                 *p++ = ':';
    1403           0 :                         *p++ = ':';
    1404           0 :                         needcolon = false;
    1405           0 :                         i += longest - 1;
    1406           0 :                         continue;
    1407             :                 }
    1408           0 :                 if (needcolon) {
    1409           0 :                         *p++ = ':';
    1410           0 :                         needcolon = false;
    1411             :                 }
    1412             :                 /* hex u16 without leading 0s */
    1413           0 :                 word = ntohs(in6.s6_addr16[i]);
    1414           0 :                 hi = word >> 8;
    1415           0 :                 lo = word & 0xff;
    1416           0 :                 if (hi) {
    1417           0 :                         if (hi > 0x0f)
    1418           0 :                                 p = hex_byte_pack(p, hi);
    1419             :                         else
    1420           0 :                                 *p++ = hex_asc_lo(hi);
    1421           0 :                         p = hex_byte_pack(p, lo);
    1422             :                 }
    1423           0 :                 else if (lo > 0x0f)
    1424           0 :                         p = hex_byte_pack(p, lo);
    1425             :                 else
    1426           0 :                         *p++ = hex_asc_lo(lo);
    1427             :                 needcolon = true;
    1428             :         }
    1429             : 
    1430           0 :         if (useIPv4) {
    1431           0 :                 if (needcolon)
    1432           0 :                         *p++ = ':';
    1433           0 :                 p = ip4_string(p, &in6.s6_addr[12], "I4");
    1434             :         }
    1435           0 :         *p = '\0';
    1436             : 
    1437           0 :         return p;
    1438             : }
    1439             : 
    1440             : static noinline_for_stack
    1441           0 : char *ip6_string(char *p, const char *addr, const char *fmt)
    1442             : {
    1443             :         int i;
    1444             : 
    1445           0 :         for (i = 0; i < 8; i++) {
    1446           0 :                 p = hex_byte_pack(p, *addr++);
    1447           0 :                 p = hex_byte_pack(p, *addr++);
    1448           0 :                 if (fmt[0] == 'I' && i != 7)
    1449           0 :                         *p++ = ':';
    1450             :         }
    1451           0 :         *p = '\0';
    1452             : 
    1453           0 :         return p;
    1454             : }
    1455             : 
    1456             : static noinline_for_stack
    1457           0 : char *ip6_addr_string(char *buf, char *end, const u8 *addr,
    1458             :                       struct printf_spec spec, const char *fmt)
    1459             : {
    1460             :         char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
    1461             : 
    1462           0 :         if (fmt[0] == 'I' && fmt[2] == 'c')
    1463           0 :                 ip6_compressed_string(ip6_addr, addr);
    1464             :         else
    1465           0 :                 ip6_string(ip6_addr, addr, fmt);
    1466             : 
    1467           0 :         return string_nocheck(buf, end, ip6_addr, spec);
    1468             : }
    1469             : 
    1470             : static noinline_for_stack
    1471           0 : char *ip4_addr_string(char *buf, char *end, const u8 *addr,
    1472             :                       struct printf_spec spec, const char *fmt)
    1473             : {
    1474             :         char ip4_addr[sizeof("255.255.255.255")];
    1475             : 
    1476           0 :         ip4_string(ip4_addr, addr, fmt);
    1477             : 
    1478           0 :         return string_nocheck(buf, end, ip4_addr, spec);
    1479             : }
    1480             : 
    1481             : static noinline_for_stack
    1482           0 : char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa,
    1483             :                          struct printf_spec spec, const char *fmt)
    1484             : {
    1485           0 :         bool have_p = false, have_s = false, have_f = false, have_c = false;
    1486             :         char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") +
    1487             :                       sizeof(":12345") + sizeof("/123456789") +
    1488             :                       sizeof("%1234567890")];
    1489           0 :         char *p = ip6_addr, *pend = ip6_addr + sizeof(ip6_addr);
    1490           0 :         const u8 *addr = (const u8 *) &sa->sin6_addr;
    1491           0 :         char fmt6[2] = { fmt[0], '6' };
    1492           0 :         u8 off = 0;
    1493             : 
    1494           0 :         fmt++;
    1495           0 :         while (isalpha(*++fmt)) {
    1496           0 :                 switch (*fmt) {
    1497             :                 case 'p':
    1498           0 :                         have_p = true;
    1499           0 :                         break;
    1500             :                 case 'f':
    1501           0 :                         have_f = true;
    1502           0 :                         break;
    1503             :                 case 's':
    1504           0 :                         have_s = true;
    1505           0 :                         break;
    1506             :                 case 'c':
    1507           0 :                         have_c = true;
    1508           0 :                         break;
    1509             :                 }
    1510             :         }
    1511             : 
    1512           0 :         if (have_p || have_s || have_f) {
    1513           0 :                 *p = '[';
    1514           0 :                 off = 1;
    1515             :         }
    1516             : 
    1517           0 :         if (fmt6[0] == 'I' && have_c)
    1518           0 :                 p = ip6_compressed_string(ip6_addr + off, addr);
    1519             :         else
    1520           0 :                 p = ip6_string(ip6_addr + off, addr, fmt6);
    1521             : 
    1522           0 :         if (have_p || have_s || have_f)
    1523           0 :                 *p++ = ']';
    1524             : 
    1525           0 :         if (have_p) {
    1526           0 :                 *p++ = ':';
    1527           0 :                 p = number(p, pend, ntohs(sa->sin6_port), spec);
    1528             :         }
    1529           0 :         if (have_f) {
    1530           0 :                 *p++ = '/';
    1531           0 :                 p = number(p, pend, ntohl(sa->sin6_flowinfo &
    1532             :                                           IPV6_FLOWINFO_MASK), spec);
    1533             :         }
    1534           0 :         if (have_s) {
    1535           0 :                 *p++ = '%';
    1536           0 :                 p = number(p, pend, sa->sin6_scope_id, spec);
    1537             :         }
    1538           0 :         *p = '\0';
    1539             : 
    1540           0 :         return string_nocheck(buf, end, ip6_addr, spec);
    1541             : }
    1542             : 
    1543             : static noinline_for_stack
    1544           0 : char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa,
    1545             :                          struct printf_spec spec, const char *fmt)
    1546             : {
    1547           0 :         bool have_p = false;
    1548             :         char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")];
    1549           0 :         char *pend = ip4_addr + sizeof(ip4_addr);
    1550           0 :         const u8 *addr = (const u8 *) &sa->sin_addr.s_addr;
    1551           0 :         char fmt4[3] = { fmt[0], '4', 0 };
    1552             : 
    1553           0 :         fmt++;
    1554           0 :         while (isalpha(*++fmt)) {
    1555             :                 switch (*fmt) {
    1556             :                 case 'p':
    1557             :                         have_p = true;
    1558             :                         break;
    1559             :                 case 'h':
    1560             :                 case 'l':
    1561             :                 case 'n':
    1562             :                 case 'b':
    1563           0 :                         fmt4[2] = *fmt;
    1564           0 :                         break;
    1565             :                 }
    1566             :         }
    1567             : 
    1568           0 :         p = ip4_string(ip4_addr, addr, fmt4);
    1569           0 :         if (have_p) {
    1570           0 :                 *p++ = ':';
    1571           0 :                 p = number(p, pend, ntohs(sa->sin_port), spec);
    1572             :         }
    1573           0 :         *p = '\0';
    1574             : 
    1575           0 :         return string_nocheck(buf, end, ip4_addr, spec);
    1576             : }
    1577             : 
    1578             : static noinline_for_stack
    1579           0 : char *ip_addr_string(char *buf, char *end, const void *ptr,
    1580             :                      struct printf_spec spec, const char *fmt)
    1581             : {
    1582             :         char *err_fmt_msg;
    1583             : 
    1584           0 :         if (check_pointer(&buf, end, ptr, spec))
    1585           0 :                 return buf;
    1586             : 
    1587           0 :         switch (fmt[1]) {
    1588             :         case '6':
    1589           0 :                 return ip6_addr_string(buf, end, ptr, spec, fmt);
    1590             :         case '4':
    1591           0 :                 return ip4_addr_string(buf, end, ptr, spec, fmt);
    1592             :         case 'S': {
    1593             :                 const union {
    1594             :                         struct sockaddr         raw;
    1595             :                         struct sockaddr_in      v4;
    1596             :                         struct sockaddr_in6     v6;
    1597           0 :                 } *sa = ptr;
    1598             : 
    1599           0 :                 switch (sa->raw.sa_family) {
    1600             :                 case AF_INET:
    1601           0 :                         return ip4_addr_string_sa(buf, end, &sa->v4, spec, fmt);
    1602             :                 case AF_INET6:
    1603           0 :                         return ip6_addr_string_sa(buf, end, &sa->v6, spec, fmt);
    1604             :                 default:
    1605           0 :                         return error_string(buf, end, "(einval)", spec);
    1606             :                 }}
    1607             :         }
    1608             : 
    1609           0 :         err_fmt_msg = fmt[0] == 'i' ? "(%pi?)" : "(%pI?)";
    1610           0 :         return error_string(buf, end, err_fmt_msg, spec);
    1611             : }
    1612             : 
    1613             : static noinline_for_stack
    1614           0 : char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
    1615             :                      const char *fmt)
    1616             : {
    1617           0 :         bool found = true;
    1618           0 :         int count = 1;
    1619           0 :         unsigned int flags = 0;
    1620             :         int len;
    1621             : 
    1622           0 :         if (spec.field_width == 0)
    1623           0 :                 return buf;                             /* nothing to print */
    1624             : 
    1625           0 :         if (check_pointer(&buf, end, addr, spec))
    1626           0 :                 return buf;
    1627             : 
    1628             :         do {
    1629           0 :                 switch (fmt[count++]) {
    1630             :                 case 'a':
    1631           0 :                         flags |= ESCAPE_ANY;
    1632           0 :                         break;
    1633             :                 case 'c':
    1634           0 :                         flags |= ESCAPE_SPECIAL;
    1635           0 :                         break;
    1636             :                 case 'h':
    1637           0 :                         flags |= ESCAPE_HEX;
    1638           0 :                         break;
    1639             :                 case 'n':
    1640           0 :                         flags |= ESCAPE_NULL;
    1641           0 :                         break;
    1642             :                 case 'o':
    1643           0 :                         flags |= ESCAPE_OCTAL;
    1644           0 :                         break;
    1645             :                 case 'p':
    1646           0 :                         flags |= ESCAPE_NP;
    1647           0 :                         break;
    1648             :                 case 's':
    1649           0 :                         flags |= ESCAPE_SPACE;
    1650           0 :                         break;
    1651             :                 default:
    1652             :                         found = false;
    1653             :                         break;
    1654             :                 }
    1655           0 :         } while (found);
    1656             : 
    1657           0 :         if (!flags)
    1658           0 :                 flags = ESCAPE_ANY_NP;
    1659             : 
    1660           0 :         len = spec.field_width < 0 ? 1 : spec.field_width;
    1661             : 
    1662             :         /*
    1663             :          * string_escape_mem() writes as many characters as it can to
    1664             :          * the given buffer, and returns the total size of the output
    1665             :          * had the buffer been big enough.
    1666             :          */
    1667           0 :         buf += string_escape_mem(addr, len, buf, buf < end ? end - buf : 0, flags, NULL);
    1668             : 
    1669           0 :         return buf;
    1670             : }
    1671             : 
    1672           0 : static char *va_format(char *buf, char *end, struct va_format *va_fmt,
    1673             :                        struct printf_spec spec, const char *fmt)
    1674             : {
    1675             :         va_list va;
    1676             : 
    1677           0 :         if (check_pointer(&buf, end, va_fmt, spec))
    1678           0 :                 return buf;
    1679             : 
    1680           0 :         va_copy(va, *va_fmt->va);
    1681           0 :         buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
    1682           0 :         va_end(va);
    1683             : 
    1684             :         return buf;
    1685             : }
    1686             : 
    1687             : static noinline_for_stack
    1688           0 : char *uuid_string(char *buf, char *end, const u8 *addr,
    1689             :                   struct printf_spec spec, const char *fmt)
    1690             : {
    1691             :         char uuid[UUID_STRING_LEN + 1];
    1692           0 :         char *p = uuid;
    1693             :         int i;
    1694           0 :         const u8 *index = uuid_index;
    1695           0 :         bool uc = false;
    1696             : 
    1697           0 :         if (check_pointer(&buf, end, addr, spec))
    1698           0 :                 return buf;
    1699             : 
    1700           0 :         switch (*(++fmt)) {
    1701             :         case 'L':
    1702           0 :                 uc = true;
    1703             :                 fallthrough;
    1704             :         case 'l':
    1705             :                 index = guid_index;
    1706             :                 break;
    1707             :         case 'B':
    1708           0 :                 uc = true;
    1709           0 :                 break;
    1710             :         }
    1711             : 
    1712           0 :         for (i = 0; i < 16; i++) {
    1713           0 :                 if (uc)
    1714           0 :                         p = hex_byte_pack_upper(p, addr[index[i]]);
    1715             :                 else
    1716           0 :                         p = hex_byte_pack(p, addr[index[i]]);
    1717             :                 switch (i) {
    1718             :                 case 3:
    1719             :                 case 5:
    1720             :                 case 7:
    1721             :                 case 9:
    1722           0 :                         *p++ = '-';
    1723           0 :                         break;
    1724             :                 }
    1725             :         }
    1726             : 
    1727           0 :         *p = 0;
    1728             : 
    1729           0 :         return string_nocheck(buf, end, uuid, spec);
    1730             : }
    1731             : 
    1732             : static noinline_for_stack
    1733           0 : char *netdev_bits(char *buf, char *end, const void *addr,
    1734             :                   struct printf_spec spec,  const char *fmt)
    1735             : {
    1736             :         unsigned long long num;
    1737             :         int size;
    1738             : 
    1739           0 :         if (check_pointer(&buf, end, addr, spec))
    1740           0 :                 return buf;
    1741             : 
    1742           0 :         switch (fmt[1]) {
    1743             :         case 'F':
    1744           0 :                 num = *(const netdev_features_t *)addr;
    1745           0 :                 size = sizeof(netdev_features_t);
    1746             :                 break;
    1747             :         default:
    1748           0 :                 return error_string(buf, end, "(%pN?)", spec);
    1749             :         }
    1750             : 
    1751           0 :         return special_hex_number(buf, end, num, size);
    1752             : }
    1753             : 
    1754             : static noinline_for_stack
    1755           0 : char *fourcc_string(char *buf, char *end, const u32 *fourcc,
    1756             :                     struct printf_spec spec, const char *fmt)
    1757             : {
    1758             :         char output[sizeof("0123 little-endian (0x01234567)")];
    1759           0 :         char *p = output;
    1760             :         unsigned int i;
    1761             :         u32 orig, val;
    1762             : 
    1763           0 :         if (fmt[1] != 'c' || fmt[2] != 'c')
    1764           0 :                 return error_string(buf, end, "(%p4?)", spec);
    1765             : 
    1766           0 :         if (check_pointer(&buf, end, fourcc, spec))
    1767           0 :                 return buf;
    1768             : 
    1769           0 :         orig = get_unaligned(fourcc);
    1770           0 :         val = orig & ~BIT(31);
    1771             : 
    1772           0 :         for (i = 0; i < sizeof(u32); i++) {
    1773           0 :                 unsigned char c = val >> (i * 8);
    1774             : 
    1775             :                 /* Print non-control ASCII characters as-is, dot otherwise */
    1776           0 :                 *p++ = isascii(c) && isprint(c) ? c : '.';
    1777             :         }
    1778             : 
    1779           0 :         *p++ = ' ';
    1780           0 :         strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian");
    1781           0 :         p += strlen(p);
    1782             : 
    1783           0 :         *p++ = ' ';
    1784           0 :         *p++ = '(';
    1785           0 :         p = special_hex_number(p, output + sizeof(output) - 2, orig, sizeof(u32));
    1786           0 :         *p++ = ')';
    1787           0 :         *p = '\0';
    1788             : 
    1789           0 :         return string(buf, end, output, spec);
    1790             : }
    1791             : 
    1792             : static noinline_for_stack
    1793           0 : char *address_val(char *buf, char *end, const void *addr,
    1794             :                   struct printf_spec spec, const char *fmt)
    1795             : {
    1796             :         unsigned long long num;
    1797             :         int size;
    1798             : 
    1799           0 :         if (check_pointer(&buf, end, addr, spec))
    1800           0 :                 return buf;
    1801             : 
    1802           0 :         switch (fmt[1]) {
    1803             :         case 'd':
    1804           0 :                 num = *(const dma_addr_t *)addr;
    1805           0 :                 size = sizeof(dma_addr_t);
    1806           0 :                 break;
    1807             :         case 'p':
    1808             :         default:
    1809           0 :                 num = *(const phys_addr_t *)addr;
    1810           0 :                 size = sizeof(phys_addr_t);
    1811           0 :                 break;
    1812             :         }
    1813             : 
    1814           0 :         return special_hex_number(buf, end, num, size);
    1815             : }
    1816             : 
    1817             : static noinline_for_stack
    1818           0 : char *date_str(char *buf, char *end, const struct rtc_time *tm, bool r)
    1819             : {
    1820           0 :         int year = tm->tm_year + (r ? 0 : 1900);
    1821           0 :         int mon = tm->tm_mon + (r ? 0 : 1);
    1822             : 
    1823           0 :         buf = number(buf, end, year, default_dec04_spec);
    1824           0 :         if (buf < end)
    1825           0 :                 *buf = '-';
    1826           0 :         buf++;
    1827             : 
    1828           0 :         buf = number(buf, end, mon, default_dec02_spec);
    1829           0 :         if (buf < end)
    1830           0 :                 *buf = '-';
    1831           0 :         buf++;
    1832             : 
    1833           0 :         return number(buf, end, tm->tm_mday, default_dec02_spec);
    1834             : }
    1835             : 
    1836             : static noinline_for_stack
    1837           0 : char *time_str(char *buf, char *end, const struct rtc_time *tm, bool r)
    1838             : {
    1839           0 :         buf = number(buf, end, tm->tm_hour, default_dec02_spec);
    1840           0 :         if (buf < end)
    1841           0 :                 *buf = ':';
    1842           0 :         buf++;
    1843             : 
    1844           0 :         buf = number(buf, end, tm->tm_min, default_dec02_spec);
    1845           0 :         if (buf < end)
    1846           0 :                 *buf = ':';
    1847           0 :         buf++;
    1848             : 
    1849           0 :         return number(buf, end, tm->tm_sec, default_dec02_spec);
    1850             : }
    1851             : 
    1852             : static noinline_for_stack
    1853           0 : char *rtc_str(char *buf, char *end, const struct rtc_time *tm,
    1854             :               struct printf_spec spec, const char *fmt)
    1855             : {
    1856           0 :         bool have_t = true, have_d = true;
    1857           0 :         bool raw = false, iso8601_separator = true;
    1858           0 :         bool found = true;
    1859           0 :         int count = 2;
    1860             : 
    1861           0 :         if (check_pointer(&buf, end, tm, spec))
    1862           0 :                 return buf;
    1863             : 
    1864           0 :         switch (fmt[count]) {
    1865             :         case 'd':
    1866           0 :                 have_t = false;
    1867           0 :                 count++;
    1868           0 :                 break;
    1869             :         case 't':
    1870           0 :                 have_d = false;
    1871           0 :                 count++;
    1872           0 :                 break;
    1873             :         }
    1874             : 
    1875             :         do {
    1876           0 :                 switch (fmt[count++]) {
    1877             :                 case 'r':
    1878             :                         raw = true;
    1879             :                         break;
    1880             :                 case 's':
    1881           0 :                         iso8601_separator = false;
    1882           0 :                         break;
    1883             :                 default:
    1884           0 :                         found = false;
    1885           0 :                         break;
    1886             :                 }
    1887           0 :         } while (found);
    1888             : 
    1889           0 :         if (have_d)
    1890           0 :                 buf = date_str(buf, end, tm, raw);
    1891           0 :         if (have_d && have_t) {
    1892           0 :                 if (buf < end)
    1893           0 :                         *buf = iso8601_separator ? 'T' : ' ';
    1894           0 :                 buf++;
    1895             :         }
    1896           0 :         if (have_t)
    1897           0 :                 buf = time_str(buf, end, tm, raw);
    1898             : 
    1899           0 :         return buf;
    1900             : }
    1901             : 
    1902             : static noinline_for_stack
    1903           0 : char *time64_str(char *buf, char *end, const time64_t time,
    1904             :                  struct printf_spec spec, const char *fmt)
    1905             : {
    1906             :         struct rtc_time rtc_time;
    1907             :         struct tm tm;
    1908             : 
    1909           0 :         time64_to_tm(time, 0, &tm);
    1910             : 
    1911           0 :         rtc_time.tm_sec = tm.tm_sec;
    1912           0 :         rtc_time.tm_min = tm.tm_min;
    1913           0 :         rtc_time.tm_hour = tm.tm_hour;
    1914           0 :         rtc_time.tm_mday = tm.tm_mday;
    1915           0 :         rtc_time.tm_mon = tm.tm_mon;
    1916           0 :         rtc_time.tm_year = tm.tm_year;
    1917           0 :         rtc_time.tm_wday = tm.tm_wday;
    1918           0 :         rtc_time.tm_yday = tm.tm_yday;
    1919             : 
    1920           0 :         rtc_time.tm_isdst = 0;
    1921             : 
    1922           0 :         return rtc_str(buf, end, &rtc_time, spec, fmt);
    1923             : }
    1924             : 
    1925             : static noinline_for_stack
    1926           0 : char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec,
    1927             :                     const char *fmt)
    1928             : {
    1929           0 :         switch (fmt[1]) {
    1930             :         case 'R':
    1931           0 :                 return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt);
    1932             :         case 'T':
    1933           0 :                 return time64_str(buf, end, *(const time64_t *)ptr, spec, fmt);
    1934             :         default:
    1935           0 :                 return error_string(buf, end, "(%pt?)", spec);
    1936             :         }
    1937             : }
    1938             : 
    1939             : static noinline_for_stack
    1940           0 : char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec,
    1941             :             const char *fmt)
    1942             : {
    1943             :         if (!IS_ENABLED(CONFIG_HAVE_CLK))
    1944           0 :                 return error_string(buf, end, "(%pC?)", spec);
    1945             : 
    1946             :         if (check_pointer(&buf, end, clk, spec))
    1947             :                 return buf;
    1948             : 
    1949             :         switch (fmt[1]) {
    1950             :         case 'n':
    1951             :         default:
    1952             : #ifdef CONFIG_COMMON_CLK
    1953             :                 return string(buf, end, __clk_get_name(clk), spec);
    1954             : #else
    1955             :                 return ptr_to_id(buf, end, clk, spec);
    1956             : #endif
    1957             :         }
    1958             : }
    1959             : 
    1960             : static
    1961           0 : char *format_flags(char *buf, char *end, unsigned long flags,
    1962             :                                         const struct trace_print_flags *names)
    1963             : {
    1964             :         unsigned long mask;
    1965             : 
    1966           0 :         for ( ; flags && names->name; names++) {
    1967           0 :                 mask = names->mask;
    1968           0 :                 if ((flags & mask) != mask)
    1969           0 :                         continue;
    1970             : 
    1971           0 :                 buf = string(buf, end, names->name, default_str_spec);
    1972             : 
    1973           0 :                 flags &= ~mask;
    1974           0 :                 if (flags) {
    1975           0 :                         if (buf < end)
    1976           0 :                                 *buf = '|';
    1977           0 :                         buf++;
    1978             :                 }
    1979             :         }
    1980             : 
    1981           0 :         if (flags)
    1982           0 :                 buf = number(buf, end, flags, default_flag_spec);
    1983             : 
    1984           0 :         return buf;
    1985             : }
    1986             : 
    1987             : struct page_flags_fields {
    1988             :         int width;
    1989             :         int shift;
    1990             :         int mask;
    1991             :         const struct printf_spec *spec;
    1992             :         const char *name;
    1993             : };
    1994             : 
    1995             : static const struct page_flags_fields pff[] = {
    1996             :         {SECTIONS_WIDTH, SECTIONS_PGSHIFT, SECTIONS_MASK,
    1997             :          &default_dec_spec, "section"},
    1998             :         {NODES_WIDTH, NODES_PGSHIFT, NODES_MASK,
    1999             :          &default_dec_spec, "node"},
    2000             :         {ZONES_WIDTH, ZONES_PGSHIFT, ZONES_MASK,
    2001             :          &default_dec_spec, "zone"},
    2002             :         {LAST_CPUPID_WIDTH, LAST_CPUPID_PGSHIFT, LAST_CPUPID_MASK,
    2003             :          &default_flag_spec, "lastcpupid"},
    2004             :         {KASAN_TAG_WIDTH, KASAN_TAG_PGSHIFT, KASAN_TAG_MASK,
    2005             :          &default_flag_spec, "kasantag"},
    2006             : };
    2007             : 
    2008             : static
    2009           0 : char *format_page_flags(char *buf, char *end, unsigned long flags)
    2010             : {
    2011           0 :         unsigned long main_flags = flags & PAGEFLAGS_MASK;
    2012           0 :         bool append = false;
    2013             :         int i;
    2014             : 
    2015           0 :         buf = number(buf, end, flags, default_flag_spec);
    2016           0 :         if (buf < end)
    2017           0 :                 *buf = '(';
    2018           0 :         buf++;
    2019             : 
    2020             :         /* Page flags from the main area. */
    2021           0 :         if (main_flags) {
    2022           0 :                 buf = format_flags(buf, end, main_flags, pageflag_names);
    2023           0 :                 append = true;
    2024             :         }
    2025             : 
    2026             :         /* Page flags from the fields area */
    2027           0 :         for (i = 0; i < ARRAY_SIZE(pff); i++) {
    2028             :                 /* Skip undefined fields. */
    2029           0 :                 if (!pff[i].width)
    2030           0 :                         continue;
    2031             : 
    2032             :                 /* Format: Flag Name + '=' (equals sign) + Number + '|' (separator) */
    2033           0 :                 if (append) {
    2034           0 :                         if (buf < end)
    2035           0 :                                 *buf = '|';
    2036           0 :                         buf++;
    2037             :                 }
    2038             : 
    2039           0 :                 buf = string(buf, end, pff[i].name, default_str_spec);
    2040           0 :                 if (buf < end)
    2041           0 :                         *buf = '=';
    2042           0 :                 buf++;
    2043           0 :                 buf = number(buf, end, (flags >> pff[i].shift) & pff[i].mask,
    2044           0 :                              *pff[i].spec);
    2045             : 
    2046           0 :                 append = true;
    2047             :         }
    2048           0 :         if (buf < end)
    2049           0 :                 *buf = ')';
    2050           0 :         buf++;
    2051             : 
    2052           0 :         return buf;
    2053             : }
    2054             : 
    2055             : static noinline_for_stack
    2056           0 : char *flags_string(char *buf, char *end, void *flags_ptr,
    2057             :                    struct printf_spec spec, const char *fmt)
    2058             : {
    2059             :         unsigned long flags;
    2060             :         const struct trace_print_flags *names;
    2061             : 
    2062           0 :         if (check_pointer(&buf, end, flags_ptr, spec))
    2063           0 :                 return buf;
    2064             : 
    2065           0 :         switch (fmt[1]) {
    2066             :         case 'p':
    2067           0 :                 return format_page_flags(buf, end, *(unsigned long *)flags_ptr);
    2068             :         case 'v':
    2069           0 :                 flags = *(unsigned long *)flags_ptr;
    2070           0 :                 names = vmaflag_names;
    2071           0 :                 break;
    2072             :         case 'g':
    2073           0 :                 flags = (__force unsigned long)(*(gfp_t *)flags_ptr);
    2074           0 :                 names = gfpflag_names;
    2075           0 :                 break;
    2076             :         default:
    2077           0 :                 return error_string(buf, end, "(%pG?)", spec);
    2078             :         }
    2079             : 
    2080           0 :         return format_flags(buf, end, flags, names);
    2081             : }
    2082             : 
    2083             : static noinline_for_stack
    2084           0 : char *fwnode_full_name_string(struct fwnode_handle *fwnode, char *buf,
    2085             :                               char *end)
    2086             : {
    2087             :         int depth;
    2088             : 
    2089             :         /* Loop starting from the root node to the current node. */
    2090           0 :         for (depth = fwnode_count_parents(fwnode); depth >= 0; depth--) {
    2091           0 :                 struct fwnode_handle *__fwnode =
    2092           0 :                         fwnode_get_nth_parent(fwnode, depth);
    2093             : 
    2094           0 :                 buf = string(buf, end, fwnode_get_name_prefix(__fwnode),
    2095             :                              default_str_spec);
    2096           0 :                 buf = string(buf, end, fwnode_get_name(__fwnode),
    2097             :                              default_str_spec);
    2098             : 
    2099           0 :                 fwnode_handle_put(__fwnode);
    2100             :         }
    2101             : 
    2102           0 :         return buf;
    2103             : }
    2104             : 
    2105             : static noinline_for_stack
    2106           0 : char *device_node_string(char *buf, char *end, struct device_node *dn,
    2107             :                          struct printf_spec spec, const char *fmt)
    2108             : {
    2109             :         char tbuf[sizeof("xxxx") + 1];
    2110             :         const char *p;
    2111             :         int ret;
    2112           0 :         char *buf_start = buf;
    2113             :         struct property *prop;
    2114             :         bool has_mult, pass;
    2115             : 
    2116           0 :         struct printf_spec str_spec = spec;
    2117           0 :         str_spec.field_width = -1;
    2118             : 
    2119           0 :         if (fmt[0] != 'F')
    2120           0 :                 return error_string(buf, end, "(%pO?)", spec);
    2121             : 
    2122             :         if (!IS_ENABLED(CONFIG_OF))
    2123           0 :                 return error_string(buf, end, "(%pOF?)", spec);
    2124             : 
    2125             :         if (check_pointer(&buf, end, dn, spec))
    2126             :                 return buf;
    2127             : 
    2128             :         /* simple case without anything any more format specifiers */
    2129             :         fmt++;
    2130             :         if (fmt[0] == '\0' || strcspn(fmt,"fnpPFcC") > 0)
    2131             :                 fmt = "f";
    2132             : 
    2133             :         for (pass = false; strspn(fmt,"fnpPFcC"); fmt++, pass = true) {
    2134             :                 int precision;
    2135             :                 if (pass) {
    2136             :                         if (buf < end)
    2137             :                                 *buf = ':';
    2138             :                         buf++;
    2139             :                 }
    2140             : 
    2141             :                 switch (*fmt) {
    2142             :                 case 'f':       /* full_name */
    2143             :                         buf = fwnode_full_name_string(of_fwnode_handle(dn), buf,
    2144             :                                                       end);
    2145             :                         break;
    2146             :                 case 'n':       /* name */
    2147             :                         p = fwnode_get_name(of_fwnode_handle(dn));
    2148             :                         precision = str_spec.precision;
    2149             :                         str_spec.precision = strchrnul(p, '@') - p;
    2150             :                         buf = string(buf, end, p, str_spec);
    2151             :                         str_spec.precision = precision;
    2152             :                         break;
    2153             :                 case 'p':       /* phandle */
    2154             :                         buf = number(buf, end, (unsigned int)dn->phandle, default_dec_spec);
    2155             :                         break;
    2156             :                 case 'P':       /* path-spec */
    2157             :                         p = fwnode_get_name(of_fwnode_handle(dn));
    2158             :                         if (!p[1])
    2159             :                                 p = "/";
    2160             :                         buf = string(buf, end, p, str_spec);
    2161             :                         break;
    2162             :                 case 'F':       /* flags */
    2163             :                         tbuf[0] = of_node_check_flag(dn, OF_DYNAMIC) ? 'D' : '-';
    2164             :                         tbuf[1] = of_node_check_flag(dn, OF_DETACHED) ? 'd' : '-';
    2165             :                         tbuf[2] = of_node_check_flag(dn, OF_POPULATED) ? 'P' : '-';
    2166             :                         tbuf[3] = of_node_check_flag(dn, OF_POPULATED_BUS) ? 'B' : '-';
    2167             :                         tbuf[4] = 0;
    2168             :                         buf = string_nocheck(buf, end, tbuf, str_spec);
    2169             :                         break;
    2170             :                 case 'c':       /* major compatible string */
    2171             :                         ret = of_property_read_string(dn, "compatible", &p);
    2172             :                         if (!ret)
    2173             :                                 buf = string(buf, end, p, str_spec);
    2174             :                         break;
    2175             :                 case 'C':       /* full compatible string */
    2176             :                         has_mult = false;
    2177             :                         of_property_for_each_string(dn, "compatible", prop, p) {
    2178             :                                 if (has_mult)
    2179             :                                         buf = string_nocheck(buf, end, ",", str_spec);
    2180             :                                 buf = string_nocheck(buf, end, "\"", str_spec);
    2181             :                                 buf = string(buf, end, p, str_spec);
    2182             :                                 buf = string_nocheck(buf, end, "\"", str_spec);
    2183             : 
    2184             :                                 has_mult = true;
    2185             :                         }
    2186             :                         break;
    2187             :                 default:
    2188             :                         break;
    2189             :                 }
    2190             :         }
    2191             : 
    2192             :         return widen_string(buf, buf - buf_start, end, spec);
    2193             : }
    2194             : 
    2195             : static noinline_for_stack
    2196           0 : char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
    2197             :                     struct printf_spec spec, const char *fmt)
    2198             : {
    2199           0 :         struct printf_spec str_spec = spec;
    2200           0 :         char *buf_start = buf;
    2201             : 
    2202           0 :         str_spec.field_width = -1;
    2203             : 
    2204           0 :         if (*fmt != 'w')
    2205           0 :                 return error_string(buf, end, "(%pf?)", spec);
    2206             : 
    2207           0 :         if (check_pointer(&buf, end, fwnode, spec))
    2208           0 :                 return buf;
    2209             : 
    2210           0 :         fmt++;
    2211             : 
    2212           0 :         switch (*fmt) {
    2213             :         case 'P':       /* name */
    2214           0 :                 buf = string(buf, end, fwnode_get_name(fwnode), str_spec);
    2215           0 :                 break;
    2216             :         case 'f':       /* full_name */
    2217             :         default:
    2218           0 :                 buf = fwnode_full_name_string(fwnode, buf, end);
    2219           0 :                 break;
    2220             :         }
    2221             : 
    2222           0 :         return widen_string(buf, buf - buf_start, end, spec);
    2223             : }
    2224             : 
    2225           0 : int __init no_hash_pointers_enable(char *str)
    2226             : {
    2227           0 :         if (no_hash_pointers)
    2228             :                 return 0;
    2229             : 
    2230           0 :         no_hash_pointers = true;
    2231             : 
    2232           0 :         pr_warn("**********************************************************\n");
    2233           0 :         pr_warn("**   NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n");
    2234           0 :         pr_warn("**                                                      **\n");
    2235           0 :         pr_warn("** This system shows unhashed kernel memory addresses   **\n");
    2236           0 :         pr_warn("** via the console, logs, and other interfaces. This    **\n");
    2237           0 :         pr_warn("** might reduce the security of your system.            **\n");
    2238           0 :         pr_warn("**                                                      **\n");
    2239           0 :         pr_warn("** If you see this message and you are not debugging    **\n");
    2240           0 :         pr_warn("** the kernel, report this immediately to your system   **\n");
    2241           0 :         pr_warn("** administrator!                                       **\n");
    2242           0 :         pr_warn("**                                                      **\n");
    2243           0 :         pr_warn("**   NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n");
    2244           0 :         pr_warn("**********************************************************\n");
    2245             : 
    2246           0 :         return 0;
    2247             : }
    2248             : early_param("no_hash_pointers", no_hash_pointers_enable);
    2249             : 
    2250             : /* Used for Rust formatting ('%pA'). */
    2251             : char *rust_fmt_argument(char *buf, char *end, void *ptr);
    2252             : 
    2253             : /*
    2254             :  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
    2255             :  * by an extra set of alphanumeric characters that are extended format
    2256             :  * specifiers.
    2257             :  *
    2258             :  * Please update scripts/checkpatch.pl when adding/removing conversion
    2259             :  * characters.  (Search for "check for vsprintf extension").
    2260             :  *
    2261             :  * Right now we handle:
    2262             :  *
    2263             :  * - 'S' For symbolic direct pointers (or function descriptors) with offset
    2264             :  * - 's' For symbolic direct pointers (or function descriptors) without offset
    2265             :  * - '[Ss]R' as above with __builtin_extract_return_addr() translation
    2266             :  * - 'S[R]b' as above with module build ID (for use in backtraces)
    2267             :  * - '[Ff]' %pf and %pF were obsoleted and later removed in favor of
    2268             :  *          %ps and %pS. Be careful when re-using these specifiers.
    2269             :  * - 'B' For backtraced symbolic direct pointers with offset
    2270             :  * - 'Bb' as above with module build ID (for use in backtraces)
    2271             :  * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
    2272             :  * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
    2273             :  * - 'b[l]' For a bitmap, the number of bits is determined by the field
    2274             :  *       width which must be explicitly specified either as part of the
    2275             :  *       format string '%32b[l]' or through '%*b[l]', [l] selects
    2276             :  *       range-list format instead of hex format
    2277             :  * - 'M' For a 6-byte MAC address, it prints the address in the
    2278             :  *       usual colon-separated hex notation
    2279             :  * - 'm' For a 6-byte MAC address, it prints the hex address without colons
    2280             :  * - 'MF' For a 6-byte MAC FDDI address, it prints the address
    2281             :  *       with a dash-separated hex notation
    2282             :  * - '[mM]R' For a 6-byte MAC address, Reverse order (Bluetooth)
    2283             :  * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
    2284             :  *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
    2285             :  *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
    2286             :  *       [S][pfs]
    2287             :  *       Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
    2288             :  *       [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
    2289             :  * - 'i' [46] for 'raw' IPv4/IPv6 addresses
    2290             :  *       IPv6 omits the colons (01020304...0f)
    2291             :  *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
    2292             :  *       [S][pfs]
    2293             :  *       Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
    2294             :  *       [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
    2295             :  * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order
    2296             :  * - 'I[6S]c' for IPv6 addresses printed as specified by
    2297             :  *       https://tools.ietf.org/html/rfc5952
    2298             :  * - 'E[achnops]' For an escaped buffer, where rules are defined by combination
    2299             :  *                of the following flags (see string_escape_mem() for the
    2300             :  *                details):
    2301             :  *                  a - ESCAPE_ANY
    2302             :  *                  c - ESCAPE_SPECIAL
    2303             :  *                  h - ESCAPE_HEX
    2304             :  *                  n - ESCAPE_NULL
    2305             :  *                  o - ESCAPE_OCTAL
    2306             :  *                  p - ESCAPE_NP
    2307             :  *                  s - ESCAPE_SPACE
    2308             :  *                By default ESCAPE_ANY_NP is used.
    2309             :  * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
    2310             :  *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    2311             :  *       Options for %pU are:
    2312             :  *         b big endian lower case hex (default)
    2313             :  *         B big endian UPPER case hex
    2314             :  *         l little endian lower case hex
    2315             :  *         L little endian UPPER case hex
    2316             :  *           big endian output byte order is:
    2317             :  *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
    2318             :  *           little endian output byte order is:
    2319             :  *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
    2320             :  * - 'V' For a struct va_format which contains a format string * and va_list *,
    2321             :  *       call vsnprintf(->format, *->va_list).
    2322             :  *       Implements a "recursive vsnprintf".
    2323             :  *       Do not use this feature without some mechanism to verify the
    2324             :  *       correctness of the format string and va_list arguments.
    2325             :  * - 'K' For a kernel pointer that should be hidden from unprivileged users.
    2326             :  *       Use only for procfs, sysfs and similar files, not printk(); please
    2327             :  *       read the documentation (path below) first.
    2328             :  * - 'NF' For a netdev_features_t
    2329             :  * - '4cc' V4L2 or DRM FourCC code, with endianness and raw numerical value.
    2330             :  * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with
    2331             :  *            a certain separator (' ' by default):
    2332             :  *              C colon
    2333             :  *              D dash
    2334             :  *              N no separator
    2335             :  *            The maximum supported length is 64 bytes of the input. Consider
    2336             :  *            to use print_hex_dump() for the larger input.
    2337             :  * - 'a[pd]' For address types [p] phys_addr_t, [d] dma_addr_t and derivatives
    2338             :  *           (default assumed to be phys_addr_t, passed by reference)
    2339             :  * - 'd[234]' For a dentry name (optionally 2-4 last components)
    2340             :  * - 'D[234]' Same as 'd' but for a struct file
    2341             :  * - 'g' For block_device name (gendisk + partition number)
    2342             :  * - 't[RT][dt][r][s]' For time and date as represented by:
    2343             :  *      R    struct rtc_time
    2344             :  *      T    time64_t
    2345             :  * - 'C' For a clock, it prints the name (Common Clock Framework) or address
    2346             :  *       (legacy clock framework) of the clock
    2347             :  * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
    2348             :  *        (legacy clock framework) of the clock
    2349             :  * - 'G' For flags to be printed as a collection of symbolic strings that would
    2350             :  *       construct the specific value. Supported flags given by option:
    2351             :  *       p page flags (see struct page) given as pointer to unsigned long
    2352             :  *       g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t
    2353             :  *       v vma flags (VM_*) given as pointer to unsigned long
    2354             :  * - 'OF[fnpPcCF]'  For a device tree object
    2355             :  *                  Without any optional arguments prints the full_name
    2356             :  *                  f device node full_name
    2357             :  *                  n device node name
    2358             :  *                  p device node phandle
    2359             :  *                  P device node path spec (name + @unit)
    2360             :  *                  F device node flags
    2361             :  *                  c major compatible string
    2362             :  *                  C full compatible string
    2363             :  * - 'fw[fP]'   For a firmware node (struct fwnode_handle) pointer
    2364             :  *              Without an option prints the full name of the node
    2365             :  *              f full name
    2366             :  *              P node name, including a possible unit address
    2367             :  * - 'x' For printing the address unmodified. Equivalent to "%lx".
    2368             :  *       Please read the documentation (path below) before using!
    2369             :  * - '[ku]s' For a BPF/tracing related format specifier, e.g. used out of
    2370             :  *           bpf_trace_printk() where [ku] prefix specifies either kernel (k)
    2371             :  *           or user (u) memory to probe, and:
    2372             :  *              s a string, equivalent to "%s" on direct vsnprintf() use
    2373             :  *
    2374             :  * ** When making changes please also update:
    2375             :  *      Documentation/core-api/printk-formats.rst
    2376             :  *
    2377             :  * Note: The default behaviour (unadorned %p) is to hash the address,
    2378             :  * rendering it useful as a unique identifier.
    2379             :  *
    2380             :  * There is also a '%pA' format specifier, but it is only intended to be used
    2381             :  * from Rust code to format core::fmt::Arguments. Do *not* use it from C.
    2382             :  * See rust/kernel/print.rs for details.
    2383             :  */
    2384             : static noinline_for_stack
    2385         242 : char *pointer(const char *fmt, char *buf, char *end, void *ptr,
    2386             :               struct printf_spec spec)
    2387             : {
    2388         242 :         switch (*fmt) {
    2389             :         case 'S':
    2390             :         case 's':
    2391             :                 ptr = dereference_symbol_descriptor(ptr);
    2392             :                 fallthrough;
    2393             :         case 'B':
    2394         242 :                 return symbol_string(buf, end, ptr, spec, fmt);
    2395             :         case 'R':
    2396             :         case 'r':
    2397           0 :                 return resource_string(buf, end, ptr, spec, fmt);
    2398             :         case 'h':
    2399           0 :                 return hex_string(buf, end, ptr, spec, fmt);
    2400             :         case 'b':
    2401           0 :                 switch (fmt[1]) {
    2402             :                 case 'l':
    2403           0 :                         return bitmap_list_string(buf, end, ptr, spec, fmt);
    2404             :                 default:
    2405           0 :                         return bitmap_string(buf, end, ptr, spec, fmt);
    2406             :                 }
    2407             :         case 'M':                       /* Colon separated: 00:01:02:03:04:05 */
    2408             :         case 'm':                       /* Contiguous: 000102030405 */
    2409             :                                         /* [mM]F (FDDI) */
    2410             :                                         /* [mM]R (Reverse order; Bluetooth) */
    2411           0 :                 return mac_address_string(buf, end, ptr, spec, fmt);
    2412             :         case 'I':                       /* Formatted IP supported
    2413             :                                          * 4:   1.2.3.4
    2414             :                                          * 6:   0001:0203:...:0708
    2415             :                                          * 6c:  1::708 or 1::1.2.3.4
    2416             :                                          */
    2417             :         case 'i':                       /* Contiguous:
    2418             :                                          * 4:   001.002.003.004
    2419             :                                          * 6:   000102...0f
    2420             :                                          */
    2421           0 :                 return ip_addr_string(buf, end, ptr, spec, fmt);
    2422             :         case 'E':
    2423           0 :                 return escaped_string(buf, end, ptr, spec, fmt);
    2424             :         case 'U':
    2425           0 :                 return uuid_string(buf, end, ptr, spec, fmt);
    2426             :         case 'V':
    2427           0 :                 return va_format(buf, end, ptr, spec, fmt);
    2428             :         case 'K':
    2429           0 :                 return restricted_pointer(buf, end, ptr, spec);
    2430             :         case 'N':
    2431           0 :                 return netdev_bits(buf, end, ptr, spec, fmt);
    2432             :         case '4':
    2433           0 :                 return fourcc_string(buf, end, ptr, spec, fmt);
    2434             :         case 'a':
    2435           0 :                 return address_val(buf, end, ptr, spec, fmt);
    2436             :         case 'd':
    2437           0 :                 return dentry_name(buf, end, ptr, spec, fmt);
    2438             :         case 't':
    2439           0 :                 return time_and_date(buf, end, ptr, spec, fmt);
    2440             :         case 'C':
    2441           0 :                 return clock(buf, end, ptr, spec, fmt);
    2442             :         case 'D':
    2443           0 :                 return file_dentry_name(buf, end, ptr, spec, fmt);
    2444             : #ifdef CONFIG_BLOCK
    2445             :         case 'g':
    2446           0 :                 return bdev_name(buf, end, ptr, spec, fmt);
    2447             : #endif
    2448             : 
    2449             :         case 'G':
    2450           0 :                 return flags_string(buf, end, ptr, spec, fmt);
    2451             :         case 'O':
    2452           0 :                 return device_node_string(buf, end, ptr, spec, fmt + 1);
    2453             :         case 'f':
    2454           0 :                 return fwnode_string(buf, end, ptr, spec, fmt + 1);
    2455             :         case 'A':
    2456             :                 if (!IS_ENABLED(CONFIG_RUST)) {
    2457           0 :                         WARN_ONCE(1, "Please remove %%pA from non-Rust code\n");
    2458           0 :                         return error_string(buf, end, "(%pA?)", spec);
    2459             :                 }
    2460             :                 return rust_fmt_argument(buf, end, ptr);
    2461             :         case 'x':
    2462           0 :                 return pointer_string(buf, end, ptr, spec);
    2463             :         case 'e':
    2464             :                 /* %pe with a non-ERR_PTR gets treated as plain %p */
    2465           0 :                 if (!IS_ERR(ptr))
    2466           0 :                         return default_pointer(buf, end, ptr, spec);
    2467           0 :                 return err_ptr(buf, end, ptr, spec);
    2468             :         case 'u':
    2469             :         case 'k':
    2470           0 :                 switch (fmt[1]) {
    2471             :                 case 's':
    2472           0 :                         return string(buf, end, ptr, spec);
    2473             :                 default:
    2474           0 :                         return error_string(buf, end, "(einval)", spec);
    2475             :                 }
    2476             :         default:
    2477           0 :                 return default_pointer(buf, end, ptr, spec);
    2478             :         }
    2479             : }
    2480             : 
    2481             : /*
    2482             :  * Helper function to decode printf style format.
    2483             :  * Each call decode a token from the format and return the
    2484             :  * number of characters read (or likely the delta where it wants
    2485             :  * to go on the next call).
    2486             :  * The decoded token is returned through the parameters
    2487             :  *
    2488             :  * 'h', 'l', or 'L' for integer fields
    2489             :  * 'z' support added 23/7/1999 S.H.
    2490             :  * 'z' changed to 'Z' --davidm 1/25/99
    2491             :  * 'Z' changed to 'z' --adobriyan 2017-01-25
    2492             :  * 't' added for ptrdiff_t
    2493             :  *
    2494             :  * @fmt: the format string
    2495             :  * @type of the token returned
    2496             :  * @flags: various flags such as +, -, # tokens..
    2497             :  * @field_width: overwritten width
    2498             :  * @base: base of the number (octal, hex, ...)
    2499             :  * @precision: precision of a number
    2500             :  * @qualifier: qualifier of a number (long, size_t, ...)
    2501             :  */
    2502             : static noinline_for_stack
    2503       24405 : int format_decode(const char *fmt, struct printf_spec *spec)
    2504             : {
    2505       24405 :         const char *start = fmt;
    2506             :         char qualifier;
    2507             : 
    2508             :         /* we finished early by reading the field width */
    2509       24405 :         if (spec->type == FORMAT_TYPE_WIDTH) {
    2510           4 :                 if (spec->field_width < 0) {
    2511           0 :                         spec->field_width = -spec->field_width;
    2512           0 :                         spec->flags |= LEFT;
    2513             :                 }
    2514           4 :                 spec->type = FORMAT_TYPE_NONE;
    2515           4 :                 goto precision;
    2516             :         }
    2517             : 
    2518             :         /* we finished early by reading the precision */
    2519       24401 :         if (spec->type == FORMAT_TYPE_PRECISION) {
    2520          10 :                 if (spec->precision < 0)
    2521           0 :                         spec->precision = 0;
    2522             : 
    2523          10 :                 spec->type = FORMAT_TYPE_NONE;
    2524          10 :                 goto qualifier;
    2525             :         }
    2526             : 
    2527             :         /* By default */
    2528       24391 :         spec->type = FORMAT_TYPE_NONE;
    2529             : 
    2530      106527 :         for (; *fmt ; ++fmt) {
    2531      104933 :                 if (*fmt == '%')
    2532             :                         break;
    2533             :         }
    2534             : 
    2535             :         /* Return the current non-format string */
    2536       24391 :         if (fmt != start || !*fmt)
    2537       11154 :                 return fmt - start;
    2538             : 
    2539             :         /* Process flags */
    2540       13237 :         spec->flags = 0;
    2541             : 
    2542             :         while (1) { /* this also skips first '%' */
    2543       14216 :                 bool found = true;
    2544             : 
    2545       14216 :                 ++fmt;
    2546             : 
    2547       14216 :                 switch (*fmt) {
    2548           2 :                 case '-': spec->flags |= LEFT;    break;
    2549          52 :                 case '+': spec->flags |= PLUS;    break;
    2550           0 :                 case ' ': spec->flags |= SPACE;   break;
    2551         504 :                 case '#': spec->flags |= SPECIAL; break;
    2552         421 :                 case '0': spec->flags |= ZEROPAD; break;
    2553             :                 default:  found = false;
    2554             :                 }
    2555             : 
    2556       14216 :                 if (!found)
    2557             :                         break;
    2558             :         }
    2559             : 
    2560             :         /* get field width */
    2561       13237 :         spec->field_width = -1;
    2562             : 
    2563       26474 :         if (isdigit(*fmt))
    2564         421 :                 spec->field_width = skip_atoi(&fmt);
    2565       12816 :         else if (*fmt == '*') {
    2566             :                 /* it's the next argument */
    2567           4 :                 spec->type = FORMAT_TYPE_WIDTH;
    2568           4 :                 return ++fmt - start;
    2569             :         }
    2570             : 
    2571             : precision:
    2572             :         /* get the precision */
    2573       13237 :         spec->precision = -1;
    2574       13237 :         if (*fmt == '.') {
    2575          20 :                 ++fmt;
    2576          40 :                 if (isdigit(*fmt)) {
    2577          10 :                         spec->precision = skip_atoi(&fmt);
    2578          10 :                         if (spec->precision < 0)
    2579           0 :                                 spec->precision = 0;
    2580          10 :                 } else if (*fmt == '*') {
    2581             :                         /* it's the next argument */
    2582          10 :                         spec->type = FORMAT_TYPE_PRECISION;
    2583          10 :                         return ++fmt - start;
    2584             :                 }
    2585             :         }
    2586             : 
    2587             : qualifier:
    2588             :         /* get the conversion qualifier */
    2589       13237 :         qualifier = 0;
    2590       26474 :         if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
    2591       10832 :             *fmt == 'z' || *fmt == 't') {
    2592        2405 :                 qualifier = *fmt++;
    2593        2405 :                 if (unlikely(qualifier == *fmt)) {
    2594         751 :                         if (qualifier == 'l') {
    2595         751 :                                 qualifier = 'L';
    2596         751 :                                 ++fmt;
    2597           0 :                         } else if (qualifier == 'h') {
    2598           0 :                                 qualifier = 'H';
    2599           0 :                                 ++fmt;
    2600             :                         }
    2601             :                 }
    2602             :         }
    2603             : 
    2604             :         /* default base */
    2605       13237 :         spec->base = 10;
    2606       13237 :         switch (*fmt) {
    2607             :         case 'c':
    2608         512 :                 spec->type = FORMAT_TYPE_CHAR;
    2609         512 :                 return ++fmt - start;
    2610             : 
    2611             :         case 's':
    2612        6472 :                 spec->type = FORMAT_TYPE_STR;
    2613        6472 :                 return ++fmt - start;
    2614             : 
    2615             :         case 'p':
    2616         242 :                 spec->type = FORMAT_TYPE_PTR;
    2617         242 :                 return ++fmt - start;
    2618             : 
    2619             :         case '%':
    2620           0 :                 spec->type = FORMAT_TYPE_PERCENT_CHAR;
    2621           0 :                 return ++fmt - start;
    2622             : 
    2623             :         /* integer number formats - set up the flags and "break" */
    2624             :         case 'o':
    2625           8 :                 spec->base = 8;
    2626           8 :                 break;
    2627             : 
    2628             :         case 'x':
    2629        1382 :                 spec->flags |= SMALL;
    2630             :                 fallthrough;
    2631             : 
    2632             :         case 'X':
    2633        1382 :                 spec->base = 16;
    2634        1382 :                 break;
    2635             : 
    2636             :         case 'd':
    2637             :         case 'i':
    2638        1250 :                 spec->flags |= SIGN;
    2639        1250 :                 break;
    2640             :         case 'u':
    2641             :                 break;
    2642             : 
    2643             :         case 'n':
    2644             :                 /*
    2645             :                  * Since %n poses a greater security risk than
    2646             :                  * utility, treat it as any other invalid or
    2647             :                  * unsupported format specifier.
    2648             :                  */
    2649             :                 fallthrough;
    2650             : 
    2651             :         default:
    2652           0 :                 WARN_ONCE(1, "Please remove unsupported %%%c in format string\n", *fmt);
    2653           0 :                 spec->type = FORMAT_TYPE_INVALID;
    2654           0 :                 return fmt - start;
    2655             :         }
    2656             : 
    2657        6011 :         if (qualifier == 'L')
    2658         763 :                 spec->type = FORMAT_TYPE_LONG_LONG;
    2659        5248 :         else if (qualifier == 'l') {
    2660             :                 BUILD_BUG_ON(FORMAT_TYPE_ULONG + SIGN != FORMAT_TYPE_LONG);
    2661        1282 :                 spec->type = FORMAT_TYPE_ULONG + (spec->flags & SIGN);
    2662        3966 :         } else if (qualifier == 'z') {
    2663         360 :                 spec->type = FORMAT_TYPE_SIZE_T;
    2664        3606 :         } else if (qualifier == 't') {
    2665           0 :                 spec->type = FORMAT_TYPE_PTRDIFF;
    2666        3606 :         } else if (qualifier == 'H') {
    2667             :                 BUILD_BUG_ON(FORMAT_TYPE_UBYTE + SIGN != FORMAT_TYPE_BYTE);
    2668           0 :                 spec->type = FORMAT_TYPE_UBYTE + (spec->flags & SIGN);
    2669        3606 :         } else if (qualifier == 'h') {
    2670             :                 BUILD_BUG_ON(FORMAT_TYPE_USHORT + SIGN != FORMAT_TYPE_SHORT);
    2671           0 :                 spec->type = FORMAT_TYPE_USHORT + (spec->flags & SIGN);
    2672             :         } else {
    2673             :                 BUILD_BUG_ON(FORMAT_TYPE_UINT + SIGN != FORMAT_TYPE_INT);
    2674        3606 :                 spec->type = FORMAT_TYPE_UINT + (spec->flags & SIGN);
    2675             :         }
    2676             : 
    2677        6011 :         return ++fmt - start;
    2678             : }
    2679             : 
    2680             : static void
    2681           4 : set_field_width(struct printf_spec *spec, int width)
    2682             : {
    2683           4 :         spec->field_width = width;
    2684           4 :         if (WARN_ONCE(spec->field_width != width, "field width %d too large", width)) {
    2685           0 :                 spec->field_width = clamp(width, -FIELD_WIDTH_MAX, FIELD_WIDTH_MAX);
    2686             :         }
    2687           4 : }
    2688             : 
    2689             : static void
    2690          10 : set_precision(struct printf_spec *spec, int prec)
    2691             : {
    2692          10 :         spec->precision = prec;
    2693          10 :         if (WARN_ONCE(spec->precision != prec, "precision %d too large", prec)) {
    2694           0 :                 spec->precision = clamp(prec, 0, PRECISION_MAX);
    2695             :         }
    2696          10 : }
    2697             : 
    2698             : /**
    2699             :  * vsnprintf - Format a string and place it in a buffer
    2700             :  * @buf: The buffer to place the result into
    2701             :  * @size: The size of the buffer, including the trailing null space
    2702             :  * @fmt: The format string to use
    2703             :  * @args: Arguments for the format string
    2704             :  *
    2705             :  * This function generally follows C99 vsnprintf, but has some
    2706             :  * extensions and a few limitations:
    2707             :  *
    2708             :  *  - ``%n`` is unsupported
    2709             :  *  - ``%p*`` is handled by pointer()
    2710             :  *
    2711             :  * See pointer() or Documentation/core-api/printk-formats.rst for more
    2712             :  * extensive description.
    2713             :  *
    2714             :  * **Please update the documentation in both places when making changes**
    2715             :  *
    2716             :  * The return value is the number of characters which would
    2717             :  * be generated for the given input, excluding the trailing
    2718             :  * '\0', as per ISO C99. If you want to have the exact
    2719             :  * number of characters written into @buf as return value
    2720             :  * (not including the trailing '\0'), use vscnprintf(). If the
    2721             :  * return is greater than or equal to @size, the resulting
    2722             :  * string is truncated.
    2723             :  *
    2724             :  * If you're not already dealing with a va_list consider using snprintf().
    2725             :  */
    2726        8801 : int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
    2727             : {
    2728             :         unsigned long long num;
    2729             :         char *str, *end;
    2730        8801 :         struct printf_spec spec = {0};
    2731             : 
    2732             :         /* Reject out-of-range values early.  Large positive sizes are
    2733             :            used for unknown buffer sizes. */
    2734        8801 :         if (WARN_ON_ONCE(size > INT_MAX))
    2735             :                 return 0;
    2736             : 
    2737        8801 :         str = buf;
    2738        8801 :         end = buf + size;
    2739             : 
    2740             :         /* Make sure end is always >= buf */
    2741        8801 :         if (end < buf) {
    2742           0 :                 end = ((void *)-1);
    2743           0 :                 size = end - buf;
    2744             :         }
    2745             : 
    2746       33206 :         while (*fmt) {
    2747       24405 :                 const char *old_fmt = fmt;
    2748       24405 :                 int read = format_decode(fmt, &spec);
    2749             : 
    2750       24405 :                 fmt += read;
    2751             : 
    2752       24405 :                 switch (spec.type) {
    2753             :                 case FORMAT_TYPE_NONE: {
    2754       11154 :                         int copy = read;
    2755       11154 :                         if (str < end) {
    2756        9464 :                                 if (copy > end - str)
    2757         732 :                                         copy = end - str;
    2758        9464 :                                 memcpy(str, old_fmt, copy);
    2759             :                         }
    2760       11154 :                         str += read;
    2761       11154 :                         break;
    2762             :                 }
    2763             : 
    2764             :                 case FORMAT_TYPE_WIDTH:
    2765           4 :                         set_field_width(&spec, va_arg(args, int));
    2766           4 :                         break;
    2767             : 
    2768             :                 case FORMAT_TYPE_PRECISION:
    2769          10 :                         set_precision(&spec, va_arg(args, int));
    2770          10 :                         break;
    2771             : 
    2772             :                 case FORMAT_TYPE_CHAR: {
    2773             :                         char c;
    2774             : 
    2775         512 :                         if (!(spec.flags & LEFT)) {
    2776         512 :                                 while (--spec.field_width > 0) {
    2777           0 :                                         if (str < end)
    2778           0 :                                                 *str = ' ';
    2779           0 :                                         ++str;
    2780             : 
    2781             :                                 }
    2782             :                         }
    2783         512 :                         c = (unsigned char) va_arg(args, int);
    2784         512 :                         if (str < end)
    2785         512 :                                 *str = c;
    2786         512 :                         ++str;
    2787        1024 :                         while (--spec.field_width > 0) {
    2788           0 :                                 if (str < end)
    2789           0 :                                         *str = ' ';
    2790           0 :                                 ++str;
    2791             :                         }
    2792             :                         break;
    2793             :                 }
    2794             : 
    2795             :                 case FORMAT_TYPE_STR:
    2796        6472 :                         str = string(str, end, va_arg(args, char *), spec);
    2797        6472 :                         break;
    2798             : 
    2799             :                 case FORMAT_TYPE_PTR:
    2800         242 :                         str = pointer(fmt, str, end, va_arg(args, void *),
    2801             :                                       spec);
    2802         726 :                         while (isalnum(*fmt))
    2803         242 :                                 fmt++;
    2804             :                         break;
    2805             : 
    2806             :                 case FORMAT_TYPE_PERCENT_CHAR:
    2807           0 :                         if (str < end)
    2808           0 :                                 *str = '%';
    2809           0 :                         ++str;
    2810           0 :                         break;
    2811             : 
    2812             :                 case FORMAT_TYPE_INVALID:
    2813             :                         /*
    2814             :                          * Presumably the arguments passed gcc's type
    2815             :                          * checking, but there is no safe or sane way
    2816             :                          * for us to continue parsing the format and
    2817             :                          * fetching from the va_list; the remaining
    2818             :                          * specifiers and arguments would be out of
    2819             :                          * sync.
    2820             :                          */
    2821             :                         goto out;
    2822             : 
    2823             :                 default:
    2824        6011 :                         switch (spec.type) {
    2825             :                         case FORMAT_TYPE_LONG_LONG:
    2826         763 :                                 num = va_arg(args, long long);
    2827         763 :                                 break;
    2828             :                         case FORMAT_TYPE_ULONG:
    2829        1270 :                                 num = va_arg(args, unsigned long);
    2830        1270 :                                 break;
    2831             :                         case FORMAT_TYPE_LONG:
    2832          12 :                                 num = va_arg(args, long);
    2833          12 :                                 break;
    2834             :                         case FORMAT_TYPE_SIZE_T:
    2835         360 :                                 if (spec.flags & SIGN)
    2836         346 :                                         num = va_arg(args, ssize_t);
    2837             :                                 else
    2838          14 :                                         num = va_arg(args, size_t);
    2839             :                                 break;
    2840             :                         case FORMAT_TYPE_PTRDIFF:
    2841           0 :                                 num = va_arg(args, ptrdiff_t);
    2842           0 :                                 break;
    2843             :                         case FORMAT_TYPE_UBYTE:
    2844           0 :                                 num = (unsigned char) va_arg(args, int);
    2845           0 :                                 break;
    2846             :                         case FORMAT_TYPE_BYTE:
    2847           0 :                                 num = (signed char) va_arg(args, int);
    2848           0 :                                 break;
    2849             :                         case FORMAT_TYPE_USHORT:
    2850           0 :                                 num = (unsigned short) va_arg(args, int);
    2851           0 :                                 break;
    2852             :                         case FORMAT_TYPE_SHORT:
    2853           0 :                                 num = (short) va_arg(args, int);
    2854           0 :                                 break;
    2855             :                         case FORMAT_TYPE_INT:
    2856         888 :                                 num = (int) va_arg(args, int);
    2857         888 :                                 break;
    2858             :                         default:
    2859        2718 :                                 num = va_arg(args, unsigned int);
    2860             :                         }
    2861             : 
    2862        6011 :                         str = number(str, end, num, spec);
    2863             :                 }
    2864             :         }
    2865             : 
    2866             : out:
    2867        8801 :         if (size > 0) {
    2868        8440 :                 if (str < end)
    2869        7324 :                         *str = '\0';
    2870             :                 else
    2871        1116 :                         end[-1] = '\0';
    2872             :         }
    2873             : 
    2874             :         /* the trailing null byte doesn't count towards the total */
    2875        8801 :         return str-buf;
    2876             : 
    2877             : }
    2878             : EXPORT_SYMBOL(vsnprintf);
    2879             : 
    2880             : /**
    2881             :  * vscnprintf - Format a string and place it in a buffer
    2882             :  * @buf: The buffer to place the result into
    2883             :  * @size: The size of the buffer, including the trailing null space
    2884             :  * @fmt: The format string to use
    2885             :  * @args: Arguments for the format string
    2886             :  *
    2887             :  * The return value is the number of characters which have been written into
    2888             :  * the @buf not including the trailing '\0'. If @size is == 0 the function
    2889             :  * returns 0.
    2890             :  *
    2891             :  * If you're not already dealing with a va_list consider using scnprintf().
    2892             :  *
    2893             :  * See the vsnprintf() documentation for format string extensions over C99.
    2894             :  */
    2895         811 : int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
    2896             : {
    2897             :         int i;
    2898             : 
    2899         811 :         if (unlikely(!size))
    2900             :                 return 0;
    2901             : 
    2902         811 :         i = vsnprintf(buf, size, fmt, args);
    2903             : 
    2904         811 :         if (likely(i < size))
    2905             :                 return i;
    2906             : 
    2907           0 :         return size - 1;
    2908             : }
    2909             : EXPORT_SYMBOL(vscnprintf);
    2910             : 
    2911             : /**
    2912             :  * snprintf - Format a string and place it in a buffer
    2913             :  * @buf: The buffer to place the result into
    2914             :  * @size: The size of the buffer, including the trailing null space
    2915             :  * @fmt: The format string to use
    2916             :  * @...: Arguments for the format string
    2917             :  *
    2918             :  * The return value is the number of characters which would be
    2919             :  * generated for the given input, excluding the trailing null,
    2920             :  * as per ISO C99.  If the return is greater than or equal to
    2921             :  * @size, the resulting string is truncated.
    2922             :  *
    2923             :  * See the vsnprintf() documentation for format string extensions over C99.
    2924             :  */
    2925         123 : int snprintf(char *buf, size_t size, const char *fmt, ...)
    2926             : {
    2927             :         va_list args;
    2928             :         int i;
    2929             : 
    2930         123 :         va_start(args, fmt);
    2931         123 :         i = vsnprintf(buf, size, fmt, args);
    2932         123 :         va_end(args);
    2933             : 
    2934         123 :         return i;
    2935             : }
    2936             : EXPORT_SYMBOL(snprintf);
    2937             : 
    2938             : /**
    2939             :  * scnprintf - Format a string and place it in a buffer
    2940             :  * @buf: The buffer to place the result into
    2941             :  * @size: The size of the buffer, including the trailing null space
    2942             :  * @fmt: The format string to use
    2943             :  * @...: Arguments for the format string
    2944             :  *
    2945             :  * The return value is the number of characters written into @buf not including
    2946             :  * the trailing '\0'. If @size is == 0 the function returns 0.
    2947             :  */
    2948             : 
    2949           0 : int scnprintf(char *buf, size_t size, const char *fmt, ...)
    2950             : {
    2951             :         va_list args;
    2952             :         int i;
    2953             : 
    2954           0 :         va_start(args, fmt);
    2955           0 :         i = vscnprintf(buf, size, fmt, args);
    2956           0 :         va_end(args);
    2957             : 
    2958           0 :         return i;
    2959             : }
    2960             : EXPORT_SYMBOL(scnprintf);
    2961             : 
    2962             : /**
    2963             :  * vsprintf - Format a string and place it in a buffer
    2964             :  * @buf: The buffer to place the result into
    2965             :  * @fmt: The format string to use
    2966             :  * @args: Arguments for the format string
    2967             :  *
    2968             :  * The function returns the number of characters written
    2969             :  * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
    2970             :  * buffer overflows.
    2971             :  *
    2972             :  * If you're not already dealing with a va_list consider using sprintf().
    2973             :  *
    2974             :  * See the vsnprintf() documentation for format string extensions over C99.
    2975             :  */
    2976           0 : int vsprintf(char *buf, const char *fmt, va_list args)
    2977             : {
    2978           0 :         return vsnprintf(buf, INT_MAX, fmt, args);
    2979             : }
    2980             : EXPORT_SYMBOL(vsprintf);
    2981             : 
    2982             : /**
    2983             :  * sprintf - Format a string and place it in a buffer
    2984             :  * @buf: The buffer to place the result into
    2985             :  * @fmt: The format string to use
    2986             :  * @...: Arguments for the format string
    2987             :  *
    2988             :  * The function returns the number of characters written
    2989             :  * into @buf. Use snprintf() or scnprintf() in order to avoid
    2990             :  * buffer overflows.
    2991             :  *
    2992             :  * See the vsnprintf() documentation for format string extensions over C99.
    2993             :  */
    2994        1419 : int sprintf(char *buf, const char *fmt, ...)
    2995             : {
    2996             :         va_list args;
    2997             :         int i;
    2998             : 
    2999        1419 :         va_start(args, fmt);
    3000        1419 :         i = vsnprintf(buf, INT_MAX, fmt, args);
    3001        1419 :         va_end(args);
    3002             : 
    3003        1419 :         return i;
    3004             : }
    3005             : EXPORT_SYMBOL(sprintf);
    3006             : 
    3007             : #ifdef CONFIG_BINARY_PRINTF
    3008             : /*
    3009             :  * bprintf service:
    3010             :  * vbin_printf() - VA arguments to binary data
    3011             :  * bstr_printf() - Binary data to text string
    3012             :  */
    3013             : 
    3014             : /**
    3015             :  * vbin_printf - Parse a format string and place args' binary value in a buffer
    3016             :  * @bin_buf: The buffer to place args' binary value
    3017             :  * @size: The size of the buffer(by words(32bits), not characters)
    3018             :  * @fmt: The format string to use
    3019             :  * @args: Arguments for the format string
    3020             :  *
    3021             :  * The format follows C99 vsnprintf, except %n is ignored, and its argument
    3022             :  * is skipped.
    3023             :  *
    3024             :  * The return value is the number of words(32bits) which would be generated for
    3025             :  * the given input.
    3026             :  *
    3027             :  * NOTE:
    3028             :  * If the return value is greater than @size, the resulting bin_buf is NOT
    3029             :  * valid for bstr_printf().
    3030             :  */
    3031             : int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
    3032             : {
    3033             :         struct printf_spec spec = {0};
    3034             :         char *str, *end;
    3035             :         int width;
    3036             : 
    3037             :         str = (char *)bin_buf;
    3038             :         end = (char *)(bin_buf + size);
    3039             : 
    3040             : #define save_arg(type)                                                  \
    3041             : ({                                                                      \
    3042             :         unsigned long long value;                                       \
    3043             :         if (sizeof(type) == 8) {                                        \
    3044             :                 unsigned long long val8;                                \
    3045             :                 str = PTR_ALIGN(str, sizeof(u32));                      \
    3046             :                 val8 = va_arg(args, unsigned long long);                \
    3047             :                 if (str + sizeof(type) <= end) {                     \
    3048             :                         *(u32 *)str = *(u32 *)&val8;                        \
    3049             :                         *(u32 *)(str + 4) = *((u32 *)&val8 + 1);    \
    3050             :                 }                                                       \
    3051             :                 value = val8;                                           \
    3052             :         } else {                                                        \
    3053             :                 unsigned int val4;                                      \
    3054             :                 str = PTR_ALIGN(str, sizeof(type));                     \
    3055             :                 val4 = va_arg(args, int);                               \
    3056             :                 if (str + sizeof(type) <= end)                               \
    3057             :                         *(typeof(type) *)str = (type)(long)val4;        \
    3058             :                 value = (unsigned long long)val4;                       \
    3059             :         }                                                               \
    3060             :         str += sizeof(type);                                            \
    3061             :         value;                                                          \
    3062             : })
    3063             : 
    3064             :         while (*fmt) {
    3065             :                 int read = format_decode(fmt, &spec);
    3066             : 
    3067             :                 fmt += read;
    3068             : 
    3069             :                 switch (spec.type) {
    3070             :                 case FORMAT_TYPE_NONE:
    3071             :                 case FORMAT_TYPE_PERCENT_CHAR:
    3072             :                         break;
    3073             :                 case FORMAT_TYPE_INVALID:
    3074             :                         goto out;
    3075             : 
    3076             :                 case FORMAT_TYPE_WIDTH:
    3077             :                 case FORMAT_TYPE_PRECISION:
    3078             :                         width = (int)save_arg(int);
    3079             :                         /* Pointers may require the width */
    3080             :                         if (*fmt == 'p')
    3081             :                                 set_field_width(&spec, width);
    3082             :                         break;
    3083             : 
    3084             :                 case FORMAT_TYPE_CHAR:
    3085             :                         save_arg(char);
    3086             :                         break;
    3087             : 
    3088             :                 case FORMAT_TYPE_STR: {
    3089             :                         const char *save_str = va_arg(args, char *);
    3090             :                         const char *err_msg;
    3091             :                         size_t len;
    3092             : 
    3093             :                         err_msg = check_pointer_msg(save_str);
    3094             :                         if (err_msg)
    3095             :                                 save_str = err_msg;
    3096             : 
    3097             :                         len = strlen(save_str) + 1;
    3098             :                         if (str + len < end)
    3099             :                                 memcpy(str, save_str, len);
    3100             :                         str += len;
    3101             :                         break;
    3102             :                 }
    3103             : 
    3104             :                 case FORMAT_TYPE_PTR:
    3105             :                         /* Dereferenced pointers must be done now */
    3106             :                         switch (*fmt) {
    3107             :                         /* Dereference of functions is still OK */
    3108             :                         case 'S':
    3109             :                         case 's':
    3110             :                         case 'x':
    3111             :                         case 'K':
    3112             :                         case 'e':
    3113             :                                 save_arg(void *);
    3114             :                                 break;
    3115             :                         default:
    3116             :                                 if (!isalnum(*fmt)) {
    3117             :                                         save_arg(void *);
    3118             :                                         break;
    3119             :                                 }
    3120             :                                 str = pointer(fmt, str, end, va_arg(args, void *),
    3121             :                                               spec);
    3122             :                                 if (str + 1 < end)
    3123             :                                         *str++ = '\0';
    3124             :                                 else
    3125             :                                         end[-1] = '\0'; /* Must be nul terminated */
    3126             :                         }
    3127             :                         /* skip all alphanumeric pointer suffixes */
    3128             :                         while (isalnum(*fmt))
    3129             :                                 fmt++;
    3130             :                         break;
    3131             : 
    3132             :                 default:
    3133             :                         switch (spec.type) {
    3134             : 
    3135             :                         case FORMAT_TYPE_LONG_LONG:
    3136             :                                 save_arg(long long);
    3137             :                                 break;
    3138             :                         case FORMAT_TYPE_ULONG:
    3139             :                         case FORMAT_TYPE_LONG:
    3140             :                                 save_arg(unsigned long);
    3141             :                                 break;
    3142             :                         case FORMAT_TYPE_SIZE_T:
    3143             :                                 save_arg(size_t);
    3144             :                                 break;
    3145             :                         case FORMAT_TYPE_PTRDIFF:
    3146             :                                 save_arg(ptrdiff_t);
    3147             :                                 break;
    3148             :                         case FORMAT_TYPE_UBYTE:
    3149             :                         case FORMAT_TYPE_BYTE:
    3150             :                                 save_arg(char);
    3151             :                                 break;
    3152             :                         case FORMAT_TYPE_USHORT:
    3153             :                         case FORMAT_TYPE_SHORT:
    3154             :                                 save_arg(short);
    3155             :                                 break;
    3156             :                         default:
    3157             :                                 save_arg(int);
    3158             :                         }
    3159             :                 }
    3160             :         }
    3161             : 
    3162             : out:
    3163             :         return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
    3164             : #undef save_arg
    3165             : }
    3166             : EXPORT_SYMBOL_GPL(vbin_printf);
    3167             : 
    3168             : /**
    3169             :  * bstr_printf - Format a string from binary arguments and place it in a buffer
    3170             :  * @buf: The buffer to place the result into
    3171             :  * @size: The size of the buffer, including the trailing null space
    3172             :  * @fmt: The format string to use
    3173             :  * @bin_buf: Binary arguments for the format string
    3174             :  *
    3175             :  * This function like C99 vsnprintf, but the difference is that vsnprintf gets
    3176             :  * arguments from stack, and bstr_printf gets arguments from @bin_buf which is
    3177             :  * a binary buffer that generated by vbin_printf.
    3178             :  *
    3179             :  * The format follows C99 vsnprintf, but has some extensions:
    3180             :  *  see vsnprintf comment for details.
    3181             :  *
    3182             :  * The return value is the number of characters which would
    3183             :  * be generated for the given input, excluding the trailing
    3184             :  * '\0', as per ISO C99. If you want to have the exact
    3185             :  * number of characters written into @buf as return value
    3186             :  * (not including the trailing '\0'), use vscnprintf(). If the
    3187             :  * return is greater than or equal to @size, the resulting
    3188             :  * string is truncated.
    3189             :  */
    3190             : int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
    3191             : {
    3192             :         struct printf_spec spec = {0};
    3193             :         char *str, *end;
    3194             :         const char *args = (const char *)bin_buf;
    3195             : 
    3196             :         if (WARN_ON_ONCE(size > INT_MAX))
    3197             :                 return 0;
    3198             : 
    3199             :         str = buf;
    3200             :         end = buf + size;
    3201             : 
    3202             : #define get_arg(type)                                                   \
    3203             : ({                                                                      \
    3204             :         typeof(type) value;                                             \
    3205             :         if (sizeof(type) == 8) {                                        \
    3206             :                 args = PTR_ALIGN(args, sizeof(u32));                    \
    3207             :                 *(u32 *)&value = *(u32 *)args;                              \
    3208             :                 *((u32 *)&value + 1) = *(u32 *)(args + 4);          \
    3209             :         } else {                                                        \
    3210             :                 args = PTR_ALIGN(args, sizeof(type));                   \
    3211             :                 value = *(typeof(type) *)args;                          \
    3212             :         }                                                               \
    3213             :         args += sizeof(type);                                           \
    3214             :         value;                                                          \
    3215             : })
    3216             : 
    3217             :         /* Make sure end is always >= buf */
    3218             :         if (end < buf) {
    3219             :                 end = ((void *)-1);
    3220             :                 size = end - buf;
    3221             :         }
    3222             : 
    3223             :         while (*fmt) {
    3224             :                 const char *old_fmt = fmt;
    3225             :                 int read = format_decode(fmt, &spec);
    3226             : 
    3227             :                 fmt += read;
    3228             : 
    3229             :                 switch (spec.type) {
    3230             :                 case FORMAT_TYPE_NONE: {
    3231             :                         int copy = read;
    3232             :                         if (str < end) {
    3233             :                                 if (copy > end - str)
    3234             :                                         copy = end - str;
    3235             :                                 memcpy(str, old_fmt, copy);
    3236             :                         }
    3237             :                         str += read;
    3238             :                         break;
    3239             :                 }
    3240             : 
    3241             :                 case FORMAT_TYPE_WIDTH:
    3242             :                         set_field_width(&spec, get_arg(int));
    3243             :                         break;
    3244             : 
    3245             :                 case FORMAT_TYPE_PRECISION:
    3246             :                         set_precision(&spec, get_arg(int));
    3247             :                         break;
    3248             : 
    3249             :                 case FORMAT_TYPE_CHAR: {
    3250             :                         char c;
    3251             : 
    3252             :                         if (!(spec.flags & LEFT)) {
    3253             :                                 while (--spec.field_width > 0) {
    3254             :                                         if (str < end)
    3255             :                                                 *str = ' ';
    3256             :                                         ++str;
    3257             :                                 }
    3258             :                         }
    3259             :                         c = (unsigned char) get_arg(char);
    3260             :                         if (str < end)
    3261             :                                 *str = c;
    3262             :                         ++str;
    3263             :                         while (--spec.field_width > 0) {
    3264             :                                 if (str < end)
    3265             :                                         *str = ' ';
    3266             :                                 ++str;
    3267             :                         }
    3268             :                         break;
    3269             :                 }
    3270             : 
    3271             :                 case FORMAT_TYPE_STR: {
    3272             :                         const char *str_arg = args;
    3273             :                         args += strlen(str_arg) + 1;
    3274             :                         str = string(str, end, (char *)str_arg, spec);
    3275             :                         break;
    3276             :                 }
    3277             : 
    3278             :                 case FORMAT_TYPE_PTR: {
    3279             :                         bool process = false;
    3280             :                         int copy, len;
    3281             :                         /* Non function dereferences were already done */
    3282             :                         switch (*fmt) {
    3283             :                         case 'S':
    3284             :                         case 's':
    3285             :                         case 'x':
    3286             :                         case 'K':
    3287             :                         case 'e':
    3288             :                                 process = true;
    3289             :                                 break;
    3290             :                         default:
    3291             :                                 if (!isalnum(*fmt)) {
    3292             :                                         process = true;
    3293             :                                         break;
    3294             :                                 }
    3295             :                                 /* Pointer dereference was already processed */
    3296             :                                 if (str < end) {
    3297             :                                         len = copy = strlen(args);
    3298             :                                         if (copy > end - str)
    3299             :                                                 copy = end - str;
    3300             :                                         memcpy(str, args, copy);
    3301             :                                         str += len;
    3302             :                                         args += len + 1;
    3303             :                                 }
    3304             :                         }
    3305             :                         if (process)
    3306             :                                 str = pointer(fmt, str, end, get_arg(void *), spec);
    3307             : 
    3308             :                         while (isalnum(*fmt))
    3309             :                                 fmt++;
    3310             :                         break;
    3311             :                 }
    3312             : 
    3313             :                 case FORMAT_TYPE_PERCENT_CHAR:
    3314             :                         if (str < end)
    3315             :                                 *str = '%';
    3316             :                         ++str;
    3317             :                         break;
    3318             : 
    3319             :                 case FORMAT_TYPE_INVALID:
    3320             :                         goto out;
    3321             : 
    3322             :                 default: {
    3323             :                         unsigned long long num;
    3324             : 
    3325             :                         switch (spec.type) {
    3326             : 
    3327             :                         case FORMAT_TYPE_LONG_LONG:
    3328             :                                 num = get_arg(long long);
    3329             :                                 break;
    3330             :                         case FORMAT_TYPE_ULONG:
    3331             :                         case FORMAT_TYPE_LONG:
    3332             :                                 num = get_arg(unsigned long);
    3333             :                                 break;
    3334             :                         case FORMAT_TYPE_SIZE_T:
    3335             :                                 num = get_arg(size_t);
    3336             :                                 break;
    3337             :                         case FORMAT_TYPE_PTRDIFF:
    3338             :                                 num = get_arg(ptrdiff_t);
    3339             :                                 break;
    3340             :                         case FORMAT_TYPE_UBYTE:
    3341             :                                 num = get_arg(unsigned char);
    3342             :                                 break;
    3343             :                         case FORMAT_TYPE_BYTE:
    3344             :                                 num = get_arg(signed char);
    3345             :                                 break;
    3346             :                         case FORMAT_TYPE_USHORT:
    3347             :                                 num = get_arg(unsigned short);
    3348             :                                 break;
    3349             :                         case FORMAT_TYPE_SHORT:
    3350             :                                 num = get_arg(short);
    3351             :                                 break;
    3352             :                         case FORMAT_TYPE_UINT:
    3353             :                                 num = get_arg(unsigned int);
    3354             :                                 break;
    3355             :                         default:
    3356             :                                 num = get_arg(int);
    3357             :                         }
    3358             : 
    3359             :                         str = number(str, end, num, spec);
    3360             :                 } /* default: */
    3361             :                 } /* switch(spec.type) */
    3362             :         } /* while(*fmt) */
    3363             : 
    3364             : out:
    3365             :         if (size > 0) {
    3366             :                 if (str < end)
    3367             :                         *str = '\0';
    3368             :                 else
    3369             :                         end[-1] = '\0';
    3370             :         }
    3371             : 
    3372             : #undef get_arg
    3373             : 
    3374             :         /* the trailing null byte doesn't count towards the total */
    3375             :         return str - buf;
    3376             : }
    3377             : EXPORT_SYMBOL_GPL(bstr_printf);
    3378             : 
    3379             : /**
    3380             :  * bprintf - Parse a format string and place args' binary value in a buffer
    3381             :  * @bin_buf: The buffer to place args' binary value
    3382             :  * @size: The size of the buffer(by words(32bits), not characters)
    3383             :  * @fmt: The format string to use
    3384             :  * @...: Arguments for the format string
    3385             :  *
    3386             :  * The function returns the number of words(u32) written
    3387             :  * into @bin_buf.
    3388             :  */
    3389             : int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
    3390             : {
    3391             :         va_list args;
    3392             :         int ret;
    3393             : 
    3394             :         va_start(args, fmt);
    3395             :         ret = vbin_printf(bin_buf, size, fmt, args);
    3396             :         va_end(args);
    3397             : 
    3398             :         return ret;
    3399             : }
    3400             : EXPORT_SYMBOL_GPL(bprintf);
    3401             : 
    3402             : #endif /* CONFIG_BINARY_PRINTF */
    3403             : 
    3404             : /**
    3405             :  * vsscanf - Unformat a buffer into a list of arguments
    3406             :  * @buf:        input buffer
    3407             :  * @fmt:        format of buffer
    3408             :  * @args:       arguments
    3409             :  */
    3410           0 : int vsscanf(const char *buf, const char *fmt, va_list args)
    3411             : {
    3412           0 :         const char *str = buf;
    3413             :         char *next;
    3414             :         char digit;
    3415           0 :         int num = 0;
    3416             :         u8 qualifier;
    3417             :         unsigned int base;
    3418             :         union {
    3419             :                 long long s;
    3420             :                 unsigned long long u;
    3421             :         } val;
    3422             :         s16 field_width;
    3423             :         bool is_sign;
    3424             : 
    3425           0 :         while (*fmt) {
    3426             :                 /* skip any white space in format */
    3427             :                 /* white space in format matches any amount of
    3428             :                  * white space, including none, in the input.
    3429             :                  */
    3430           0 :                 if (isspace(*fmt)) {
    3431           0 :                         fmt = skip_spaces(++fmt);
    3432           0 :                         str = skip_spaces(str);
    3433             :                 }
    3434             : 
    3435             :                 /* anything that is not a conversion must match exactly */
    3436           0 :                 if (*fmt != '%' && *fmt) {
    3437           0 :                         if (*fmt++ != *str++)
    3438             :                                 break;
    3439           0 :                         continue;
    3440             :                 }
    3441             : 
    3442           0 :                 if (!*fmt)
    3443             :                         break;
    3444           0 :                 ++fmt;
    3445             : 
    3446             :                 /* skip this conversion.
    3447             :                  * advance both strings to next white space
    3448             :                  */
    3449           0 :                 if (*fmt == '*') {
    3450           0 :                         if (!*str)
    3451             :                                 break;
    3452           0 :                         while (!isspace(*fmt) && *fmt != '%' && *fmt) {
    3453             :                                 /* '%*[' not yet supported, invalid format */
    3454           0 :                                 if (*fmt == '[')
    3455             :                                         return num;
    3456           0 :                                 fmt++;
    3457             :                         }
    3458           0 :                         while (!isspace(*str) && *str)
    3459           0 :                                 str++;
    3460           0 :                         continue;
    3461             :                 }
    3462             : 
    3463             :                 /* get field width */
    3464           0 :                 field_width = -1;
    3465           0 :                 if (isdigit(*fmt)) {
    3466           0 :                         field_width = skip_atoi(&fmt);
    3467           0 :                         if (field_width <= 0)
    3468             :                                 break;
    3469             :                 }
    3470             : 
    3471             :                 /* get conversion qualifier */
    3472           0 :                 qualifier = -1;
    3473           0 :                 if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
    3474             :                     *fmt == 'z') {
    3475           0 :                         qualifier = *fmt++;
    3476           0 :                         if (unlikely(qualifier == *fmt)) {
    3477           0 :                                 if (qualifier == 'h') {
    3478           0 :                                         qualifier = 'H';
    3479           0 :                                         fmt++;
    3480           0 :                                 } else if (qualifier == 'l') {
    3481           0 :                                         qualifier = 'L';
    3482           0 :                                         fmt++;
    3483             :                                 }
    3484             :                         }
    3485             :                 }
    3486             : 
    3487           0 :                 if (!*fmt)
    3488             :                         break;
    3489             : 
    3490           0 :                 if (*fmt == 'n') {
    3491             :                         /* return number of characters read so far */
    3492           0 :                         *va_arg(args, int *) = str - buf;
    3493           0 :                         ++fmt;
    3494           0 :                         continue;
    3495             :                 }
    3496             : 
    3497           0 :                 if (!*str)
    3498             :                         break;
    3499             : 
    3500           0 :                 base = 10;
    3501           0 :                 is_sign = false;
    3502             : 
    3503           0 :                 switch (*fmt++) {
    3504             :                 case 'c':
    3505             :                 {
    3506           0 :                         char *s = (char *)va_arg(args, char*);
    3507           0 :                         if (field_width == -1)
    3508           0 :                                 field_width = 1;
    3509             :                         do {
    3510           0 :                                 *s++ = *str++;
    3511           0 :                         } while (--field_width > 0 && *str);
    3512           0 :                         num++;
    3513             :                 }
    3514           0 :                 continue;
    3515             :                 case 's':
    3516             :                 {
    3517           0 :                         char *s = (char *)va_arg(args, char *);
    3518           0 :                         if (field_width == -1)
    3519           0 :                                 field_width = SHRT_MAX;
    3520             :                         /* first, skip leading white space in buffer */
    3521           0 :                         str = skip_spaces(str);
    3522             : 
    3523             :                         /* now copy until next white space */
    3524           0 :                         while (*str && !isspace(*str) && field_width--)
    3525           0 :                                 *s++ = *str++;
    3526           0 :                         *s = '\0';
    3527           0 :                         num++;
    3528             :                 }
    3529           0 :                 continue;
    3530             :                 /*
    3531             :                  * Warning: This implementation of the '[' conversion specifier
    3532             :                  * deviates from its glibc counterpart in the following ways:
    3533             :                  * (1) It does NOT support ranges i.e. '-' is NOT a special
    3534             :                  *     character
    3535             :                  * (2) It cannot match the closing bracket ']' itself
    3536             :                  * (3) A field width is required
    3537             :                  * (4) '%*[' (discard matching input) is currently not supported
    3538             :                  *
    3539             :                  * Example usage:
    3540             :                  * ret = sscanf("00:0a:95","%2[^:]:%2[^:]:%2[^:]",
    3541             :                  *              buf1, buf2, buf3);
    3542             :                  * if (ret < 3)
    3543             :                  *    // etc..
    3544             :                  */
    3545             :                 case '[':
    3546             :                 {
    3547           0 :                         char *s = (char *)va_arg(args, char *);
    3548           0 :                         DECLARE_BITMAP(set, 256) = {0};
    3549           0 :                         unsigned int len = 0;
    3550           0 :                         bool negate = (*fmt == '^');
    3551             : 
    3552             :                         /* field width is required */
    3553           0 :                         if (field_width == -1)
    3554           0 :                                 return num;
    3555             : 
    3556           0 :                         if (negate)
    3557           0 :                                 ++fmt;
    3558             : 
    3559           0 :                         for ( ; *fmt && *fmt != ']'; ++fmt, ++len)
    3560           0 :                                 __set_bit((u8)*fmt, set);
    3561             : 
    3562             :                         /* no ']' or no character set found */
    3563           0 :                         if (!*fmt || !len)
    3564             :                                 return num;
    3565           0 :                         ++fmt;
    3566             : 
    3567           0 :                         if (negate) {
    3568           0 :                                 bitmap_complement(set, set, 256);
    3569             :                                 /* exclude null '\0' byte */
    3570           0 :                                 __clear_bit(0, set);
    3571             :                         }
    3572             : 
    3573             :                         /* match must be non-empty */
    3574           0 :                         if (!test_bit((u8)*str, set))
    3575             :                                 return num;
    3576             : 
    3577           0 :                         while (test_bit((u8)*str, set) && field_width--)
    3578           0 :                                 *s++ = *str++;
    3579           0 :                         *s = '\0';
    3580           0 :                         ++num;
    3581             :                 }
    3582           0 :                 continue;
    3583             :                 case 'o':
    3584           0 :                         base = 8;
    3585           0 :                         break;
    3586             :                 case 'x':
    3587             :                 case 'X':
    3588           0 :                         base = 16;
    3589           0 :                         break;
    3590             :                 case 'i':
    3591           0 :                         base = 0;
    3592             :                         fallthrough;
    3593             :                 case 'd':
    3594             :                         is_sign = true;
    3595             :                         fallthrough;
    3596             :                 case 'u':
    3597             :                         break;
    3598             :                 case '%':
    3599             :                         /* looking for '%' in str */
    3600           0 :                         if (*str++ != '%')
    3601             :                                 return num;
    3602           0 :                         continue;
    3603             :                 default:
    3604             :                         /* invalid format; stop here */
    3605             :                         return num;
    3606             :                 }
    3607             : 
    3608             :                 /* have some sort of integer conversion.
    3609             :                  * first, skip white space in buffer.
    3610             :                  */
    3611           0 :                 str = skip_spaces(str);
    3612             : 
    3613           0 :                 digit = *str;
    3614           0 :                 if (is_sign && digit == '-') {
    3615           0 :                         if (field_width == 1)
    3616             :                                 break;
    3617             : 
    3618           0 :                         digit = *(str + 1);
    3619             :                 }
    3620             : 
    3621           0 :                 if (!digit
    3622           0 :                     || (base == 16 && !isxdigit(digit))
    3623           0 :                     || (base == 10 && !isdigit(digit))
    3624           0 :                     || (base == 8 && (!isdigit(digit) || digit > '7'))
    3625           0 :                     || (base == 0 && !isdigit(digit)))
    3626             :                         break;
    3627             : 
    3628           0 :                 if (is_sign)
    3629           0 :                         val.s = simple_strntoll(str,
    3630             :                                                 field_width >= 0 ? field_width : INT_MAX,
    3631             :                                                 &next, base);
    3632             :                 else
    3633           0 :                         val.u = simple_strntoull(str,
    3634             :                                                  field_width >= 0 ? field_width : INT_MAX,
    3635             :                                                  &next, base);
    3636             : 
    3637           0 :                 switch (qualifier) {
    3638             :                 case 'H':       /* that's 'hh' in format */
    3639           0 :                         if (is_sign)
    3640           0 :                                 *va_arg(args, signed char *) = val.s;
    3641             :                         else
    3642           0 :                                 *va_arg(args, unsigned char *) = val.u;
    3643             :                         break;
    3644             :                 case 'h':
    3645           0 :                         if (is_sign)
    3646           0 :                                 *va_arg(args, short *) = val.s;
    3647             :                         else
    3648           0 :                                 *va_arg(args, unsigned short *) = val.u;
    3649             :                         break;
    3650             :                 case 'l':
    3651           0 :                         if (is_sign)
    3652           0 :                                 *va_arg(args, long *) = val.s;
    3653             :                         else
    3654           0 :                                 *va_arg(args, unsigned long *) = val.u;
    3655             :                         break;
    3656             :                 case 'L':
    3657           0 :                         if (is_sign)
    3658           0 :                                 *va_arg(args, long long *) = val.s;
    3659             :                         else
    3660           0 :                                 *va_arg(args, unsigned long long *) = val.u;
    3661             :                         break;
    3662             :                 case 'z':
    3663           0 :                         *va_arg(args, size_t *) = val.u;
    3664           0 :                         break;
    3665             :                 default:
    3666           0 :                         if (is_sign)
    3667           0 :                                 *va_arg(args, int *) = val.s;
    3668             :                         else
    3669           0 :                                 *va_arg(args, unsigned int *) = val.u;
    3670             :                         break;
    3671             :                 }
    3672           0 :                 num++;
    3673             : 
    3674           0 :                 if (!next)
    3675             :                         break;
    3676             :                 str = next;
    3677             :         }
    3678             : 
    3679             :         return num;
    3680             : }
    3681             : EXPORT_SYMBOL(vsscanf);
    3682             : 
    3683             : /**
    3684             :  * sscanf - Unformat a buffer into a list of arguments
    3685             :  * @buf:        input buffer
    3686             :  * @fmt:        formatting of buffer
    3687             :  * @...:        resulting arguments
    3688             :  */
    3689           0 : int sscanf(const char *buf, const char *fmt, ...)
    3690             : {
    3691             :         va_list args;
    3692             :         int i;
    3693             : 
    3694           0 :         va_start(args, fmt);
    3695           0 :         i = vsscanf(buf, fmt, args);
    3696           0 :         va_end(args);
    3697             : 
    3698           0 :         return i;
    3699             : }
    3700             : EXPORT_SYMBOL(sscanf);

Generated by: LCOV version 1.14