• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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