1 #include <stdint.h> 2 #include <stdbool.h> 3 /* 4 * KERNEL 5 */ 6 7 struct core_reloc_kernel_output { 8 int valid[10]; 9 char comm[sizeof("test_progs")]; 10 int comm_len; 11 }; 12 13 /* 14 * FLAVORS 15 */ 16 struct core_reloc_flavors { 17 int a; 18 int b; 19 int c; 20 }; 21 22 /* this is not a flavor, as it doesn't have triple underscore */ 23 struct core_reloc_flavors__err_wrong_name { 24 int a; 25 int b; 26 int c; 27 }; 28 29 /* 30 * NESTING 31 */ 32 /* original set up, used to record relocations in BPF program */ 33 struct core_reloc_nesting_substruct { 34 int a; 35 }; 36 37 union core_reloc_nesting_subunion { 38 int b; 39 }; 40 41 struct core_reloc_nesting { 42 union { 43 struct core_reloc_nesting_substruct a; 44 } a; 45 struct { 46 union core_reloc_nesting_subunion b; 47 } b; 48 }; 49 50 /* inlined anonymous struct/union instead of named structs in original */ 51 struct core_reloc_nesting___anon_embed { 52 int __just_for_padding; 53 union { 54 struct { 55 int a; 56 } a; 57 } a; 58 struct { 59 union { 60 int b; 61 } b; 62 } b; 63 }; 64 65 /* different mix of nested structs/unions than in original */ 66 struct core_reloc_nesting___struct_union_mixup { 67 int __a; 68 struct { 69 int __a; 70 union { 71 char __a; 72 int a; 73 } a; 74 } a; 75 int __b; 76 union { 77 int __b; 78 union { 79 char __b; 80 int b; 81 } b; 82 } b; 83 }; 84 85 /* extra anon structs/unions, but still valid a.a.a and b.b.b accessors */ 86 struct core_reloc_nesting___extra_nesting { 87 int __padding; 88 struct { 89 struct { 90 struct { 91 struct { 92 union { 93 int a; 94 } a; 95 }; 96 }; 97 } a; 98 int __some_more; 99 struct { 100 union { 101 union { 102 union { 103 struct { 104 int b; 105 }; 106 } b; 107 }; 108 } b; 109 }; 110 }; 111 }; 112 113 /* three flavors of same struct with different structure but same layout for 114 * a.a.a and b.b.b, thus successfully resolved and relocatable */ 115 struct core_reloc_nesting___dup_compat_types { 116 char __just_for_padding; 117 /* 3 more bytes of padding */ 118 struct { 119 struct { 120 int a; /* offset 4 */ 121 } a; 122 } a; 123 long long __more_padding; 124 struct { 125 struct { 126 int b; /* offset 16 */ 127 } b; 128 } b; 129 }; 130 131 struct core_reloc_nesting___dup_compat_types__2 { 132 int __aligned_padding; 133 struct { 134 int __trickier_noop[0]; 135 struct { 136 char __some_more_noops[0]; 137 int a; /* offset 4 */ 138 } a; 139 } a; 140 int __more_padding; 141 struct { 142 struct { 143 struct { 144 int __critical_padding; 145 int b; /* offset 16 */ 146 } b; 147 int __does_not_matter; 148 }; 149 } b; 150 int __more_irrelevant_stuff; 151 }; 152 153 struct core_reloc_nesting___dup_compat_types__3 { 154 char __correct_padding[4]; 155 struct { 156 struct { 157 int a; /* offset 4 */ 158 } a; 159 } a; 160 /* 8 byte padding due to next struct's alignment */ 161 struct { 162 struct { 163 int b; 164 } b; 165 } b __attribute__((aligned(16))); 166 }; 167 168 /* b.b.b field is missing */ 169 struct core_reloc_nesting___err_missing_field { 170 struct { 171 struct { 172 int a; 173 } a; 174 } a; 175 struct { 176 struct { 177 int x; 178 } b; 179 } b; 180 }; 181 182 /* b.b.b field is an array of integers instead of plain int */ 183 struct core_reloc_nesting___err_array_field { 184 struct { 185 struct { 186 int a; 187 } a; 188 } a; 189 struct { 190 struct { 191 int b[1]; 192 } b; 193 } b; 194 }; 195 196 /* middle b container is missing */ 197 struct core_reloc_nesting___err_missing_container { 198 struct { 199 struct { 200 int a; 201 } a; 202 } a; 203 struct { 204 int x; 205 } b; 206 }; 207 208 /* middle b container is referenced through pointer instead of being embedded */ 209 struct core_reloc_nesting___err_nonstruct_container { 210 struct { 211 struct { 212 int a; 213 } a; 214 } a; 215 struct { 216 struct { 217 int b; 218 } *b; 219 } b; 220 }; 221 222 /* middle b container is an array of structs instead of plain struct */ 223 struct core_reloc_nesting___err_array_container { 224 struct { 225 struct { 226 int a; 227 } a; 228 } a; 229 struct { 230 struct { 231 int b; 232 } b[1]; 233 } b; 234 }; 235 236 /* two flavors of same struct with incompatible layout for b.b.b */ 237 struct core_reloc_nesting___err_dup_incompat_types__1 { 238 struct { 239 struct { 240 int a; /* offset 0 */ 241 } a; 242 } a; 243 struct { 244 struct { 245 int b; /* offset 4 */ 246 } b; 247 } b; 248 }; 249 250 struct core_reloc_nesting___err_dup_incompat_types__2 { 251 struct { 252 struct { 253 int a; /* offset 0 */ 254 } a; 255 } a; 256 int __extra_padding; 257 struct { 258 struct { 259 int b; /* offset 8 (!) */ 260 } b; 261 } b; 262 }; 263 264 /* two flavors of same struct having one of a.a.a and b.b.b, but not both */ 265 struct core_reloc_nesting___err_partial_match_dups__a { 266 struct { 267 struct { 268 int a; 269 } a; 270 } a; 271 }; 272 273 struct core_reloc_nesting___err_partial_match_dups__b { 274 struct { 275 struct { 276 int b; 277 } b; 278 } b; 279 }; 280 281 struct core_reloc_nesting___err_too_deep { 282 struct { 283 struct { 284 int a; 285 } a; 286 } a; 287 /* 65 levels of nestedness for b.b.b */ 288 struct { 289 struct { 290 struct { struct { struct { struct { struct { 291 struct { struct { struct { struct { struct { 292 struct { struct { struct { struct { struct { 293 struct { struct { struct { struct { struct { 294 struct { struct { struct { struct { struct { 295 struct { struct { struct { struct { struct { 296 struct { struct { struct { struct { struct { 297 struct { struct { struct { struct { struct { 298 struct { struct { struct { struct { struct { 299 struct { struct { struct { struct { struct { 300 struct { struct { struct { struct { struct { 301 struct { struct { struct { struct { struct { 302 /* this one is one too much */ 303 struct { 304 int b; 305 }; 306 }; }; }; }; }; 307 }; }; }; }; }; 308 }; }; }; }; }; 309 }; }; }; }; }; 310 }; }; }; }; }; 311 }; }; }; }; }; 312 }; }; }; }; }; 313 }; }; }; }; }; 314 }; }; }; }; }; 315 }; }; }; }; }; 316 }; }; }; }; }; 317 }; }; }; }; }; 318 } b; 319 } b; 320 }; 321 322 /* 323 * ARRAYS 324 */ 325 struct core_reloc_arrays_output { 326 int a2; 327 char b123; 328 int c1c; 329 int d00d; 330 int f10c; 331 }; 332 333 struct core_reloc_arrays_substruct { 334 int c; 335 int d; 336 }; 337 338 struct core_reloc_arrays { 339 int a[5]; 340 char b[2][3][4]; 341 struct core_reloc_arrays_substruct c[3]; 342 struct core_reloc_arrays_substruct d[1][2]; 343 struct core_reloc_arrays_substruct f[][2]; 344 }; 345 346 /* bigger array dimensions */ 347 struct core_reloc_arrays___diff_arr_dim { 348 int a[7]; 349 char b[3][4][5]; 350 struct core_reloc_arrays_substruct c[4]; 351 struct core_reloc_arrays_substruct d[2][3]; 352 struct core_reloc_arrays_substruct f[1][3]; 353 }; 354 355 /* different size of array's value (struct) */ 356 struct core_reloc_arrays___diff_arr_val_sz { 357 int a[5]; 358 char b[2][3][4]; 359 struct { 360 int __padding1; 361 int c; 362 int __padding2; 363 } c[3]; 364 struct { 365 int __padding1; 366 int d; 367 int __padding2; 368 } d[1][2]; 369 struct { 370 int __padding1; 371 int c; 372 int __padding2; 373 } f[][2]; 374 }; 375 376 struct core_reloc_arrays___equiv_zero_sz_arr { 377 int a[5]; 378 char b[2][3][4]; 379 struct core_reloc_arrays_substruct c[3]; 380 struct core_reloc_arrays_substruct d[1][2]; 381 /* equivalent to flexible array */ 382 struct core_reloc_arrays_substruct f[0][2]; 383 }; 384 385 struct core_reloc_arrays___fixed_arr { 386 int a[5]; 387 char b[2][3][4]; 388 struct core_reloc_arrays_substruct c[3]; 389 struct core_reloc_arrays_substruct d[1][2]; 390 /* not a flexible array anymore, but within access bounds */ 391 struct core_reloc_arrays_substruct f[1][2]; 392 }; 393 394 struct core_reloc_arrays___err_too_small { 395 int a[2]; /* this one is too small */ 396 char b[2][3][4]; 397 struct core_reloc_arrays_substruct c[3]; 398 struct core_reloc_arrays_substruct d[1][2]; 399 struct core_reloc_arrays_substruct f[][2]; 400 }; 401 402 struct core_reloc_arrays___err_too_shallow { 403 int a[5]; 404 char b[2][3]; /* this one lacks one dimension */ 405 struct core_reloc_arrays_substruct c[3]; 406 struct core_reloc_arrays_substruct d[1][2]; 407 struct core_reloc_arrays_substruct f[][2]; 408 }; 409 410 struct core_reloc_arrays___err_non_array { 411 int a; /* not an array */ 412 char b[2][3][4]; 413 struct core_reloc_arrays_substruct c[3]; 414 struct core_reloc_arrays_substruct d[1][2]; 415 struct core_reloc_arrays_substruct f[][2]; 416 }; 417 418 struct core_reloc_arrays___err_wrong_val_type { 419 int a[5]; 420 char b[2][3][4]; 421 int c[3]; /* value is not a struct */ 422 struct core_reloc_arrays_substruct d[1][2]; 423 struct core_reloc_arrays_substruct f[][2]; 424 }; 425 426 struct core_reloc_arrays___err_bad_zero_sz_arr { 427 /* zero-sized array, but not at the end */ 428 struct core_reloc_arrays_substruct f[0][2]; 429 int a[5]; 430 char b[2][3][4]; 431 struct core_reloc_arrays_substruct c[3]; 432 struct core_reloc_arrays_substruct d[1][2]; 433 }; 434 435 /* 436 * PRIMITIVES 437 */ 438 enum core_reloc_primitives_enum { 439 A = 0, 440 B = 1, 441 }; 442 443 struct core_reloc_primitives { 444 char a; 445 int b; 446 enum core_reloc_primitives_enum c; 447 void *d; 448 int (*f)(const char *); 449 }; 450 451 struct core_reloc_primitives___diff_enum_def { 452 char a; 453 int b; 454 void *d; 455 int (*f)(const char *); 456 enum { 457 X = 100, 458 Y = 200, 459 } c; /* inline enum def with differing set of values */ 460 }; 461 462 struct core_reloc_primitives___diff_func_proto { 463 void (*f)(int); /* incompatible function prototype */ 464 void *d; 465 enum core_reloc_primitives_enum c; 466 int b; 467 char a; 468 }; 469 470 struct core_reloc_primitives___diff_ptr_type { 471 const char * const d; /* different pointee type + modifiers */ 472 char a; 473 int b; 474 enum core_reloc_primitives_enum c; 475 int (*f)(const char *); 476 }; 477 478 struct core_reloc_primitives___err_non_enum { 479 char a[1]; 480 int b; 481 int c; /* int instead of enum */ 482 void *d; 483 int (*f)(const char *); 484 }; 485 486 struct core_reloc_primitives___err_non_int { 487 char a[1]; 488 int *b; /* ptr instead of int */ 489 enum core_reloc_primitives_enum c; 490 void *d; 491 int (*f)(const char *); 492 }; 493 494 struct core_reloc_primitives___err_non_ptr { 495 char a[1]; 496 int b; 497 enum core_reloc_primitives_enum c; 498 int d; /* int instead of ptr */ 499 int (*f)(const char *); 500 }; 501 502 /* 503 * MODS 504 */ 505 struct core_reloc_mods_output { 506 int a, b, c, d, e, f, g, h; 507 }; 508 509 typedef const int int_t; 510 typedef const char *char_ptr_t; 511 typedef const int arr_t[7]; 512 513 struct core_reloc_mods_substruct { 514 int x; 515 int y; 516 }; 517 518 typedef struct { 519 int x; 520 int y; 521 } core_reloc_mods_substruct_t; 522 523 struct core_reloc_mods { 524 int a; 525 int_t b; 526 char *c; 527 char_ptr_t d; 528 int e[3]; 529 arr_t f; 530 struct core_reloc_mods_substruct g; 531 core_reloc_mods_substruct_t h; 532 }; 533 534 /* a/b, c/d, e/f, and g/h pairs are swapped */ 535 struct core_reloc_mods___mod_swap { 536 int b; 537 int_t a; 538 char *d; 539 char_ptr_t c; 540 int f[3]; 541 arr_t e; 542 struct { 543 int y; 544 int x; 545 } h; 546 core_reloc_mods_substruct_t g; 547 }; 548 549 typedef int int1_t; 550 typedef int1_t int2_t; 551 typedef int2_t int3_t; 552 553 typedef int arr1_t[5]; 554 typedef arr1_t arr2_t; 555 typedef arr2_t arr3_t; 556 typedef arr3_t arr4_t; 557 558 typedef const char * const volatile fancy_char_ptr_t; 559 560 typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt; 561 562 /* we need more typedefs */ 563 struct core_reloc_mods___typedefs { 564 core_reloc_mods_substruct_tt g; 565 core_reloc_mods_substruct_tt h; 566 arr4_t f; 567 arr4_t e; 568 fancy_char_ptr_t d; 569 fancy_char_ptr_t c; 570 int3_t b; 571 int3_t a; 572 }; 573 574 /* 575 * PTR_AS_ARR 576 */ 577 struct core_reloc_ptr_as_arr { 578 int a; 579 }; 580 581 struct core_reloc_ptr_as_arr___diff_sz { 582 int :32; /* padding */ 583 char __some_more_padding; 584 int a; 585 }; 586 587 /* 588 * INTS 589 */ 590 struct core_reloc_ints { 591 uint8_t u8_field; 592 int8_t s8_field; 593 uint16_t u16_field; 594 int16_t s16_field; 595 uint32_t u32_field; 596 int32_t s32_field; 597 uint64_t u64_field; 598 int64_t s64_field; 599 }; 600 601 /* signed/unsigned types swap */ 602 struct core_reloc_ints___reverse_sign { 603 int8_t u8_field; 604 uint8_t s8_field; 605 int16_t u16_field; 606 uint16_t s16_field; 607 int32_t u32_field; 608 uint32_t s32_field; 609 int64_t u64_field; 610 uint64_t s64_field; 611 }; 612 613 struct core_reloc_ints___bool { 614 bool u8_field; /* bool instead of uint8 */ 615 int8_t s8_field; 616 uint16_t u16_field; 617 int16_t s16_field; 618 uint32_t u32_field; 619 int32_t s32_field; 620 uint64_t u64_field; 621 int64_t s64_field; 622 }; 623 624 /* 625 * MISC 626 */ 627 struct core_reloc_misc_output { 628 int a, b, c; 629 }; 630 631 struct core_reloc_misc___a { 632 int a1; 633 int a2; 634 }; 635 636 struct core_reloc_misc___b { 637 int b1; 638 int b2; 639 }; 640 641 /* this one extends core_reloc_misc_extensible struct from BPF prog */ 642 struct core_reloc_misc_extensible { 643 int a; 644 int b; 645 int c; 646 int d; 647 }; 648 649 /* 650 * EXISTENCE 651 */ 652 struct core_reloc_existence_output { 653 int a_exists; 654 int a_value; 655 int b_exists; 656 int b_value; 657 int c_exists; 658 int c_value; 659 int arr_exists; 660 int arr_value; 661 int s_exists; 662 int s_value; 663 }; 664 665 struct core_reloc_existence { 666 int a; 667 struct { 668 int b; 669 }; 670 int c; 671 int arr[1]; 672 struct { 673 int x; 674 } s; 675 }; 676 677 struct core_reloc_existence___minimal { 678 int a; 679 }; 680 681 struct core_reloc_existence___err_wrong_int_sz { 682 short a; 683 }; 684 685 struct core_reloc_existence___err_wrong_int_type { 686 int b[1]; 687 }; 688 689 struct core_reloc_existence___err_wrong_int_kind { 690 struct{ int x; } c; 691 }; 692 693 struct core_reloc_existence___err_wrong_arr_kind { 694 int arr; 695 }; 696 697 struct core_reloc_existence___err_wrong_arr_value_type { 698 short arr[1]; 699 }; 700 701 struct core_reloc_existence___err_wrong_struct_type { 702 int s; 703 }; 704 705 /* 706 * BITFIELDS 707 */ 708 /* bitfield read results, all as plain integers */ 709 struct core_reloc_bitfields_output { 710 int64_t ub1; 711 int64_t ub2; 712 int64_t ub7; 713 int64_t sb4; 714 int64_t sb20; 715 int64_t u32; 716 int64_t s32; 717 }; 718 719 struct core_reloc_bitfields { 720 /* unsigned bitfields */ 721 uint8_t ub1: 1; 722 uint8_t ub2: 2; 723 uint32_t ub7: 7; 724 /* signed bitfields */ 725 int8_t sb4: 4; 726 int32_t sb20: 20; 727 /* non-bitfields */ 728 uint32_t u32; 729 int32_t s32; 730 }; 731 732 /* different bit sizes (both up and down) */ 733 struct core_reloc_bitfields___bit_sz_change { 734 /* unsigned bitfields */ 735 uint16_t ub1: 3; /* 1 -> 3 */ 736 uint32_t ub2: 20; /* 2 -> 20 */ 737 uint8_t ub7: 1; /* 7 -> 1 */ 738 /* signed bitfields */ 739 int8_t sb4: 1; /* 4 -> 1 */ 740 int32_t sb20: 30; /* 20 -> 30 */ 741 /* non-bitfields */ 742 uint16_t u32; /* 32 -> 16 */ 743 int64_t s32; /* 32 -> 64 */ 744 }; 745 746 /* turn bitfield into non-bitfield and vice versa */ 747 struct core_reloc_bitfields___bitfield_vs_int { 748 uint64_t ub1; /* 3 -> 64 non-bitfield */ 749 uint8_t ub2; /* 20 -> 8 non-bitfield */ 750 int64_t ub7; /* 7 -> 64 non-bitfield signed */ 751 int64_t sb4; /* 4 -> 64 non-bitfield signed */ 752 uint64_t sb20; /* 20 -> 16 non-bitfield unsigned */ 753 int32_t u32: 20; /* 32 non-bitfield -> 20 bitfield */ 754 uint64_t s32: 60; /* 32 non-bitfield -> 60 bitfield */ 755 }; 756 757 struct core_reloc_bitfields___just_big_enough { 758 uint64_t ub1: 4; 759 uint64_t ub2: 60; /* packed tightly */ 760 uint32_t ub7; 761 uint32_t sb4; 762 uint32_t sb20; 763 uint32_t u32; 764 uint32_t s32; 765 } __attribute__((packed)) ; 766 767 struct core_reloc_bitfields___err_too_big_bitfield { 768 uint64_t ub1: 4; 769 uint64_t ub2: 61; /* packed tightly */ 770 uint32_t ub7; 771 uint32_t sb4; 772 uint32_t sb20; 773 uint32_t u32; 774 uint32_t s32; 775 } __attribute__((packed)) ; 776 777 /* 778 * SIZE 779 */ 780 struct core_reloc_size_output { 781 int int_sz; 782 int struct_sz; 783 int union_sz; 784 int arr_sz; 785 int arr_elem_sz; 786 int ptr_sz; 787 int enum_sz; 788 }; 789 790 struct core_reloc_size { 791 int int_field; 792 struct { int x; } struct_field; 793 union { int x; } union_field; 794 int arr_field[4]; 795 void *ptr_field; 796 enum { VALUE = 123 } enum_field; 797 }; 798 799 struct core_reloc_size___diff_sz { 800 uint64_t int_field; 801 struct { int x; int y; int z; } struct_field; 802 union { int x; char bla[123]; } union_field; 803 char arr_field[10]; 804 void *ptr_field; 805 enum { OTHER_VALUE = 0xFFFFFFFFFFFFFFFF } enum_field; 806 }; 807