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 28union u8 29{ 30 uint8_t v; 31 unsigned char c[1]; 32}; 33 34union s8 35{ 36 int8_t v; 37 unsigned char c[1]; 38}; 39 40union u16 41{ 42 uint16_t v; 43 unsigned char c[2]; 44}; 45 46union s16 47{ 48 int16_t v; 49 unsigned char c[2]; 50}; 51 52union u24 53{ 54 uint32_t v:24; 55 unsigned char c[3]; 56} __attribute__((packed)); 57 58union u32 59{ 60 uint32_t v; 61 unsigned char c[4]; 62}; 63 64union s32 65{ 66 int32_t v; 67 unsigned char c[4]; 68}; 69 70union u64 71{ 72 uint64_t v; 73 unsigned char c[8]; 74}; 75 76union s64 77{ 78 uint64_t v; 79 unsigned char c[8]; 80}; 81 82uint8_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 93int8_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 104uint16_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 115int16_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 128uint32_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 139uint32_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 150int32_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 161uint64_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 172int64_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 183static 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 259static 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 335int 336main (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