1 /* Test program for read_[type]_unaligned.
2 Copyright (C) 2020, Red Hat Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #include <assert.h>
19 #include <endian.h>
20 #include <inttypes.h>
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <stdio.h>
24
25 #include "../libdw/libdwP.h"
26 #include "../libdw/memory-access.h"
27
28 union u8
29 {
30 uint8_t v;
31 unsigned char c[1];
32 };
33
34 union s8
35 {
36 int8_t v;
37 unsigned char c[1];
38 };
39
40 union u16
41 {
42 uint16_t v;
43 unsigned char c[2];
44 };
45
46 union s16
47 {
48 int16_t v;
49 unsigned char c[2];
50 };
51
52 union u24
53 {
54 uint32_t v:24;
55 unsigned char c[3];
56 } __attribute__((packed));
57
58 union u32
59 {
60 uint32_t v;
61 unsigned char c[4];
62 };
63
64 union s32
65 {
66 int32_t v;
67 unsigned char c[4];
68 };
69
70 union u64
71 {
72 uint64_t v;
73 unsigned char c[8];
74 };
75
76 union s64
77 {
78 uint64_t v;
79 unsigned char c[8];
80 };
81
82 uint8_t u8_nums[] =
83 {
84 0,
85 1,
86 UINT8_MAX / 2 - 1,
87 UINT8_MAX / 2,
88 UINT8_MAX / 2 + 1,
89 UINT8_MAX,
90 UINT8_MAX -1
91 };
92
93 int8_t s8_nums[] =
94 {
95 INT8_MIN,
96 INT8_MIN + 1,
97 -1,
98 0,
99 1,
100 INT8_MAX,
101 INT8_MAX - 1
102 };
103
104 uint16_t u16_nums[] =
105 {
106 0,
107 1,
108 UINT16_MAX / 2 - 1,
109 UINT16_MAX / 2,
110 UINT16_MAX / 2 + 1,
111 UINT16_MAX,
112 UINT16_MAX -1
113 };
114
115 int16_t s16_nums[] =
116 {
117 INT16_MIN,
118 INT16_MIN + 1,
119 -1,
120 0,
121 1,
122 INT16_MAX,
123 INT16_MAX - 1
124 };
125
126 #define UINT24_MAX 0xffffff
127
128 uint32_t u24_nums[] =
129 {
130 0,
131 1,
132 UINT24_MAX / 2 - 1,
133 UINT24_MAX / 2,
134 UINT24_MAX / 2 + 1,
135 UINT24_MAX,
136 UINT24_MAX -1
137 };
138
139 uint32_t u32_nums[] =
140 {
141 0,
142 1,
143 UINT32_MAX / 2 - 1,
144 UINT32_MAX / 2,
145 UINT32_MAX / 2 + 1,
146 UINT32_MAX,
147 UINT32_MAX -1
148 };
149
150 int32_t s32_nums[] =
151 {
152 INT32_MIN,
153 INT32_MIN + 1,
154 -1,
155 0,
156 1,
157 INT32_MAX,
158 INT32_MAX - 1
159 };
160
161 uint64_t u64_nums[] =
162 {
163 0,
164 1,
165 UINT64_MAX / 2 - 1,
166 UINT64_MAX / 2,
167 UINT64_MAX / 2 + 1,
168 UINT64_MAX,
169 UINT64_MAX -1
170 };
171
172 int64_t s64_nums[] =
173 {
174 INT64_MIN,
175 INT64_MIN + 1,
176 -1,
177 0,
178 1,
179 INT64_MAX,
180 INT64_MAX - 1
181 };
182
183 static unsigned char le_mem[] =
184 {
185 /* u8 */
186 0x00,
187 0x01,
188 0x7e,
189 0x7f,
190 0x80,
191 0xff,
192 0xfe,
193 /* s8 */
194 0x80,
195 0x81,
196 0xff,
197 0x00,
198 0x01,
199 0x7f,
200 0x7e,
201 /* u16 */
202 0x00, 0x00,
203 0x01, 0x00,
204 0xfe, 0x7f,
205 0xff, 0x7f,
206 0x00, 0x80,
207 0xff, 0xff,
208 0xfe, 0xff,
209 /* s16 */
210 0x00, 0x80,
211 0x01, 0x80,
212 0xff, 0xff,
213 0x00, 0x00,
214 0x01, 0x00,
215 0xff, 0x7f,
216 0xfe, 0x7f,
217 /* u24 */
218 0x00, 0x00, 0x00,
219 0x01, 0x00, 0x00,
220 0xfe, 0xff, 0x7f,
221 0xff, 0xff, 0x7f,
222 0x00, 0x00, 0x80,
223 0xff, 0xff, 0xff,
224 0xfe, 0xff, 0xff,
225 /* u32 */
226 0x00, 0x00, 0x00, 0x00,
227 0x01, 0x00, 0x00, 0x00,
228 0xfe, 0xff, 0xff, 0x7f,
229 0xff, 0xff, 0xff, 0x7f,
230 0x00, 0x00, 0x00, 0x80,
231 0xff, 0xff, 0xff, 0xff,
232 0xfe, 0xff, 0xff, 0xff,
233 /* s32 */
234 0x00, 0x00, 0x00, 0x80,
235 0x01, 0x00, 0x00, 0x80,
236 0xff, 0xff, 0xff, 0xff,
237 0x00, 0x00, 0x00, 0x00,
238 0x01, 0x00, 0x00, 0x00,
239 0xff, 0xff, 0xff, 0x7f,
240 0xfe, 0xff, 0xff, 0x7f,
241 /* u64 */
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
245 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
247 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
248 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
249 /* s64 */
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
251 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
252 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
256 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
257 };
258
259 static unsigned char be_mem[] =
260 {
261 /* u8 */
262 0x00,
263 0x01,
264 0x7e,
265 0x7f,
266 0x80,
267 0xff,
268 0xfe,
269 /* s8 */
270 0x80,
271 0x81,
272 0xff,
273 0x00,
274 0x01,
275 0x7f,
276 0x7e,
277 /* u16 */
278 0x00, 0x00,
279 0x00, 0x01,
280 0x7f, 0xfe,
281 0x7f, 0xff,
282 0x80, 0x00,
283 0xff, 0xff,
284 0xff, 0xfe,
285 /* s16 */
286 0x80, 0x00,
287 0x80, 0x01,
288 0xff, 0xff,
289 0x00, 0x00,
290 0x00, 0x01,
291 0x7f, 0xff,
292 0x7f, 0xfe,
293 /* u24 */
294 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x01,
296 0x7f, 0xff, 0xfe,
297 0x7f, 0xff, 0xff,
298 0x80, 0x00, 0x00,
299 0xff, 0xff, 0xff,
300 0xff, 0xff, 0xfe,
301 /* u32 */
302 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x01,
304 0x7f, 0xff, 0xff, 0xfe,
305 0x7f, 0xff, 0xff, 0xff,
306 0x80, 0x00, 0x00, 0x00,
307 0xff, 0xff, 0xff, 0xff,
308 0xff, 0xff, 0xff, 0xfe,
309 /* s32 */
310 0x80, 0x00, 0x00, 0x00,
311 0x80, 0x00, 0x00, 0x01,
312 0xff, 0xff, 0xff, 0xff,
313 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x01,
315 0x7f, 0xff, 0xff, 0xff,
316 0x7f, 0xff, 0xff, 0xfe,
317 /* u64 */
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
320 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
321 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
322 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
324 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
325 /* s64 */
326 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
328 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
331 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
332 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
333 };
334
335 int
main(int argc,char ** argv)336 main (int argc, char **argv __attribute__((unused)))
337 {
338 /* No arguments means check, otherwise Write out the memory array. */
339 bool write = false;
340 if (argc > 1)
341 write = true;
342
343 bool is_le = (BYTE_ORDER == LITTLE_ENDIAN);
344
345 if (write)
346 {
347 if (is_le)
348 printf ("static unsigned char le_mem[] =\n");
349 else
350 printf ("static unsigned char be_mem[] =\n");
351 printf (" {\n");
352 }
353
354 Dwarf dbg_le = { .other_byte_order = !is_le };
355 Dwarf dbg_be = { .other_byte_order = is_le };
356
357 unsigned char *p_le = le_mem;
358 unsigned char *p_be = be_mem;
359
360 union u8 u8;
361 if (write)
362 printf (" /* u8 */\n");
363 for (size_t i = 0; i < sizeof (u8_nums) / sizeof (u8); i++)
364 {
365 if (write)
366 {
367 u8.v = u8_nums[i];
368 printf (" 0x%02" PRIx8 ",\n", u8.c[0]);
369 }
370 else
371 {
372 uint8_t v = *p_le++;
373 assert (v == u8_nums[i]);
374 v = *p_be++;
375 assert (v == u8_nums[i]);
376 }
377 }
378
379 union s8 s8;
380 if (write)
381 printf (" /* s8 */\n");
382 for (size_t i = 0; i < sizeof (s8_nums) / sizeof (s8); i++)
383 {
384 if (write)
385 {
386 s8.v = s8_nums[i];
387 printf (" 0x%02" PRIx8 ",\n", s8.c[0]);
388 }
389 else
390 {
391 int8_t v = *p_le++;
392 assert (v == s8_nums[i]);
393 v = *p_be++;
394 assert (v == s8_nums[i]);
395 }
396 }
397
398 union u16 u16;
399 if (write)
400 printf (" /* u16 */\n");
401 for (size_t i = 0; i < sizeof (u16_nums) / sizeof (u16); i++)
402 {
403 if (write)
404 {
405 u16.v = u16_nums[i];
406 printf (" 0x%02" PRIx8 ", ", u16.c[0]);
407 printf ("0x%02" PRIx8 ",\n", u16.c[1]);
408 }
409 else
410 {
411 uint16_t v = read_2ubyte_unaligned_inc (&dbg_le, p_le);
412 assert (v == u16_nums[i]);
413 v = read_2ubyte_unaligned_inc (&dbg_be, p_be);
414 assert (v == u16_nums[i]);
415 }
416 }
417
418 union s16 s16;
419 if (write)
420 printf (" /* s16 */\n");
421 for (size_t i = 0; i < sizeof (s16_nums) / sizeof (s16); i++)
422 {
423 if (write)
424 {
425 s16.v = s16_nums[i];
426 printf (" 0x%02" PRIx8 ", ", s16.c[0]);
427 printf ("0x%02" PRIx8 ",\n", s16.c[1]);
428 }
429 else
430 {
431 int16_t v = read_2sbyte_unaligned_inc (&dbg_le, p_le);
432 assert (v == s16_nums[i]);
433 v = read_2sbyte_unaligned_inc (&dbg_be, p_be);
434 assert (v == s16_nums[i]);
435 }
436 }
437
438 union u24 u24;
439 if (write)
440 printf (" /* u24 */\n");
441 for (size_t i = 0; i < sizeof (u24_nums) / sizeof (uint32_t); i++)
442 {
443 if (write)
444 {
445 u24.v = u24_nums[i];
446 printf (" 0x%02" PRIx8 ", ", u24.c[0]);
447 printf ("0x%02" PRIx8 ", ", u24.c[1]);
448 printf ("0x%02" PRIx8 ",\n", u24.c[2]);
449 }
450 else
451 {
452 uint32_t v = read_3ubyte_unaligned_inc (&dbg_le, p_le);
453 assert (v == u24_nums[i]);
454 v = read_3ubyte_unaligned_inc (&dbg_be, p_be);
455 assert (v == u24_nums[i]);
456 }
457 }
458
459 union u32 u32;
460 if (write)
461 printf (" /* u32 */\n");
462 for (size_t i = 0; i < sizeof (u32_nums) / sizeof (u32); i++)
463 {
464 if (write)
465 {
466 u32.v = u32_nums[i];
467 printf (" 0x%02" PRIx8 ", ", u32.c[0]);
468 printf ("0x%02" PRIx8 ", ", u32.c[1]);
469 printf ("0x%02" PRIx8 ", ", u32.c[2]);
470 printf ("0x%02" PRIx8 ",\n", u32.c[3]);
471 }
472 else
473 {
474 uint32_t v = read_4ubyte_unaligned_inc (&dbg_le, p_le);
475 assert (v == u32_nums[i]);
476 v = read_4ubyte_unaligned_inc (&dbg_be, p_be);
477 assert (v == u32_nums[i]);
478 }
479 }
480
481 union s32 s32;
482 if (write)
483 printf (" /* s32 */\n");
484 for (size_t i = 0; i < sizeof (s32_nums) / sizeof (s32); i++)
485 {
486 if (write)
487 {
488 s32.v = s32_nums[i];
489 printf (" 0x%02" PRIx8 ", ", s32.c[0]);
490 printf ("0x%02" PRIx8 ", ", s32.c[1]);
491 printf ("0x%02" PRIx8 ", ", s32.c[2]);
492 printf ("0x%02" PRIx8 ",\n", s32.c[3]);
493 }
494 else
495 {
496 int32_t v = read_4sbyte_unaligned_inc (&dbg_le, p_le);
497 assert (v == s32_nums[i]);
498 v = read_4sbyte_unaligned_inc (&dbg_be, p_be);
499 assert (v == s32_nums[i]);
500 }
501 }
502
503 union u64 u64;
504 if (write)
505 printf (" /* u64 */\n");
506 for (size_t i = 0; i < sizeof (u64_nums) / sizeof (u64); i++)
507 {
508 if (write)
509 {
510 u64.v = u64_nums[i];
511 printf (" 0x%02" PRIx8 ", ", u64.c[0]);
512 printf ("0x%02" PRIx8 ", ", u64.c[1]);
513 printf ("0x%02" PRIx8 ", ", u64.c[2]);
514 printf ("0x%02" PRIx8 ", ", u64.c[3]);
515 printf ("0x%02" PRIx8 ", ", u64.c[4]);
516 printf ("0x%02" PRIx8 ", ", u64.c[5]);
517 printf ("0x%02" PRIx8 ", ", u64.c[6]);
518 printf ("0x%02" PRIx8 ",\n", u64.c[7]);
519 }
520 else
521 {
522 uint64_t v = read_8ubyte_unaligned_inc (&dbg_le, p_le);
523 assert (v == u64_nums[i]);
524 v = read_8ubyte_unaligned_inc (&dbg_be, p_be);
525 assert (v == u64_nums[i]);
526 }
527 }
528
529 union s64 s64;
530 if (write)
531 printf (" /* s64 */\n");
532 for (size_t i = 0; i < sizeof (s64_nums) / sizeof (s64); i++)
533 {
534 if (write)
535 {
536 s64.v = s64_nums[i];
537 printf (" 0x%02" PRIx8 ", ", s64.c[0]);
538 printf ("0x%02" PRIx8 ", ", s64.c[1]);
539 printf ("0x%02" PRIx8 ", ", s64.c[2]);
540 printf ("0x%02" PRIx8 ", ", s64.c[3]);
541 printf ("0x%02" PRIx8 ", ", s64.c[4]);
542 printf ("0x%02" PRIx8 ", ", s64.c[5]);
543 printf ("0x%02" PRIx8 ", ", s64.c[6]);
544 printf ("0x%02" PRIx8 ",\n", s64.c[7]);
545 }
546 else
547 {
548 int64_t v = read_8sbyte_unaligned_inc (&dbg_le, p_le);
549 assert (v == s64_nums[i]);
550 v = read_8sbyte_unaligned_inc (&dbg_be, p_be);
551 assert (v == s64_nums[i]);
552 }
553 }
554
555 if (write)
556 printf (" };\n");
557 else
558 {
559 assert (p_le == le_mem + sizeof (le_mem));
560 assert (p_be == be_mem + sizeof (be_mem));
561 }
562
563 return 0;
564 }
565