0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007
0008 #include <linux/bitops.h>
0009 #include <linux/init.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/overflow.h>
0013 #include <linux/printk.h>
0014 #include <linux/random.h>
0015 #include <linux/slab.h>
0016 #include <linux/string.h>
0017
0018 #include "../tools/testing/selftests/kselftest_module.h"
0019
0020 #define BUF_SIZE 1024
0021
0022 KSTM_MODULE_GLOBALS();
0023 static char *test_buffer __initdata;
0024 static char *fmt_buffer __initdata;
0025 static struct rnd_state rnd_state __initdata;
0026
0027 typedef int (*check_fn)(const void *check_data, const char *string,
0028 const char *fmt, int n_args, va_list ap);
0029
0030 static void __scanf(4, 6) __init
0031 _test(check_fn fn, const void *check_data, const char *string, const char *fmt,
0032 int n_args, ...)
0033 {
0034 va_list ap, ap_copy;
0035 int ret;
0036
0037 total_tests++;
0038
0039 va_start(ap, n_args);
0040 va_copy(ap_copy, ap);
0041 ret = vsscanf(string, fmt, ap_copy);
0042 va_end(ap_copy);
0043
0044 if (ret != n_args) {
0045 pr_warn("vsscanf(\"%s\", \"%s\", ...) returned %d expected %d\n",
0046 string, fmt, ret, n_args);
0047 goto fail;
0048 }
0049
0050 ret = (*fn)(check_data, string, fmt, n_args, ap);
0051 if (ret)
0052 goto fail;
0053
0054 va_end(ap);
0055
0056 return;
0057
0058 fail:
0059 failed_tests++;
0060 va_end(ap);
0061 }
0062
0063 #define _check_numbers_template(arg_fmt, expect, str, fmt, n_args, ap) \
0064 do { \
0065 pr_debug("\"%s\", \"%s\" ->\n", str, fmt); \
0066 for (; n_args > 0; n_args--, expect++) { \
0067 typeof(*expect) got = *va_arg(ap, typeof(expect)); \
0068 pr_debug("\t" arg_fmt "\n", got); \
0069 if (got != *expect) { \
0070 pr_warn("vsscanf(\"%s\", \"%s\", ...) expected " arg_fmt " got " arg_fmt "\n", \
0071 str, fmt, *expect, got); \
0072 return 1; \
0073 } \
0074 } \
0075 return 0; \
0076 } while (0)
0077
0078 static int __init check_ull(const void *check_data, const char *string,
0079 const char *fmt, int n_args, va_list ap)
0080 {
0081 const unsigned long long *pval = check_data;
0082
0083 _check_numbers_template("%llu", pval, string, fmt, n_args, ap);
0084 }
0085
0086 static int __init check_ll(const void *check_data, const char *string,
0087 const char *fmt, int n_args, va_list ap)
0088 {
0089 const long long *pval = check_data;
0090
0091 _check_numbers_template("%lld", pval, string, fmt, n_args, ap);
0092 }
0093
0094 static int __init check_ulong(const void *check_data, const char *string,
0095 const char *fmt, int n_args, va_list ap)
0096 {
0097 const unsigned long *pval = check_data;
0098
0099 _check_numbers_template("%lu", pval, string, fmt, n_args, ap);
0100 }
0101
0102 static int __init check_long(const void *check_data, const char *string,
0103 const char *fmt, int n_args, va_list ap)
0104 {
0105 const long *pval = check_data;
0106
0107 _check_numbers_template("%ld", pval, string, fmt, n_args, ap);
0108 }
0109
0110 static int __init check_uint(const void *check_data, const char *string,
0111 const char *fmt, int n_args, va_list ap)
0112 {
0113 const unsigned int *pval = check_data;
0114
0115 _check_numbers_template("%u", pval, string, fmt, n_args, ap);
0116 }
0117
0118 static int __init check_int(const void *check_data, const char *string,
0119 const char *fmt, int n_args, va_list ap)
0120 {
0121 const int *pval = check_data;
0122
0123 _check_numbers_template("%d", pval, string, fmt, n_args, ap);
0124 }
0125
0126 static int __init check_ushort(const void *check_data, const char *string,
0127 const char *fmt, int n_args, va_list ap)
0128 {
0129 const unsigned short *pval = check_data;
0130
0131 _check_numbers_template("%hu", pval, string, fmt, n_args, ap);
0132 }
0133
0134 static int __init check_short(const void *check_data, const char *string,
0135 const char *fmt, int n_args, va_list ap)
0136 {
0137 const short *pval = check_data;
0138
0139 _check_numbers_template("%hd", pval, string, fmt, n_args, ap);
0140 }
0141
0142 static int __init check_uchar(const void *check_data, const char *string,
0143 const char *fmt, int n_args, va_list ap)
0144 {
0145 const unsigned char *pval = check_data;
0146
0147 _check_numbers_template("%hhu", pval, string, fmt, n_args, ap);
0148 }
0149
0150 static int __init check_char(const void *check_data, const char *string,
0151 const char *fmt, int n_args, va_list ap)
0152 {
0153 const signed char *pval = check_data;
0154
0155 _check_numbers_template("%hhd", pval, string, fmt, n_args, ap);
0156 }
0157
0158
0159 static const unsigned long long numbers[] __initconst = {
0160 0x0ULL,
0161 0x1ULL,
0162 0x7fULL,
0163 0x80ULL,
0164 0x81ULL,
0165 0xffULL,
0166 0x100ULL,
0167 0x101ULL,
0168 0x7fffULL,
0169 0x8000ULL,
0170 0x8001ULL,
0171 0xffffULL,
0172 0x10000ULL,
0173 0x10001ULL,
0174 0x7fffffffULL,
0175 0x80000000ULL,
0176 0x80000001ULL,
0177 0xffffffffULL,
0178 0x100000000ULL,
0179 0x100000001ULL,
0180 0x7fffffffffffffffULL,
0181 0x8000000000000000ULL,
0182 0x8000000000000001ULL,
0183 0xfffffffffffffffeULL,
0184 0xffffffffffffffffULL,
0185 };
0186
0187 #define value_representable_in_type(T, val) \
0188 (is_signed_type(T) \
0189 ? ((long long)(val) >= type_min(T)) && ((long long)(val) <= type_max(T)) \
0190 : ((unsigned long long)(val) <= type_max(T)))
0191
0192
0193 #define test_one_number(T, gen_fmt, scan_fmt, val, fn) \
0194 do { \
0195 const T expect_val = (T)(val); \
0196 T result = ~expect_val; \
0197 \
0198 snprintf(test_buffer, BUF_SIZE, gen_fmt, expect_val); \
0199 _test(fn, &expect_val, test_buffer, "%" scan_fmt, 1, &result); \
0200 } while (0)
0201
0202 #define simple_numbers_loop(T, gen_fmt, scan_fmt, fn) \
0203 do { \
0204 int i; \
0205 \
0206 for (i = 0; i < ARRAY_SIZE(numbers); i++) { \
0207 if (value_representable_in_type(T, numbers[i])) \
0208 test_one_number(T, gen_fmt, scan_fmt, \
0209 numbers[i], fn); \
0210 \
0211 if (value_representable_in_type(T, -numbers[i])) \
0212 test_one_number(T, gen_fmt, scan_fmt, \
0213 -numbers[i], fn); \
0214 } \
0215 } while (0)
0216
0217 static void __init numbers_simple(void)
0218 {
0219 simple_numbers_loop(unsigned long long, "%llu", "llu", check_ull);
0220 simple_numbers_loop(long long, "%lld", "lld", check_ll);
0221 simple_numbers_loop(long long, "%lld", "lli", check_ll);
0222 simple_numbers_loop(unsigned long long, "%llx", "llx", check_ull);
0223 simple_numbers_loop(long long, "%llx", "llx", check_ll);
0224 simple_numbers_loop(long long, "0x%llx", "lli", check_ll);
0225 simple_numbers_loop(unsigned long long, "0x%llx", "llx", check_ull);
0226 simple_numbers_loop(long long, "0x%llx", "llx", check_ll);
0227
0228 simple_numbers_loop(unsigned long, "%lu", "lu", check_ulong);
0229 simple_numbers_loop(long, "%ld", "ld", check_long);
0230 simple_numbers_loop(long, "%ld", "li", check_long);
0231 simple_numbers_loop(unsigned long, "%lx", "lx", check_ulong);
0232 simple_numbers_loop(long, "%lx", "lx", check_long);
0233 simple_numbers_loop(long, "0x%lx", "li", check_long);
0234 simple_numbers_loop(unsigned long, "0x%lx", "lx", check_ulong);
0235 simple_numbers_loop(long, "0x%lx", "lx", check_long);
0236
0237 simple_numbers_loop(unsigned int, "%u", "u", check_uint);
0238 simple_numbers_loop(int, "%d", "d", check_int);
0239 simple_numbers_loop(int, "%d", "i", check_int);
0240 simple_numbers_loop(unsigned int, "%x", "x", check_uint);
0241 simple_numbers_loop(int, "%x", "x", check_int);
0242 simple_numbers_loop(int, "0x%x", "i", check_int);
0243 simple_numbers_loop(unsigned int, "0x%x", "x", check_uint);
0244 simple_numbers_loop(int, "0x%x", "x", check_int);
0245
0246 simple_numbers_loop(unsigned short, "%hu", "hu", check_ushort);
0247 simple_numbers_loop(short, "%hd", "hd", check_short);
0248 simple_numbers_loop(short, "%hd", "hi", check_short);
0249 simple_numbers_loop(unsigned short, "%hx", "hx", check_ushort);
0250 simple_numbers_loop(short, "%hx", "hx", check_short);
0251 simple_numbers_loop(short, "0x%hx", "hi", check_short);
0252 simple_numbers_loop(unsigned short, "0x%hx", "hx", check_ushort);
0253 simple_numbers_loop(short, "0x%hx", "hx", check_short);
0254
0255 simple_numbers_loop(unsigned char, "%hhu", "hhu", check_uchar);
0256 simple_numbers_loop(signed char, "%hhd", "hhd", check_char);
0257 simple_numbers_loop(signed char, "%hhd", "hhi", check_char);
0258 simple_numbers_loop(unsigned char, "%hhx", "hhx", check_uchar);
0259 simple_numbers_loop(signed char, "%hhx", "hhx", check_char);
0260 simple_numbers_loop(signed char, "0x%hhx", "hhi", check_char);
0261 simple_numbers_loop(unsigned char, "0x%hhx", "hhx", check_uchar);
0262 simple_numbers_loop(signed char, "0x%hhx", "hhx", check_char);
0263 }
0264
0265
0266
0267
0268
0269
0270 static u32 __init next_test_random(u32 max_bits)
0271 {
0272 u32 n_bits = hweight32(prandom_u32_state(&rnd_state)) % (max_bits + 1);
0273
0274 return prandom_u32_state(&rnd_state) & GENMASK(n_bits, 0);
0275 }
0276
0277 static unsigned long long __init next_test_random_ull(void)
0278 {
0279 u32 rand1 = prandom_u32_state(&rnd_state);
0280 u32 n_bits = (hweight32(rand1) * 3) % 64;
0281 u64 val = (u64)prandom_u32_state(&rnd_state) * rand1;
0282
0283 return val & GENMASK_ULL(n_bits, 0);
0284 }
0285
0286 #define random_for_type(T) \
0287 ((T)(sizeof(T) <= sizeof(u32) \
0288 ? next_test_random(BITS_PER_TYPE(T)) \
0289 : next_test_random_ull()))
0290
0291
0292
0293
0294
0295 #define NEGATIVES_PATTERN 0x3246
0296
0297 #define fill_random_array(arr) \
0298 do { \
0299 unsigned int neg_pattern = NEGATIVES_PATTERN; \
0300 int i; \
0301 \
0302 for (i = 0; i < ARRAY_SIZE(arr); i++, neg_pattern >>= 1) { \
0303 (arr)[i] = random_for_type(typeof((arr)[0])); \
0304 if (is_signed_type(typeof((arr)[0])) && (neg_pattern & 1)) \
0305 (arr)[i] = -(arr)[i]; \
0306 } \
0307 } while (0)
0308
0309
0310
0311
0312
0313
0314 static int __init __printf(4, 5)
0315 append_fmt(char *buf, int *buf_pos, int buf_len, const char *val_fmt, ...)
0316 {
0317 va_list ap;
0318 int field_len;
0319
0320 va_start(ap, val_fmt);
0321 field_len = vsnprintf(buf + *buf_pos, buf_len - *buf_pos, val_fmt, ap);
0322 va_end(ap);
0323
0324 if (field_len < 0)
0325 field_len = 0;
0326
0327 *buf_pos += field_len;
0328
0329 return field_len;
0330 }
0331
0332
0333
0334
0335
0336 static void __init append_delim(char *str_buf, int *str_buf_pos, int str_buf_len,
0337 char *fmt_buf, int *fmt_buf_pos, int fmt_buf_len,
0338 const char *delim_str)
0339 {
0340 append_fmt(str_buf, str_buf_pos, str_buf_len, delim_str);
0341 append_fmt(fmt_buf, fmt_buf_pos, fmt_buf_len, delim_str);
0342 }
0343
0344 #define test_array_8(fn, check_data, string, fmt, arr) \
0345 do { \
0346 BUILD_BUG_ON(ARRAY_SIZE(arr) != 8); \
0347 _test(fn, check_data, string, fmt, 8, \
0348 &(arr)[0], &(arr)[1], &(arr)[2], &(arr)[3], \
0349 &(arr)[4], &(arr)[5], &(arr)[6], &(arr)[7]); \
0350 } while (0)
0351
0352 #define numbers_list_8(T, gen_fmt, field_sep, scan_fmt, fn) \
0353 do { \
0354 int i, pos = 0, fmt_pos = 0; \
0355 T expect[8], result[8]; \
0356 \
0357 fill_random_array(expect); \
0358 \
0359 for (i = 0; i < ARRAY_SIZE(expect); i++) { \
0360 if (i != 0) \
0361 append_delim(test_buffer, &pos, BUF_SIZE, \
0362 fmt_buffer, &fmt_pos, BUF_SIZE, \
0363 field_sep); \
0364 \
0365 append_fmt(test_buffer, &pos, BUF_SIZE, gen_fmt, expect[i]); \
0366 append_fmt(fmt_buffer, &fmt_pos, BUF_SIZE, "%%%s", scan_fmt); \
0367 } \
0368 \
0369 test_array_8(fn, expect, test_buffer, fmt_buffer, result); \
0370 } while (0)
0371
0372 #define numbers_list_fix_width(T, gen_fmt, field_sep, width, scan_fmt, fn) \
0373 do { \
0374 char full_fmt[16]; \
0375 \
0376 snprintf(full_fmt, sizeof(full_fmt), "%u%s", width, scan_fmt); \
0377 numbers_list_8(T, gen_fmt, field_sep, full_fmt, fn); \
0378 } while (0)
0379
0380 #define numbers_list_val_width(T, gen_fmt, field_sep, scan_fmt, fn) \
0381 do { \
0382 int i, val_len, pos = 0, fmt_pos = 0; \
0383 T expect[8], result[8]; \
0384 \
0385 fill_random_array(expect); \
0386 \
0387 for (i = 0; i < ARRAY_SIZE(expect); i++) { \
0388 if (i != 0) \
0389 append_delim(test_buffer, &pos, BUF_SIZE, \
0390 fmt_buffer, &fmt_pos, BUF_SIZE, field_sep);\
0391 \
0392 val_len = append_fmt(test_buffer, &pos, BUF_SIZE, gen_fmt, \
0393 expect[i]); \
0394 append_fmt(fmt_buffer, &fmt_pos, BUF_SIZE, \
0395 "%%%u%s", val_len, scan_fmt); \
0396 } \
0397 \
0398 test_array_8(fn, expect, test_buffer, fmt_buffer, result); \
0399 } while (0)
0400
0401 static void __init numbers_list_ll(const char *delim)
0402 {
0403 numbers_list_8(unsigned long long, "%llu", delim, "llu", check_ull);
0404 numbers_list_8(long long, "%lld", delim, "lld", check_ll);
0405 numbers_list_8(long long, "%lld", delim, "lli", check_ll);
0406 numbers_list_8(unsigned long long, "%llx", delim, "llx", check_ull);
0407 numbers_list_8(unsigned long long, "0x%llx", delim, "llx", check_ull);
0408 numbers_list_8(long long, "0x%llx", delim, "lli", check_ll);
0409 }
0410
0411 static void __init numbers_list_l(const char *delim)
0412 {
0413 numbers_list_8(unsigned long, "%lu", delim, "lu", check_ulong);
0414 numbers_list_8(long, "%ld", delim, "ld", check_long);
0415 numbers_list_8(long, "%ld", delim, "li", check_long);
0416 numbers_list_8(unsigned long, "%lx", delim, "lx", check_ulong);
0417 numbers_list_8(unsigned long, "0x%lx", delim, "lx", check_ulong);
0418 numbers_list_8(long, "0x%lx", delim, "li", check_long);
0419 }
0420
0421 static void __init numbers_list_d(const char *delim)
0422 {
0423 numbers_list_8(unsigned int, "%u", delim, "u", check_uint);
0424 numbers_list_8(int, "%d", delim, "d", check_int);
0425 numbers_list_8(int, "%d", delim, "i", check_int);
0426 numbers_list_8(unsigned int, "%x", delim, "x", check_uint);
0427 numbers_list_8(unsigned int, "0x%x", delim, "x", check_uint);
0428 numbers_list_8(int, "0x%x", delim, "i", check_int);
0429 }
0430
0431 static void __init numbers_list_h(const char *delim)
0432 {
0433 numbers_list_8(unsigned short, "%hu", delim, "hu", check_ushort);
0434 numbers_list_8(short, "%hd", delim, "hd", check_short);
0435 numbers_list_8(short, "%hd", delim, "hi", check_short);
0436 numbers_list_8(unsigned short, "%hx", delim, "hx", check_ushort);
0437 numbers_list_8(unsigned short, "0x%hx", delim, "hx", check_ushort);
0438 numbers_list_8(short, "0x%hx", delim, "hi", check_short);
0439 }
0440
0441 static void __init numbers_list_hh(const char *delim)
0442 {
0443 numbers_list_8(unsigned char, "%hhu", delim, "hhu", check_uchar);
0444 numbers_list_8(signed char, "%hhd", delim, "hhd", check_char);
0445 numbers_list_8(signed char, "%hhd", delim, "hhi", check_char);
0446 numbers_list_8(unsigned char, "%hhx", delim, "hhx", check_uchar);
0447 numbers_list_8(unsigned char, "0x%hhx", delim, "hhx", check_uchar);
0448 numbers_list_8(signed char, "0x%hhx", delim, "hhi", check_char);
0449 }
0450
0451 static void __init numbers_list(const char *delim)
0452 {
0453 numbers_list_ll(delim);
0454 numbers_list_l(delim);
0455 numbers_list_d(delim);
0456 numbers_list_h(delim);
0457 numbers_list_hh(delim);
0458 }
0459
0460 static void __init numbers_list_field_width_ll(const char *delim)
0461 {
0462 numbers_list_fix_width(unsigned long long, "%llu", delim, 20, "llu", check_ull);
0463 numbers_list_fix_width(long long, "%lld", delim, 20, "lld", check_ll);
0464 numbers_list_fix_width(long long, "%lld", delim, 20, "lli", check_ll);
0465 numbers_list_fix_width(unsigned long long, "%llx", delim, 16, "llx", check_ull);
0466 numbers_list_fix_width(unsigned long long, "0x%llx", delim, 18, "llx", check_ull);
0467 numbers_list_fix_width(long long, "0x%llx", delim, 18, "lli", check_ll);
0468 }
0469
0470 static void __init numbers_list_field_width_l(const char *delim)
0471 {
0472 #if BITS_PER_LONG == 64
0473 numbers_list_fix_width(unsigned long, "%lu", delim, 20, "lu", check_ulong);
0474 numbers_list_fix_width(long, "%ld", delim, 20, "ld", check_long);
0475 numbers_list_fix_width(long, "%ld", delim, 20, "li", check_long);
0476 numbers_list_fix_width(unsigned long, "%lx", delim, 16, "lx", check_ulong);
0477 numbers_list_fix_width(unsigned long, "0x%lx", delim, 18, "lx", check_ulong);
0478 numbers_list_fix_width(long, "0x%lx", delim, 18, "li", check_long);
0479 #else
0480 numbers_list_fix_width(unsigned long, "%lu", delim, 10, "lu", check_ulong);
0481 numbers_list_fix_width(long, "%ld", delim, 11, "ld", check_long);
0482 numbers_list_fix_width(long, "%ld", delim, 11, "li", check_long);
0483 numbers_list_fix_width(unsigned long, "%lx", delim, 8, "lx", check_ulong);
0484 numbers_list_fix_width(unsigned long, "0x%lx", delim, 10, "lx", check_ulong);
0485 numbers_list_fix_width(long, "0x%lx", delim, 10, "li", check_long);
0486 #endif
0487 }
0488
0489 static void __init numbers_list_field_width_d(const char *delim)
0490 {
0491 numbers_list_fix_width(unsigned int, "%u", delim, 10, "u", check_uint);
0492 numbers_list_fix_width(int, "%d", delim, 11, "d", check_int);
0493 numbers_list_fix_width(int, "%d", delim, 11, "i", check_int);
0494 numbers_list_fix_width(unsigned int, "%x", delim, 8, "x", check_uint);
0495 numbers_list_fix_width(unsigned int, "0x%x", delim, 10, "x", check_uint);
0496 numbers_list_fix_width(int, "0x%x", delim, 10, "i", check_int);
0497 }
0498
0499 static void __init numbers_list_field_width_h(const char *delim)
0500 {
0501 numbers_list_fix_width(unsigned short, "%hu", delim, 5, "hu", check_ushort);
0502 numbers_list_fix_width(short, "%hd", delim, 6, "hd", check_short);
0503 numbers_list_fix_width(short, "%hd", delim, 6, "hi", check_short);
0504 numbers_list_fix_width(unsigned short, "%hx", delim, 4, "hx", check_ushort);
0505 numbers_list_fix_width(unsigned short, "0x%hx", delim, 6, "hx", check_ushort);
0506 numbers_list_fix_width(short, "0x%hx", delim, 6, "hi", check_short);
0507 }
0508
0509 static void __init numbers_list_field_width_hh(const char *delim)
0510 {
0511 numbers_list_fix_width(unsigned char, "%hhu", delim, 3, "hhu", check_uchar);
0512 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhd", check_char);
0513 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhi", check_char);
0514 numbers_list_fix_width(unsigned char, "%hhx", delim, 2, "hhx", check_uchar);
0515 numbers_list_fix_width(unsigned char, "0x%hhx", delim, 4, "hhx", check_uchar);
0516 numbers_list_fix_width(signed char, "0x%hhx", delim, 4, "hhi", check_char);
0517 }
0518
0519
0520
0521
0522
0523 static void __init numbers_list_field_width_typemax(const char *delim)
0524 {
0525 numbers_list_field_width_ll(delim);
0526 numbers_list_field_width_l(delim);
0527 numbers_list_field_width_d(delim);
0528 numbers_list_field_width_h(delim);
0529 numbers_list_field_width_hh(delim);
0530 }
0531
0532 static void __init numbers_list_field_width_val_ll(const char *delim)
0533 {
0534 numbers_list_val_width(unsigned long long, "%llu", delim, "llu", check_ull);
0535 numbers_list_val_width(long long, "%lld", delim, "lld", check_ll);
0536 numbers_list_val_width(long long, "%lld", delim, "lli", check_ll);
0537 numbers_list_val_width(unsigned long long, "%llx", delim, "llx", check_ull);
0538 numbers_list_val_width(unsigned long long, "0x%llx", delim, "llx", check_ull);
0539 numbers_list_val_width(long long, "0x%llx", delim, "lli", check_ll);
0540 }
0541
0542 static void __init numbers_list_field_width_val_l(const char *delim)
0543 {
0544 numbers_list_val_width(unsigned long, "%lu", delim, "lu", check_ulong);
0545 numbers_list_val_width(long, "%ld", delim, "ld", check_long);
0546 numbers_list_val_width(long, "%ld", delim, "li", check_long);
0547 numbers_list_val_width(unsigned long, "%lx", delim, "lx", check_ulong);
0548 numbers_list_val_width(unsigned long, "0x%lx", delim, "lx", check_ulong);
0549 numbers_list_val_width(long, "0x%lx", delim, "li", check_long);
0550 }
0551
0552 static void __init numbers_list_field_width_val_d(const char *delim)
0553 {
0554 numbers_list_val_width(unsigned int, "%u", delim, "u", check_uint);
0555 numbers_list_val_width(int, "%d", delim, "d", check_int);
0556 numbers_list_val_width(int, "%d", delim, "i", check_int);
0557 numbers_list_val_width(unsigned int, "%x", delim, "x", check_uint);
0558 numbers_list_val_width(unsigned int, "0x%x", delim, "x", check_uint);
0559 numbers_list_val_width(int, "0x%x", delim, "i", check_int);
0560 }
0561
0562 static void __init numbers_list_field_width_val_h(const char *delim)
0563 {
0564 numbers_list_val_width(unsigned short, "%hu", delim, "hu", check_ushort);
0565 numbers_list_val_width(short, "%hd", delim, "hd", check_short);
0566 numbers_list_val_width(short, "%hd", delim, "hi", check_short);
0567 numbers_list_val_width(unsigned short, "%hx", delim, "hx", check_ushort);
0568 numbers_list_val_width(unsigned short, "0x%hx", delim, "hx", check_ushort);
0569 numbers_list_val_width(short, "0x%hx", delim, "hi", check_short);
0570 }
0571
0572 static void __init numbers_list_field_width_val_hh(const char *delim)
0573 {
0574 numbers_list_val_width(unsigned char, "%hhu", delim, "hhu", check_uchar);
0575 numbers_list_val_width(signed char, "%hhd", delim, "hhd", check_char);
0576 numbers_list_val_width(signed char, "%hhd", delim, "hhi", check_char);
0577 numbers_list_val_width(unsigned char, "%hhx", delim, "hhx", check_uchar);
0578 numbers_list_val_width(unsigned char, "0x%hhx", delim, "hhx", check_uchar);
0579 numbers_list_val_width(signed char, "0x%hhx", delim, "hhi", check_char);
0580 }
0581
0582
0583
0584
0585
0586 static void __init numbers_list_field_width_val_width(const char *delim)
0587 {
0588 numbers_list_field_width_val_ll(delim);
0589 numbers_list_field_width_val_l(delim);
0590 numbers_list_field_width_val_d(delim);
0591 numbers_list_field_width_val_h(delim);
0592 numbers_list_field_width_val_hh(delim);
0593 }
0594
0595
0596
0597
0598
0599
0600
0601 static void __init numbers_slice(void)
0602 {
0603 numbers_list_field_width_val_width("");
0604 }
0605
0606 #define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn) \
0607 do { \
0608 const T expect[2] = { expect0, expect1 }; \
0609 T result[2] = {~expect[0], ~expect[1]}; \
0610 \
0611 _test(fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]); \
0612 } while (0)
0613
0614
0615
0616
0617
0618 static void __init numbers_prefix_overflow(void)
0619 {
0620
0621
0622
0623
0624 test_number_prefix(long long, "-1 1", "%1lld %lld", 0, 0, 0, check_ll);
0625 test_number_prefix(long, "-1 1", "%1ld %ld", 0, 0, 0, check_long);
0626 test_number_prefix(int, "-1 1", "%1d %d", 0, 0, 0, check_int);
0627 test_number_prefix(short, "-1 1", "%1hd %hd", 0, 0, 0, check_short);
0628 test_number_prefix(signed char, "-1 1", "%1hhd %hhd", 0, 0, 0, check_char);
0629
0630 test_number_prefix(long long, "-1 1", "%1lli %lli", 0, 0, 0, check_ll);
0631 test_number_prefix(long, "-1 1", "%1li %li", 0, 0, 0, check_long);
0632 test_number_prefix(int, "-1 1", "%1i %i", 0, 0, 0, check_int);
0633 test_number_prefix(short, "-1 1", "%1hi %hi", 0, 0, 0, check_short);
0634 test_number_prefix(signed char, "-1 1", "%1hhi %hhi", 0, 0, 0, check_char);
0635
0636
0637
0638
0639
0640
0641 test_number_prefix(unsigned long long, "0xA7", "%1llx%llx", 0, 0, 1, check_ull);
0642 test_number_prefix(unsigned long, "0xA7", "%1lx%lx", 0, 0, 1, check_ulong);
0643 test_number_prefix(unsigned int, "0xA7", "%1x%x", 0, 0, 1, check_uint);
0644 test_number_prefix(unsigned short, "0xA7", "%1hx%hx", 0, 0, 1, check_ushort);
0645 test_number_prefix(unsigned char, "0xA7", "%1hhx%hhx", 0, 0, 1, check_uchar);
0646 test_number_prefix(long long, "0xA7", "%1lli%llx", 0, 0, 1, check_ll);
0647 test_number_prefix(long, "0xA7", "%1li%lx", 0, 0, 1, check_long);
0648 test_number_prefix(int, "0xA7", "%1i%x", 0, 0, 1, check_int);
0649 test_number_prefix(short, "0xA7", "%1hi%hx", 0, 0, 1, check_short);
0650 test_number_prefix(char, "0xA7", "%1hhi%hhx", 0, 0, 1, check_char);
0651
0652
0653
0654
0655
0656
0657 test_number_prefix(unsigned long long, "0xA7", "%2llx%llx", 0, 0xa7, 2, check_ull);
0658 test_number_prefix(unsigned long, "0xA7", "%2lx%lx", 0, 0xa7, 2, check_ulong);
0659 test_number_prefix(unsigned int, "0xA7", "%2x%x", 0, 0xa7, 2, check_uint);
0660 test_number_prefix(unsigned short, "0xA7", "%2hx%hx", 0, 0xa7, 2, check_ushort);
0661 test_number_prefix(unsigned char, "0xA7", "%2hhx%hhx", 0, 0xa7, 2, check_uchar);
0662
0663
0664
0665
0666
0667
0668
0669 test_number_prefix(long long, "0x67", "%2lli%lli", 0, 67, 2, check_ll);
0670 test_number_prefix(long, "0x67", "%2li%li", 0, 67, 2, check_long);
0671 test_number_prefix(int, "0x67", "%2i%i", 0, 67, 2, check_int);
0672 test_number_prefix(short, "0x67", "%2hi%hi", 0, 67, 2, check_short);
0673 test_number_prefix(char, "0x67", "%2hhi%hhi", 0, 67, 2, check_char);
0674
0675 test_number_prefix(long long, "0xA7", "%2lli%lli", 0, 0, 1, check_ll);
0676 test_number_prefix(long, "0xA7", "%2li%li", 0, 0, 1, check_long);
0677 test_number_prefix(int, "0xA7", "%2i%i", 0, 0, 1, check_int);
0678 test_number_prefix(short, "0xA7", "%2hi%hi", 0, 0, 1, check_short);
0679 test_number_prefix(char, "0xA7", "%2hhi%hhi", 0, 0, 1, check_char);
0680 }
0681
0682 #define _test_simple_strtoxx(T, fn, gen_fmt, expect, base) \
0683 do { \
0684 T got; \
0685 char *endp; \
0686 int len; \
0687 bool fail = false; \
0688 \
0689 total_tests++; \
0690 len = snprintf(test_buffer, BUF_SIZE, gen_fmt, expect); \
0691 got = (fn)(test_buffer, &endp, base); \
0692 pr_debug(#fn "(\"%s\", %d) -> " gen_fmt "\n", test_buffer, base, got); \
0693 if (got != (expect)) { \
0694 fail = true; \
0695 pr_warn(#fn "(\"%s\", %d): got " gen_fmt " expected " gen_fmt "\n", \
0696 test_buffer, base, got, expect); \
0697 } else if (endp != test_buffer + len) { \
0698 fail = true; \
0699 pr_warn(#fn "(\"%s\", %d) startp=0x%px got endp=0x%px expected 0x%px\n", \
0700 test_buffer, base, test_buffer, \
0701 test_buffer + len, endp); \
0702 } \
0703 \
0704 if (fail) \
0705 failed_tests++; \
0706 } while (0)
0707
0708 #define test_simple_strtoxx(T, fn, gen_fmt, base) \
0709 do { \
0710 int i; \
0711 \
0712 for (i = 0; i < ARRAY_SIZE(numbers); i++) { \
0713 _test_simple_strtoxx(T, fn, gen_fmt, (T)numbers[i], base); \
0714 \
0715 if (is_signed_type(T)) \
0716 _test_simple_strtoxx(T, fn, gen_fmt, \
0717 -(T)numbers[i], base); \
0718 } \
0719 } while (0)
0720
0721 static void __init test_simple_strtoull(void)
0722 {
0723 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 10);
0724 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 0);
0725 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llx", 16);
0726 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 16);
0727 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 0);
0728 }
0729
0730 static void __init test_simple_strtoll(void)
0731 {
0732 test_simple_strtoxx(long long, simple_strtoll, "%lld", 10);
0733 test_simple_strtoxx(long long, simple_strtoll, "%lld", 0);
0734 test_simple_strtoxx(long long, simple_strtoll, "%llx", 16);
0735 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 16);
0736 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 0);
0737 }
0738
0739 static void __init test_simple_strtoul(void)
0740 {
0741 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 10);
0742 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 0);
0743 test_simple_strtoxx(unsigned long, simple_strtoul, "%lx", 16);
0744 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 16);
0745 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 0);
0746 }
0747
0748 static void __init test_simple_strtol(void)
0749 {
0750 test_simple_strtoxx(long, simple_strtol, "%ld", 10);
0751 test_simple_strtoxx(long, simple_strtol, "%ld", 0);
0752 test_simple_strtoxx(long, simple_strtol, "%lx", 16);
0753 test_simple_strtoxx(long, simple_strtol, "0x%lx", 16);
0754 test_simple_strtoxx(long, simple_strtol, "0x%lx", 0);
0755 }
0756
0757
0758 static const char * const number_delimiters[] __initconst = {
0759 " ", ":", ",", "-", "/",
0760 };
0761
0762 static void __init test_numbers(void)
0763 {
0764 int i;
0765
0766
0767 numbers_simple();
0768
0769
0770 for (i = 0; i < ARRAY_SIZE(number_delimiters); i++) {
0771 numbers_list(number_delimiters[i]);
0772
0773
0774 numbers_list_field_width_typemax(number_delimiters[i]);
0775
0776
0777 numbers_list_field_width_val_width(number_delimiters[i]);
0778 }
0779
0780
0781 numbers_slice();
0782
0783 numbers_prefix_overflow();
0784 }
0785
0786 static void __init selftest(void)
0787 {
0788 test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
0789 if (!test_buffer)
0790 return;
0791
0792 fmt_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
0793 if (!fmt_buffer) {
0794 kfree(test_buffer);
0795 return;
0796 }
0797
0798 prandom_seed_state(&rnd_state, 3141592653589793238ULL);
0799
0800 test_numbers();
0801
0802 test_simple_strtoull();
0803 test_simple_strtoll();
0804 test_simple_strtoul();
0805 test_simple_strtol();
0806
0807 kfree(fmt_buffer);
0808 kfree(test_buffer);
0809 }
0810
0811 KSTM_MODULE_LOADERS(test_scanf);
0812 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
0813 MODULE_LICENSE("GPL v2");