linux/lib/test_string.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2#include <linux/module.h>
   3#include <linux/printk.h>
   4#include <linux/slab.h>
   5#include <linux/string.h>
   6
   7static __init int memset16_selftest(void)
   8{
   9        unsigned i, j, k;
  10        u16 v, *p;
  11
  12        p = kmalloc(256 * 2 * 2, GFP_KERNEL);
  13        if (!p)
  14                return -1;
  15
  16        for (i = 0; i < 256; i++) {
  17                for (j = 0; j < 256; j++) {
  18                        memset(p, 0xa1, 256 * 2 * sizeof(v));
  19                        memset16(p + i, 0xb1b2, j);
  20                        for (k = 0; k < 512; k++) {
  21                                v = p[k];
  22                                if (k < i) {
  23                                        if (v != 0xa1a1)
  24                                                goto fail;
  25                                } else if (k < i + j) {
  26                                        if (v != 0xb1b2)
  27                                                goto fail;
  28                                } else {
  29                                        if (v != 0xa1a1)
  30                                                goto fail;
  31                                }
  32                        }
  33                }
  34        }
  35
  36fail:
  37        kfree(p);
  38        if (i < 256)
  39                return (i << 24) | (j << 16) | k | 0x8000;
  40        return 0;
  41}
  42
  43static __init int memset32_selftest(void)
  44{
  45        unsigned i, j, k;
  46        u32 v, *p;
  47
  48        p = kmalloc(256 * 2 * 4, GFP_KERNEL);
  49        if (!p)
  50                return -1;
  51
  52        for (i = 0; i < 256; i++) {
  53                for (j = 0; j < 256; j++) {
  54                        memset(p, 0xa1, 256 * 2 * sizeof(v));
  55                        memset32(p + i, 0xb1b2b3b4, j);
  56                        for (k = 0; k < 512; k++) {
  57                                v = p[k];
  58                                if (k < i) {
  59                                        if (v != 0xa1a1a1a1)
  60                                                goto fail;
  61                                } else if (k < i + j) {
  62                                        if (v != 0xb1b2b3b4)
  63                                                goto fail;
  64                                } else {
  65                                        if (v != 0xa1a1a1a1)
  66                                                goto fail;
  67                                }
  68                        }
  69                }
  70        }
  71
  72fail:
  73        kfree(p);
  74        if (i < 256)
  75                return (i << 24) | (j << 16) | k | 0x8000;
  76        return 0;
  77}
  78
  79static __init int memset64_selftest(void)
  80{
  81        unsigned i, j, k;
  82        u64 v, *p;
  83
  84        p = kmalloc(256 * 2 * 8, GFP_KERNEL);
  85        if (!p)
  86                return -1;
  87
  88        for (i = 0; i < 256; i++) {
  89                for (j = 0; j < 256; j++) {
  90                        memset(p, 0xa1, 256 * 2 * sizeof(v));
  91                        memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j);
  92                        for (k = 0; k < 512; k++) {
  93                                v = p[k];
  94                                if (k < i) {
  95                                        if (v != 0xa1a1a1a1a1a1a1a1ULL)
  96                                                goto fail;
  97                                } else if (k < i + j) {
  98                                        if (v != 0xb1b2b3b4b5b6b7b8ULL)
  99                                                goto fail;
 100                                } else {
 101                                        if (v != 0xa1a1a1a1a1a1a1a1ULL)
 102                                                goto fail;
 103                                }
 104                        }
 105                }
 106        }
 107
 108fail:
 109        kfree(p);
 110        if (i < 256)
 111                return (i << 24) | (j << 16) | k | 0x8000;
 112        return 0;
 113}
 114
 115static __init int strchr_selftest(void)
 116{
 117        const char *test_string = "abcdefghijkl";
 118        const char *empty_string = "";
 119        char *result;
 120        int i;
 121
 122        for (i = 0; i < strlen(test_string) + 1; i++) {
 123                result = strchr(test_string, test_string[i]);
 124                if (result - test_string != i)
 125                        return i + 'a';
 126        }
 127
 128        result = strchr(empty_string, '\0');
 129        if (result != empty_string)
 130                return 0x101;
 131
 132        result = strchr(empty_string, 'a');
 133        if (result)
 134                return 0x102;
 135
 136        result = strchr(test_string, 'z');
 137        if (result)
 138                return 0x103;
 139
 140        return 0;
 141}
 142
 143static __init int strnchr_selftest(void)
 144{
 145        const char *test_string = "abcdefghijkl";
 146        const char *empty_string = "";
 147        char *result;
 148        int i, j;
 149
 150        for (i = 0; i < strlen(test_string) + 1; i++) {
 151                for (j = 0; j < strlen(test_string) + 2; j++) {
 152                        result = strnchr(test_string, j, test_string[i]);
 153                        if (j <= i) {
 154                                if (!result)
 155                                        continue;
 156                                return ((i + 'a') << 8) | j;
 157                        }
 158                        if (result - test_string != i)
 159                                return ((i + 'a') << 8) | j;
 160                }
 161        }
 162
 163        result = strnchr(empty_string, 0, '\0');
 164        if (result)
 165                return 0x10001;
 166
 167        result = strnchr(empty_string, 1, '\0');
 168        if (result != empty_string)
 169                return 0x10002;
 170
 171        result = strnchr(empty_string, 1, 'a');
 172        if (result)
 173                return 0x10003;
 174
 175        result = strnchr(NULL, 0, '\0');
 176        if (result)
 177                return 0x10004;
 178
 179        return 0;
 180}
 181
 182static __init int string_selftest_init(void)
 183{
 184        int test, subtest;
 185
 186        test = 1;
 187        subtest = memset16_selftest();
 188        if (subtest)
 189                goto fail;
 190
 191        test = 2;
 192        subtest = memset32_selftest();
 193        if (subtest)
 194                goto fail;
 195
 196        test = 3;
 197        subtest = memset64_selftest();
 198        if (subtest)
 199                goto fail;
 200
 201        test = 4;
 202        subtest = strchr_selftest();
 203        if (subtest)
 204                goto fail;
 205
 206        test = 5;
 207        subtest = strnchr_selftest();
 208        if (subtest)
 209                goto fail;
 210
 211        pr_info("String selftests succeeded\n");
 212        return 0;
 213fail:
 214        pr_crit("String selftest failure %d.%08x\n", test, subtest);
 215        return 0;
 216}
 217
 218module_init(string_selftest_init);
 219MODULE_LICENSE("GPL v2");
 220