23,6 → 23,7 |
#include <linux/ctype.h> |
#include <linux/kernel.h> |
|
#include <linux/math64.h> |
#include <linux/ioport.h> |
#include <linux/export.h> |
|
29,20 → 30,6 |
#include <asm/div64.h> |
#include <asm/page.h> /* for PAGE_SIZE */ |
|
|
static inline u64 div_u64(u64 dividend, u32 divisor) |
{ |
u32 remainder; |
return div_u64_rem(dividend, divisor, &remainder); |
} |
|
static inline s64 div_s64(s64 dividend, s32 divisor) |
{ |
s32 remainder; |
return div_s64_rem(dividend, divisor, &remainder); |
} |
|
|
#define ZERO_SIZE_PTR ((void *)16) |
|
#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \ |
55,6 → 42,7 |
#define KSTRTOX_OVERFLOW (1U << 31) |
|
const char hex_asc[] = "0123456789abcdef"; |
const char hex_asc_upper[] = "0123456789ABCDEF"; |
|
/* Works only for digits and letters, but small and fast */ |
#define TOLOWER(x) ((x) | 0x20) |
210,148 → 198,152 |
{ |
int i = 0; |
|
while (isdigit(**s)) |
do { |
i = i*10 + *((*s)++) - '0'; |
} while (isdigit(**s)); |
|
return i; |
} |
|
/* Decimal conversion is by far the most typical, and is used |
* for /proc and /sys data. This directly impacts e.g. top performance |
* with many processes running. We optimize it for speed |
* using ideas described at <http://www.cs.uiowa.edu/~jones/bcd/divide.html> |
* (with permission from the author, Douglas W. Jones). |
/* |
* Decimal conversion is by far the most typical, and is used for |
* /proc and /sys data. This directly impacts e.g. top performance |
* with many processes running. We optimize it for speed by emitting |
* two characters at a time, using a 200 byte lookup table. This |
* roughly halves the number of multiplications compared to computing |
* the digits one at a time. Implementation strongly inspired by the |
* previous version, which in turn used ideas described at |
* <http://www.cs.uiowa.edu/~jones/bcd/divide.html> (with permission |
* from the author, Douglas W. Jones). |
* |
* It turns out there is precisely one 26 bit fixed-point |
* approximation a of 64/100 for which x/100 == (x * (u64)a) >> 32 |
* holds for all x in [0, 10^8-1], namely a = 0x28f5c29. The actual |
* range happens to be somewhat larger (x <= 1073741898), but that's |
* irrelevant for our purpose. |
* |
* For dividing a number in the range [10^4, 10^6-1] by 100, we still |
* need a 32x32->64 bit multiply, so we simply use the same constant. |
* |
* For dividing a number in the range [100, 10^4-1] by 100, there are |
* several options. The simplest is (x * 0x147b) >> 19, which is valid |
* for all x <= 43698. |
*/ |
|
#if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64 |
/* Formats correctly any integer in [0, 999999999] */ |
static noinline_for_stack |
char *put_dec_full9(char *buf, unsigned q) |
{ |
unsigned r; |
static const u16 decpair[100] = { |
#define _(x) (__force u16) cpu_to_le16(((x % 10) | ((x / 10) << 8)) + 0x3030) |
_( 0), _( 1), _( 2), _( 3), _( 4), _( 5), _( 6), _( 7), _( 8), _( 9), |
_(10), _(11), _(12), _(13), _(14), _(15), _(16), _(17), _(18), _(19), |
_(20), _(21), _(22), _(23), _(24), _(25), _(26), _(27), _(28), _(29), |
_(30), _(31), _(32), _(33), _(34), _(35), _(36), _(37), _(38), _(39), |
_(40), _(41), _(42), _(43), _(44), _(45), _(46), _(47), _(48), _(49), |
_(50), _(51), _(52), _(53), _(54), _(55), _(56), _(57), _(58), _(59), |
_(60), _(61), _(62), _(63), _(64), _(65), _(66), _(67), _(68), _(69), |
_(70), _(71), _(72), _(73), _(74), _(75), _(76), _(77), _(78), _(79), |
_(80), _(81), _(82), _(83), _(84), _(85), _(86), _(87), _(88), _(89), |
_(90), _(91), _(92), _(93), _(94), _(95), _(96), _(97), _(98), _(99), |
#undef _ |
}; |
|
/* |
* Possible ways to approx. divide by 10 |
* (x * 0x1999999a) >> 32 x < 1073741829 (multiply must be 64-bit) |
* (x * 0xcccd) >> 19 x < 81920 (x < 262149 when 64-bit mul) |
* (x * 0x6667) >> 18 x < 43699 |
* (x * 0x3334) >> 17 x < 16389 |
* (x * 0x199a) >> 16 x < 16389 |
* (x * 0x0ccd) >> 15 x < 16389 |
* (x * 0x0667) >> 14 x < 2739 |
* (x * 0x0334) >> 13 x < 1029 |
* (x * 0x019a) >> 12 x < 1029 |
* (x * 0x00cd) >> 11 x < 1029 shorter code than * 0x67 (on i386) |
* (x * 0x0067) >> 10 x < 179 |
* (x * 0x0034) >> 9 x < 69 same |
* (x * 0x001a) >> 8 x < 69 same |
* (x * 0x000d) >> 7 x < 69 same, shortest code (on i386) |
* (x * 0x0007) >> 6 x < 19 |
* See <http://www.cs.uiowa.edu/~jones/bcd/divide.html> |
* This will print a single '0' even if r == 0, since we would |
* immediately jump to out_r where two 0s would be written but only |
* one of them accounted for in buf. This is needed by ip4_string |
* below. All other callers pass a non-zero value of r. |
*/ |
r = (q * (uint64_t)0x1999999a) >> 32; |
*buf++ = (q - 10 * r) + '0'; /* 1 */ |
q = (r * (uint64_t)0x1999999a) >> 32; |
*buf++ = (r - 10 * q) + '0'; /* 2 */ |
r = (q * (uint64_t)0x1999999a) >> 32; |
*buf++ = (q - 10 * r) + '0'; /* 3 */ |
q = (r * (uint64_t)0x1999999a) >> 32; |
*buf++ = (r - 10 * q) + '0'; /* 4 */ |
r = (q * (uint64_t)0x1999999a) >> 32; |
*buf++ = (q - 10 * r) + '0'; /* 5 */ |
/* Now value is under 10000, can avoid 64-bit multiply */ |
q = (r * 0x199a) >> 16; |
*buf++ = (r - 10 * q) + '0'; /* 6 */ |
r = (q * 0xcd) >> 11; |
*buf++ = (q - 10 * r) + '0'; /* 7 */ |
q = (r * 0xcd) >> 11; |
*buf++ = (r - 10 * q) + '0'; /* 8 */ |
*buf++ = q + '0'; /* 9 */ |
return buf; |
} |
#endif |
|
/* Similar to above but do not pad with zeros. |
* Code can be easily arranged to print 9 digits too, but our callers |
* always call put_dec_full9() instead when the number has 9 decimal digits. |
*/ |
static noinline_for_stack |
char *put_dec_trunc8(char *buf, unsigned r) |
{ |
unsigned q; |
|
/* Copy of previous function's body with added early returns */ |
while (r >= 10000) { |
q = r + '0'; |
r = (r * (uint64_t)0x1999999a) >> 32; |
*buf++ = q - 10*r; |
} |
/* 1 <= r < 10^8 */ |
if (r < 100) |
goto out_r; |
|
q = (r * 0x199a) >> 16; /* r <= 9999 */ |
*buf++ = (r - 10 * q) + '0'; |
if (q == 0) |
/* 100 <= r < 10^8 */ |
q = (r * (u64)0x28f5c29) >> 32; |
*((u16 *)buf) = decpair[r - 100*q]; |
buf += 2; |
|
/* 1 <= q < 10^6 */ |
if (q < 100) |
goto out_q; |
|
/* 100 <= q < 10^6 */ |
r = (q * (u64)0x28f5c29) >> 32; |
*((u16 *)buf) = decpair[q - 100*r]; |
buf += 2; |
|
/* 1 <= r < 10^4 */ |
if (r < 100) |
goto out_r; |
|
/* 100 <= r < 10^4 */ |
q = (r * 0x147b) >> 19; |
*((u16 *)buf) = decpair[r - 100*q]; |
buf += 2; |
out_q: |
/* 1 <= q < 100 */ |
r = q; |
out_r: |
/* 1 <= r < 100 */ |
*((u16 *)buf) = decpair[r]; |
buf += r < 10 ? 1 : 2; |
return buf; |
r = (q * 0xcd) >> 11; /* q <= 999 */ |
*buf++ = (q - 10 * r) + '0'; |
if (r == 0) |
return buf; |
q = (r * 0xcd) >> 11; /* r <= 99 */ |
*buf++ = (r - 10 * q) + '0'; |
if (q == 0) |
return buf; |
*buf++ = q + '0'; /* q <= 9 */ |
return buf; |
} |
|
/* There are two algorithms to print larger numbers. |
* One is generic: divide by 1000000000 and repeatedly print |
* groups of (up to) 9 digits. It's conceptually simple, |
* but requires a (unsigned long long) / 1000000000 division. |
* |
* Second algorithm splits 64-bit unsigned long long into 16-bit chunks, |
* manipulates them cleverly and generates groups of 4 decimal digits. |
* It so happens that it does NOT require long long division. |
* |
* If long is > 32 bits, division of 64-bit values is relatively easy, |
* and we will use the first algorithm. |
* If long long is > 64 bits (strange architecture with VERY large long long), |
* second algorithm can't be used, and we again use the first one. |
* |
* Else (if long is 32 bits and long long is 64 bits) we use second one. |
*/ |
#if BITS_PER_LONG == 64 && BITS_PER_LONG_LONG == 64 |
static noinline_for_stack |
char *put_dec_full8(char *buf, unsigned r) |
{ |
unsigned q; |
|
#if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64 |
/* 0 <= r < 10^8 */ |
q = (r * (u64)0x28f5c29) >> 32; |
*((u16 *)buf) = decpair[r - 100*q]; |
buf += 2; |
|
/* First algorithm: generic */ |
/* 0 <= q < 10^6 */ |
r = (q * (u64)0x28f5c29) >> 32; |
*((u16 *)buf) = decpair[q - 100*r]; |
buf += 2; |
|
static |
/* 0 <= r < 10^4 */ |
q = (r * 0x147b) >> 19; |
*((u16 *)buf) = decpair[r - 100*q]; |
buf += 2; |
|
/* 0 <= q < 100 */ |
*((u16 *)buf) = decpair[q]; |
buf += 2; |
return buf; |
} |
|
static noinline_for_stack |
char *put_dec(char *buf, unsigned long long n) |
{ |
if (n >= 100*1000*1000) { |
while (n >= 1000*1000*1000) |
buf = put_dec_full9(buf, do_div(n, 1000*1000*1000)); |
if (n >= 100*1000*1000) |
return put_dec_full9(buf, n); |
} |
buf = put_dec_full8(buf, do_div(n, 100*1000*1000)); |
/* 1 <= n <= 1.6e11 */ |
if (n >= 100*1000*1000) |
buf = put_dec_full8(buf, do_div(n, 100*1000*1000)); |
/* 1 <= n < 1e8 */ |
return put_dec_trunc8(buf, n); |
} |
|
#else |
#elif BITS_PER_LONG == 32 && BITS_PER_LONG_LONG == 64 |
|
/* Second algorithm: valid only for 64-bit long longs */ |
static void |
put_dec_full4(char *buf, unsigned r) |
{ |
unsigned q; |
|
/* See comment in put_dec_full9 for choice of constants */ |
static noinline_for_stack |
void put_dec_full4(char *buf, unsigned q) |
{ |
unsigned r; |
r = (q * 0xccd) >> 15; |
buf[0] = (q - 10 * r) + '0'; |
q = (r * 0xcd) >> 11; |
buf[1] = (r - 10 * q) + '0'; |
r = (q * 0xcd) >> 11; |
buf[2] = (q - 10 * r) + '0'; |
buf[3] = r + '0'; |
/* 0 <= r < 10^4 */ |
q = (r * 0x147b) >> 19; |
*((u16 *)buf) = decpair[r - 100*q]; |
buf += 2; |
/* 0 <= q < 100 */ |
*((u16 *)buf) = decpair[q]; |
} |
|
/* |
359,9 → 351,9 |
* The approximation x/10000 == (x * 0x346DC5D7) >> 43 |
* holds for all x < 1,128,869,999. The largest value this |
* helper will ever be asked to convert is 1,125,520,955. |
* (d1 in the put_dec code, assuming n is all-ones). |
* (second call in the put_dec code, assuming n is all-ones). |
*/ |
static |
static noinline_for_stack |
unsigned put_dec_helper4(char *buf, unsigned x) |
{ |
uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43; |
388,6 → 380,8 |
d2 = (h ) & 0xffff; |
d3 = (h >> 16); /* implicit "& 0xffff" */ |
|
/* n = 2^48 d3 + 2^32 d2 + 2^16 d1 + d0 |
= 281_4749_7671_0656 d3 + 42_9496_7296 d2 + 6_5536 d1 + d0 */ |
q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff); |
q = put_dec_helper4(buf, q); |
|
417,7 → 411,8 |
*/ |
int num_to_str(char *buf, int size, unsigned long long num) |
{ |
char tmp[sizeof(num) * 3]; |
/* put_dec requires 2-byte alignment of the buffer. */ |
char tmp[sizeof(num) * 3] __aligned(2); |
int idx, len; |
|
/* put_dec() may work incorrectly for num = 0 (generate "", not "0") */ |
435,11 → 430,11 |
return len; |
} |
|
#define ZEROPAD 1 /* pad with zero */ |
#define SIGN 2 /* unsigned/signed long */ |
#define SIGN 1 /* unsigned/signed, must be 1 */ |
#define LEFT 2 /* left justified */ |
#define PLUS 4 /* show plus */ |
#define SPACE 8 /* space if plus */ |
#define LEFT 16 /* left justified */ |
#define ZEROPAD 16 /* pad with zero, must be 16 == '0' - ' ' */ |
#define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */ |
#define SPECIAL 64 /* prefix hex with "0x", octal with "0" */ |
|
478,10 → 473,8 |
char *number(char *buf, char *end, unsigned long long num, |
struct printf_spec spec) |
{ |
/* we are called with base 8, 10 or 16, only, thus don't need "G..." */ |
static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */ |
|
char tmp[66]; |
/* put_dec requires 2-byte alignment of the buffer. */ |
char tmp[3 * sizeof(num)] __aligned(2); |
char sign; |
char locase; |
int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); |
517,12 → 510,7 |
/* generate full string in tmp[], in reverse order */ |
i = 0; |
if (num < spec.base) |
tmp[i++] = digits[num] | locase; |
/* Generic code, for any base: |
else do { |
tmp[i++] = (digits[do_div(num,base)] | locase); |
} while (num != 0); |
*/ |
tmp[i++] = hex_asc_upper[num] | locase; |
else if (spec.base != 10) { /* 8 or 16 */ |
int mask = spec.base - 1; |
int shift = 3; |
530,7 → 518,7 |
if (spec.base == 16) |
shift = 4; |
do { |
tmp[i++] = (digits[((unsigned char)num) & mask] | locase); |
tmp[i++] = (hex_asc_upper[((unsigned char)num) & mask] | locase); |
num >>= shift; |
} while (num); |
} else { /* base 10 */ |
542,7 → 530,7 |
spec.precision = i; |
/* leading space padding */ |
spec.field_width -= spec.precision; |
if (!(spec.flags & (ZEROPAD+LEFT))) { |
if (!(spec.flags & (ZEROPAD | LEFT))) { |
while (--spec.field_width >= 0) { |
if (buf < end) |
*buf = ' '; |
570,7 → 558,8 |
} |
/* zero or space padding */ |
if (!(spec.flags & LEFT)) { |
char c = (spec.flags & ZEROPAD) ? '0' : ' '; |
char c = ' ' + (spec.flags & ZEROPAD); |
BUILD_BUG_ON(' ' + ZEROPAD != '0'); |
while (--spec.field_width >= 0) { |
if (buf < end) |
*buf = c; |
712,8 → 701,6 |
#define FLAG_BUF_SIZE (2 * sizeof(res->flags)) |
#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]") |
#define RAW_BUF_SIZE sizeof("[mem - flags 0x]") |
#undef max |
#define max(a,b) ((a) > (b) ? (a) : (b)) |
char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, |
2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; |
|
742,11 → 729,16 |
specp = &mem_spec; |
decode = 0; |
} |
if (decode && res->flags & IORESOURCE_UNSET) { |
p = string(p, pend, "size ", str_spec); |
p = number(p, pend, resource_size(res), *specp); |
} else { |
p = number(p, pend, res->start, *specp); |
if (res->start != res->end) { |
*p++ = '-'; |
p = number(p, pend, res->end, *specp); |
} |
} |
if (decode) { |
if (res->flags & IORESOURCE_MEM_64) |
p = string(p, pend, " 64bit", str_spec); |
800,17 → 792,106 |
if (spec.field_width > 0) |
len = min_t(int, spec.field_width, 64); |
|
for (i = 0; i < len && buf < end - 1; i++) { |
buf = hex_byte_pack(buf, addr[i]); |
for (i = 0; i < len; ++i) { |
if (buf < end) |
*buf = hex_asc_hi(addr[i]); |
++buf; |
if (buf < end) |
*buf = hex_asc_lo(addr[i]); |
++buf; |
|
if (buf < end && separator && i != len - 1) |
*buf++ = separator; |
if (separator && i != len - 1) { |
if (buf < end) |
*buf = separator; |
++buf; |
} |
} |
|
return buf; |
} |
|
static noinline_for_stack |
char *bitmap_string(char *buf, char *end, unsigned long *bitmap, |
struct printf_spec spec, const char *fmt) |
{ |
const int CHUNKSZ = 32; |
int nr_bits = max_t(int, spec.field_width, 0); |
int i, chunksz; |
bool first = true; |
|
/* reused to print numbers */ |
spec = (struct printf_spec){ .flags = SMALL | ZEROPAD, .base = 16 }; |
|
chunksz = nr_bits & (CHUNKSZ - 1); |
if (chunksz == 0) |
chunksz = CHUNKSZ; |
|
i = ALIGN(nr_bits, CHUNKSZ) - CHUNKSZ; |
for (; i >= 0; i -= CHUNKSZ) { |
u32 chunkmask, val; |
int word, bit; |
|
chunkmask = ((1ULL << chunksz) - 1); |
word = i / BITS_PER_LONG; |
bit = i % BITS_PER_LONG; |
val = (bitmap[word] >> bit) & chunkmask; |
|
if (!first) { |
if (buf < end) |
*buf = ','; |
buf++; |
} |
first = false; |
|
spec.field_width = DIV_ROUND_UP(chunksz, 4); |
buf = number(buf, end, val, spec); |
|
chunksz = CHUNKSZ; |
} |
return buf; |
} |
|
static noinline_for_stack |
char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, |
struct printf_spec spec, const char *fmt) |
{ |
int nr_bits = max_t(int, spec.field_width, 0); |
/* current bit is 'cur', most recently seen range is [rbot, rtop] */ |
int cur, rbot, rtop; |
bool first = true; |
|
/* reused to print numbers */ |
spec = (struct printf_spec){ .base = 10 }; |
|
rbot = cur = find_first_bit(bitmap, nr_bits); |
while (cur < nr_bits) { |
rtop = cur; |
cur = find_next_bit(bitmap, nr_bits, cur + 1); |
if (cur < nr_bits && cur <= rtop + 1) |
continue; |
|
if (!first) { |
if (buf < end) |
*buf = ','; |
buf++; |
} |
first = false; |
|
buf = number(buf, end, rbot, spec); |
if (rbot < rtop) { |
if (buf < end) |
*buf = '-'; |
buf++; |
|
buf = number(buf, end, rtop, spec); |
} |
|
rbot = cur; |
} |
return buf; |
} |
|
static noinline_for_stack |
char *mac_address_string(char *buf, char *end, u8 *addr, |
struct printf_spec spec, const char *fmt) |
{ |
878,7 → 959,7 |
break; |
} |
for (i = 0; i < 4; i++) { |
char temp[3]; /* hold each IP quad in reverse order */ |
char temp[4] __aligned(2); /* hold each IP quad in reverse order */ |
int digits = put_dec_trunc8(temp, addr[index]) - temp; |
if (leading_zeros) { |
if (digits < 3) |
928,6 → 1009,10 |
* - 'B' For backtraced symbolic direct pointers with offset |
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
* - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] |
* - 'b[l]' For a bitmap, the number of bits is determined by the field |
* width which must be explicitly specified either as part of the |
* format string '%32b[l]' or through '%*b[l]', [l] selects |
* range-list format instead of hex format |
* - 'M' For a 6-byte MAC address, it prints the address in the |
* usual colon-separated hex notation |
* - 'm' For a 6-byte MAC address, it prints the hex address without colons |
949,6 → 1034,17 |
* - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order |
* - 'I[6S]c' for IPv6 addresses printed as specified by |
* http://tools.ietf.org/html/rfc5952 |
* - 'E[achnops]' For an escaped buffer, where rules are defined by combination |
* of the following flags (see string_escape_mem() for the |
* details): |
* a - ESCAPE_ANY |
* c - ESCAPE_SPECIAL |
* h - ESCAPE_HEX |
* n - ESCAPE_NULL |
* o - ESCAPE_OCTAL |
* p - ESCAPE_NP |
* s - ESCAPE_SPACE |
* By default ESCAPE_ANY_NP is used. |
* - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form |
* "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" |
* Options for %pU are: |
978,6 → 1074,11 |
* (default assumed to be phys_addr_t, passed by reference) |
* - 'd[234]' For a dentry name (optionally 2-4 last components) |
* - 'D[234]' Same as 'd' but for a struct file |
* - 'C' For a clock, it prints the name (Common Clock Framework) or address |
* (legacy clock framework) of the clock |
* - 'Cn' For a clock, it prints the name (Common Clock Framework) or address |
* (legacy clock framework) of the clock |
* - 'Cr' For a clock, it prints the current rate of the clock |
* |
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
* function pointers are really function descriptors, which contain a |
1188,8 → 1289,7 |
|
case 'p': |
spec->type = FORMAT_TYPE_PTR; |
return fmt - start; |
/* skip alnum */ |
return ++fmt - start; |
|
case '%': |
spec->type = FORMAT_TYPE_PERCENT_CHAR; |
1230,29 → 1330,21 |
if (spec->qualifier == 'L') |
spec->type = FORMAT_TYPE_LONG_LONG; |
else if (spec->qualifier == 'l') { |
if (spec->flags & SIGN) |
spec->type = FORMAT_TYPE_LONG; |
else |
spec->type = FORMAT_TYPE_ULONG; |
BUILD_BUG_ON(FORMAT_TYPE_ULONG + SIGN != FORMAT_TYPE_LONG); |
spec->type = FORMAT_TYPE_ULONG + (spec->flags & SIGN); |
} else if (_tolower(spec->qualifier) == 'z') { |
spec->type = FORMAT_TYPE_SIZE_T; |
} else if (spec->qualifier == 't') { |
spec->type = FORMAT_TYPE_PTRDIFF; |
} else if (spec->qualifier == 'H') { |
if (spec->flags & SIGN) |
spec->type = FORMAT_TYPE_BYTE; |
else |
spec->type = FORMAT_TYPE_UBYTE; |
BUILD_BUG_ON(FORMAT_TYPE_UBYTE + SIGN != FORMAT_TYPE_BYTE); |
spec->type = FORMAT_TYPE_UBYTE + (spec->flags & SIGN); |
} else if (spec->qualifier == 'h') { |
if (spec->flags & SIGN) |
spec->type = FORMAT_TYPE_SHORT; |
else |
spec->type = FORMAT_TYPE_USHORT; |
BUILD_BUG_ON(FORMAT_TYPE_USHORT + SIGN != FORMAT_TYPE_SHORT); |
spec->type = FORMAT_TYPE_USHORT + (spec->flags & SIGN); |
} else { |
if (spec->flags & SIGN) |
spec->type = FORMAT_TYPE_INT; |
else |
spec->type = FORMAT_TYPE_UINT; |
BUILD_BUG_ON(FORMAT_TYPE_UINT + SIGN != FORMAT_TYPE_INT); |
spec->type = FORMAT_TYPE_UINT + (spec->flags & SIGN); |
} |
|
return ++fmt - start; |
1273,6 → 1365,8 |
* %pB output the name of a backtrace symbol with its offset |
* %pR output the address range in a struct resource with decoded flags |
* %pr output the address range in a struct resource with raw flags |
* %pb output the bitmap with field width as the number of bits |
* %pbl output the bitmap as range list with field width as the number of bits |
* %pM output a 6-byte MAC address with colons |
* %pMR output a 6-byte MAC address with colons in reversed order |
* %pMF output a 6-byte MAC address with dashes |
1290,6 → 1384,11 |
* %*pE[achnops] print an escaped buffer |
* %*ph[CDN] a variable-length hex string with a separator (supports up to 64 |
* bytes of the input) |
* %pC output the name (Common Clock Framework) or address (legacy clock |
* framework) of a clock |
* %pCn output the name (Common Clock Framework) or address (legacy clock |
* framework) of a clock |
* %pCr output the current rate of a clock |
* %n is ignored |
* |
* ** Please update Documentation/printk-formats.txt when making changes ** |
1312,7 → 1411,7 |
|
/* Reject out-of-range values early. Large positive sizes are |
used for unknown buffer sizes. */ |
if ((int) size < 0) |
if (WARN_ON_ONCE(size > INT_MAX)) |
return 0; |
|
str = buf; |
1378,7 → 1477,7 |
break; |
|
case FORMAT_TYPE_PTR: |
str = pointer(fmt+1, str, end, va_arg(args, void *), |
str = pointer(fmt, str, end, va_arg(args, void *), |
spec); |
while (isalnum(*fmt)) |
fmt++; |