LCOV - code coverage report
Current view: top level - lib - vsprintf.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 350 1226 28.5 %
Date: 2023-08-24 13:40:31 Functions: 26 75 34.7 %

          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           6 : 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           6 :         unsigned long long result = 0ULL;
      66             :         size_t prefix_chars;
      67             :         unsigned int rv;
      68             : 
      69           6 :         cp = _parse_integer_fixup_radix(startp, &base);
      70           6 :         prefix_chars = cp - startp;
      71           6 :         if (prefix_chars < max_chars) {
      72           6 :                 rv = _parse_integer_limit(cp, base, &result, max_chars - prefix_chars);
      73             :                 /* FIXME */
      74           6 :                 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           6 :         if (endp)
      81           5 :                 *endp = (char *)cp;
      82             : 
      83           6 :         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           6 : unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
      96             : {
      97           6 :         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           1 :         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           0 : long simple_strtol(const char *cp, char **endp, unsigned int base)
     124             : {
     125           0 :         if (*cp == '-')
     126           0 :                 return -simple_strtoul(cp + 1, endp, base);
     127             : 
     128           0 :         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         141 : int skip_atoi(const char **s)
     163             : {
     164         141 :         int i = 0;
     165             : 
     166             :         do {
     167         157 :                 i = i*10 + *((*s)++) - '0';
     168         314 :         } while (isdigit(**s));
     169             : 
     170         141 :         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        1849 : char *put_dec_trunc8(char *buf, unsigned r)
     221             : {
     222             :         unsigned q;
     223             : 
     224             :         /* 1 <= r < 10^8 */
     225        1849 :         if (r < 100)
     226             :                 goto out_r;
     227             : 
     228             :         /* 100 <= r < 10^8 */
     229        1267 :         q = (r * (u64)0x28f5c29) >> 32;
     230        1267 :         *((u16 *)buf) = decpair[r - 100*q];
     231        1267 :         buf += 2;
     232             : 
     233             :         /* 1 <= q < 10^6 */
     234        1267 :         if (q < 100)
     235             :                 goto out_q;
     236             : 
     237             :         /*  100 <= q < 10^6 */
     238          31 :         r = (q * (u64)0x28f5c29) >> 32;
     239          31 :         *((u16 *)buf) = decpair[q - 100*r];
     240          31 :         buf += 2;
     241             : 
     242             :         /* 1 <= r < 10^4 */
     243          31 :         if (r < 100)
     244             :                 goto out_r;
     245             : 
     246             :         /* 100 <= r < 10^4 */
     247           8 :         q = (r * 0x147b) >> 19;
     248           8 :         *((u16 *)buf) = decpair[r - 100*q];
     249           8 :         buf += 2;
     250             : out_q:
     251             :         /* 1 <= q < 100 */
     252             :         r = q;
     253             : out_r:
     254             :         /* 1 <= r < 100 */
     255        1849 :         *((u16 *)buf) = decpair[r];
     256        1849 :         buf += r < 10 ? 1 : 2;
     257        1849 :         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        1849 : char *put_dec(char *buf, unsigned long long n)
     289             : {
     290        1849 :         if (n >= 100*1000*1000)
     291           4 :                 buf = put_dec_full8(buf, do_div(n, 100*1000*1000));
     292             :         /* 1 <= n <= 1.6e11 */
     293        1849 :         if (n >= 100*1000*1000)
     294           2 :                 buf = put_dec_full8(buf, do_div(n, 100*1000*1000));
     295             :         /* 1 <= n < 1e8 */
     296        1849 :         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        4149 : 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        4149 :         int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
     463             :         int i;
     464        4149 :         bool is_zero = num == 0LL;
     465        4149 :         int field_width = spec.field_width;
     466        4149 :         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        4149 :         locase = (spec.flags & SMALL);
     471        4149 :         if (spec.flags & LEFT)
     472           0 :                 spec.flags &= ~ZEROPAD;
     473        4149 :         sign = 0;
     474        4149 :         if (spec.flags & SIGN) {
     475         384 :                 if ((signed long long)num < 0) {
     476           2 :                         sign = '-';
     477           2 :                         num = -(signed long long)num;
     478           2 :                         field_width--;
     479         382 :                 } else if (spec.flags & PLUS) {
     480           0 :                         sign = '+';
     481           0 :                         field_width--;
     482         382 :                 } else if (spec.flags & SPACE) {
     483           0 :                         sign = ' ';
     484           0 :                         field_width--;
     485             :                 }
     486             :         }
     487        4149 :         if (need_pfx) {
     488         144 :                 if (spec.base == 16)
     489         136 :                         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        4149 :         i = 0;
     496        4149 :         if (num < spec.base)
     497        2102 :                 tmp[i++] = hex_asc_upper[num] | locase;
     498        2047 :         else if (spec.base != 10) { /* 8 or 16 */
     499         198 :                 int mask = spec.base - 1;
     500         198 :                 int shift = 3;
     501             : 
     502         198 :                 if (spec.base == 16)
     503         190 :                         shift = 4;
     504             :                 do {
     505        1086 :                         tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] | locase);
     506        1086 :                         num >>= shift;
     507        1086 :                 } while (num);
     508             :         } else { /* base 10 */
     509        1849 :                 i = put_dec(tmp, num) - tmp;
     510             :         }
     511             : 
     512             :         /* printing 100 using %2d gives "100", not "00" */
     513        4149 :         if (i > precision)
     514        4149 :                 precision = i;
     515             :         /* leading space padding */
     516        4149 :         field_width -= precision;
     517        4149 :         if (!(spec.flags & (ZEROPAD | LEFT))) {
     518        4002 :                 while (--field_width >= 0) {
     519           4 :                         if (buf < end)
     520           2 :                                 *buf = ' ';
     521           4 :                         ++buf;
     522             :                 }
     523             :         }
     524             :         /* sign */
     525        4149 :         if (sign) {
     526           2 :                 if (buf < end)
     527           1 :                         *buf = sign;
     528           2 :                 ++buf;
     529             :         }
     530             :         /* "0x" / "0" prefix */
     531        4149 :         if (need_pfx) {
     532         144 :                 if (spec.base == 16 || !is_zero) {
     533         144 :                         if (buf < end)
     534         139 :                                 *buf = '0';
     535         144 :                         ++buf;
     536             :                 }
     537         144 :                 if (spec.base == 16) {
     538         136 :                         if (buf < end)
     539         130 :                                 *buf = ('X' | locase);
     540         136 :                         ++buf;
     541             :                 }
     542             :         }
     543             :         /* zero or space padding */
     544        4149 :         if (!(spec.flags & LEFT)) {
     545        4149 :                 char c = ' ' + (spec.flags & ZEROPAD);
     546             : 
     547        8651 :                 while (--field_width >= 0) {
     548         353 :                         if (buf < end)
     549         267 :                                 *buf = c;
     550         353 :                         ++buf;
     551             :                 }
     552             :         }
     553             :         /* hmm even more zero padding? */
     554        4149 :         while (i <= --precision) {
     555           0 :                 if (buf < end)
     556           0 :                         *buf = '0';
     557           0 :                 ++buf;
     558             :         }
     559             :         /* actual digits of result */
     560       12460 :         while (--i >= 0) {
     561        8311 :                 if (buf < end)
     562        7709 :                         *buf = tmp[i];
     563        8311 :                 ++buf;
     564             :         }
     565             :         /* trailing space padding */
     566        4149 :         while (--field_width >= 0) {
     567           0 :                 if (buf < end)
     568           0 :                         *buf = ' ';
     569           0 :                 ++buf;
     570             :         }
     571             : 
     572        4149 :         return buf;
     573             : }
     574             : 
     575             : static noinline_for_stack
     576          12 : char *special_hex_number(char *buf, char *end, unsigned long long num, int size)
     577             : {
     578             :         struct printf_spec spec;
     579             : 
     580          12 :         spec.type = FORMAT_TYPE_PTR;
     581          12 :         spec.field_width = 2 + 2 * size;        /* 0x + hex */
     582          12 :         spec.flags = SPECIAL | SMALL | ZEROPAD;
     583          12 :         spec.base = 16;
     584          12 :         spec.precision = -1;
     585             : 
     586          12 :         return number(buf, end, num, spec);
     587             : }
     588             : 
     589         194 : static void move_right(char *buf, char *end, unsigned len, unsigned spaces)
     590             : {
     591             :         size_t size;
     592         194 :         if (buf >= end)      /* nowhere to put anything */
     593             :                 return;
     594         194 :         size = end - buf;
     595         194 :         if (size <= spaces) {
     596         160 :                 memset(buf, ' ', size);
     597          80 :                 return;
     598             :         }
     599         114 :         if (len) {
     600           0 :                 if (len > size - spaces)
     601           0 :                         len = size - spaces;
     602           0 :                 memmove(buf + spaces, buf, len);
     603             :         }
     604         228 :         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        4442 : char *widen_string(char *buf, int n, char *end, struct printf_spec spec)
     617             : {
     618             :         unsigned spaces;
     619             : 
     620        4442 :         if (likely(n >= spec.field_width))
     621             :                 return buf;
     622             :         /* we want to pad the sucker */
     623         196 :         spaces = spec.field_width - n;
     624         196 :         if (!(spec.flags & LEFT)) {
     625         194 :                 move_right(buf - n, end, n, spaces);
     626         194 :                 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        4442 : static char *string_nocheck(char *buf, char *end, const char *s,
     638             :                             struct printf_spec spec)
     639             : {
     640        4442 :         int len = 0;
     641        4442 :         int lim = spec.precision;
     642             : 
     643       47509 :         while (lim--) {
     644       43065 :                 char c = *s++;
     645       43065 :                 if (!c)
     646             :                         break;
     647       38625 :                 if (buf < end)
     648       33220 :                         *buf = c;
     649       38625 :                 ++buf;
     650       38625 :                 ++len;
     651             :         }
     652        4442 :         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           0 :         if (spec.precision == -1)
     684           0 :                 spec.precision = 2 * sizeof(void *);
     685             : 
     686           0 :         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        4398 :         if (!ptr)
     697             :                 return "(null)";
     698             : 
     699        4398 :         if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr))
     700             :                 return "(efault)";
     701             : 
     702             :         return NULL;
     703             : }
     704             : 
     705        4398 : static int check_pointer(char **buf, char *end, const void *ptr,
     706             :                          struct printf_spec spec)
     707             : {
     708             :         const char *err_msg;
     709             : 
     710        4398 :         err_msg = check_pointer_msg(ptr);
     711        4398 :         if (err_msg) {
     712           0 :                 *buf = error_string(*buf, end, err_msg, spec);
     713           0 :                 return -EFAULT;
     714             :         }
     715             : 
     716             :         return 0;
     717             : }
     718             : 
     719             : static noinline_for_stack
     720        4386 : char *string(char *buf, char *end, const char *s,
     721             :              struct printf_spec spec)
     722             : {
     723        4386 :         if (check_pointer(&buf, end, s, spec))
     724           0 :                 return buf;
     725             : 
     726        4386 :         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          56 : 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          56 :         if (fmt[1] == 'R')
     989           0 :                 ptr = __builtin_extract_return_addr(ptr);
     990          56 :         value = (unsigned long)ptr;
     991             : 
     992             : #ifdef CONFIG_KALLSYMS
     993          56 :         if (*fmt == 'B' && fmt[1] == 'b')
     994           0 :                 sprint_backtrace_build_id(sym, value);
     995          56 :         else if (*fmt == 'B')
     996           0 :                 sprint_backtrace(sym, value);
     997          56 :         else if (*fmt == 'S' && (fmt[1] == 'b' || (fmt[1] == 'R' && fmt[2] == 'b')))
     998           0 :                 sprint_symbol_build_id(sym, value);
     999          56 :         else if (*fmt != 's')
    1000          56 :                 sprint_symbol(sym, value);
    1001             :         else
    1002           0 :                 sprint_symbol_no_offset(sym, value);
    1003             : 
    1004          56 :         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          12 : 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          12 :         char *p = output;
    1760             :         unsigned int i;
    1761             :         u32 orig, val;
    1762             : 
    1763          12 :         if (fmt[1] != 'c' || fmt[2] != 'c')
    1764           0 :                 return error_string(buf, end, "(%p4?)", spec);
    1765             : 
    1766          12 :         if (check_pointer(&buf, end, fourcc, spec))
    1767           0 :                 return buf;
    1768             : 
    1769          12 :         orig = get_unaligned(fourcc);
    1770          12 :         val = orig & ~BIT(31);
    1771             : 
    1772          60 :         for (i = 0; i < sizeof(u32); i++) {
    1773          48 :                 unsigned char c = val >> (i * 8);
    1774             : 
    1775             :                 /* Print non-control ASCII characters as-is, dot otherwise */
    1776          48 :                 *p++ = isascii(c) && isprint(c) ? c : '.';
    1777             :         }
    1778             : 
    1779          12 :         *p++ = ' ';
    1780          24 :         strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian");
    1781          12 :         p += strlen(p);
    1782             : 
    1783          12 :         *p++ = ' ';
    1784          12 :         *p++ = '(';
    1785          12 :         p = special_hex_number(p, output + sizeof(output) - 2, orig, sizeof(u32));
    1786          12 :         *p++ = ')';
    1787          12 :         *p = '\0';
    1788             : 
    1789          12 :         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
    2056           0 : char *format_page_type(char *buf, char *end, unsigned int page_type)
    2057             : {
    2058           0 :         buf = number(buf, end, page_type, default_flag_spec);
    2059             : 
    2060           0 :         if (buf < end)
    2061           0 :                 *buf = '(';
    2062           0 :         buf++;
    2063             : 
    2064           0 :         if (page_type_has_type(page_type))
    2065           0 :                 buf = format_flags(buf, end, ~page_type, pagetype_names);
    2066             : 
    2067           0 :         if (buf < end)
    2068           0 :                 *buf = ')';
    2069           0 :         buf++;
    2070             : 
    2071           0 :         return buf;
    2072             : }
    2073             : 
    2074             : static noinline_for_stack
    2075           0 : char *flags_string(char *buf, char *end, void *flags_ptr,
    2076             :                    struct printf_spec spec, const char *fmt)
    2077             : {
    2078             :         unsigned long flags;
    2079             :         const struct trace_print_flags *names;
    2080             : 
    2081           0 :         if (check_pointer(&buf, end, flags_ptr, spec))
    2082           0 :                 return buf;
    2083             : 
    2084           0 :         switch (fmt[1]) {
    2085             :         case 'p':
    2086           0 :                 return format_page_flags(buf, end, *(unsigned long *)flags_ptr);
    2087             :         case 't':
    2088           0 :                 return format_page_type(buf, end, *(unsigned int *)flags_ptr);
    2089             :         case 'v':
    2090           0 :                 flags = *(unsigned long *)flags_ptr;
    2091           0 :                 names = vmaflag_names;
    2092           0 :                 break;
    2093             :         case 'g':
    2094           0 :                 flags = (__force unsigned long)(*(gfp_t *)flags_ptr);
    2095           0 :                 names = gfpflag_names;
    2096           0 :                 break;
    2097             :         default:
    2098           0 :                 return error_string(buf, end, "(%pG?)", spec);
    2099             :         }
    2100             : 
    2101           0 :         return format_flags(buf, end, flags, names);
    2102             : }
    2103             : 
    2104             : static noinline_for_stack
    2105           0 : char *fwnode_full_name_string(struct fwnode_handle *fwnode, char *buf,
    2106             :                               char *end)
    2107             : {
    2108             :         int depth;
    2109             : 
    2110             :         /* Loop starting from the root node to the current node. */
    2111           0 :         for (depth = fwnode_count_parents(fwnode); depth >= 0; depth--) {
    2112           0 :                 struct fwnode_handle *__fwnode =
    2113           0 :                         fwnode_get_nth_parent(fwnode, depth);
    2114             : 
    2115           0 :                 buf = string(buf, end, fwnode_get_name_prefix(__fwnode),
    2116             :                              default_str_spec);
    2117           0 :                 buf = string(buf, end, fwnode_get_name(__fwnode),
    2118             :                              default_str_spec);
    2119             : 
    2120           0 :                 fwnode_handle_put(__fwnode);
    2121             :         }
    2122             : 
    2123           0 :         return buf;
    2124             : }
    2125             : 
    2126             : static noinline_for_stack
    2127           0 : char *device_node_string(char *buf, char *end, struct device_node *dn,
    2128             :                          struct printf_spec spec, const char *fmt)
    2129             : {
    2130             :         char tbuf[sizeof("xxxx") + 1];
    2131             :         const char *p;
    2132             :         int ret;
    2133           0 :         char *buf_start = buf;
    2134             :         struct property *prop;
    2135             :         bool has_mult, pass;
    2136             : 
    2137           0 :         struct printf_spec str_spec = spec;
    2138           0 :         str_spec.field_width = -1;
    2139             : 
    2140           0 :         if (fmt[0] != 'F')
    2141           0 :                 return error_string(buf, end, "(%pO?)", spec);
    2142             : 
    2143             :         if (!IS_ENABLED(CONFIG_OF))
    2144           0 :                 return error_string(buf, end, "(%pOF?)", spec);
    2145             : 
    2146             :         if (check_pointer(&buf, end, dn, spec))
    2147             :                 return buf;
    2148             : 
    2149             :         /* simple case without anything any more format specifiers */
    2150             :         fmt++;
    2151             :         if (fmt[0] == '\0' || strcspn(fmt,"fnpPFcC") > 0)
    2152             :                 fmt = "f";
    2153             : 
    2154             :         for (pass = false; strspn(fmt,"fnpPFcC"); fmt++, pass = true) {
    2155             :                 int precision;
    2156             :                 if (pass) {
    2157             :                         if (buf < end)
    2158             :                                 *buf = ':';
    2159             :                         buf++;
    2160             :                 }
    2161             : 
    2162             :                 switch (*fmt) {
    2163             :                 case 'f':       /* full_name */
    2164             :                         buf = fwnode_full_name_string(of_fwnode_handle(dn), buf,
    2165             :                                                       end);
    2166             :                         break;
    2167             :                 case 'n':       /* name */
    2168             :                         p = fwnode_get_name(of_fwnode_handle(dn));
    2169             :                         precision = str_spec.precision;
    2170             :                         str_spec.precision = strchrnul(p, '@') - p;
    2171             :                         buf = string(buf, end, p, str_spec);
    2172             :                         str_spec.precision = precision;
    2173             :                         break;
    2174             :                 case 'p':       /* phandle */
    2175             :                         buf = number(buf, end, (unsigned int)dn->phandle, default_dec_spec);
    2176             :                         break;
    2177             :                 case 'P':       /* path-spec */
    2178             :                         p = fwnode_get_name(of_fwnode_handle(dn));
    2179             :                         if (!p[1])
    2180             :                                 p = "/";
    2181             :                         buf = string(buf, end, p, str_spec);
    2182             :                         break;
    2183             :                 case 'F':       /* flags */
    2184             :                         tbuf[0] = of_node_check_flag(dn, OF_DYNAMIC) ? 'D' : '-';
    2185             :                         tbuf[1] = of_node_check_flag(dn, OF_DETACHED) ? 'd' : '-';
    2186             :                         tbuf[2] = of_node_check_flag(dn, OF_POPULATED) ? 'P' : '-';
    2187             :                         tbuf[3] = of_node_check_flag(dn, OF_POPULATED_BUS) ? 'B' : '-';
    2188             :                         tbuf[4] = 0;
    2189             :                         buf = string_nocheck(buf, end, tbuf, str_spec);
    2190             :                         break;
    2191             :                 case 'c':       /* major compatible string */
    2192             :                         ret = of_property_read_string(dn, "compatible", &p);
    2193             :                         if (!ret)
    2194             :                                 buf = string(buf, end, p, str_spec);
    2195             :                         break;
    2196             :                 case 'C':       /* full compatible string */
    2197             :                         has_mult = false;
    2198             :                         of_property_for_each_string(dn, "compatible", prop, p) {
    2199             :                                 if (has_mult)
    2200             :                                         buf = string_nocheck(buf, end, ",", str_spec);
    2201             :                                 buf = string_nocheck(buf, end, "\"", str_spec);
    2202             :                                 buf = string(buf, end, p, str_spec);
    2203             :                                 buf = string_nocheck(buf, end, "\"", str_spec);
    2204             : 
    2205             :                                 has_mult = true;
    2206             :                         }
    2207             :                         break;
    2208             :                 default:
    2209             :                         break;
    2210             :                 }
    2211             :         }
    2212             : 
    2213             :         return widen_string(buf, buf - buf_start, end, spec);
    2214             : }
    2215             : 
    2216             : static noinline_for_stack
    2217           0 : char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
    2218             :                     struct printf_spec spec, const char *fmt)
    2219             : {
    2220           0 :         struct printf_spec str_spec = spec;
    2221           0 :         char *buf_start = buf;
    2222             : 
    2223           0 :         str_spec.field_width = -1;
    2224             : 
    2225           0 :         if (*fmt != 'w')
    2226           0 :                 return error_string(buf, end, "(%pf?)", spec);
    2227             : 
    2228           0 :         if (check_pointer(&buf, end, fwnode, spec))
    2229           0 :                 return buf;
    2230             : 
    2231           0 :         fmt++;
    2232             : 
    2233           0 :         switch (*fmt) {
    2234             :         case 'P':       /* name */
    2235           0 :                 buf = string(buf, end, fwnode_get_name(fwnode), str_spec);
    2236           0 :                 break;
    2237             :         case 'f':       /* full_name */
    2238             :         default:
    2239           0 :                 buf = fwnode_full_name_string(fwnode, buf, end);
    2240           0 :                 break;
    2241             :         }
    2242             : 
    2243           0 :         return widen_string(buf, buf - buf_start, end, spec);
    2244             : }
    2245             : 
    2246           0 : int __init no_hash_pointers_enable(char *str)
    2247             : {
    2248           0 :         if (no_hash_pointers)
    2249             :                 return 0;
    2250             : 
    2251           0 :         no_hash_pointers = true;
    2252             : 
    2253           0 :         pr_warn("**********************************************************\n");
    2254           0 :         pr_warn("**   NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n");
    2255           0 :         pr_warn("**                                                      **\n");
    2256           0 :         pr_warn("** This system shows unhashed kernel memory addresses   **\n");
    2257           0 :         pr_warn("** via the console, logs, and other interfaces. This    **\n");
    2258           0 :         pr_warn("** might reduce the security of your system.            **\n");
    2259           0 :         pr_warn("**                                                      **\n");
    2260           0 :         pr_warn("** If you see this message and you are not debugging    **\n");
    2261           0 :         pr_warn("** the kernel, report this immediately to your system   **\n");
    2262           0 :         pr_warn("** administrator!                                       **\n");
    2263           0 :         pr_warn("**                                                      **\n");
    2264           0 :         pr_warn("**   NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n");
    2265           0 :         pr_warn("**********************************************************\n");
    2266             : 
    2267           0 :         return 0;
    2268             : }
    2269             : early_param("no_hash_pointers", no_hash_pointers_enable);
    2270             : 
    2271             : /* Used for Rust formatting ('%pA'). */
    2272             : char *rust_fmt_argument(char *buf, char *end, void *ptr);
    2273             : 
    2274             : /*
    2275             :  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
    2276             :  * by an extra set of alphanumeric characters that are extended format
    2277             :  * specifiers.
    2278             :  *
    2279             :  * Please update scripts/checkpatch.pl when adding/removing conversion
    2280             :  * characters.  (Search for "check for vsprintf extension").
    2281             :  *
    2282             :  * Right now we handle:
    2283             :  *
    2284             :  * - 'S' For symbolic direct pointers (or function descriptors) with offset
    2285             :  * - 's' For symbolic direct pointers (or function descriptors) without offset
    2286             :  * - '[Ss]R' as above with __builtin_extract_return_addr() translation
    2287             :  * - 'S[R]b' as above with module build ID (for use in backtraces)
    2288             :  * - '[Ff]' %pf and %pF were obsoleted and later removed in favor of
    2289             :  *          %ps and %pS. Be careful when re-using these specifiers.
    2290             :  * - 'B' For backtraced symbolic direct pointers with offset
    2291             :  * - 'Bb' as above with module build ID (for use in backtraces)
    2292             :  * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
    2293             :  * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
    2294             :  * - 'b[l]' For a bitmap, the number of bits is determined by the field
    2295             :  *       width which must be explicitly specified either as part of the
    2296             :  *       format string '%32b[l]' or through '%*b[l]', [l] selects
    2297             :  *       range-list format instead of hex format
    2298             :  * - 'M' For a 6-byte MAC address, it prints the address in the
    2299             :  *       usual colon-separated hex notation
    2300             :  * - 'm' For a 6-byte MAC address, it prints the hex address without colons
    2301             :  * - 'MF' For a 6-byte MAC FDDI address, it prints the address
    2302             :  *       with a dash-separated hex notation
    2303             :  * - '[mM]R' For a 6-byte MAC address, Reverse order (Bluetooth)
    2304             :  * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
    2305             :  *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
    2306             :  *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
    2307             :  *       [S][pfs]
    2308             :  *       Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
    2309             :  *       [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
    2310             :  * - 'i' [46] for 'raw' IPv4/IPv6 addresses
    2311             :  *       IPv6 omits the colons (01020304...0f)
    2312             :  *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
    2313             :  *       [S][pfs]
    2314             :  *       Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
    2315             :  *       [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
    2316             :  * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order
    2317             :  * - 'I[6S]c' for IPv6 addresses printed as specified by
    2318             :  *       https://tools.ietf.org/html/rfc5952
    2319             :  * - 'E[achnops]' For an escaped buffer, where rules are defined by combination
    2320             :  *                of the following flags (see string_escape_mem() for the
    2321             :  *                details):
    2322             :  *                  a - ESCAPE_ANY
    2323             :  *                  c - ESCAPE_SPECIAL
    2324             :  *                  h - ESCAPE_HEX
    2325             :  *                  n - ESCAPE_NULL
    2326             :  *                  o - ESCAPE_OCTAL
    2327             :  *                  p - ESCAPE_NP
    2328             :  *                  s - ESCAPE_SPACE
    2329             :  *                By default ESCAPE_ANY_NP is used.
    2330             :  * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
    2331             :  *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    2332             :  *       Options for %pU are:
    2333             :  *         b big endian lower case hex (default)
    2334             :  *         B big endian UPPER case hex
    2335             :  *         l little endian lower case hex
    2336             :  *         L little endian UPPER case hex
    2337             :  *           big endian output byte order is:
    2338             :  *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
    2339             :  *           little endian output byte order is:
    2340             :  *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
    2341             :  * - 'V' For a struct va_format which contains a format string * and va_list *,
    2342             :  *       call vsnprintf(->format, *->va_list).
    2343             :  *       Implements a "recursive vsnprintf".
    2344             :  *       Do not use this feature without some mechanism to verify the
    2345             :  *       correctness of the format string and va_list arguments.
    2346             :  * - 'K' For a kernel pointer that should be hidden from unprivileged users.
    2347             :  *       Use only for procfs, sysfs and similar files, not printk(); please
    2348             :  *       read the documentation (path below) first.
    2349             :  * - 'NF' For a netdev_features_t
    2350             :  * - '4cc' V4L2 or DRM FourCC code, with endianness and raw numerical value.
    2351             :  * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with
    2352             :  *            a certain separator (' ' by default):
    2353             :  *              C colon
    2354             :  *              D dash
    2355             :  *              N no separator
    2356             :  *            The maximum supported length is 64 bytes of the input. Consider
    2357             :  *            to use print_hex_dump() for the larger input.
    2358             :  * - 'a[pd]' For address types [p] phys_addr_t, [d] dma_addr_t and derivatives
    2359             :  *           (default assumed to be phys_addr_t, passed by reference)
    2360             :  * - 'd[234]' For a dentry name (optionally 2-4 last components)
    2361             :  * - 'D[234]' Same as 'd' but for a struct file
    2362             :  * - 'g' For block_device name (gendisk + partition number)
    2363             :  * - 't[RT][dt][r][s]' For time and date as represented by:
    2364             :  *      R    struct rtc_time
    2365             :  *      T    time64_t
    2366             :  * - 'C' For a clock, it prints the name (Common Clock Framework) or address
    2367             :  *       (legacy clock framework) of the clock
    2368             :  * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
    2369             :  *        (legacy clock framework) of the clock
    2370             :  * - 'G' For flags to be printed as a collection of symbolic strings that would
    2371             :  *       construct the specific value. Supported flags given by option:
    2372             :  *       p page flags (see struct page) given as pointer to unsigned long
    2373             :  *       g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t
    2374             :  *       v vma flags (VM_*) given as pointer to unsigned long
    2375             :  * - 'OF[fnpPcCF]'  For a device tree object
    2376             :  *                  Without any optional arguments prints the full_name
    2377             :  *                  f device node full_name
    2378             :  *                  n device node name
    2379             :  *                  p device node phandle
    2380             :  *                  P device node path spec (name + @unit)
    2381             :  *                  F device node flags
    2382             :  *                  c major compatible string
    2383             :  *                  C full compatible string
    2384             :  * - 'fw[fP]'   For a firmware node (struct fwnode_handle) pointer
    2385             :  *              Without an option prints the full name of the node
    2386             :  *              f full name
    2387             :  *              P node name, including a possible unit address
    2388             :  * - 'x' For printing the address unmodified. Equivalent to "%lx".
    2389             :  *       Please read the documentation (path below) before using!
    2390             :  * - '[ku]s' For a BPF/tracing related format specifier, e.g. used out of
    2391             :  *           bpf_trace_printk() where [ku] prefix specifies either kernel (k)
    2392             :  *           or user (u) memory to probe, and:
    2393             :  *              s a string, equivalent to "%s" on direct vsnprintf() use
    2394             :  *
    2395             :  * ** When making changes please also update:
    2396             :  *      Documentation/core-api/printk-formats.rst
    2397             :  *
    2398             :  * Note: The default behaviour (unadorned %p) is to hash the address,
    2399             :  * rendering it useful as a unique identifier.
    2400             :  *
    2401             :  * There is also a '%pA' format specifier, but it is only intended to be used
    2402             :  * from Rust code to format core::fmt::Arguments. Do *not* use it from C.
    2403             :  * See rust/kernel/print.rs for details.
    2404             :  */
    2405             : static noinline_for_stack
    2406          68 : char *pointer(const char *fmt, char *buf, char *end, void *ptr,
    2407             :               struct printf_spec spec)
    2408             : {
    2409          68 :         switch (*fmt) {
    2410             :         case 'S':
    2411             :         case 's':
    2412             :                 ptr = dereference_symbol_descriptor(ptr);
    2413             :                 fallthrough;
    2414             :         case 'B':
    2415          56 :                 return symbol_string(buf, end, ptr, spec, fmt);
    2416             :         case 'R':
    2417             :         case 'r':
    2418           0 :                 return resource_string(buf, end, ptr, spec, fmt);
    2419             :         case 'h':
    2420           0 :                 return hex_string(buf, end, ptr, spec, fmt);
    2421             :         case 'b':
    2422           0 :                 switch (fmt[1]) {
    2423             :                 case 'l':
    2424           0 :                         return bitmap_list_string(buf, end, ptr, spec, fmt);
    2425             :                 default:
    2426           0 :                         return bitmap_string(buf, end, ptr, spec, fmt);
    2427             :                 }
    2428             :         case 'M':                       /* Colon separated: 00:01:02:03:04:05 */
    2429             :         case 'm':                       /* Contiguous: 000102030405 */
    2430             :                                         /* [mM]F (FDDI) */
    2431             :                                         /* [mM]R (Reverse order; Bluetooth) */
    2432           0 :                 return mac_address_string(buf, end, ptr, spec, fmt);
    2433             :         case 'I':                       /* Formatted IP supported
    2434             :                                          * 4:   1.2.3.4
    2435             :                                          * 6:   0001:0203:...:0708
    2436             :                                          * 6c:  1::708 or 1::1.2.3.4
    2437             :                                          */
    2438             :         case 'i':                       /* Contiguous:
    2439             :                                          * 4:   001.002.003.004
    2440             :                                          * 6:   000102...0f
    2441             :                                          */
    2442           0 :                 return ip_addr_string(buf, end, ptr, spec, fmt);
    2443             :         case 'E':
    2444           0 :                 return escaped_string(buf, end, ptr, spec, fmt);
    2445             :         case 'U':
    2446           0 :                 return uuid_string(buf, end, ptr, spec, fmt);
    2447             :         case 'V':
    2448           0 :                 return va_format(buf, end, ptr, spec, fmt);
    2449             :         case 'K':
    2450           0 :                 return restricted_pointer(buf, end, ptr, spec);
    2451             :         case 'N':
    2452           0 :                 return netdev_bits(buf, end, ptr, spec, fmt);
    2453             :         case '4':
    2454          12 :                 return fourcc_string(buf, end, ptr, spec, fmt);
    2455             :         case 'a':
    2456           0 :                 return address_val(buf, end, ptr, spec, fmt);
    2457             :         case 'd':
    2458           0 :                 return dentry_name(buf, end, ptr, spec, fmt);
    2459             :         case 't':
    2460           0 :                 return time_and_date(buf, end, ptr, spec, fmt);
    2461             :         case 'C':
    2462           0 :                 return clock(buf, end, ptr, spec, fmt);
    2463             :         case 'D':
    2464           0 :                 return file_dentry_name(buf, end, ptr, spec, fmt);
    2465             : #ifdef CONFIG_BLOCK
    2466             :         case 'g':
    2467           0 :                 return bdev_name(buf, end, ptr, spec, fmt);
    2468             : #endif
    2469             : 
    2470             :         case 'G':
    2471           0 :                 return flags_string(buf, end, ptr, spec, fmt);
    2472             :         case 'O':
    2473           0 :                 return device_node_string(buf, end, ptr, spec, fmt + 1);
    2474             :         case 'f':
    2475           0 :                 return fwnode_string(buf, end, ptr, spec, fmt + 1);
    2476             :         case 'A':
    2477             :                 if (!IS_ENABLED(CONFIG_RUST)) {
    2478           0 :                         WARN_ONCE(1, "Please remove %%pA from non-Rust code\n");
    2479           0 :                         return error_string(buf, end, "(%pA?)", spec);
    2480             :                 }
    2481             :                 return rust_fmt_argument(buf, end, ptr);
    2482             :         case 'x':
    2483           0 :                 return pointer_string(buf, end, ptr, spec);
    2484             :         case 'e':
    2485             :                 /* %pe with a non-ERR_PTR gets treated as plain %p */
    2486           0 :                 if (!IS_ERR(ptr))
    2487           0 :                         return default_pointer(buf, end, ptr, spec);
    2488           0 :                 return err_ptr(buf, end, ptr, spec);
    2489             :         case 'u':
    2490             :         case 'k':
    2491           0 :                 switch (fmt[1]) {
    2492             :                 case 's':
    2493           0 :                         return string(buf, end, ptr, spec);
    2494             :                 default:
    2495           0 :                         return error_string(buf, end, "(einval)", spec);
    2496             :                 }
    2497             :         default:
    2498           0 :                 return default_pointer(buf, end, ptr, spec);
    2499             :         }
    2500             : }
    2501             : 
    2502             : /*
    2503             :  * Helper function to decode printf style format.
    2504             :  * Each call decode a token from the format and return the
    2505             :  * number of characters read (or likely the delta where it wants
    2506             :  * to go on the next call).
    2507             :  * The decoded token is returned through the parameters
    2508             :  *
    2509             :  * 'h', 'l', or 'L' for integer fields
    2510             :  * 'z' support added 23/7/1999 S.H.
    2511             :  * 'z' changed to 'Z' --davidm 1/25/99
    2512             :  * 'Z' changed to 'z' --adobriyan 2017-01-25
    2513             :  * 't' added for ptrdiff_t
    2514             :  *
    2515             :  * @fmt: the format string
    2516             :  * @type of the token returned
    2517             :  * @flags: various flags such as +, -, # tokens..
    2518             :  * @field_width: overwritten width
    2519             :  * @base: base of the number (octal, hex, ...)
    2520             :  * @precision: precision of a number
    2521             :  * @qualifier: qualifier of a number (long, size_t, ...)
    2522             :  */
    2523             : static noinline_for_stack
    2524       16041 : int format_decode(const char *fmt, struct printf_spec *spec)
    2525             : {
    2526       16041 :         const char *start = fmt;
    2527             :         char qualifier;
    2528             : 
    2529             :         /* we finished early by reading the field width */
    2530       16041 :         if (spec->type == FORMAT_TYPE_WIDTH) {
    2531         198 :                 if (spec->field_width < 0) {
    2532           0 :                         spec->field_width = -spec->field_width;
    2533           0 :                         spec->flags |= LEFT;
    2534             :                 }
    2535         198 :                 spec->type = FORMAT_TYPE_NONE;
    2536         198 :                 goto precision;
    2537             :         }
    2538             : 
    2539             :         /* we finished early by reading the precision */
    2540       15843 :         if (spec->type == FORMAT_TYPE_PRECISION) {
    2541           2 :                 if (spec->precision < 0)
    2542           0 :                         spec->precision = 0;
    2543             : 
    2544           2 :                 spec->type = FORMAT_TYPE_NONE;
    2545           2 :                 goto qualifier;
    2546             :         }
    2547             : 
    2548             :         /* By default */
    2549       15841 :         spec->type = FORMAT_TYPE_NONE;
    2550             : 
    2551       66117 :         for (; *fmt ; ++fmt) {
    2552       65499 :                 if (*fmt == '%')
    2553             :                         break;
    2554             :         }
    2555             : 
    2556             :         /* Return the current non-format string */
    2557       15841 :         if (fmt != start || !*fmt)
    2558        6750 :                 return fmt - start;
    2559             : 
    2560             :         /* Process flags */
    2561        9091 :         spec->flags = 0;
    2562             : 
    2563             :         while (1) { /* this also skips first '%' */
    2564        9364 :                 bool found = true;
    2565             : 
    2566        9364 :                 ++fmt;
    2567             : 
    2568        9364 :                 switch (*fmt) {
    2569           2 :                 case '-': spec->flags |= LEFT;    break;
    2570           0 :                 case '+': spec->flags |= PLUS;    break;
    2571           0 :                 case ' ': spec->flags |= SPACE;   break;
    2572         132 :                 case '#': spec->flags |= SPECIAL; break;
    2573         139 :                 case '0': spec->flags |= ZEROPAD; break;
    2574             :                 default:  found = false;
    2575             :                 }
    2576             : 
    2577        9364 :                 if (!found)
    2578             :                         break;
    2579             :         }
    2580             : 
    2581             :         /* get field width */
    2582        9091 :         spec->field_width = -1;
    2583             : 
    2584       18182 :         if (isdigit(*fmt))
    2585         139 :                 spec->field_width = skip_atoi(&fmt);
    2586        8952 :         else if (*fmt == '*') {
    2587             :                 /* it's the next argument */
    2588         198 :                 spec->type = FORMAT_TYPE_WIDTH;
    2589         198 :                 return ++fmt - start;
    2590             :         }
    2591             : 
    2592             : precision:
    2593             :         /* get the precision */
    2594        9091 :         spec->precision = -1;
    2595        9091 :         if (*fmt == '.') {
    2596           4 :                 ++fmt;
    2597           8 :                 if (isdigit(*fmt)) {
    2598           2 :                         spec->precision = skip_atoi(&fmt);
    2599           2 :                         if (spec->precision < 0)
    2600           0 :                                 spec->precision = 0;
    2601           2 :                 } else if (*fmt == '*') {
    2602             :                         /* it's the next argument */
    2603           2 :                         spec->type = FORMAT_TYPE_PRECISION;
    2604           2 :                         return ++fmt - start;
    2605             :                 }
    2606             :         }
    2607             : 
    2608             : qualifier:
    2609             :         /* get the conversion qualifier */
    2610        9091 :         qualifier = 0;
    2611       18182 :         if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
    2612        7815 :             *fmt == 'z' || *fmt == 't') {
    2613        1276 :                 qualifier = *fmt++;
    2614        1276 :                 if (unlikely(qualifier == *fmt)) {
    2615         664 :                         if (qualifier == 'l') {
    2616         664 :                                 qualifier = 'L';
    2617         664 :                                 ++fmt;
    2618           0 :                         } else if (qualifier == 'h') {
    2619           0 :                                 qualifier = 'H';
    2620           0 :                                 ++fmt;
    2621             :                         }
    2622             :                 }
    2623             :         }
    2624             : 
    2625             :         /* default base */
    2626        9091 :         spec->base = 10;
    2627        9091 :         switch (*fmt) {
    2628             :         case 'c':
    2629         512 :                 spec->type = FORMAT_TYPE_CHAR;
    2630         512 :                 return ++fmt - start;
    2631             : 
    2632             :         case 's':
    2633        4374 :                 spec->type = FORMAT_TYPE_STR;
    2634        4374 :                 return ++fmt - start;
    2635             : 
    2636             :         case 'p':
    2637          68 :                 spec->type = FORMAT_TYPE_PTR;
    2638          68 :                 return ++fmt - start;
    2639             : 
    2640             :         case '%':
    2641           0 :                 spec->type = FORMAT_TYPE_PERCENT_CHAR;
    2642           0 :                 return ++fmt - start;
    2643             : 
    2644             :         /* integer number formats - set up the flags and "break" */
    2645             :         case 'o':
    2646           8 :                 spec->base = 8;
    2647           8 :                 break;
    2648             : 
    2649             :         case 'x':
    2650         724 :                 spec->flags |= SMALL;
    2651             :                 fallthrough;
    2652             : 
    2653             :         case 'X':
    2654         724 :                 spec->base = 16;
    2655         724 :                 break;
    2656             : 
    2657             :         case 'd':
    2658             :         case 'i':
    2659         384 :                 spec->flags |= SIGN;
    2660         384 :                 break;
    2661             :         case 'u':
    2662             :                 break;
    2663             : 
    2664             :         case 'n':
    2665             :                 /*
    2666             :                  * Since %n poses a greater security risk than
    2667             :                  * utility, treat it as any other invalid or
    2668             :                  * unsupported format specifier.
    2669             :                  */
    2670             :                 fallthrough;
    2671             : 
    2672             :         default:
    2673           0 :                 WARN_ONCE(1, "Please remove unsupported %%%c in format string\n", *fmt);
    2674           0 :                 spec->type = FORMAT_TYPE_INVALID;
    2675           0 :                 return fmt - start;
    2676             :         }
    2677             : 
    2678        4137 :         if (qualifier == 'L')
    2679         676 :                 spec->type = FORMAT_TYPE_LONG_LONG;
    2680        3461 :         else if (qualifier == 'l') {
    2681             :                 BUILD_BUG_ON(FORMAT_TYPE_ULONG + SIGN != FORMAT_TYPE_LONG);
    2682         388 :                 spec->type = FORMAT_TYPE_ULONG + (spec->flags & SIGN);
    2683        3073 :         } else if (qualifier == 'z') {
    2684         212 :                 spec->type = FORMAT_TYPE_SIZE_T;
    2685        2861 :         } else if (qualifier == 't') {
    2686           0 :                 spec->type = FORMAT_TYPE_PTRDIFF;
    2687        2861 :         } else if (qualifier == 'H') {
    2688             :                 BUILD_BUG_ON(FORMAT_TYPE_UBYTE + SIGN != FORMAT_TYPE_BYTE);
    2689           0 :                 spec->type = FORMAT_TYPE_UBYTE + (spec->flags & SIGN);
    2690        2861 :         } else if (qualifier == 'h') {
    2691             :                 BUILD_BUG_ON(FORMAT_TYPE_USHORT + SIGN != FORMAT_TYPE_SHORT);
    2692           0 :                 spec->type = FORMAT_TYPE_USHORT + (spec->flags & SIGN);
    2693             :         } else {
    2694             :                 BUILD_BUG_ON(FORMAT_TYPE_UINT + SIGN != FORMAT_TYPE_INT);
    2695        2861 :                 spec->type = FORMAT_TYPE_UINT + (spec->flags & SIGN);
    2696             :         }
    2697             : 
    2698        4137 :         return ++fmt - start;
    2699             : }
    2700             : 
    2701             : static void
    2702         198 : set_field_width(struct printf_spec *spec, int width)
    2703             : {
    2704         198 :         spec->field_width = width;
    2705         198 :         if (WARN_ONCE(spec->field_width != width, "field width %d too large", width)) {
    2706           0 :                 spec->field_width = clamp(width, -FIELD_WIDTH_MAX, FIELD_WIDTH_MAX);
    2707             :         }
    2708         198 : }
    2709             : 
    2710             : static void
    2711           2 : set_precision(struct printf_spec *spec, int prec)
    2712             : {
    2713           2 :         spec->precision = prec;
    2714           2 :         if (WARN_ONCE(spec->precision != prec, "precision %d too large", prec)) {
    2715           0 :                 spec->precision = clamp(prec, 0, PRECISION_MAX);
    2716             :         }
    2717           2 : }
    2718             : 
    2719             : /**
    2720             :  * vsnprintf - Format a string and place it in a buffer
    2721             :  * @buf: The buffer to place the result into
    2722             :  * @size: The size of the buffer, including the trailing null space
    2723             :  * @fmt: The format string to use
    2724             :  * @args: Arguments for the format string
    2725             :  *
    2726             :  * This function generally follows C99 vsnprintf, but has some
    2727             :  * extensions and a few limitations:
    2728             :  *
    2729             :  *  - ``%n`` is unsupported
    2730             :  *  - ``%p*`` is handled by pointer()
    2731             :  *
    2732             :  * See pointer() or Documentation/core-api/printk-formats.rst for more
    2733             :  * extensive description.
    2734             :  *
    2735             :  * **Please update the documentation in both places when making changes**
    2736             :  *
    2737             :  * The return value is the number of characters which would
    2738             :  * be generated for the given input, excluding the trailing
    2739             :  * '\0', as per ISO C99. If you want to have the exact
    2740             :  * number of characters written into @buf as return value
    2741             :  * (not including the trailing '\0'), use vscnprintf(). If the
    2742             :  * return is greater than or equal to @size, the resulting
    2743             :  * string is truncated.
    2744             :  *
    2745             :  * If you're not already dealing with a va_list consider using snprintf().
    2746             :  */
    2747        6390 : int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
    2748             : {
    2749             :         unsigned long long num;
    2750             :         char *str, *end;
    2751        6390 :         struct printf_spec spec = {0};
    2752             : 
    2753             :         /* Reject out-of-range values early.  Large positive sizes are
    2754             :            used for unknown buffer sizes. */
    2755        6390 :         if (WARN_ON_ONCE(size > INT_MAX))
    2756             :                 return 0;
    2757             : 
    2758        6390 :         str = buf;
    2759        6390 :         end = buf + size;
    2760             : 
    2761             :         /* Make sure end is always >= buf */
    2762        6390 :         if (end < buf) {
    2763           0 :                 end = ((void *)-1);
    2764           0 :                 size = end - buf;
    2765             :         }
    2766             : 
    2767       22431 :         while (*fmt) {
    2768       16041 :                 const char *old_fmt = fmt;
    2769       16041 :                 int read = format_decode(fmt, &spec);
    2770             : 
    2771       16041 :                 fmt += read;
    2772             : 
    2773       16041 :                 switch (spec.type) {
    2774             :                 case FORMAT_TYPE_NONE: {
    2775        6750 :                         int copy = read;
    2776        6750 :                         if (str < end) {
    2777        6118 :                                 if (copy > end - str)
    2778         111 :                                         copy = end - str;
    2779       12236 :                                 memcpy(str, old_fmt, copy);
    2780             :                         }
    2781        6750 :                         str += read;
    2782        6750 :                         break;
    2783             :                 }
    2784             : 
    2785             :                 case FORMAT_TYPE_WIDTH:
    2786         198 :                         set_field_width(&spec, va_arg(args, int));
    2787         198 :                         break;
    2788             : 
    2789             :                 case FORMAT_TYPE_PRECISION:
    2790           2 :                         set_precision(&spec, va_arg(args, int));
    2791           2 :                         break;
    2792             : 
    2793             :                 case FORMAT_TYPE_CHAR: {
    2794             :                         char c;
    2795             : 
    2796         512 :                         if (!(spec.flags & LEFT)) {
    2797         512 :                                 while (--spec.field_width > 0) {
    2798           0 :                                         if (str < end)
    2799           0 :                                                 *str = ' ';
    2800           0 :                                         ++str;
    2801             : 
    2802             :                                 }
    2803             :                         }
    2804         512 :                         c = (unsigned char) va_arg(args, int);
    2805         512 :                         if (str < end)
    2806         512 :                                 *str = c;
    2807         512 :                         ++str;
    2808        1024 :                         while (--spec.field_width > 0) {
    2809           0 :                                 if (str < end)
    2810           0 :                                         *str = ' ';
    2811           0 :                                 ++str;
    2812             :                         }
    2813             :                         break;
    2814             :                 }
    2815             : 
    2816             :                 case FORMAT_TYPE_STR:
    2817        4374 :                         str = string(str, end, va_arg(args, char *), spec);
    2818        4374 :                         break;
    2819             : 
    2820             :                 case FORMAT_TYPE_PTR:
    2821          68 :                         str = pointer(fmt, str, end, va_arg(args, void *),
    2822             :                                       spec);
    2823         228 :                         while (isalnum(*fmt))
    2824          92 :                                 fmt++;
    2825             :                         break;
    2826             : 
    2827             :                 case FORMAT_TYPE_PERCENT_CHAR:
    2828           0 :                         if (str < end)
    2829           0 :                                 *str = '%';
    2830           0 :                         ++str;
    2831           0 :                         break;
    2832             : 
    2833             :                 case FORMAT_TYPE_INVALID:
    2834             :                         /*
    2835             :                          * Presumably the arguments passed gcc's type
    2836             :                          * checking, but there is no safe or sane way
    2837             :                          * for us to continue parsing the format and
    2838             :                          * fetching from the va_list; the remaining
    2839             :                          * specifiers and arguments would be out of
    2840             :                          * sync.
    2841             :                          */
    2842             :                         goto out;
    2843             : 
    2844             :                 default:
    2845        4137 :                         switch (spec.type) {
    2846             :                         case FORMAT_TYPE_LONG_LONG:
    2847         676 :                                 num = va_arg(args, long long);
    2848         676 :                                 break;
    2849             :                         case FORMAT_TYPE_ULONG:
    2850         376 :                                 num = va_arg(args, unsigned long);
    2851         376 :                                 break;
    2852             :                         case FORMAT_TYPE_LONG:
    2853          12 :                                 num = va_arg(args, long);
    2854          12 :                                 break;
    2855             :                         case FORMAT_TYPE_SIZE_T:
    2856         212 :                                 if (spec.flags & SIGN)
    2857         198 :                                         num = va_arg(args, ssize_t);
    2858             :                                 else
    2859          14 :                                         num = va_arg(args, size_t);
    2860             :                                 break;
    2861             :                         case FORMAT_TYPE_PTRDIFF:
    2862           0 :                                 num = va_arg(args, ptrdiff_t);
    2863           0 :                                 break;
    2864             :                         case FORMAT_TYPE_UBYTE:
    2865           0 :                                 num = (unsigned char) va_arg(args, int);
    2866           0 :                                 break;
    2867             :                         case FORMAT_TYPE_BYTE:
    2868           0 :                                 num = (signed char) va_arg(args, int);
    2869           0 :                                 break;
    2870             :                         case FORMAT_TYPE_USHORT:
    2871           0 :                                 num = (unsigned short) va_arg(args, int);
    2872           0 :                                 break;
    2873             :                         case FORMAT_TYPE_SHORT:
    2874           0 :                                 num = (short) va_arg(args, int);
    2875           0 :                                 break;
    2876             :                         case FORMAT_TYPE_INT:
    2877         170 :                                 num = (int) va_arg(args, int);
    2878         170 :                                 break;
    2879             :                         default:
    2880        2691 :                                 num = va_arg(args, unsigned int);
    2881             :                         }
    2882             : 
    2883        4137 :                         str = number(str, end, num, spec);
    2884             :                 }
    2885             :         }
    2886             : 
    2887             : out:
    2888        6390 :         if (size > 0) {
    2889        6209 :                 if (str < end)
    2890        5934 :                         *str = '\0';
    2891             :                 else
    2892         275 :                         end[-1] = '\0';
    2893             :         }
    2894             : 
    2895             :         /* the trailing null byte doesn't count towards the total */
    2896        6390 :         return str-buf;
    2897             : 
    2898             : }
    2899             : EXPORT_SYMBOL(vsnprintf);
    2900             : 
    2901             : /**
    2902             :  * vscnprintf - Format a string and place it in a buffer
    2903             :  * @buf: The buffer to place the result into
    2904             :  * @size: The size of the buffer, including the trailing null space
    2905             :  * @fmt: The format string to use
    2906             :  * @args: Arguments for the format string
    2907             :  *
    2908             :  * The return value is the number of characters which have been written into
    2909             :  * the @buf not including the trailing '\0'. If @size is == 0 the function
    2910             :  * returns 0.
    2911             :  *
    2912             :  * If you're not already dealing with a va_list consider using scnprintf().
    2913             :  *
    2914             :  * See the vsnprintf() documentation for format string extensions over C99.
    2915             :  */
    2916         284 : int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
    2917             : {
    2918             :         int i;
    2919             : 
    2920         284 :         if (unlikely(!size))
    2921             :                 return 0;
    2922             : 
    2923         284 :         i = vsnprintf(buf, size, fmt, args);
    2924             : 
    2925         284 :         if (likely(i < size))
    2926             :                 return i;
    2927             : 
    2928           0 :         return size - 1;
    2929             : }
    2930             : EXPORT_SYMBOL(vscnprintf);
    2931             : 
    2932             : /**
    2933             :  * snprintf - Format a string and place it in a buffer
    2934             :  * @buf: The buffer to place the result into
    2935             :  * @size: The size of the buffer, including the trailing null space
    2936             :  * @fmt: The format string to use
    2937             :  * @...: Arguments for the format string
    2938             :  *
    2939             :  * The return value is the number of characters which would be
    2940             :  * generated for the given input, excluding the trailing null,
    2941             :  * as per ISO C99.  If the return is greater than or equal to
    2942             :  * @size, the resulting string is truncated.
    2943             :  *
    2944             :  * See the vsnprintf() documentation for format string extensions over C99.
    2945             :  */
    2946          75 : int snprintf(char *buf, size_t size, const char *fmt, ...)
    2947             : {
    2948             :         va_list args;
    2949             :         int i;
    2950             : 
    2951          75 :         va_start(args, fmt);
    2952          75 :         i = vsnprintf(buf, size, fmt, args);
    2953          75 :         va_end(args);
    2954             : 
    2955          75 :         return i;
    2956             : }
    2957             : EXPORT_SYMBOL(snprintf);
    2958             : 
    2959             : /**
    2960             :  * scnprintf - Format a string and place it in a buffer
    2961             :  * @buf: The buffer to place the result into
    2962             :  * @size: The size of the buffer, including the trailing null space
    2963             :  * @fmt: The format string to use
    2964             :  * @...: Arguments for the format string
    2965             :  *
    2966             :  * The return value is the number of characters written into @buf not including
    2967             :  * the trailing '\0'. If @size is == 0 the function returns 0.
    2968             :  */
    2969             : 
    2970           0 : int scnprintf(char *buf, size_t size, const char *fmt, ...)
    2971             : {
    2972             :         va_list args;
    2973             :         int i;
    2974             : 
    2975           0 :         va_start(args, fmt);
    2976           0 :         i = vscnprintf(buf, size, fmt, args);
    2977           0 :         va_end(args);
    2978             : 
    2979           0 :         return i;
    2980             : }
    2981             : EXPORT_SYMBOL(scnprintf);
    2982             : 
    2983             : /**
    2984             :  * vsprintf - Format a string and place it in a buffer
    2985             :  * @buf: The buffer to place the result into
    2986             :  * @fmt: The format string to use
    2987             :  * @args: Arguments for the format string
    2988             :  *
    2989             :  * The function returns the number of characters written
    2990             :  * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
    2991             :  * buffer overflows.
    2992             :  *
    2993             :  * If you're not already dealing with a va_list consider using sprintf().
    2994             :  *
    2995             :  * See the vsnprintf() documentation for format string extensions over C99.
    2996             :  */
    2997           0 : int vsprintf(char *buf, const char *fmt, va_list args)
    2998             : {
    2999           0 :         return vsnprintf(buf, INT_MAX, fmt, args);
    3000             : }
    3001             : EXPORT_SYMBOL(vsprintf);
    3002             : 
    3003             : /**
    3004             :  * sprintf - Format a string and place it in a buffer
    3005             :  * @buf: The buffer to place the result into
    3006             :  * @fmt: The format string to use
    3007             :  * @...: Arguments for the format string
    3008             :  *
    3009             :  * The function returns the number of characters written
    3010             :  * into @buf. Use snprintf() or scnprintf() in order to avoid
    3011             :  * buffer overflows.
    3012             :  *
    3013             :  * See the vsnprintf() documentation for format string extensions over C99.
    3014             :  */
    3015        1163 : int sprintf(char *buf, const char *fmt, ...)
    3016             : {
    3017             :         va_list args;
    3018             :         int i;
    3019             : 
    3020        1163 :         va_start(args, fmt);
    3021        1163 :         i = vsnprintf(buf, INT_MAX, fmt, args);
    3022        1163 :         va_end(args);
    3023             : 
    3024        1163 :         return i;
    3025             : }
    3026             : EXPORT_SYMBOL(sprintf);
    3027             : 
    3028             : #ifdef CONFIG_BINARY_PRINTF
    3029             : /*
    3030             :  * bprintf service:
    3031             :  * vbin_printf() - VA arguments to binary data
    3032             :  * bstr_printf() - Binary data to text string
    3033             :  */
    3034             : 
    3035             : /**
    3036             :  * vbin_printf - Parse a format string and place args' binary value in a buffer
    3037             :  * @bin_buf: The buffer to place args' binary value
    3038             :  * @size: The size of the buffer(by words(32bits), not characters)
    3039             :  * @fmt: The format string to use
    3040             :  * @args: Arguments for the format string
    3041             :  *
    3042             :  * The format follows C99 vsnprintf, except %n is ignored, and its argument
    3043             :  * is skipped.
    3044             :  *
    3045             :  * The return value is the number of words(32bits) which would be generated for
    3046             :  * the given input.
    3047             :  *
    3048             :  * NOTE:
    3049             :  * If the return value is greater than @size, the resulting bin_buf is NOT
    3050             :  * valid for bstr_printf().
    3051             :  */
    3052             : int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
    3053             : {
    3054             :         struct printf_spec spec = {0};
    3055             :         char *str, *end;
    3056             :         int width;
    3057             : 
    3058             :         str = (char *)bin_buf;
    3059             :         end = (char *)(bin_buf + size);
    3060             : 
    3061             : #define save_arg(type)                                                  \
    3062             : ({                                                                      \
    3063             :         unsigned long long value;                                       \
    3064             :         if (sizeof(type) == 8) {                                        \
    3065             :                 unsigned long long val8;                                \
    3066             :                 str = PTR_ALIGN(str, sizeof(u32));                      \
    3067             :                 val8 = va_arg(args, unsigned long long);                \
    3068             :                 if (str + sizeof(type) <= end) {                     \
    3069             :                         *(u32 *)str = *(u32 *)&val8;                        \
    3070             :                         *(u32 *)(str + 4) = *((u32 *)&val8 + 1);    \
    3071             :                 }                                                       \
    3072             :                 value = val8;                                           \
    3073             :         } else {                                                        \
    3074             :                 unsigned int val4;                                      \
    3075             :                 str = PTR_ALIGN(str, sizeof(type));                     \
    3076             :                 val4 = va_arg(args, int);                               \
    3077             :                 if (str + sizeof(type) <= end)                               \
    3078             :                         *(typeof(type) *)str = (type)(long)val4;        \
    3079             :                 value = (unsigned long long)val4;                       \
    3080             :         }                                                               \
    3081             :         str += sizeof(type);                                            \
    3082             :         value;                                                          \
    3083             : })
    3084             : 
    3085             :         while (*fmt) {
    3086             :                 int read = format_decode(fmt, &spec);
    3087             : 
    3088             :                 fmt += read;
    3089             : 
    3090             :                 switch (spec.type) {
    3091             :                 case FORMAT_TYPE_NONE:
    3092             :                 case FORMAT_TYPE_PERCENT_CHAR:
    3093             :                         break;
    3094             :                 case FORMAT_TYPE_INVALID:
    3095             :                         goto out;
    3096             : 
    3097             :                 case FORMAT_TYPE_WIDTH:
    3098             :                 case FORMAT_TYPE_PRECISION:
    3099             :                         width = (int)save_arg(int);
    3100             :                         /* Pointers may require the width */
    3101             :                         if (*fmt == 'p')
    3102             :                                 set_field_width(&spec, width);
    3103             :                         break;
    3104             : 
    3105             :                 case FORMAT_TYPE_CHAR:
    3106             :                         save_arg(char);
    3107             :                         break;
    3108             : 
    3109             :                 case FORMAT_TYPE_STR: {
    3110             :                         const char *save_str = va_arg(args, char *);
    3111             :                         const char *err_msg;
    3112             :                         size_t len;
    3113             : 
    3114             :                         err_msg = check_pointer_msg(save_str);
    3115             :                         if (err_msg)
    3116             :                                 save_str = err_msg;
    3117             : 
    3118             :                         len = strlen(save_str) + 1;
    3119             :                         if (str + len < end)
    3120             :                                 memcpy(str, save_str, len);
    3121             :                         str += len;
    3122             :                         break;
    3123             :                 }
    3124             : 
    3125             :                 case FORMAT_TYPE_PTR:
    3126             :                         /* Dereferenced pointers must be done now */
    3127             :                         switch (*fmt) {
    3128             :                         /* Dereference of functions is still OK */
    3129             :                         case 'S':
    3130             :                         case 's':
    3131             :                         case 'x':
    3132             :                         case 'K':
    3133             :                         case 'e':
    3134             :                                 save_arg(void *);
    3135             :                                 break;
    3136             :                         default:
    3137             :                                 if (!isalnum(*fmt)) {
    3138             :                                         save_arg(void *);
    3139             :                                         break;
    3140             :                                 }
    3141             :                                 str = pointer(fmt, str, end, va_arg(args, void *),
    3142             :                                               spec);
    3143             :                                 if (str + 1 < end)
    3144             :                                         *str++ = '\0';
    3145             :                                 else
    3146             :                                         end[-1] = '\0'; /* Must be nul terminated */
    3147             :                         }
    3148             :                         /* skip all alphanumeric pointer suffixes */
    3149             :                         while (isalnum(*fmt))
    3150             :                                 fmt++;
    3151             :                         break;
    3152             : 
    3153             :                 default:
    3154             :                         switch (spec.type) {
    3155             : 
    3156             :                         case FORMAT_TYPE_LONG_LONG:
    3157             :                                 save_arg(long long);
    3158             :                                 break;
    3159             :                         case FORMAT_TYPE_ULONG:
    3160             :                         case FORMAT_TYPE_LONG:
    3161             :                                 save_arg(unsigned long);
    3162             :                                 break;
    3163             :                         case FORMAT_TYPE_SIZE_T:
    3164             :                                 save_arg(size_t);
    3165             :                                 break;
    3166             :                         case FORMAT_TYPE_PTRDIFF:
    3167             :                                 save_arg(ptrdiff_t);
    3168             :                                 break;
    3169             :                         case FORMAT_TYPE_UBYTE:
    3170             :                         case FORMAT_TYPE_BYTE:
    3171             :                                 save_arg(char);
    3172             :                                 break;
    3173             :                         case FORMAT_TYPE_USHORT:
    3174             :                         case FORMAT_TYPE_SHORT:
    3175             :                                 save_arg(short);
    3176             :                                 break;
    3177             :                         default:
    3178             :                                 save_arg(int);
    3179             :                         }
    3180             :                 }
    3181             :         }
    3182             : 
    3183             : out:
    3184             :         return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
    3185             : #undef save_arg
    3186             : }
    3187             : EXPORT_SYMBOL_GPL(vbin_printf);
    3188             : 
    3189             : /**
    3190             :  * bstr_printf - Format a string from binary arguments and place it in a buffer
    3191             :  * @buf: The buffer to place the result into
    3192             :  * @size: The size of the buffer, including the trailing null space
    3193             :  * @fmt: The format string to use
    3194             :  * @bin_buf: Binary arguments for the format string
    3195             :  *
    3196             :  * This function like C99 vsnprintf, but the difference is that vsnprintf gets
    3197             :  * arguments from stack, and bstr_printf gets arguments from @bin_buf which is
    3198             :  * a binary buffer that generated by vbin_printf.
    3199             :  *
    3200             :  * The format follows C99 vsnprintf, but has some extensions:
    3201             :  *  see vsnprintf comment for details.
    3202             :  *
    3203             :  * The return value is the number of characters which would
    3204             :  * be generated for the given input, excluding the trailing
    3205             :  * '\0', as per ISO C99. If you want to have the exact
    3206             :  * number of characters written into @buf as return value
    3207             :  * (not including the trailing '\0'), use vscnprintf(). If the
    3208             :  * return is greater than or equal to @size, the resulting
    3209             :  * string is truncated.
    3210             :  */
    3211             : int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
    3212             : {
    3213             :         struct printf_spec spec = {0};
    3214             :         char *str, *end;
    3215             :         const char *args = (const char *)bin_buf;
    3216             : 
    3217             :         if (WARN_ON_ONCE(size > INT_MAX))
    3218             :                 return 0;
    3219             : 
    3220             :         str = buf;
    3221             :         end = buf + size;
    3222             : 
    3223             : #define get_arg(type)                                                   \
    3224             : ({                                                                      \
    3225             :         typeof(type) value;                                             \
    3226             :         if (sizeof(type) == 8) {                                        \
    3227             :                 args = PTR_ALIGN(args, sizeof(u32));                    \
    3228             :                 *(u32 *)&value = *(u32 *)args;                              \
    3229             :                 *((u32 *)&value + 1) = *(u32 *)(args + 4);          \
    3230             :         } else {                                                        \
    3231             :                 args = PTR_ALIGN(args, sizeof(type));                   \
    3232             :                 value = *(typeof(type) *)args;                          \
    3233             :         }                                                               \
    3234             :         args += sizeof(type);                                           \
    3235             :         value;                                                          \
    3236             : })
    3237             : 
    3238             :         /* Make sure end is always >= buf */
    3239             :         if (end < buf) {
    3240             :                 end = ((void *)-1);
    3241             :                 size = end - buf;
    3242             :         }
    3243             : 
    3244             :         while (*fmt) {
    3245             :                 const char *old_fmt = fmt;
    3246             :                 int read = format_decode(fmt, &spec);
    3247             : 
    3248             :                 fmt += read;
    3249             : 
    3250             :                 switch (spec.type) {
    3251             :                 case FORMAT_TYPE_NONE: {
    3252             :                         int copy = read;
    3253             :                         if (str < end) {
    3254             :                                 if (copy > end - str)
    3255             :                                         copy = end - str;
    3256             :                                 memcpy(str, old_fmt, copy);
    3257             :                         }
    3258             :                         str += read;
    3259             :                         break;
    3260             :                 }
    3261             : 
    3262             :                 case FORMAT_TYPE_WIDTH:
    3263             :                         set_field_width(&spec, get_arg(int));
    3264             :                         break;
    3265             : 
    3266             :                 case FORMAT_TYPE_PRECISION:
    3267             :                         set_precision(&spec, get_arg(int));
    3268             :                         break;
    3269             : 
    3270             :                 case FORMAT_TYPE_CHAR: {
    3271             :                         char c;
    3272             : 
    3273             :                         if (!(spec.flags & LEFT)) {
    3274             :                                 while (--spec.field_width > 0) {
    3275             :                                         if (str < end)
    3276             :                                                 *str = ' ';
    3277             :                                         ++str;
    3278             :                                 }
    3279             :                         }
    3280             :                         c = (unsigned char) get_arg(char);
    3281             :                         if (str < end)
    3282             :                                 *str = c;
    3283             :                         ++str;
    3284             :                         while (--spec.field_width > 0) {
    3285             :                                 if (str < end)
    3286             :                                         *str = ' ';
    3287             :                                 ++str;
    3288             :                         }
    3289             :                         break;
    3290             :                 }
    3291             : 
    3292             :                 case FORMAT_TYPE_STR: {
    3293             :                         const char *str_arg = args;
    3294             :                         args += strlen(str_arg) + 1;
    3295             :                         str = string(str, end, (char *)str_arg, spec);
    3296             :                         break;
    3297             :                 }
    3298             : 
    3299             :                 case FORMAT_TYPE_PTR: {
    3300             :                         bool process = false;
    3301             :                         int copy, len;
    3302             :                         /* Non function dereferences were already done */
    3303             :                         switch (*fmt) {
    3304             :                         case 'S':
    3305             :                         case 's':
    3306             :                         case 'x':
    3307             :                         case 'K':
    3308             :                         case 'e':
    3309             :                                 process = true;
    3310             :                                 break;
    3311             :                         default:
    3312             :                                 if (!isalnum(*fmt)) {
    3313             :                                         process = true;
    3314             :                                         break;
    3315             :                                 }
    3316             :                                 /* Pointer dereference was already processed */
    3317             :                                 if (str < end) {
    3318             :                                         len = copy = strlen(args);
    3319             :                                         if (copy > end - str)
    3320             :                                                 copy = end - str;
    3321             :                                         memcpy(str, args, copy);
    3322             :                                         str += len;
    3323             :                                         args += len + 1;
    3324             :                                 }
    3325             :                         }
    3326             :                         if (process)
    3327             :                                 str = pointer(fmt, str, end, get_arg(void *), spec);
    3328             : 
    3329             :                         while (isalnum(*fmt))
    3330             :                                 fmt++;
    3331             :                         break;
    3332             :                 }
    3333             : 
    3334             :                 case FORMAT_TYPE_PERCENT_CHAR:
    3335             :                         if (str < end)
    3336             :                                 *str = '%';
    3337             :                         ++str;
    3338             :                         break;
    3339             : 
    3340             :                 case FORMAT_TYPE_INVALID:
    3341             :                         goto out;
    3342             : 
    3343             :                 default: {
    3344             :                         unsigned long long num;
    3345             : 
    3346             :                         switch (spec.type) {
    3347             : 
    3348             :                         case FORMAT_TYPE_LONG_LONG:
    3349             :                                 num = get_arg(long long);
    3350             :                                 break;
    3351             :                         case FORMAT_TYPE_ULONG:
    3352             :                         case FORMAT_TYPE_LONG:
    3353             :                                 num = get_arg(unsigned long);
    3354             :                                 break;
    3355             :                         case FORMAT_TYPE_SIZE_T:
    3356             :                                 num = get_arg(size_t);
    3357             :                                 break;
    3358             :                         case FORMAT_TYPE_PTRDIFF:
    3359             :                                 num = get_arg(ptrdiff_t);
    3360             :                                 break;
    3361             :                         case FORMAT_TYPE_UBYTE:
    3362             :                                 num = get_arg(unsigned char);
    3363             :                                 break;
    3364             :                         case FORMAT_TYPE_BYTE:
    3365             :                                 num = get_arg(signed char);
    3366             :                                 break;
    3367             :                         case FORMAT_TYPE_USHORT:
    3368             :                                 num = get_arg(unsigned short);
    3369             :                                 break;
    3370             :                         case FORMAT_TYPE_SHORT:
    3371             :                                 num = get_arg(short);
    3372             :                                 break;
    3373             :                         case FORMAT_TYPE_UINT:
    3374             :                                 num = get_arg(unsigned int);
    3375             :                                 break;
    3376             :                         default:
    3377             :                                 num = get_arg(int);
    3378             :                         }
    3379             : 
    3380             :                         str = number(str, end, num, spec);
    3381             :                 } /* default: */
    3382             :                 } /* switch(spec.type) */
    3383             :         } /* while(*fmt) */
    3384             : 
    3385             : out:
    3386             :         if (size > 0) {
    3387             :                 if (str < end)
    3388             :                         *str = '\0';
    3389             :                 else
    3390             :                         end[-1] = '\0';
    3391             :         }
    3392             : 
    3393             : #undef get_arg
    3394             : 
    3395             :         /* the trailing null byte doesn't count towards the total */
    3396             :         return str - buf;
    3397             : }
    3398             : EXPORT_SYMBOL_GPL(bstr_printf);
    3399             : 
    3400             : /**
    3401             :  * bprintf - Parse a format string and place args' binary value in a buffer
    3402             :  * @bin_buf: The buffer to place args' binary value
    3403             :  * @size: The size of the buffer(by words(32bits), not characters)
    3404             :  * @fmt: The format string to use
    3405             :  * @...: Arguments for the format string
    3406             :  *
    3407             :  * The function returns the number of words(u32) written
    3408             :  * into @bin_buf.
    3409             :  */
    3410             : int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
    3411             : {
    3412             :         va_list args;
    3413             :         int ret;
    3414             : 
    3415             :         va_start(args, fmt);
    3416             :         ret = vbin_printf(bin_buf, size, fmt, args);
    3417             :         va_end(args);
    3418             : 
    3419             :         return ret;
    3420             : }
    3421             : EXPORT_SYMBOL_GPL(bprintf);
    3422             : 
    3423             : #endif /* CONFIG_BINARY_PRINTF */
    3424             : 
    3425             : /**
    3426             :  * vsscanf - Unformat a buffer into a list of arguments
    3427             :  * @buf:        input buffer
    3428             :  * @fmt:        format of buffer
    3429             :  * @args:       arguments
    3430             :  */
    3431           0 : int vsscanf(const char *buf, const char *fmt, va_list args)
    3432             : {
    3433           0 :         const char *str = buf;
    3434             :         char *next;
    3435             :         char digit;
    3436           0 :         int num = 0;
    3437             :         u8 qualifier;
    3438             :         unsigned int base;
    3439             :         union {
    3440             :                 long long s;
    3441             :                 unsigned long long u;
    3442             :         } val;
    3443             :         s16 field_width;
    3444             :         bool is_sign;
    3445             : 
    3446           0 :         while (*fmt) {
    3447             :                 /* skip any white space in format */
    3448             :                 /* white space in format matches any amount of
    3449             :                  * white space, including none, in the input.
    3450             :                  */
    3451           0 :                 if (isspace(*fmt)) {
    3452           0 :                         fmt = skip_spaces(++fmt);
    3453           0 :                         str = skip_spaces(str);
    3454             :                 }
    3455             : 
    3456             :                 /* anything that is not a conversion must match exactly */
    3457           0 :                 if (*fmt != '%' && *fmt) {
    3458           0 :                         if (*fmt++ != *str++)
    3459             :                                 break;
    3460           0 :                         continue;
    3461             :                 }
    3462             : 
    3463           0 :                 if (!*fmt)
    3464             :                         break;
    3465           0 :                 ++fmt;
    3466             : 
    3467             :                 /* skip this conversion.
    3468             :                  * advance both strings to next white space
    3469             :                  */
    3470           0 :                 if (*fmt == '*') {
    3471           0 :                         if (!*str)
    3472             :                                 break;
    3473           0 :                         while (!isspace(*fmt) && *fmt != '%' && *fmt) {
    3474             :                                 /* '%*[' not yet supported, invalid format */
    3475           0 :                                 if (*fmt == '[')
    3476             :                                         return num;
    3477           0 :                                 fmt++;
    3478             :                         }
    3479           0 :                         while (!isspace(*str) && *str)
    3480           0 :                                 str++;
    3481           0 :                         continue;
    3482             :                 }
    3483             : 
    3484             :                 /* get field width */
    3485           0 :                 field_width = -1;
    3486           0 :                 if (isdigit(*fmt)) {
    3487           0 :                         field_width = skip_atoi(&fmt);
    3488           0 :                         if (field_width <= 0)
    3489             :                                 break;
    3490             :                 }
    3491             : 
    3492             :                 /* get conversion qualifier */
    3493           0 :                 qualifier = -1;
    3494           0 :                 if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
    3495             :                     *fmt == 'z') {
    3496           0 :                         qualifier = *fmt++;
    3497           0 :                         if (unlikely(qualifier == *fmt)) {
    3498           0 :                                 if (qualifier == 'h') {
    3499           0 :                                         qualifier = 'H';
    3500           0 :                                         fmt++;
    3501           0 :                                 } else if (qualifier == 'l') {
    3502           0 :                                         qualifier = 'L';
    3503           0 :                                         fmt++;
    3504             :                                 }
    3505             :                         }
    3506             :                 }
    3507             : 
    3508           0 :                 if (!*fmt)
    3509             :                         break;
    3510             : 
    3511           0 :                 if (*fmt == 'n') {
    3512             :                         /* return number of characters read so far */
    3513           0 :                         *va_arg(args, int *) = str - buf;
    3514           0 :                         ++fmt;
    3515           0 :                         continue;
    3516             :                 }
    3517             : 
    3518           0 :                 if (!*str)
    3519             :                         break;
    3520             : 
    3521           0 :                 base = 10;
    3522           0 :                 is_sign = false;
    3523             : 
    3524           0 :                 switch (*fmt++) {
    3525             :                 case 'c':
    3526             :                 {
    3527           0 :                         char *s = (char *)va_arg(args, char*);
    3528           0 :                         if (field_width == -1)
    3529           0 :                                 field_width = 1;
    3530             :                         do {
    3531           0 :                                 *s++ = *str++;
    3532           0 :                         } while (--field_width > 0 && *str);
    3533           0 :                         num++;
    3534             :                 }
    3535           0 :                 continue;
    3536             :                 case 's':
    3537             :                 {
    3538           0 :                         char *s = (char *)va_arg(args, char *);
    3539           0 :                         if (field_width == -1)
    3540           0 :                                 field_width = SHRT_MAX;
    3541             :                         /* first, skip leading white space in buffer */
    3542           0 :                         str = skip_spaces(str);
    3543             : 
    3544             :                         /* now copy until next white space */
    3545           0 :                         while (*str && !isspace(*str) && field_width--)
    3546           0 :                                 *s++ = *str++;
    3547           0 :                         *s = '\0';
    3548           0 :                         num++;
    3549             :                 }
    3550           0 :                 continue;
    3551             :                 /*
    3552             :                  * Warning: This implementation of the '[' conversion specifier
    3553             :                  * deviates from its glibc counterpart in the following ways:
    3554             :                  * (1) It does NOT support ranges i.e. '-' is NOT a special
    3555             :                  *     character
    3556             :                  * (2) It cannot match the closing bracket ']' itself
    3557             :                  * (3) A field width is required
    3558             :                  * (4) '%*[' (discard matching input) is currently not supported
    3559             :                  *
    3560             :                  * Example usage:
    3561             :                  * ret = sscanf("00:0a:95","%2[^:]:%2[^:]:%2[^:]",
    3562             :                  *              buf1, buf2, buf3);
    3563             :                  * if (ret < 3)
    3564             :                  *    // etc..
    3565             :                  */
    3566             :                 case '[':
    3567             :                 {
    3568           0 :                         char *s = (char *)va_arg(args, char *);
    3569           0 :                         DECLARE_BITMAP(set, 256) = {0};
    3570           0 :                         unsigned int len = 0;
    3571           0 :                         bool negate = (*fmt == '^');
    3572             : 
    3573             :                         /* field width is required */
    3574           0 :                         if (field_width == -1)
    3575           0 :                                 return num;
    3576             : 
    3577           0 :                         if (negate)
    3578           0 :                                 ++fmt;
    3579             : 
    3580           0 :                         for ( ; *fmt && *fmt != ']'; ++fmt, ++len)
    3581           0 :                                 __set_bit((u8)*fmt, set);
    3582             : 
    3583             :                         /* no ']' or no character set found */
    3584           0 :                         if (!*fmt || !len)
    3585             :                                 return num;
    3586           0 :                         ++fmt;
    3587             : 
    3588           0 :                         if (negate) {
    3589           0 :                                 bitmap_complement(set, set, 256);
    3590             :                                 /* exclude null '\0' byte */
    3591           0 :                                 __clear_bit(0, set);
    3592             :                         }
    3593             : 
    3594             :                         /* match must be non-empty */
    3595           0 :                         if (!test_bit((u8)*str, set))
    3596             :                                 return num;
    3597             : 
    3598           0 :                         while (test_bit((u8)*str, set) && field_width--)
    3599           0 :                                 *s++ = *str++;
    3600           0 :                         *s = '\0';
    3601           0 :                         ++num;
    3602             :                 }
    3603           0 :                 continue;
    3604             :                 case 'o':
    3605           0 :                         base = 8;
    3606           0 :                         break;
    3607             :                 case 'x':
    3608             :                 case 'X':
    3609           0 :                         base = 16;
    3610           0 :                         break;
    3611             :                 case 'i':
    3612           0 :                         base = 0;
    3613             :                         fallthrough;
    3614             :                 case 'd':
    3615             :                         is_sign = true;
    3616             :                         fallthrough;
    3617             :                 case 'u':
    3618             :                         break;
    3619             :                 case '%':
    3620             :                         /* looking for '%' in str */
    3621           0 :                         if (*str++ != '%')
    3622             :                                 return num;
    3623           0 :                         continue;
    3624             :                 default:
    3625             :                         /* invalid format; stop here */
    3626             :                         return num;
    3627             :                 }
    3628             : 
    3629             :                 /* have some sort of integer conversion.
    3630             :                  * first, skip white space in buffer.
    3631             :                  */
    3632           0 :                 str = skip_spaces(str);
    3633             : 
    3634           0 :                 digit = *str;
    3635           0 :                 if (is_sign && digit == '-') {
    3636           0 :                         if (field_width == 1)
    3637             :                                 break;
    3638             : 
    3639           0 :                         digit = *(str + 1);
    3640             :                 }
    3641             : 
    3642           0 :                 if (!digit
    3643           0 :                     || (base == 16 && !isxdigit(digit))
    3644           0 :                     || (base == 10 && !isdigit(digit))
    3645           0 :                     || (base == 8 && !isodigit(digit))
    3646           0 :                     || (base == 0 && !isdigit(digit)))
    3647             :                         break;
    3648             : 
    3649           0 :                 if (is_sign)
    3650           0 :                         val.s = simple_strntoll(str,
    3651             :                                                 field_width >= 0 ? field_width : INT_MAX,
    3652             :                                                 &next, base);
    3653             :                 else
    3654           0 :                         val.u = simple_strntoull(str,
    3655             :                                                  field_width >= 0 ? field_width : INT_MAX,
    3656             :                                                  &next, base);
    3657             : 
    3658           0 :                 switch (qualifier) {
    3659             :                 case 'H':       /* that's 'hh' in format */
    3660           0 :                         if (is_sign)
    3661           0 :                                 *va_arg(args, signed char *) = val.s;
    3662             :                         else
    3663           0 :                                 *va_arg(args, unsigned char *) = val.u;
    3664             :                         break;
    3665             :                 case 'h':
    3666           0 :                         if (is_sign)
    3667           0 :                                 *va_arg(args, short *) = val.s;
    3668             :                         else
    3669           0 :                                 *va_arg(args, unsigned short *) = val.u;
    3670             :                         break;
    3671             :                 case 'l':
    3672           0 :                         if (is_sign)
    3673           0 :                                 *va_arg(args, long *) = val.s;
    3674             :                         else
    3675           0 :                                 *va_arg(args, unsigned long *) = val.u;
    3676             :                         break;
    3677             :                 case 'L':
    3678           0 :                         if (is_sign)
    3679           0 :                                 *va_arg(args, long long *) = val.s;
    3680             :                         else
    3681           0 :                                 *va_arg(args, unsigned long long *) = val.u;
    3682             :                         break;
    3683             :                 case 'z':
    3684           0 :                         *va_arg(args, size_t *) = val.u;
    3685           0 :                         break;
    3686             :                 default:
    3687           0 :                         if (is_sign)
    3688           0 :                                 *va_arg(args, int *) = val.s;
    3689             :                         else
    3690           0 :                                 *va_arg(args, unsigned int *) = val.u;
    3691             :                         break;
    3692             :                 }
    3693           0 :                 num++;
    3694             : 
    3695           0 :                 if (!next)
    3696             :                         break;
    3697             :                 str = next;
    3698             :         }
    3699             : 
    3700             :         return num;
    3701             : }
    3702             : EXPORT_SYMBOL(vsscanf);
    3703             : 
    3704             : /**
    3705             :  * sscanf - Unformat a buffer into a list of arguments
    3706             :  * @buf:        input buffer
    3707             :  * @fmt:        formatting of buffer
    3708             :  * @...:        resulting arguments
    3709             :  */
    3710           0 : int sscanf(const char *buf, const char *fmt, ...)
    3711             : {
    3712             :         va_list args;
    3713             :         int i;
    3714             : 
    3715           0 :         va_start(args, fmt);
    3716           0 :         i = vsscanf(buf, fmt, args);
    3717           0 :         va_end(args);
    3718             : 
    3719           0 :         return i;
    3720             : }
    3721             : EXPORT_SYMBOL(sscanf);

Generated by: LCOV version 1.14