Fix: test_bitfield: buffer overrun accesses
[babeltrace.git] / tests / lib / test_bitfield.c
CommitLineData
6dc2ca62
MD
1/*
2 * test-bitfield.c
3 *
d79865b9 4 * BabelTrace - bitfield test program
6dc2ca62 5 *
0675eb8c 6 * Copyright 2010-2019 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6dc2ca62
MD
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
9cb421e5 10 * the Free Software Foundation; under version 2 of the License.
6dc2ca62
MD
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
3d9990ac 22#include <babeltrace/bitfield-internal.h>
47e0f2e2
MD
23#include <time.h>
24#include <stdlib.h>
6dc2ca62
MD
25#include <stdio.h>
26
1833a3d1 27#include <tap/tap.h>
9e8e57d0 28
6dc2ca62
MD
29unsigned int glob;
30
31/*
32 * This function is only declared to show the size of a bitfield write in
33 * objdump.
34 */
35void fct(void)
36{
47e0f2e2 37 bt_bitfield_write(&glob, unsigned int, 12, 15, 0x12345678);
6dc2ca62
MD
38}
39
40/* Test array size, in bytes */
41#define TEST_LEN 128
42#define NR_TESTS 10
0675eb8c
MD
43#define SIGNED_INT_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed int dest, varying read unit size"
44#define SIGNED_INT_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed int source, varying write unit size"
45#define SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, signed long long dest, varying read unit size"
46#define SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, signed long long source, varying write unit size"
47#define UNSIGNED_INT_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned int dest, varying read unit size"
48#define UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned int source, varying write unit size"
49#define UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, unsigned long long dest, varying read unit size"
50#define UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, unsigned long long source, varying write unit size"
9e8e57d0
JG
51#define DIAG_FMT_STR "Failed reading value written \"%s\"-wise, with start=%i" \
52 " and length=%i. Read %llX"
6dc2ca62 53
0675eb8c
MD
54static
55unsigned int fls_u64(uint64_t x)
6dc2ca62 56{
0675eb8c 57 unsigned int r = 64;
6dc2ca62 58
0675eb8c
MD
59 if (!x)
60 return 0;
6dc2ca62 61
0675eb8c
MD
62 if (!(x & 0xFFFFFFFF00000000ULL)) {
63 x <<= 32;
64 r -= 32;
65 }
66 if (!(x & 0xFFFF000000000000ULL)) {
67 x <<= 16;
68 r -= 16;
69 }
70 if (!(x & 0xFF00000000000000ULL)) {
71 x <<= 8;
72 r -= 8;
73 }
74 if (!(x & 0xF000000000000000ULL)) {
75 x <<= 4;
76 r -= 4;
77 }
78 if (!(x & 0xC000000000000000ULL)) {
79 x <<= 2;
80 r -= 2;
81 }
82 if (!(x & 0x8000000000000000ULL)) {
83 x <<= 1;
84 r -= 1;
85 }
86 return r;
6dc2ca62
MD
87}
88
0675eb8c
MD
89static
90unsigned int fls_u32(uint32_t x)
6dc2ca62 91{
0675eb8c 92 unsigned int r = 32;
6dc2ca62
MD
93
94 if (!x)
95 return 0;
96 if (!(x & 0xFFFF0000U)) {
97 x <<= 16;
98 r -= 16;
99 }
100 if (!(x & 0xFF000000U)) {
101 x <<= 8;
102 r -= 8;
103 }
104 if (!(x & 0xF0000000U)) {
105 x <<= 4;
106 r -= 4;
107 }
108 if (!(x & 0xC0000000U)) {
109 x <<= 2;
110 r -= 2;
111 }
112 if (!(x & 0x80000000U)) {
113 x <<= 1;
114 r -= 1;
115 }
116 return r;
117}
118
47e0f2e2
MD
119#define print_byte_array(c, len) \
120do { \
121 unsigned long i; \
122 \
123 for (i = 0; i < (len); i++) { \
124 printf("0x%X", (c)[i]); \
125 if (i != (len) - 1) \
126 printf(" "); \
127 } \
128 printf("\n"); \
129} while (0)
130
131#define init_byte_array(c, len, val) \
132do { \
133 unsigned long i; \
134 \
135 for (i = 0; i < (len); i++) \
136 (c)[i] = (val); \
137} while (0)
6dc2ca62 138
9e8e57d0 139#define check_result(ref, val, buffer, typename, start, len, \
0675eb8c 140 desc_fmt_str) \
9e8e57d0
JG
141({ \
142 if ((val) != (ref)) { \
143 fail(desc_fmt_str, ref); \
144 diag(DIAG_FMT_STR, #typename, start, len, val); \
145 printf("# "); \
146 print_byte_array(buffer, TEST_LEN); \
147 } \
148 (val) != (ref); \
149})
150
0675eb8c 151void run_test_unsigned_write(unsigned int src_ui, unsigned long long src_ull)
6dc2ca62 152{
0675eb8c 153 unsigned int nrbits_ui, nrbits_ull;
6dc2ca62
MD
154 union {
155 unsigned char c[TEST_LEN];
156 unsigned short s[TEST_LEN/sizeof(unsigned short)];
157 unsigned int i[TEST_LEN/sizeof(unsigned int)];
158 unsigned long l[TEST_LEN/sizeof(unsigned long)];
159 unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
160 } target;
380d60b1 161 unsigned long long readval;
6dc2ca62 162 unsigned int s, l;
6dc2ca62 163
0675eb8c 164 nrbits_ui = fls_u32(src_ui);
6dc2ca62 165
0675eb8c 166 /* Write from unsigned integer src input. */
6dc2ca62 167 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
0675eb8c 168 for (l = nrbits_ui; l < (CHAR_BIT * TEST_LEN) - s; l++) {
6dc2ca62 169 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 170 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
47e0f2e2 171 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c
MD
172 if (check_result(src_ui, readval, target.c, unsigned char,
173 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 174 return;
6dc2ca62
MD
175 }
176
177 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 178 bt_bitfield_write(target.s, unsigned short, s, l, src_ui);
47e0f2e2 179 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c
MD
180 if (check_result(src_ui, readval, target.c, unsigned short,
181 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 182 return;
6dc2ca62
MD
183 }
184
185 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 186 bt_bitfield_write(target.i, unsigned int, s, l, src_ui);
47e0f2e2 187 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c
MD
188 if (check_result(src_ui, readval, target.c, unsigned int,
189 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 190 return;
6dc2ca62
MD
191 }
192
193 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 194 bt_bitfield_write(target.l, unsigned long, s, l, src_ui);
47e0f2e2 195 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c
MD
196 if (check_result(src_ui, readval, target.c, unsigned long,
197 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 198 return;
6dc2ca62
MD
199 }
200
201 init_byte_array(target.c, TEST_LEN, 0xFF);
0675eb8c 202 bt_bitfield_write(target.ll, unsigned long long, s, l, src_ui);
47e0f2e2 203 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
0675eb8c
MD
204 if (check_result(src_ui, readval, target.c, unsigned long long,
205 s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 206 return;
6dc2ca62
MD
207 }
208 }
209 }
0675eb8c
MD
210 pass(UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR, src_ui);
211
212 nrbits_ull = fls_u64(src_ull);
213
214 /* Write from unsigned long long src input. */
215 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
216 for (l = nrbits_ull; l < (CHAR_BIT * TEST_LEN) - s; l++) {
217 init_byte_array(target.c, TEST_LEN, 0xFF);
218 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
219 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
220 if (check_result(src_ull, readval, target.c, unsigned char,
221 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
222 return;
223 }
9e8e57d0 224
0675eb8c
MD
225 init_byte_array(target.c, TEST_LEN, 0xFF);
226 bt_bitfield_write(target.s, unsigned short, s, l, src_ull);
227 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
228 if (check_result(src_ull, readval, target.c, unsigned short,
229 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
230 return;
231 }
232
233 init_byte_array(target.c, TEST_LEN, 0xFF);
234 bt_bitfield_write(target.i, unsigned int, s, l, src_ull);
235 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
236 if (check_result(src_ull, readval, target.c, unsigned int,
237 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
238 return;
239 }
240
241 init_byte_array(target.c, TEST_LEN, 0xFF);
242 bt_bitfield_write(target.l, unsigned long, s, l, src_ull);
243 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
244 if (check_result(src_ull, readval, target.c, unsigned long,
245 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
246 return;
247 }
248
249 init_byte_array(target.c, TEST_LEN, 0xFF);
250 bt_bitfield_write(target.ll, unsigned long long, s, l, src_ull);
251 bt_bitfield_read(target.c, unsigned char, s, l, &readval);
252 if (check_result(src_ull, readval, target.c, unsigned long long,
253 s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
254 return;
255 }
256 }
257 }
258 pass(UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR, src_ull);
6dc2ca62
MD
259}
260
0675eb8c 261void run_test_unsigned_read(unsigned int src_ui, unsigned long long src_ull)
6dc2ca62 262{
0675eb8c
MD
263 unsigned int nrbits_ui, nrbits_ull, readval_ui;
264 union {
265 unsigned char c[TEST_LEN];
266 unsigned short s[TEST_LEN/sizeof(unsigned short)];
267 unsigned int i[TEST_LEN/sizeof(unsigned int)];
268 unsigned long l[TEST_LEN/sizeof(unsigned long)];
269 unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
270 } target;
271 unsigned long long readval_ull;
272 unsigned int s, l;
273
274 nrbits_ui = fls_u32(src_ui);
275
276 /* Read to unsigned integer readval output. */
277 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
278 for (l = nrbits_ui; l < (CHAR_BIT * TEST_LEN) - s; l++) {
279 init_byte_array(target.c, TEST_LEN, 0xFF);
280 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
281 bt_bitfield_read(target.c, unsigned char, s, l, &readval_ui);
282 if (check_result(src_ui, readval_ui, target.c, unsigned char,
283 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR)) {
284 return;
285 }
286
287 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
288 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
289 bt_bitfield_read(target.s, unsigned short, s, l, &readval_ui);
0675eb8c
MD
290 if (check_result(src_ui, readval_ui, target.c, unsigned short,
291 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR)) {
292 return;
293 }
294
295 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
296 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
297 bt_bitfield_read(target.i, unsigned int, s, l, &readval_ui);
0675eb8c
MD
298 if (check_result(src_ui, readval_ui, target.c, unsigned int,
299 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR)) {
300 return;
301 }
302
303 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
304 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
305 bt_bitfield_read(target.l, unsigned long, s, l, &readval_ui);
0675eb8c
MD
306 if (check_result(src_ui, readval_ui, target.c, unsigned long,
307 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR)) {
308 return;
309 }
310
311 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
312 bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
313 bt_bitfield_read(target.ll, unsigned long long, s, l, &readval_ui);
0675eb8c
MD
314 if (check_result(src_ui, readval_ui, target.c, unsigned long long,
315 s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR)) {
316 return;
317 }
318 }
319 }
320 pass(UNSIGNED_INT_READ_TEST_DESC_FMT_STR, src_ui);
321
322 nrbits_ull = fls_u64(src_ull);
323
324 /* Read to unsigned long long readval output. */
325 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
326 for (l = nrbits_ull; l < (CHAR_BIT * TEST_LEN) - s; l++) {
327 init_byte_array(target.c, TEST_LEN, 0xFF);
328 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
329 bt_bitfield_read(target.c, unsigned char, s, l, &readval_ull);
330 if (check_result(src_ull, readval_ull, target.c, unsigned char,
331 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
332 return;
333 }
334
335 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
336 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
337 bt_bitfield_read(target.s, unsigned short, s, l, &readval_ull);
0675eb8c
MD
338 if (check_result(src_ull, readval_ull, target.c, unsigned short,
339 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
340 return;
341 }
342
343 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
344 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
345 bt_bitfield_read(target.i, unsigned int, s, l, &readval_ull);
0675eb8c
MD
346 if (check_result(src_ull, readval_ull, target.c, unsigned int,
347 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
348 return;
349 }
350
351 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
352 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
353 bt_bitfield_read(target.l, unsigned long, s, l, &readval_ull);
0675eb8c
MD
354 if (check_result(src_ull, readval_ull, target.c, unsigned long,
355 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
356 return;
357 }
358
359 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
360 bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
361 bt_bitfield_read(target.ll, unsigned long long, s, l, &readval_ull);
0675eb8c
MD
362 if (check_result(src_ull, readval_ull, target.c, unsigned long long,
363 s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
364 return;
365 }
366 }
367 }
368 pass(UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR, src_ull);
369}
370
371void run_test_unsigned(unsigned int src_ui, unsigned long long src_ull)
372{
373 run_test_unsigned_write(src_ui, src_ull);
374 run_test_unsigned_read(src_ui, src_ull);
375}
376
377void run_test_signed_write(int src_i, long long src_ll)
378{
379 int nrbits_i, nrbits_ll;
6dc2ca62 380 union {
47e0f2e2 381 signed char c[TEST_LEN];
6dc2ca62
MD
382 short s[TEST_LEN/sizeof(short)];
383 int i[TEST_LEN/sizeof(int)];
384 long l[TEST_LEN/sizeof(long)];
385 long long ll[TEST_LEN/sizeof(long long)];
386 } target;
380d60b1 387 long long readval;
6dc2ca62 388 unsigned int s, l;
6dc2ca62 389
0675eb8c
MD
390 if (src_i & 0x80000000U)
391 nrbits_i = fls_u32(~src_i) + 1; /* Find least significant bit conveying sign */
6dc2ca62 392 else
0675eb8c 393 nrbits_i = fls_u32(src_i) + 1; /* Keep sign at 0 */
6dc2ca62 394
0675eb8c 395 /* Write from signed integer src input. */
9e8e57d0 396 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
0675eb8c 397 for (l = nrbits_i; l < (CHAR_BIT * TEST_LEN) - s; l++) {
6dc2ca62 398 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 399 bt_bitfield_write(target.c, signed char, s, l, src_i);
47e0f2e2 400 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c
MD
401 if (check_result(src_i, readval, target.c, signed char,
402 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 403 return;
6dc2ca62
MD
404 }
405
406 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 407 bt_bitfield_write(target.s, short, s, l, src_i);
47e0f2e2 408 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c
MD
409 if (check_result(src_i, readval, target.c, short,
410 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 411 return;
6dc2ca62
MD
412 }
413
414 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 415 bt_bitfield_write(target.i, int, s, l, src_i);
47e0f2e2 416 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c
MD
417 if (check_result(src_i, readval, target.c, int,
418 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 419 return;
6dc2ca62
MD
420 }
421
422 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 423 bt_bitfield_write(target.l, long, s, l, src_i);
47e0f2e2 424 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c
MD
425 if (check_result(src_i, readval, target.c, long,
426 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 427 return;
6dc2ca62
MD
428 }
429
430 init_byte_array(target.c, TEST_LEN, 0x0);
0675eb8c 431 bt_bitfield_write(target.ll, long long, s, l, src_i);
47e0f2e2 432 bt_bitfield_read(target.c, signed char, s, l, &readval);
0675eb8c
MD
433 if (check_result(src_i, readval, target.c, long long,
434 s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR)) {
9e8e57d0 435 return;
6dc2ca62
MD
436 }
437 }
438 }
0675eb8c
MD
439 pass(SIGNED_INT_WRITE_TEST_DESC_FMT_STR, src_i);
440
441 if (src_ll & 0x8000000000000000ULL)
442 nrbits_ll = fls_u64(~src_ll) + 1; /* Find least significant bit conveying sign */
443 else
444 nrbits_ll = fls_u64(src_ll) + 1; /* Keep sign at 0 */
445
446 /* Write from signed long long src input. */
447 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
448 for (l = nrbits_ll; l < (CHAR_BIT * TEST_LEN) - s; l++) {
449 init_byte_array(target.c, TEST_LEN, 0x0);
450 bt_bitfield_write(target.c, signed char, s, l, src_ll);
451 bt_bitfield_read(target.c, signed char, s, l, &readval);
452 if (check_result(src_ll, readval, target.c, signed char,
453 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
454 return;
455 }
456
457 init_byte_array(target.c, TEST_LEN, 0x0);
458 bt_bitfield_write(target.s, short, s, l, src_ll);
459 bt_bitfield_read(target.c, signed char, s, l, &readval);
460 if (check_result(src_ll, readval, target.c, short,
461 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
462 return;
463 }
464
465 init_byte_array(target.c, TEST_LEN, 0x0);
466 bt_bitfield_write(target.i, int, s, l, src_ll);
467 bt_bitfield_read(target.c, signed char, s, l, &readval);
468 if (check_result(src_ll, readval, target.c, int,
469 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
470 return;
471 }
9e8e57d0 472
0675eb8c
MD
473 init_byte_array(target.c, TEST_LEN, 0x0);
474 bt_bitfield_write(target.l, long, s, l, src_ll);
475 bt_bitfield_read(target.c, signed char, s, l, &readval);
476 if (check_result(src_ll, readval, target.c, long,
477 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
478 return;
479 }
480
481 init_byte_array(target.c, TEST_LEN, 0x0);
482 bt_bitfield_write(target.ll, long long, s, l, src_ll);
483 bt_bitfield_read(target.c, signed char, s, l, &readval);
484 if (check_result(src_ll, readval, target.c, long long,
485 s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR)) {
486 return;
487 }
488 }
489 }
490 pass(SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR, src_ll);
6dc2ca62
MD
491}
492
0675eb8c 493void run_test_signed_read(int src_i, long long src_ll)
6dc2ca62 494{
0675eb8c
MD
495 int nrbits_i, nrbits_ll, readval_i;
496 union {
497 unsigned char c[TEST_LEN];
498 unsigned short s[TEST_LEN/sizeof(unsigned short)];
499 unsigned int i[TEST_LEN/sizeof(unsigned int)];
500 unsigned long l[TEST_LEN/sizeof(unsigned long)];
501 unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
502 } target;
503 long long readval_ll;
504 unsigned int s, l;
6dc2ca62 505
0675eb8c
MD
506 if (src_i & 0x80000000U)
507 nrbits_i = fls_u32(~src_i) + 1; /* Find least significant bit conveying sign */
508 else
509 nrbits_i = fls_u32(src_i) + 1; /* Keep sign at 0 */
6dc2ca62 510
0675eb8c
MD
511 /* Read to signed integer readval output. */
512 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
513 for (l = nrbits_i; l < (CHAR_BIT * TEST_LEN) - s; l++) {
514 init_byte_array(target.c, TEST_LEN, 0xFF);
515 bt_bitfield_write(target.c, signed char, s, l, src_i);
516 bt_bitfield_read(target.c, signed char, s, l, &readval_i);
517 if (check_result(src_i, readval_i, target.c, signed char,
518 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR)) {
519 return;
520 }
9e8e57d0 521
0675eb8c 522 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
523 bt_bitfield_write(target.c, signed char, s, l, src_i);
524 bt_bitfield_read(target.s, short, s, l, &readval_i);
0675eb8c
MD
525 if (check_result(src_i, readval_i, target.c, short,
526 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR)) {
527 return;
528 }
9e8e57d0 529
0675eb8c 530 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
531 bt_bitfield_write(target.c, signed char, s, l, src_i);
532 bt_bitfield_read(target.i, int, s, l, &readval_i);
0675eb8c
MD
533 if (check_result(src_i, readval_i, target.c, int,
534 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR)) {
535 return;
536 }
9e8e57d0 537
0675eb8c 538 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
539 bt_bitfield_write(target.c, signed char, s, l, src_i);
540 bt_bitfield_read(target.l, long, s, l, &readval_i);
0675eb8c
MD
541 if (check_result(src_i, readval_i, target.c, long,
542 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR)) {
543 return;
544 }
9e8e57d0 545
0675eb8c 546 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
547 bt_bitfield_write(target.c, signed char, s, l, src_i);
548 bt_bitfield_read(target.ll, long long, s, l, &readval_i);
0675eb8c
MD
549 if (check_result(src_i, readval_i, target.c, long long,
550 s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR)) {
551 return;
552 }
553 }
554 }
555 pass(SIGNED_INT_READ_TEST_DESC_FMT_STR, src_i);
556
557 if (src_ll & 0x8000000000000000ULL)
558 nrbits_ll = fls_u64(~src_ll) + 1; /* Find least significant bit conveying sign */
559 else
560 nrbits_ll = fls_u64(src_ll) + 1; /* Keep sign at 0 */
561
562 /* Read to signed long long readval output. */
563 for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
564 for (l = nrbits_ll; l < (CHAR_BIT * TEST_LEN) - s; l++) {
565 init_byte_array(target.c, TEST_LEN, 0xFF);
566 bt_bitfield_write(target.c, signed char, s, l, src_ll);
567 bt_bitfield_read(target.c, signed char, s, l, &readval_ll);
568 if (check_result(src_ll, readval_ll, target.c, signed char,
569 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
570 return;
571 }
572
573 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
574 bt_bitfield_write(target.c, signed char, s, l, src_ll);
575 bt_bitfield_read(target.s, short, s, l, &readval_ll);
0675eb8c
MD
576 if (check_result(src_ll, readval_ll, target.c, short,
577 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
578 return;
579 }
580
581 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
582 bt_bitfield_write(target.c, signed char, s, l, src_ll);
583 bt_bitfield_read(target.i, int, s, l, &readval_ll);
0675eb8c
MD
584 if (check_result(src_ll, readval_ll, target.c, int,
585 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
586 return;
587 }
588
589 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
590 bt_bitfield_write(target.c, signed char, s, l, src_ll);
591 bt_bitfield_read(target.l, long, s, l, &readval_ll);
0675eb8c
MD
592 if (check_result(src_ll, readval_ll, target.c, long,
593 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
594 return;
595 }
596
597 init_byte_array(target.c, TEST_LEN, 0xFF);
056d0f40
MD
598 bt_bitfield_write(target.c, signed char, s, l, src_ll);
599 bt_bitfield_read(target.ll, long long, s, l, &readval_ll);
0675eb8c
MD
600 if (check_result(src_ll, readval_ll, target.c, long long,
601 s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR)) {
602 return;
603 }
604 }
605 }
606 pass(SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR, src_ll);
607}
608
609void run_test_signed(int src_i, long long src_ll)
610{
611 run_test_signed_write(src_i, src_ll);
612 run_test_signed_read(src_i, src_ll);
613}
614
615void run_test(void)
616{
617 int i;
618
619 plan_tests(NR_TESTS * 8 + 24);
620
621 srand(time(NULL));
622
623 run_test_unsigned(0, 0);
624 run_test_signed(0, 0);
625 run_test_unsigned(1, 1);
626 run_test_unsigned(~0U, ~0ULL);
627 run_test_signed(-1U, -1ULL);
628 run_test_signed(0x80000000U, 0x8000000000000000ULL);
6dc2ca62
MD
629
630 for (i = 0; i < NR_TESTS; i++) {
0675eb8c
MD
631 unsigned int src_ui = rand();
632 unsigned long long src_ull = ((unsigned long long) (unsigned int) rand() << 32) |
633 (unsigned long long) (unsigned int) rand();
634
635 run_test_unsigned(src_ui, src_ull);
636 run_test_signed((int) src_ui, (long long) src_ull);
6dc2ca62 637 }
6dc2ca62
MD
638}
639
9e8e57d0
JG
640static
641int print_encodings(unsigned long src, unsigned int shift, unsigned int len)
6dc2ca62 642{
6dc2ca62
MD
643 union {
644 unsigned char c[8];
645 unsigned short s[4];
646 unsigned int i[2];
647 unsigned long l[2];
648 unsigned long long ll[1];
649 } target;
380d60b1 650 unsigned long long readval;
6dc2ca62 651
9e8e57d0 652 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 653 bt_bitfield_write(target.c, unsigned char, shift, len, src);
6dc2ca62
MD
654 printf("bytewise\n");
655 print_byte_array(target.c, 8);
656
9e8e57d0 657 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 658 bt_bitfield_write(target.s, unsigned short, shift, len, src);
6dc2ca62
MD
659 printf("shortwise\n");
660 print_byte_array(target.c, 8);
661
9e8e57d0 662 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 663 bt_bitfield_write(target.i, unsigned int, shift, len, src);
6dc2ca62
MD
664 printf("intwise\n");
665 print_byte_array(target.c, 8);
666
9e8e57d0 667 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 668 bt_bitfield_write(target.l, unsigned long, shift, len, src);
6dc2ca62
MD
669 printf("longwise\n");
670 print_byte_array(target.c, 8);
671
9e8e57d0 672 init_byte_array(target.c, 8, 0xFF);
47e0f2e2 673 bt_bitfield_write(target.ll, unsigned long long, shift, len, src);
6dc2ca62
MD
674 printf("lluwise\n");
675 print_byte_array(target.c, 8);
676
47e0f2e2 677 bt_bitfield_read(target.c, unsigned char, shift, len, &readval);
6dc2ca62 678 printf("read: %llX\n", readval);
9e8e57d0 679 print_byte_array(target.c, 8);
6dc2ca62 680
9e8e57d0
JG
681 return 0;
682}
683
684int main(int argc, char **argv)
685{
686 if (argc > 1) {
687 /* Print encodings */
688 unsigned long src;
689 unsigned int shift, len;
690
691 src = atoi(argv[1]);
692 if (argc > 2)
693 shift = atoi(argv[2]);
694 else
695 shift = 12;
696 if (argc > 3)
697 len = atoi(argv[3]);
698 else
699 len = 40;
700 return print_encodings(src, shift, len);
701 }
6dc2ca62 702
9e8e57d0
JG
703 /* Run tap-formated tests */
704 run_test();
705 return exit_status();
6dc2ca62 706}
This page took 0.089796 seconds and 4 git commands to generate.