linux/lib/test_printf.c
<<
>>
Prefs
   1/*
   2 * Test cases for printf facility.
   3 */
   4
   5#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   6
   7#include <linux/init.h>
   8#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <linux/printk.h>
  11#include <linux/random.h>
  12#include <linux/slab.h>
  13#include <linux/string.h>
  14
  15#include <linux/bitmap.h>
  16#include <linux/dcache.h>
  17#include <linux/socket.h>
  18#include <linux/in.h>
  19
  20#include <linux/gfp.h>
  21#include <linux/mm.h>
  22
  23#define BUF_SIZE 256
  24#define PAD_SIZE 16
  25#define FILL_CHAR '$'
  26
  27static unsigned total_tests __initdata;
  28static unsigned failed_tests __initdata;
  29static char *test_buffer __initdata;
  30static char *alloced_buffer __initdata;
  31
  32static int __printf(4, 0) __init
  33do_test(int bufsize, const char *expect, int elen,
  34        const char *fmt, va_list ap)
  35{
  36        va_list aq;
  37        int ret, written;
  38
  39        total_tests++;
  40
  41        memset(alloced_buffer, FILL_CHAR, BUF_SIZE + 2*PAD_SIZE);
  42        va_copy(aq, ap);
  43        ret = vsnprintf(test_buffer, bufsize, fmt, aq);
  44        va_end(aq);
  45
  46        if (ret != elen) {
  47                pr_warn("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n",
  48                        bufsize, fmt, ret, elen);
  49                return 1;
  50        }
  51
  52        if (memchr_inv(alloced_buffer, FILL_CHAR, PAD_SIZE)) {
  53                pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote before buffer\n", bufsize, fmt);
  54                return 1;
  55        }
  56
  57        if (!bufsize) {
  58                if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE + PAD_SIZE)) {
  59                        pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n",
  60                                fmt);
  61                        return 1;
  62                }
  63                return 0;
  64        }
  65
  66        written = min(bufsize-1, elen);
  67        if (test_buffer[written]) {
  68                pr_warn("vsnprintf(buf, %d, \"%s\", ...) did not nul-terminate buffer\n",
  69                        bufsize, fmt);
  70                return 1;
  71        }
  72
  73        if (memchr_inv(test_buffer + written + 1, FILL_CHAR, BUF_SIZE + PAD_SIZE - (written + 1))) {
  74                pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator\n",
  75                        bufsize, fmt);
  76                return 1;
  77        }
  78
  79        if (memcmp(test_buffer, expect, written)) {
  80                pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n",
  81                        bufsize, fmt, test_buffer, written, expect);
  82                return 1;
  83        }
  84        return 0;
  85}
  86
  87static void __printf(3, 4) __init
  88__test(const char *expect, int elen, const char *fmt, ...)
  89{
  90        va_list ap;
  91        int rand;
  92        char *p;
  93
  94        if (elen >= BUF_SIZE) {
  95                pr_err("error in test suite: expected output length %d too long. Format was '%s'.\n",
  96                       elen, fmt);
  97                failed_tests++;
  98                return;
  99        }
 100
 101        va_start(ap, fmt);
 102
 103        /*
 104         * Every fmt+args is subjected to four tests: Three where we
 105         * tell vsnprintf varying buffer sizes (plenty, not quite
 106         * enough and 0), and then we also test that kvasprintf would
 107         * be able to print it as expected.
 108         */
 109        failed_tests += do_test(BUF_SIZE, expect, elen, fmt, ap);
 110        rand = 1 + prandom_u32_max(elen+1);
 111        /* Since elen < BUF_SIZE, we have 1 <= rand <= BUF_SIZE. */
 112        failed_tests += do_test(rand, expect, elen, fmt, ap);
 113        failed_tests += do_test(0, expect, elen, fmt, ap);
 114
 115        p = kvasprintf(GFP_KERNEL, fmt, ap);
 116        if (p) {
 117                total_tests++;
 118                if (memcmp(p, expect, elen+1)) {
 119                        pr_warn("kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n",
 120                                fmt, p, expect);
 121                        failed_tests++;
 122                }
 123                kfree(p);
 124        }
 125        va_end(ap);
 126}
 127
 128#define test(expect, fmt, ...)                                  \
 129        __test(expect, strlen(expect), fmt, ##__VA_ARGS__)
 130
 131static void __init
 132test_basic(void)
 133{
 134        /* Work around annoying "warning: zero-length gnu_printf format string". */
 135        char nul = '\0';
 136
 137        test("", &nul);
 138        test("100%", "100%%");
 139        test("xxx%yyy", "xxx%cyyy", '%');
 140        __test("xxx\0yyy", 7, "xxx%cyyy", '\0');
 141}
 142
 143static void __init
 144test_number(void)
 145{
 146        test("0x1234abcd  ", "%#-12x", 0x1234abcd);
 147        test("  0x1234abcd", "%#12x", 0x1234abcd);
 148        test("0|001| 12|+123| 1234|-123|-1234", "%d|%03d|%3d|%+d|% d|%+d|% d", 0, 1, 12, 123, 1234, -123, -1234);
 149        test("0|1|1|128|255", "%hhu|%hhu|%hhu|%hhu|%hhu", 0, 1, 257, 128, -1);
 150        test("0|1|1|-128|-1", "%hhd|%hhd|%hhd|%hhd|%hhd", 0, 1, 257, 128, -1);
 151        test("2015122420151225", "%ho%ho%#ho", 1037, 5282, -11627);
 152        /*
 153         * POSIX/C99: »The result of converting zero with an explicit
 154         * precision of zero shall be no characters.« Hence the output
 155         * from the below test should really be "00|0||| ". However,
 156         * the kernel's printf also produces a single 0 in that
 157         * case. This test case simply documents the current
 158         * behaviour.
 159         */
 160        test("00|0|0|0|0", "%.2d|%.1d|%.0d|%.*d|%1.0d", 0, 0, 0, 0, 0, 0);
 161#ifndef __CHAR_UNSIGNED__
 162        {
 163                /*
 164                 * Passing a 'char' to a %02x specifier doesn't do
 165                 * what was presumably the intention when char is
 166                 * signed and the value is negative. One must either &
 167                 * with 0xff or cast to u8.
 168                 */
 169                char val = -16;
 170                test("0xfffffff0|0xf0|0xf0", "%#02x|%#02x|%#02x", val, val & 0xff, (u8)val);
 171        }
 172#endif
 173}
 174
 175static void __init
 176test_string(void)
 177{
 178        test("", "%s%.0s", "", "123");
 179        test("ABCD|abc|123", "%s|%.3s|%.*s", "ABCD", "abcdef", 3, "123456");
 180        test("1  |  2|3  |  4|5  ", "%-3s|%3s|%-*s|%*s|%*s", "1", "2", 3, "3", 3, "4", -3, "5");
 181        test("1234      ", "%-10.4s", "123456");
 182        test("      1234", "%10.4s", "123456");
 183        /*
 184         * POSIX and C99 say that a negative precision (which is only
 185         * possible to pass via a * argument) should be treated as if
 186         * the precision wasn't present, and that if the precision is
 187         * omitted (as in %.s), the precision should be taken to be
 188         * 0. However, the kernel's printf behave exactly opposite,
 189         * treating a negative precision as 0 and treating an omitted
 190         * precision specifier as if no precision was given.
 191         *
 192         * These test cases document the current behaviour; should
 193         * anyone ever feel the need to follow the standards more
 194         * closely, this can be revisited.
 195         */
 196        test("    ", "%4.*s", -5, "123456");
 197        test("123456", "%.s", "123456");
 198        test("a||", "%.s|%.0s|%.*s", "a", "b", 0, "c");
 199        test("a  |   |   ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c");
 200}
 201
 202#define PLAIN_BUF_SIZE 64       /* leave some space so we don't oops */
 203
 204#if BITS_PER_LONG == 64
 205
 206#define PTR_WIDTH 16
 207#define PTR ((void *)0xffff0123456789ab)
 208#define PTR_STR "ffff0123456789ab"
 209#define ZEROS "00000000"        /* hex 32 zero bits */
 210
 211static int __init
 212plain_format(void)
 213{
 214        char buf[PLAIN_BUF_SIZE];
 215        int nchars;
 216
 217        nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR);
 218
 219        if (nchars != PTR_WIDTH || strncmp(buf, ZEROS, strlen(ZEROS)) != 0)
 220                return -1;
 221
 222        return 0;
 223}
 224
 225#else
 226
 227#define PTR_WIDTH 8
 228#define PTR ((void *)0x456789ab)
 229#define PTR_STR "456789ab"
 230
 231static int __init
 232plain_format(void)
 233{
 234        /* Format is implicitly tested for 32 bit machines by plain_hash() */
 235        return 0;
 236}
 237
 238#endif  /* BITS_PER_LONG == 64 */
 239
 240static int __init
 241plain_hash(void)
 242{
 243        char buf[PLAIN_BUF_SIZE];
 244        int nchars;
 245
 246        nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR);
 247
 248        if (nchars != PTR_WIDTH || strncmp(buf, PTR_STR, PTR_WIDTH) == 0)
 249                return -1;
 250
 251        return 0;
 252}
 253
 254/*
 255 * We can't use test() to test %p because we don't know what output to expect
 256 * after an address is hashed.
 257 */
 258static void __init
 259plain(void)
 260{
 261        int err;
 262
 263        err = plain_hash();
 264        if (err) {
 265                pr_warn("plain 'p' does not appear to be hashed\n");
 266                failed_tests++;
 267                return;
 268        }
 269
 270        err = plain_format();
 271        if (err) {
 272                pr_warn("hashing plain 'p' has unexpected format\n");
 273                failed_tests++;
 274        }
 275}
 276
 277static void __init
 278symbol_ptr(void)
 279{
 280}
 281
 282static void __init
 283kernel_ptr(void)
 284{
 285        /* We can't test this without access to kptr_restrict. */
 286}
 287
 288static void __init
 289struct_resource(void)
 290{
 291}
 292
 293static void __init
 294addr(void)
 295{
 296}
 297
 298static void __init
 299escaped_str(void)
 300{
 301}
 302
 303static void __init
 304hex_string(void)
 305{
 306        const char buf[3] = {0xc0, 0xff, 0xee};
 307
 308        test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
 309             "%3ph|%3phC|%3phD|%3phN", buf, buf, buf, buf);
 310        test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
 311             "%*ph|%*phC|%*phD|%*phN", 3, buf, 3, buf, 3, buf, 3, buf);
 312}
 313
 314static void __init
 315mac(void)
 316{
 317        const u8 addr[6] = {0x2d, 0x48, 0xd6, 0xfc, 0x7a, 0x05};
 318
 319        test("2d:48:d6:fc:7a:05", "%pM", addr);
 320        test("05:7a:fc:d6:48:2d", "%pMR", addr);
 321        test("2d-48-d6-fc-7a-05", "%pMF", addr);
 322        test("2d48d6fc7a05", "%pm", addr);
 323        test("057afcd6482d", "%pmR", addr);
 324}
 325
 326static void __init
 327ip4(void)
 328{
 329        struct sockaddr_in sa;
 330
 331        sa.sin_family = AF_INET;
 332        sa.sin_port = cpu_to_be16(12345);
 333        sa.sin_addr.s_addr = cpu_to_be32(0x7f000001);
 334
 335        test("127.000.000.001|127.0.0.1", "%pi4|%pI4", &sa.sin_addr, &sa.sin_addr);
 336        test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa);
 337        sa.sin_addr.s_addr = cpu_to_be32(0x01020304);
 338        test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa);
 339}
 340
 341static void __init
 342ip6(void)
 343{
 344}
 345
 346static void __init
 347ip(void)
 348{
 349        ip4();
 350        ip6();
 351}
 352
 353static void __init
 354uuid(void)
 355{
 356        const char uuid[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
 357                               0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
 358
 359        test("00010203-0405-0607-0809-0a0b0c0d0e0f", "%pUb", uuid);
 360        test("00010203-0405-0607-0809-0A0B0C0D0E0F", "%pUB", uuid);
 361        test("03020100-0504-0706-0809-0a0b0c0d0e0f", "%pUl", uuid);
 362        test("03020100-0504-0706-0809-0A0B0C0D0E0F", "%pUL", uuid);
 363}
 364
 365static struct dentry test_dentry[4] __initdata = {
 366        { .d_parent = &test_dentry[0],
 367          .d_name = QSTR_INIT(test_dentry[0].d_iname, 3),
 368          .d_iname = "foo" },
 369        { .d_parent = &test_dentry[0],
 370          .d_name = QSTR_INIT(test_dentry[1].d_iname, 5),
 371          .d_iname = "bravo" },
 372        { .d_parent = &test_dentry[1],
 373          .d_name = QSTR_INIT(test_dentry[2].d_iname, 4),
 374          .d_iname = "alfa" },
 375        { .d_parent = &test_dentry[2],
 376          .d_name = QSTR_INIT(test_dentry[3].d_iname, 5),
 377          .d_iname = "romeo" },
 378};
 379
 380static void __init
 381dentry(void)
 382{
 383        test("foo", "%pd", &test_dentry[0]);
 384        test("foo", "%pd2", &test_dentry[0]);
 385
 386        test("romeo", "%pd", &test_dentry[3]);
 387        test("alfa/romeo", "%pd2", &test_dentry[3]);
 388        test("bravo/alfa/romeo", "%pd3", &test_dentry[3]);
 389        test("/bravo/alfa/romeo", "%pd4", &test_dentry[3]);
 390        test("/bravo/alfa", "%pd4", &test_dentry[2]);
 391
 392        test("bravo/alfa  |bravo/alfa  ", "%-12pd2|%*pd2", &test_dentry[2], -12, &test_dentry[2]);
 393        test("  bravo/alfa|  bravo/alfa", "%12pd2|%*pd2", &test_dentry[2], 12, &test_dentry[2]);
 394}
 395
 396static void __init
 397struct_va_format(void)
 398{
 399}
 400
 401static void __init
 402struct_clk(void)
 403{
 404}
 405
 406static void __init
 407large_bitmap(void)
 408{
 409        const int nbits = 1 << 16;
 410        unsigned long *bits = kcalloc(BITS_TO_LONGS(nbits), sizeof(long), GFP_KERNEL);
 411        if (!bits)
 412                return;
 413
 414        bitmap_set(bits, 1, 20);
 415        bitmap_set(bits, 60000, 15);
 416        test("1-20,60000-60014", "%*pbl", nbits, bits);
 417        kfree(bits);
 418}
 419
 420static void __init
 421bitmap(void)
 422{
 423        DECLARE_BITMAP(bits, 20);
 424        const int primes[] = {2,3,5,7,11,13,17,19};
 425        int i;
 426
 427        bitmap_zero(bits, 20);
 428        test("00000|00000", "%20pb|%*pb", bits, 20, bits);
 429        test("|", "%20pbl|%*pbl", bits, 20, bits);
 430
 431        for (i = 0; i < ARRAY_SIZE(primes); ++i)
 432                set_bit(primes[i], bits);
 433        test("a28ac|a28ac", "%20pb|%*pb", bits, 20, bits);
 434        test("2-3,5,7,11,13,17,19|2-3,5,7,11,13,17,19", "%20pbl|%*pbl", bits, 20, bits);
 435
 436        bitmap_fill(bits, 20);
 437        test("fffff|fffff", "%20pb|%*pb", bits, 20, bits);
 438        test("0-19|0-19", "%20pbl|%*pbl", bits, 20, bits);
 439
 440        large_bitmap();
 441}
 442
 443static void __init
 444netdev_features(void)
 445{
 446}
 447
 448static void __init
 449flags(void)
 450{
 451        unsigned long flags;
 452        gfp_t gfp;
 453        char *cmp_buffer;
 454
 455        flags = 0;
 456        test("", "%pGp", &flags);
 457
 458        /* Page flags should filter the zone id */
 459        flags = 1UL << NR_PAGEFLAGS;
 460        test("", "%pGp", &flags);
 461
 462        flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru
 463                | 1UL << PG_active | 1UL << PG_swapbacked;
 464        test("uptodate|dirty|lru|active|swapbacked", "%pGp", &flags);
 465
 466
 467        flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC
 468                        | VM_DENYWRITE;
 469        test("read|exec|mayread|maywrite|mayexec|denywrite", "%pGv", &flags);
 470
 471        gfp = GFP_TRANSHUGE;
 472        test("GFP_TRANSHUGE", "%pGg", &gfp);
 473
 474        gfp = GFP_ATOMIC|__GFP_DMA;
 475        test("GFP_ATOMIC|GFP_DMA", "%pGg", &gfp);
 476
 477        gfp = __GFP_ATOMIC;
 478        test("__GFP_ATOMIC", "%pGg", &gfp);
 479
 480        cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
 481        if (!cmp_buffer)
 482                return;
 483
 484        /* Any flags not translated by the table should remain numeric */
 485        gfp = ~__GFP_BITS_MASK;
 486        snprintf(cmp_buffer, BUF_SIZE, "%#lx", (unsigned long) gfp);
 487        test(cmp_buffer, "%pGg", &gfp);
 488
 489        snprintf(cmp_buffer, BUF_SIZE, "__GFP_ATOMIC|%#lx",
 490                                                        (unsigned long) gfp);
 491        gfp |= __GFP_ATOMIC;
 492        test(cmp_buffer, "%pGg", &gfp);
 493
 494        kfree(cmp_buffer);
 495}
 496
 497static void __init
 498test_pointer(void)
 499{
 500        plain();
 501        symbol_ptr();
 502        kernel_ptr();
 503        struct_resource();
 504        addr();
 505        escaped_str();
 506        hex_string();
 507        mac();
 508        ip();
 509        uuid();
 510        dentry();
 511        struct_va_format();
 512        struct_clk();
 513        bitmap();
 514        netdev_features();
 515        flags();
 516}
 517
 518static int __init
 519test_printf_init(void)
 520{
 521        alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL);
 522        if (!alloced_buffer)
 523                return -ENOMEM;
 524        test_buffer = alloced_buffer + PAD_SIZE;
 525
 526        test_basic();
 527        test_number();
 528        test_string();
 529        test_pointer();
 530
 531        kfree(alloced_buffer);
 532
 533        if (failed_tests == 0)
 534                pr_info("all %u tests passed\n", total_tests);
 535        else
 536                pr_warn("failed %u out of %u tests\n", failed_tests, total_tests);
 537
 538        return failed_tests ? -EINVAL : 0;
 539}
 540
 541module_init(test_printf_init);
 542
 543MODULE_AUTHOR("Rasmus Villemoes <linux@rasmusvillemoes.dk>");
 544MODULE_LICENSE("GPL");
 545