1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Test cases for printf facility.
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/init.h>
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/printk.h>
12*4882a593Smuzhiyun #include <linux/random.h>
13*4882a593Smuzhiyun #include <linux/rtc.h>
14*4882a593Smuzhiyun #include <linux/slab.h>
15*4882a593Smuzhiyun #include <linux/string.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include <linux/bitmap.h>
18*4882a593Smuzhiyun #include <linux/dcache.h>
19*4882a593Smuzhiyun #include <linux/socket.h>
20*4882a593Smuzhiyun #include <linux/in.h>
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #include <linux/gfp.h>
23*4882a593Smuzhiyun #include <linux/mm.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #include <linux/property.h>
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #include "../tools/testing/selftests/kselftest_module.h"
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define BUF_SIZE 256
30*4882a593Smuzhiyun #define PAD_SIZE 16
31*4882a593Smuzhiyun #define FILL_CHAR '$'
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun KSTM_MODULE_GLOBALS();
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun static char *test_buffer __initdata;
36*4882a593Smuzhiyun static char *alloced_buffer __initdata;
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun extern bool no_hash_pointers;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun static int __printf(4, 0) __init
do_test(int bufsize,const char * expect,int elen,const char * fmt,va_list ap)41*4882a593Smuzhiyun do_test(int bufsize, const char *expect, int elen,
42*4882a593Smuzhiyun const char *fmt, va_list ap)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun va_list aq;
45*4882a593Smuzhiyun int ret, written;
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun total_tests++;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun memset(alloced_buffer, FILL_CHAR, BUF_SIZE + 2*PAD_SIZE);
50*4882a593Smuzhiyun va_copy(aq, ap);
51*4882a593Smuzhiyun ret = vsnprintf(test_buffer, bufsize, fmt, aq);
52*4882a593Smuzhiyun va_end(aq);
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun if (ret != elen) {
55*4882a593Smuzhiyun pr_warn("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n",
56*4882a593Smuzhiyun bufsize, fmt, ret, elen);
57*4882a593Smuzhiyun return 1;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun if (memchr_inv(alloced_buffer, FILL_CHAR, PAD_SIZE)) {
61*4882a593Smuzhiyun pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote before buffer\n", bufsize, fmt);
62*4882a593Smuzhiyun return 1;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun if (!bufsize) {
66*4882a593Smuzhiyun if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE + PAD_SIZE)) {
67*4882a593Smuzhiyun pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n",
68*4882a593Smuzhiyun fmt);
69*4882a593Smuzhiyun return 1;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun return 0;
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun written = min(bufsize-1, elen);
75*4882a593Smuzhiyun if (test_buffer[written]) {
76*4882a593Smuzhiyun pr_warn("vsnprintf(buf, %d, \"%s\", ...) did not nul-terminate buffer\n",
77*4882a593Smuzhiyun bufsize, fmt);
78*4882a593Smuzhiyun return 1;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun if (memchr_inv(test_buffer + written + 1, FILL_CHAR, BUF_SIZE + PAD_SIZE - (written + 1))) {
82*4882a593Smuzhiyun pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator\n",
83*4882a593Smuzhiyun bufsize, fmt);
84*4882a593Smuzhiyun return 1;
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (memcmp(test_buffer, expect, written)) {
88*4882a593Smuzhiyun pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n",
89*4882a593Smuzhiyun bufsize, fmt, test_buffer, written, expect);
90*4882a593Smuzhiyun return 1;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun return 0;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun static void __printf(3, 4) __init
__test(const char * expect,int elen,const char * fmt,...)96*4882a593Smuzhiyun __test(const char *expect, int elen, const char *fmt, ...)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun va_list ap;
99*4882a593Smuzhiyun int rand;
100*4882a593Smuzhiyun char *p;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun if (elen >= BUF_SIZE) {
103*4882a593Smuzhiyun pr_err("error in test suite: expected output length %d too long. Format was '%s'.\n",
104*4882a593Smuzhiyun elen, fmt);
105*4882a593Smuzhiyun failed_tests++;
106*4882a593Smuzhiyun return;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun va_start(ap, fmt);
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /*
112*4882a593Smuzhiyun * Every fmt+args is subjected to four tests: Three where we
113*4882a593Smuzhiyun * tell vsnprintf varying buffer sizes (plenty, not quite
114*4882a593Smuzhiyun * enough and 0), and then we also test that kvasprintf would
115*4882a593Smuzhiyun * be able to print it as expected.
116*4882a593Smuzhiyun */
117*4882a593Smuzhiyun failed_tests += do_test(BUF_SIZE, expect, elen, fmt, ap);
118*4882a593Smuzhiyun rand = 1 + prandom_u32_max(elen+1);
119*4882a593Smuzhiyun /* Since elen < BUF_SIZE, we have 1 <= rand <= BUF_SIZE. */
120*4882a593Smuzhiyun failed_tests += do_test(rand, expect, elen, fmt, ap);
121*4882a593Smuzhiyun failed_tests += do_test(0, expect, elen, fmt, ap);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun p = kvasprintf(GFP_KERNEL, fmt, ap);
124*4882a593Smuzhiyun if (p) {
125*4882a593Smuzhiyun total_tests++;
126*4882a593Smuzhiyun if (memcmp(p, expect, elen+1)) {
127*4882a593Smuzhiyun pr_warn("kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n",
128*4882a593Smuzhiyun fmt, p, expect);
129*4882a593Smuzhiyun failed_tests++;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun kfree(p);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun va_end(ap);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun #define test(expect, fmt, ...) \
137*4882a593Smuzhiyun __test(expect, strlen(expect), fmt, ##__VA_ARGS__)
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun static void __init
test_basic(void)140*4882a593Smuzhiyun test_basic(void)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun /* Work around annoying "warning: zero-length gnu_printf format string". */
143*4882a593Smuzhiyun char nul = '\0';
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun test("", &nul);
146*4882a593Smuzhiyun test("100%", "100%%");
147*4882a593Smuzhiyun test("xxx%yyy", "xxx%cyyy", '%');
148*4882a593Smuzhiyun __test("xxx\0yyy", 7, "xxx%cyyy", '\0');
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun static void __init
test_number(void)152*4882a593Smuzhiyun test_number(void)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun test("0x1234abcd ", "%#-12x", 0x1234abcd);
155*4882a593Smuzhiyun test(" 0x1234abcd", "%#12x", 0x1234abcd);
156*4882a593Smuzhiyun test("0|001| 12|+123| 1234|-123|-1234", "%d|%03d|%3d|%+d|% d|%+d|% d", 0, 1, 12, 123, 1234, -123, -1234);
157*4882a593Smuzhiyun test("0|1|1|128|255", "%hhu|%hhu|%hhu|%hhu|%hhu", 0, 1, 257, 128, -1);
158*4882a593Smuzhiyun test("0|1|1|-128|-1", "%hhd|%hhd|%hhd|%hhd|%hhd", 0, 1, 257, 128, -1);
159*4882a593Smuzhiyun test("2015122420151225", "%ho%ho%#ho", 1037, 5282, -11627);
160*4882a593Smuzhiyun /*
161*4882a593Smuzhiyun * POSIX/C99: »The result of converting zero with an explicit
162*4882a593Smuzhiyun * precision of zero shall be no characters.« Hence the output
163*4882a593Smuzhiyun * from the below test should really be "00|0||| ". However,
164*4882a593Smuzhiyun * the kernel's printf also produces a single 0 in that
165*4882a593Smuzhiyun * case. This test case simply documents the current
166*4882a593Smuzhiyun * behaviour.
167*4882a593Smuzhiyun */
168*4882a593Smuzhiyun test("00|0|0|0|0", "%.2d|%.1d|%.0d|%.*d|%1.0d", 0, 0, 0, 0, 0, 0);
169*4882a593Smuzhiyun #ifndef __CHAR_UNSIGNED__
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun /*
172*4882a593Smuzhiyun * Passing a 'char' to a %02x specifier doesn't do
173*4882a593Smuzhiyun * what was presumably the intention when char is
174*4882a593Smuzhiyun * signed and the value is negative. One must either &
175*4882a593Smuzhiyun * with 0xff or cast to u8.
176*4882a593Smuzhiyun */
177*4882a593Smuzhiyun char val = -16;
178*4882a593Smuzhiyun test("0xfffffff0|0xf0|0xf0", "%#02x|%#02x|%#02x", val, val & 0xff, (u8)val);
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun #endif
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun static void __init
test_string(void)184*4882a593Smuzhiyun test_string(void)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun test("", "%s%.0s", "", "123");
187*4882a593Smuzhiyun test("ABCD|abc|123", "%s|%.3s|%.*s", "ABCD", "abcdef", 3, "123456");
188*4882a593Smuzhiyun test("1 | 2|3 | 4|5 ", "%-3s|%3s|%-*s|%*s|%*s", "1", "2", 3, "3", 3, "4", -3, "5");
189*4882a593Smuzhiyun test("1234 ", "%-10.4s", "123456");
190*4882a593Smuzhiyun test(" 1234", "%10.4s", "123456");
191*4882a593Smuzhiyun /*
192*4882a593Smuzhiyun * POSIX and C99 say that a negative precision (which is only
193*4882a593Smuzhiyun * possible to pass via a * argument) should be treated as if
194*4882a593Smuzhiyun * the precision wasn't present, and that if the precision is
195*4882a593Smuzhiyun * omitted (as in %.s), the precision should be taken to be
196*4882a593Smuzhiyun * 0. However, the kernel's printf behave exactly opposite,
197*4882a593Smuzhiyun * treating a negative precision as 0 and treating an omitted
198*4882a593Smuzhiyun * precision specifier as if no precision was given.
199*4882a593Smuzhiyun *
200*4882a593Smuzhiyun * These test cases document the current behaviour; should
201*4882a593Smuzhiyun * anyone ever feel the need to follow the standards more
202*4882a593Smuzhiyun * closely, this can be revisited.
203*4882a593Smuzhiyun */
204*4882a593Smuzhiyun test(" ", "%4.*s", -5, "123456");
205*4882a593Smuzhiyun test("123456", "%.s", "123456");
206*4882a593Smuzhiyun test("a||", "%.s|%.0s|%.*s", "a", "b", 0, "c");
207*4882a593Smuzhiyun test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c");
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun #define PLAIN_BUF_SIZE 64 /* leave some space so we don't oops */
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun #if BITS_PER_LONG == 64
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun #define PTR_WIDTH 16
215*4882a593Smuzhiyun #define PTR ((void *)0xffff0123456789abUL)
216*4882a593Smuzhiyun #define PTR_STR "ffff0123456789ab"
217*4882a593Smuzhiyun #define PTR_VAL_NO_CRNG "(____ptrval____)"
218*4882a593Smuzhiyun #define ZEROS "00000000" /* hex 32 zero bits */
219*4882a593Smuzhiyun #define ONES "ffffffff" /* hex 32 one bits */
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun static int __init
plain_format(void)222*4882a593Smuzhiyun plain_format(void)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun char buf[PLAIN_BUF_SIZE];
225*4882a593Smuzhiyun int nchars;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun if (nchars != PTR_WIDTH)
230*4882a593Smuzhiyun return -1;
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) {
233*4882a593Smuzhiyun pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"",
234*4882a593Smuzhiyun PTR_VAL_NO_CRNG);
235*4882a593Smuzhiyun return 0;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun if (strncmp(buf, ZEROS, strlen(ZEROS)) != 0)
239*4882a593Smuzhiyun return -1;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun return 0;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun #else
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun #define PTR_WIDTH 8
247*4882a593Smuzhiyun #define PTR ((void *)0x456789ab)
248*4882a593Smuzhiyun #define PTR_STR "456789ab"
249*4882a593Smuzhiyun #define PTR_VAL_NO_CRNG "(ptrval)"
250*4882a593Smuzhiyun #define ZEROS ""
251*4882a593Smuzhiyun #define ONES ""
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun static int __init
plain_format(void)254*4882a593Smuzhiyun plain_format(void)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun /* Format is implicitly tested for 32 bit machines by plain_hash() */
257*4882a593Smuzhiyun return 0;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun #endif /* BITS_PER_LONG == 64 */
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun static int __init
plain_hash_to_buffer(const void * p,char * buf,size_t len)263*4882a593Smuzhiyun plain_hash_to_buffer(const void *p, char *buf, size_t len)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun int nchars;
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun nchars = snprintf(buf, len, "%p", p);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun if (nchars != PTR_WIDTH)
270*4882a593Smuzhiyun return -1;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) {
273*4882a593Smuzhiyun pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"",
274*4882a593Smuzhiyun PTR_VAL_NO_CRNG);
275*4882a593Smuzhiyun return 0;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun return 0;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun static int __init
plain_hash(void)282*4882a593Smuzhiyun plain_hash(void)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun char buf[PLAIN_BUF_SIZE];
285*4882a593Smuzhiyun int ret;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun ret = plain_hash_to_buffer(PTR, buf, PLAIN_BUF_SIZE);
288*4882a593Smuzhiyun if (ret)
289*4882a593Smuzhiyun return ret;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0)
292*4882a593Smuzhiyun return -1;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun return 0;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun /*
298*4882a593Smuzhiyun * We can't use test() to test %p because we don't know what output to expect
299*4882a593Smuzhiyun * after an address is hashed.
300*4882a593Smuzhiyun */
301*4882a593Smuzhiyun static void __init
plain(void)302*4882a593Smuzhiyun plain(void)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun int err;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun if (no_hash_pointers) {
307*4882a593Smuzhiyun pr_warn("skipping plain 'p' tests");
308*4882a593Smuzhiyun skipped_tests += 2;
309*4882a593Smuzhiyun return;
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun err = plain_hash();
313*4882a593Smuzhiyun if (err) {
314*4882a593Smuzhiyun pr_warn("plain 'p' does not appear to be hashed\n");
315*4882a593Smuzhiyun failed_tests++;
316*4882a593Smuzhiyun return;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun err = plain_format();
320*4882a593Smuzhiyun if (err) {
321*4882a593Smuzhiyun pr_warn("hashing plain 'p' has unexpected format\n");
322*4882a593Smuzhiyun failed_tests++;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun static void __init
test_hashed(const char * fmt,const void * p)327*4882a593Smuzhiyun test_hashed(const char *fmt, const void *p)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun char buf[PLAIN_BUF_SIZE];
330*4882a593Smuzhiyun int ret;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun /*
333*4882a593Smuzhiyun * No need to increase failed test counter since this is assumed
334*4882a593Smuzhiyun * to be called after plain().
335*4882a593Smuzhiyun */
336*4882a593Smuzhiyun ret = plain_hash_to_buffer(p, buf, PLAIN_BUF_SIZE);
337*4882a593Smuzhiyun if (ret)
338*4882a593Smuzhiyun return;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun test(buf, fmt, p);
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun /*
344*4882a593Smuzhiyun * NULL pointers aren't hashed.
345*4882a593Smuzhiyun */
346*4882a593Smuzhiyun static void __init
null_pointer(void)347*4882a593Smuzhiyun null_pointer(void)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun test(ZEROS "00000000", "%p", NULL);
350*4882a593Smuzhiyun test(ZEROS "00000000", "%px", NULL);
351*4882a593Smuzhiyun test("(null)", "%pE", NULL);
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun /*
355*4882a593Smuzhiyun * Error pointers aren't hashed.
356*4882a593Smuzhiyun */
357*4882a593Smuzhiyun static void __init
error_pointer(void)358*4882a593Smuzhiyun error_pointer(void)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun test(ONES "fffffff5", "%p", ERR_PTR(-11));
361*4882a593Smuzhiyun test(ONES "fffffff5", "%px", ERR_PTR(-11));
362*4882a593Smuzhiyun test("(efault)", "%pE", ERR_PTR(-11));
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun #define PTR_INVALID ((void *)0x000000ab)
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun static void __init
invalid_pointer(void)368*4882a593Smuzhiyun invalid_pointer(void)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun test_hashed("%p", PTR_INVALID);
371*4882a593Smuzhiyun test(ZEROS "000000ab", "%px", PTR_INVALID);
372*4882a593Smuzhiyun test("(efault)", "%pE", PTR_INVALID);
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun static void __init
symbol_ptr(void)376*4882a593Smuzhiyun symbol_ptr(void)
377*4882a593Smuzhiyun {
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun static void __init
kernel_ptr(void)381*4882a593Smuzhiyun kernel_ptr(void)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun /* We can't test this without access to kptr_restrict. */
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun static void __init
struct_resource(void)387*4882a593Smuzhiyun struct_resource(void)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun static void __init
addr(void)392*4882a593Smuzhiyun addr(void)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun static void __init
escaped_str(void)397*4882a593Smuzhiyun escaped_str(void)
398*4882a593Smuzhiyun {
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun static void __init
hex_string(void)402*4882a593Smuzhiyun hex_string(void)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun const char buf[3] = {0xc0, 0xff, 0xee};
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
407*4882a593Smuzhiyun "%3ph|%3phC|%3phD|%3phN", buf, buf, buf, buf);
408*4882a593Smuzhiyun test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
409*4882a593Smuzhiyun "%*ph|%*phC|%*phD|%*phN", 3, buf, 3, buf, 3, buf, 3, buf);
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun static void __init
mac(void)413*4882a593Smuzhiyun mac(void)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun const u8 addr[6] = {0x2d, 0x48, 0xd6, 0xfc, 0x7a, 0x05};
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun test("2d:48:d6:fc:7a:05", "%pM", addr);
418*4882a593Smuzhiyun test("05:7a:fc:d6:48:2d", "%pMR", addr);
419*4882a593Smuzhiyun test("2d-48-d6-fc-7a-05", "%pMF", addr);
420*4882a593Smuzhiyun test("2d48d6fc7a05", "%pm", addr);
421*4882a593Smuzhiyun test("057afcd6482d", "%pmR", addr);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun static void __init
ip4(void)425*4882a593Smuzhiyun ip4(void)
426*4882a593Smuzhiyun {
427*4882a593Smuzhiyun struct sockaddr_in sa;
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun sa.sin_family = AF_INET;
430*4882a593Smuzhiyun sa.sin_port = cpu_to_be16(12345);
431*4882a593Smuzhiyun sa.sin_addr.s_addr = cpu_to_be32(0x7f000001);
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun test("127.000.000.001|127.0.0.1", "%pi4|%pI4", &sa.sin_addr, &sa.sin_addr);
434*4882a593Smuzhiyun test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa);
435*4882a593Smuzhiyun sa.sin_addr.s_addr = cpu_to_be32(0x01020304);
436*4882a593Smuzhiyun test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa);
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun static void __init
ip6(void)440*4882a593Smuzhiyun ip6(void)
441*4882a593Smuzhiyun {
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun static void __init
ip(void)445*4882a593Smuzhiyun ip(void)
446*4882a593Smuzhiyun {
447*4882a593Smuzhiyun ip4();
448*4882a593Smuzhiyun ip6();
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun static void __init
uuid(void)452*4882a593Smuzhiyun uuid(void)
453*4882a593Smuzhiyun {
454*4882a593Smuzhiyun const char uuid[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
455*4882a593Smuzhiyun 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun test("00010203-0405-0607-0809-0a0b0c0d0e0f", "%pUb", uuid);
458*4882a593Smuzhiyun test("00010203-0405-0607-0809-0A0B0C0D0E0F", "%pUB", uuid);
459*4882a593Smuzhiyun test("03020100-0504-0706-0809-0a0b0c0d0e0f", "%pUl", uuid);
460*4882a593Smuzhiyun test("03020100-0504-0706-0809-0A0B0C0D0E0F", "%pUL", uuid);
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun static struct dentry test_dentry[4] __initdata = {
464*4882a593Smuzhiyun { .d_parent = &test_dentry[0],
465*4882a593Smuzhiyun .d_name = QSTR_INIT(test_dentry[0].d_iname, 3),
466*4882a593Smuzhiyun .d_iname = "foo" },
467*4882a593Smuzhiyun { .d_parent = &test_dentry[0],
468*4882a593Smuzhiyun .d_name = QSTR_INIT(test_dentry[1].d_iname, 5),
469*4882a593Smuzhiyun .d_iname = "bravo" },
470*4882a593Smuzhiyun { .d_parent = &test_dentry[1],
471*4882a593Smuzhiyun .d_name = QSTR_INIT(test_dentry[2].d_iname, 4),
472*4882a593Smuzhiyun .d_iname = "alfa" },
473*4882a593Smuzhiyun { .d_parent = &test_dentry[2],
474*4882a593Smuzhiyun .d_name = QSTR_INIT(test_dentry[3].d_iname, 5),
475*4882a593Smuzhiyun .d_iname = "romeo" },
476*4882a593Smuzhiyun };
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun static void __init
dentry(void)479*4882a593Smuzhiyun dentry(void)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun test("foo", "%pd", &test_dentry[0]);
482*4882a593Smuzhiyun test("foo", "%pd2", &test_dentry[0]);
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun test("(null)", "%pd", NULL);
485*4882a593Smuzhiyun test("(efault)", "%pd", PTR_INVALID);
486*4882a593Smuzhiyun test("(null)", "%pD", NULL);
487*4882a593Smuzhiyun test("(efault)", "%pD", PTR_INVALID);
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun test("romeo", "%pd", &test_dentry[3]);
490*4882a593Smuzhiyun test("alfa/romeo", "%pd2", &test_dentry[3]);
491*4882a593Smuzhiyun test("bravo/alfa/romeo", "%pd3", &test_dentry[3]);
492*4882a593Smuzhiyun test("/bravo/alfa/romeo", "%pd4", &test_dentry[3]);
493*4882a593Smuzhiyun test("/bravo/alfa", "%pd4", &test_dentry[2]);
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun test("bravo/alfa |bravo/alfa ", "%-12pd2|%*pd2", &test_dentry[2], -12, &test_dentry[2]);
496*4882a593Smuzhiyun test(" bravo/alfa| bravo/alfa", "%12pd2|%*pd2", &test_dentry[2], 12, &test_dentry[2]);
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun static void __init
struct_va_format(void)500*4882a593Smuzhiyun struct_va_format(void)
501*4882a593Smuzhiyun {
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun static void __init
time_and_date(void)505*4882a593Smuzhiyun time_and_date(void)
506*4882a593Smuzhiyun {
507*4882a593Smuzhiyun /* 1543210543 */
508*4882a593Smuzhiyun const struct rtc_time tm = {
509*4882a593Smuzhiyun .tm_sec = 43,
510*4882a593Smuzhiyun .tm_min = 35,
511*4882a593Smuzhiyun .tm_hour = 5,
512*4882a593Smuzhiyun .tm_mday = 26,
513*4882a593Smuzhiyun .tm_mon = 10,
514*4882a593Smuzhiyun .tm_year = 118,
515*4882a593Smuzhiyun };
516*4882a593Smuzhiyun /* 2019-01-04T15:32:23 */
517*4882a593Smuzhiyun time64_t t = 1546615943;
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun test("(%pt?)", "%pt", &tm);
520*4882a593Smuzhiyun test("2018-11-26T05:35:43", "%ptR", &tm);
521*4882a593Smuzhiyun test("0118-10-26T05:35:43", "%ptRr", &tm);
522*4882a593Smuzhiyun test("05:35:43|2018-11-26", "%ptRt|%ptRd", &tm, &tm);
523*4882a593Smuzhiyun test("05:35:43|0118-10-26", "%ptRtr|%ptRdr", &tm, &tm);
524*4882a593Smuzhiyun test("05:35:43|2018-11-26", "%ptRttr|%ptRdtr", &tm, &tm);
525*4882a593Smuzhiyun test("05:35:43 tr|2018-11-26 tr", "%ptRt tr|%ptRd tr", &tm, &tm);
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun test("2019-01-04T15:32:23", "%ptT", &t);
528*4882a593Smuzhiyun test("0119-00-04T15:32:23", "%ptTr", &t);
529*4882a593Smuzhiyun test("15:32:23|2019-01-04", "%ptTt|%ptTd", &t, &t);
530*4882a593Smuzhiyun test("15:32:23|0119-00-04", "%ptTtr|%ptTdr", &t, &t);
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun static void __init
struct_clk(void)534*4882a593Smuzhiyun struct_clk(void)
535*4882a593Smuzhiyun {
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun static void __init
large_bitmap(void)539*4882a593Smuzhiyun large_bitmap(void)
540*4882a593Smuzhiyun {
541*4882a593Smuzhiyun const int nbits = 1 << 16;
542*4882a593Smuzhiyun unsigned long *bits = bitmap_zalloc(nbits, GFP_KERNEL);
543*4882a593Smuzhiyun if (!bits)
544*4882a593Smuzhiyun return;
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun bitmap_set(bits, 1, 20);
547*4882a593Smuzhiyun bitmap_set(bits, 60000, 15);
548*4882a593Smuzhiyun test("1-20,60000-60014", "%*pbl", nbits, bits);
549*4882a593Smuzhiyun bitmap_free(bits);
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun static void __init
bitmap(void)553*4882a593Smuzhiyun bitmap(void)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun DECLARE_BITMAP(bits, 20);
556*4882a593Smuzhiyun const int primes[] = {2,3,5,7,11,13,17,19};
557*4882a593Smuzhiyun int i;
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun bitmap_zero(bits, 20);
560*4882a593Smuzhiyun test("00000|00000", "%20pb|%*pb", bits, 20, bits);
561*4882a593Smuzhiyun test("|", "%20pbl|%*pbl", bits, 20, bits);
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(primes); ++i)
564*4882a593Smuzhiyun set_bit(primes[i], bits);
565*4882a593Smuzhiyun test("a28ac|a28ac", "%20pb|%*pb", bits, 20, bits);
566*4882a593Smuzhiyun test("2-3,5,7,11,13,17,19|2-3,5,7,11,13,17,19", "%20pbl|%*pbl", bits, 20, bits);
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun bitmap_fill(bits, 20);
569*4882a593Smuzhiyun test("fffff|fffff", "%20pb|%*pb", bits, 20, bits);
570*4882a593Smuzhiyun test("0-19|0-19", "%20pbl|%*pbl", bits, 20, bits);
571*4882a593Smuzhiyun
572*4882a593Smuzhiyun large_bitmap();
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun static void __init
netdev_features(void)576*4882a593Smuzhiyun netdev_features(void)
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun static void __init
flags(void)581*4882a593Smuzhiyun flags(void)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun unsigned long flags;
584*4882a593Smuzhiyun gfp_t gfp;
585*4882a593Smuzhiyun char *cmp_buffer;
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun flags = 0;
588*4882a593Smuzhiyun test("", "%pGp", &flags);
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun /* Page flags should filter the zone id */
591*4882a593Smuzhiyun flags = 1UL << NR_PAGEFLAGS;
592*4882a593Smuzhiyun test("", "%pGp", &flags);
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru
595*4882a593Smuzhiyun | 1UL << PG_active | 1UL << PG_swapbacked;
596*4882a593Smuzhiyun test("uptodate|dirty|lru|active|swapbacked", "%pGp", &flags);
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC
600*4882a593Smuzhiyun | VM_DENYWRITE;
601*4882a593Smuzhiyun test("read|exec|mayread|maywrite|mayexec|denywrite", "%pGv", &flags);
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun gfp = GFP_TRANSHUGE;
604*4882a593Smuzhiyun test("GFP_TRANSHUGE", "%pGg", &gfp);
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun gfp = GFP_ATOMIC|__GFP_DMA;
607*4882a593Smuzhiyun test("GFP_ATOMIC|GFP_DMA", "%pGg", &gfp);
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun gfp = __GFP_ATOMIC;
610*4882a593Smuzhiyun test("__GFP_ATOMIC", "%pGg", &gfp);
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
613*4882a593Smuzhiyun if (!cmp_buffer)
614*4882a593Smuzhiyun return;
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun /* Any flags not translated by the table should remain numeric */
617*4882a593Smuzhiyun gfp = ~__GFP_BITS_MASK;
618*4882a593Smuzhiyun snprintf(cmp_buffer, BUF_SIZE, "%#lx", (unsigned long) gfp);
619*4882a593Smuzhiyun test(cmp_buffer, "%pGg", &gfp);
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun snprintf(cmp_buffer, BUF_SIZE, "__GFP_ATOMIC|%#lx",
622*4882a593Smuzhiyun (unsigned long) gfp);
623*4882a593Smuzhiyun gfp |= __GFP_ATOMIC;
624*4882a593Smuzhiyun test(cmp_buffer, "%pGg", &gfp);
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun kfree(cmp_buffer);
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun
fwnode_pointer(void)629*4882a593Smuzhiyun static void __init fwnode_pointer(void)
630*4882a593Smuzhiyun {
631*4882a593Smuzhiyun const struct software_node softnodes[] = {
632*4882a593Smuzhiyun { .name = "first", },
633*4882a593Smuzhiyun { .name = "second", .parent = &softnodes[0], },
634*4882a593Smuzhiyun { .name = "third", .parent = &softnodes[1], },
635*4882a593Smuzhiyun { NULL /* Guardian */ }
636*4882a593Smuzhiyun };
637*4882a593Smuzhiyun const char * const full_name = "first/second/third";
638*4882a593Smuzhiyun const char * const full_name_second = "first/second";
639*4882a593Smuzhiyun const char * const second_name = "second";
640*4882a593Smuzhiyun const char * const third_name = "third";
641*4882a593Smuzhiyun int rval;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun rval = software_node_register_nodes(softnodes);
644*4882a593Smuzhiyun if (rval) {
645*4882a593Smuzhiyun pr_warn("cannot register softnodes; rval %d\n", rval);
646*4882a593Smuzhiyun return;
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun test(full_name_second, "%pfw", software_node_fwnode(&softnodes[1]));
650*4882a593Smuzhiyun test(full_name, "%pfw", software_node_fwnode(&softnodes[2]));
651*4882a593Smuzhiyun test(full_name, "%pfwf", software_node_fwnode(&softnodes[2]));
652*4882a593Smuzhiyun test(second_name, "%pfwP", software_node_fwnode(&softnodes[1]));
653*4882a593Smuzhiyun test(third_name, "%pfwP", software_node_fwnode(&softnodes[2]));
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun software_node_unregister(&softnodes[2]);
656*4882a593Smuzhiyun software_node_unregister(&softnodes[1]);
657*4882a593Smuzhiyun software_node_unregister(&softnodes[0]);
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun static void __init
errptr(void)661*4882a593Smuzhiyun errptr(void)
662*4882a593Smuzhiyun {
663*4882a593Smuzhiyun test("-1234", "%pe", ERR_PTR(-1234));
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun /* Check that %pe with a non-ERR_PTR gets treated as ordinary %p. */
666*4882a593Smuzhiyun BUILD_BUG_ON(IS_ERR(PTR));
667*4882a593Smuzhiyun test_hashed("%pe", PTR);
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun #ifdef CONFIG_SYMBOLIC_ERRNAME
670*4882a593Smuzhiyun test("(-ENOTSOCK)", "(%pe)", ERR_PTR(-ENOTSOCK));
671*4882a593Smuzhiyun test("(-EAGAIN)", "(%pe)", ERR_PTR(-EAGAIN));
672*4882a593Smuzhiyun BUILD_BUG_ON(EAGAIN != EWOULDBLOCK);
673*4882a593Smuzhiyun test("(-EAGAIN)", "(%pe)", ERR_PTR(-EWOULDBLOCK));
674*4882a593Smuzhiyun test("[-EIO ]", "[%-8pe]", ERR_PTR(-EIO));
675*4882a593Smuzhiyun test("[ -EIO]", "[%8pe]", ERR_PTR(-EIO));
676*4882a593Smuzhiyun test("-EPROBE_DEFER", "%pe", ERR_PTR(-EPROBE_DEFER));
677*4882a593Smuzhiyun #endif
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun static void __init
test_pointer(void)681*4882a593Smuzhiyun test_pointer(void)
682*4882a593Smuzhiyun {
683*4882a593Smuzhiyun plain();
684*4882a593Smuzhiyun null_pointer();
685*4882a593Smuzhiyun error_pointer();
686*4882a593Smuzhiyun invalid_pointer();
687*4882a593Smuzhiyun symbol_ptr();
688*4882a593Smuzhiyun kernel_ptr();
689*4882a593Smuzhiyun struct_resource();
690*4882a593Smuzhiyun addr();
691*4882a593Smuzhiyun escaped_str();
692*4882a593Smuzhiyun hex_string();
693*4882a593Smuzhiyun mac();
694*4882a593Smuzhiyun ip();
695*4882a593Smuzhiyun uuid();
696*4882a593Smuzhiyun dentry();
697*4882a593Smuzhiyun struct_va_format();
698*4882a593Smuzhiyun time_and_date();
699*4882a593Smuzhiyun struct_clk();
700*4882a593Smuzhiyun bitmap();
701*4882a593Smuzhiyun netdev_features();
702*4882a593Smuzhiyun flags();
703*4882a593Smuzhiyun errptr();
704*4882a593Smuzhiyun fwnode_pointer();
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun
selftest(void)707*4882a593Smuzhiyun static void __init selftest(void)
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL);
710*4882a593Smuzhiyun if (!alloced_buffer)
711*4882a593Smuzhiyun return;
712*4882a593Smuzhiyun test_buffer = alloced_buffer + PAD_SIZE;
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun test_basic();
715*4882a593Smuzhiyun test_number();
716*4882a593Smuzhiyun test_string();
717*4882a593Smuzhiyun test_pointer();
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun kfree(alloced_buffer);
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun KSTM_MODULE_LOADERS(test_printf);
723*4882a593Smuzhiyun MODULE_AUTHOR("Rasmus Villemoes <linux@rasmusvillemoes.dk>");
724*4882a593Smuzhiyun MODULE_LICENSE("GPL");
725