]> git.ipfire.org Git - thirdparty/linux.git/blame - lib/test_hexdump.c
mm: remove both instances of __vmalloc_node_flags
[thirdparty/linux.git] / lib / test_hexdump.c
CommitLineData
64d1d77a
AS
1/*
2 * Test cases for lib/hexdump.c module.
3 */
4#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5
6#include <linux/init.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/random.h>
10#include <linux/string.h>
11
12static const unsigned char data_b[] = {
13 '\xbe', '\x32', '\xdb', '\x7b', '\x0a', '\x18', '\x93', '\xb2', /* 00 - 07 */
14 '\x70', '\xba', '\xc4', '\x24', '\x7d', '\x83', '\x34', '\x9b', /* 08 - 0f */
15 '\xa6', '\x9c', '\x31', '\xad', '\x9c', '\x0f', '\xac', '\xe9', /* 10 - 17 */
16 '\x4c', '\xd1', '\x19', '\x99', '\x43', '\xb1', '\xaf', '\x0c', /* 18 - 1f */
17};
18
19static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C...";
20
de9df399 21static const char * const test_data_1[] __initconst = {
64d1d77a
AS
22 "be", "32", "db", "7b", "0a", "18", "93", "b2",
23 "70", "ba", "c4", "24", "7d", "83", "34", "9b",
24 "a6", "9c", "31", "ad", "9c", "0f", "ac", "e9",
25 "4c", "d1", "19", "99", "43", "b1", "af", "0c",
26};
27
79e23d57 28static const char * const test_data_2_le[] __initconst = {
64d1d77a
AS
29 "32be", "7bdb", "180a", "b293",
30 "ba70", "24c4", "837d", "9b34",
31 "9ca6", "ad31", "0f9c", "e9ac",
32 "d14c", "9919", "b143", "0caf",
33};
34
de9df399
CL
35static const char * const test_data_2_be[] __initconst = {
36 "be32", "db7b", "0a18", "93b2",
37 "70ba", "c424", "7d83", "349b",
38 "a69c", "31ad", "9c0f", "ace9",
39 "4cd1", "1999", "43b1", "af0c",
40};
41
79e23d57 42static const char * const test_data_4_le[] __initconst = {
64d1d77a
AS
43 "7bdb32be", "b293180a", "24c4ba70", "9b34837d",
44 "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143",
45};
46
de9df399
CL
47static const char * const test_data_4_be[] __initconst = {
48 "be32db7b", "0a1893b2", "70bac424", "7d83349b",
49 "a69c31ad", "9c0face9", "4cd11999", "43b1af0c",
50};
51
79e23d57 52static const char * const test_data_8_le[] __initconst = {
64d1d77a
AS
53 "b293180a7bdb32be", "9b34837d24c4ba70",
54 "e9ac0f9cad319ca6", "0cafb1439919d14c",
55};
56
de9df399
CL
57static const char * const test_data_8_be[] __initconst = {
58 "be32db7b0a1893b2", "70bac4247d83349b",
59 "a69c31ad9c0face9", "4cd1199943b1af0c",
60};
61
3db4a987
AS
62#define FILL_CHAR '#'
63
7aaf4c3e
AS
64static unsigned total_tests __initdata;
65static unsigned failed_tests __initdata;
66
87977ca6
AS
67static void __init test_hexdump_prepare_test(size_t len, int rowsize,
68 int groupsize, char *test,
69 size_t testlen, bool ascii)
64d1d77a 70{
64d1d77a 71 char *p;
17974c05 72 const char * const *result;
64d1d77a
AS
73 size_t l = len;
74 int gs = groupsize, rs = rowsize;
75 unsigned int i;
de9df399 76 const bool is_be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
64d1d77a 77
64d1d77a
AS
78 if (rs != 16 && rs != 32)
79 rs = 16;
80
81 if (l > rs)
82 l = rs;
83
84 if (!is_power_of_2(gs) || gs > 8 || (len % gs != 0))
85 gs = 1;
86
87 if (gs == 8)
de9df399 88 result = is_be ? test_data_8_be : test_data_8_le;
64d1d77a 89 else if (gs == 4)
de9df399 90 result = is_be ? test_data_4_be : test_data_4_le;
64d1d77a 91 else if (gs == 2)
de9df399 92 result = is_be ? test_data_2_be : test_data_2_le;
64d1d77a 93 else
de9df399 94 result = test_data_1;
64d1d77a 95
64d1d77a
AS
96 /* hex dump */
97 p = test;
98 for (i = 0; i < l / gs; i++) {
99 const char *q = *result++;
100 size_t amount = strlen(q);
101
b1286ed7 102 memcpy(p, q, amount);
3db4a987
AS
103 p += amount;
104
105 *p++ = ' ';
64d1d77a
AS
106 }
107 if (i)
108 p--;
109
110 /* ASCII part */
111 if (ascii) {
3db4a987
AS
112 do {
113 *p++ = ' ';
114 } while (p < test + rs * 2 + rs / gs + 1);
115
64d1d77a
AS
116 strncpy(p, data_a, l);
117 p += l;
118 }
119
120 *p = '\0';
87977ca6
AS
121}
122
123#define TEST_HEXDUMP_BUF_SIZE (32 * 3 + 2 + 32 + 1)
124
125static void __init test_hexdump(size_t len, int rowsize, int groupsize,
126 bool ascii)
127{
128 char test[TEST_HEXDUMP_BUF_SIZE];
129 char real[TEST_HEXDUMP_BUF_SIZE];
130
7aaf4c3e
AS
131 total_tests++;
132
7047d813 133 memset(real, FILL_CHAR, sizeof(real));
87977ca6
AS
134 hex_dump_to_buffer(data_b, len, rowsize, groupsize, real, sizeof(real),
135 ascii);
136
7047d813 137 memset(test, FILL_CHAR, sizeof(test));
87977ca6
AS
138 test_hexdump_prepare_test(len, rowsize, groupsize, test, sizeof(test),
139 ascii);
64d1d77a 140
7047d813 141 if (memcmp(test, real, TEST_HEXDUMP_BUF_SIZE)) {
64d1d77a
AS
142 pr_err("Len: %zu row: %d group: %d\n", len, rowsize, groupsize);
143 pr_err("Result: '%s'\n", real);
144 pr_err("Expect: '%s'\n", test);
7aaf4c3e 145 failed_tests++;
64d1d77a
AS
146 }
147}
148
149static void __init test_hexdump_set(int rowsize, bool ascii)
150{
151 size_t d = min_t(size_t, sizeof(data_b), rowsize);
152 size_t len = get_random_int() % d + 1;
153
154 test_hexdump(len, rowsize, 4, ascii);
155 test_hexdump(len, rowsize, 2, ascii);
156 test_hexdump(len, rowsize, 8, ascii);
157 test_hexdump(len, rowsize, 1, ascii);
158}
159
1dacd9dd
AS
160static void __init test_hexdump_overflow(size_t buflen, size_t len,
161 int rowsize, int groupsize,
162 bool ascii)
114fc1af 163{
cc77a719 164 char test[TEST_HEXDUMP_BUF_SIZE];
a3d601fc 165 char buf[TEST_HEXDUMP_BUF_SIZE];
cc77a719
AS
166 int rs = rowsize, gs = groupsize;
167 int ae, he, e, f, r;
114fc1af 168 bool a;
114fc1af 169
7aaf4c3e
AS
170 total_tests++;
171
3db4a987 172 memset(buf, FILL_CHAR, sizeof(buf));
114fc1af 173
ad27a755
AS
174 r = hex_dump_to_buffer(data_b, len, rs, gs, buf, buflen, ascii);
175
176 /*
177 * Caller must provide the data length multiple of groupsize. The
178 * calculations below are made with that assumption in mind.
179 */
180 ae = rs * 2 /* hex */ + rs / gs /* spaces */ + 1 /* space */ + len /* ascii */;
181 he = (gs * 2 /* hex */ + 1 /* space */) * len / gs - 1 /* no trailing space */;
114fc1af
AS
182
183 if (ascii)
ad27a755 184 e = ae;
114fc1af 185 else
ad27a755 186 e = he;
cc77a719
AS
187
188 f = min_t(int, e + 1, buflen);
189 if (buflen) {
190 test_hexdump_prepare_test(len, rs, gs, test, sizeof(test), ascii);
191 test[f - 1] = '\0';
114fc1af 192 }
cc77a719
AS
193 memset(test + f, FILL_CHAR, sizeof(test) - f);
194
195 a = r == e && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
196
197 buf[sizeof(buf) - 1] = '\0';
114fc1af
AS
198
199 if (!a) {
cc77a719
AS
200 pr_err("Len: %zu buflen: %zu strlen: %zu\n",
201 len, buflen, strnlen(buf, sizeof(buf)));
202 pr_err("Result: %d '%s'\n", r, buf);
203 pr_err("Expect: %d '%s'\n", e, test);
7aaf4c3e 204 failed_tests++;
114fc1af
AS
205 }
206}
207
1dacd9dd
AS
208static void __init test_hexdump_overflow_set(size_t buflen, bool ascii)
209{
210 unsigned int i = 0;
211 int rs = (get_random_int() % 2 + 1) * 16;
212
213 do {
214 int gs = 1 << i;
215 size_t len = get_random_int() % rs + gs;
216
217 test_hexdump_overflow(buflen, rounddown(len, gs), rs, gs, ascii);
218 } while (i++ < 3);
219}
220
64d1d77a
AS
221static int __init test_hexdump_init(void)
222{
223 unsigned int i;
224 int rowsize;
225
64d1d77a
AS
226 rowsize = (get_random_int() % 2 + 1) * 16;
227 for (i = 0; i < 16; i++)
228 test_hexdump_set(rowsize, false);
229
230 rowsize = (get_random_int() % 2 + 1) * 16;
231 for (i = 0; i < 16; i++)
232 test_hexdump_set(rowsize, true);
233
a3d601fc 234 for (i = 0; i <= TEST_HEXDUMP_BUF_SIZE; i++)
1dacd9dd 235 test_hexdump_overflow_set(i, false);
114fc1af 236
a3d601fc 237 for (i = 0; i <= TEST_HEXDUMP_BUF_SIZE; i++)
1dacd9dd 238 test_hexdump_overflow_set(i, true);
114fc1af 239
7aaf4c3e
AS
240 if (failed_tests == 0)
241 pr_info("all %u tests passed\n", total_tests);
242 else
243 pr_err("failed %u out of %u tests\n", failed_tests, total_tests);
244
245 return failed_tests ? -EINVAL : 0;
64d1d77a
AS
246}
247module_init(test_hexdump_init);
7aaf4c3e
AS
248
249static void __exit test_hexdump_exit(void)
250{
251 /* do nothing */
252}
253module_exit(test_hexdump_exit);
254
255MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
64d1d77a 256MODULE_LICENSE("Dual BSD/GPL");