Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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