1 | #include <stdint.h> |
2 | #include <stdbool.h> |
3 | |
4 | void preserce_ptr_sz_fn(long x) {} |
5 | |
6 | #define __bpf_aligned __attribute__((aligned(8))) |
7 | |
8 | /* |
9 | * KERNEL |
10 | */ |
11 | |
12 | struct core_reloc_kernel_output { |
13 | int valid[10]; |
14 | char comm[sizeof("test_progs" )]; |
15 | int comm_len; |
16 | bool local_task_struct_matches; |
17 | }; |
18 | |
19 | /* |
20 | * MODULE |
21 | */ |
22 | |
23 | struct core_reloc_module_output { |
24 | long long len; |
25 | long long off; |
26 | int read_ctx_sz; |
27 | bool read_ctx_exists; |
28 | bool buf_exists; |
29 | bool len_exists; |
30 | bool off_exists; |
31 | /* we have test_progs[-flavor], so cut flavor part */ |
32 | char comm[sizeof("test_progs" )]; |
33 | int comm_len; |
34 | }; |
35 | |
36 | /* |
37 | * FLAVORS |
38 | */ |
39 | struct core_reloc_flavors { |
40 | int a; |
41 | int b; |
42 | int c; |
43 | }; |
44 | |
45 | /* this is not a flavor, as it doesn't have triple underscore */ |
46 | struct core_reloc_flavors__err_wrong_name { |
47 | int a; |
48 | int b; |
49 | int c; |
50 | }; |
51 | |
52 | /* |
53 | * NESTING |
54 | */ |
55 | /* original set up, used to record relocations in BPF program */ |
56 | struct core_reloc_nesting_substruct { |
57 | int a; |
58 | }; |
59 | |
60 | union core_reloc_nesting_subunion { |
61 | int b; |
62 | }; |
63 | |
64 | struct core_reloc_nesting { |
65 | union { |
66 | struct core_reloc_nesting_substruct a; |
67 | } a; |
68 | struct { |
69 | union core_reloc_nesting_subunion b; |
70 | } b; |
71 | }; |
72 | |
73 | /* inlined anonymous struct/union instead of named structs in original */ |
74 | struct core_reloc_nesting___anon_embed { |
75 | int __just_for_padding; |
76 | union { |
77 | struct { |
78 | int a; |
79 | } a; |
80 | } a; |
81 | struct { |
82 | union { |
83 | int b; |
84 | } b; |
85 | } b; |
86 | }; |
87 | |
88 | /* different mix of nested structs/unions than in original */ |
89 | struct core_reloc_nesting___struct_union_mixup { |
90 | int __a; |
91 | struct { |
92 | int __a; |
93 | union { |
94 | char __a; |
95 | int a; |
96 | } a; |
97 | } a; |
98 | int __b; |
99 | union { |
100 | int __b; |
101 | union { |
102 | char __b; |
103 | int b; |
104 | } b; |
105 | } b; |
106 | }; |
107 | |
108 | /* extra anon structs/unions, but still valid a.a.a and b.b.b accessors */ |
109 | struct { |
110 | int ; |
111 | struct { |
112 | struct { |
113 | struct { |
114 | struct { |
115 | union { |
116 | int ; |
117 | } ; |
118 | }; |
119 | }; |
120 | } ; |
121 | int ; |
122 | struct { |
123 | union { |
124 | union { |
125 | union { |
126 | struct { |
127 | int ; |
128 | }; |
129 | } ; |
130 | }; |
131 | } ; |
132 | }; |
133 | }; |
134 | }; |
135 | |
136 | /* three flavors of same struct with different structure but same layout for |
137 | * a.a.a and b.b.b, thus successfully resolved and relocatable */ |
138 | struct core_reloc_nesting___dup_compat_types { |
139 | char __just_for_padding; |
140 | /* 3 more bytes of padding */ |
141 | struct { |
142 | struct { |
143 | int a; /* offset 4 */ |
144 | } a; |
145 | } a; |
146 | long long __more_padding; |
147 | struct { |
148 | struct { |
149 | int b; /* offset 16 */ |
150 | } b; |
151 | } b; |
152 | }; |
153 | |
154 | struct core_reloc_nesting___dup_compat_types__2 { |
155 | int __aligned_padding; |
156 | struct { |
157 | int __trickier_noop[0]; |
158 | struct { |
159 | char __some_more_noops[0]; |
160 | int a; /* offset 4 */ |
161 | } a; |
162 | } a; |
163 | int __more_padding; |
164 | struct { |
165 | struct { |
166 | struct { |
167 | int __critical_padding; |
168 | int b; /* offset 16 */ |
169 | } b; |
170 | int __does_not_matter; |
171 | }; |
172 | } b; |
173 | int __more_irrelevant_stuff; |
174 | }; |
175 | |
176 | struct core_reloc_nesting___dup_compat_types__3 { |
177 | char __correct_padding[4]; |
178 | struct { |
179 | struct { |
180 | int a; /* offset 4 */ |
181 | } a; |
182 | } a; |
183 | /* 8 byte padding due to next struct's alignment */ |
184 | struct { |
185 | struct { |
186 | int b; |
187 | } b; |
188 | } b __attribute__((aligned(16))); |
189 | }; |
190 | |
191 | /* b.b.b field is missing */ |
192 | struct core_reloc_nesting___err_missing_field { |
193 | struct { |
194 | struct { |
195 | int a; |
196 | } a; |
197 | } a; |
198 | struct { |
199 | struct { |
200 | int x; |
201 | } b; |
202 | } b; |
203 | }; |
204 | |
205 | /* b.b.b field is an array of integers instead of plain int */ |
206 | struct core_reloc_nesting___err_array_field { |
207 | struct { |
208 | struct { |
209 | int a; |
210 | } a; |
211 | } a; |
212 | struct { |
213 | struct { |
214 | int b[1]; |
215 | } b; |
216 | } b; |
217 | }; |
218 | |
219 | /* middle b container is missing */ |
220 | struct core_reloc_nesting___err_missing_container { |
221 | struct { |
222 | struct { |
223 | int a; |
224 | } a; |
225 | } a; |
226 | struct { |
227 | int x; |
228 | } b; |
229 | }; |
230 | |
231 | /* middle b container is referenced through pointer instead of being embedded */ |
232 | struct core_reloc_nesting___err_nonstruct_container { |
233 | struct { |
234 | struct { |
235 | int a; |
236 | } a; |
237 | } a; |
238 | struct { |
239 | struct { |
240 | int b; |
241 | } *b; |
242 | } b; |
243 | }; |
244 | |
245 | /* middle b container is an array of structs instead of plain struct */ |
246 | struct core_reloc_nesting___err_array_container { |
247 | struct { |
248 | struct { |
249 | int a; |
250 | } a; |
251 | } a; |
252 | struct { |
253 | struct { |
254 | int b; |
255 | } b[1]; |
256 | } b; |
257 | }; |
258 | |
259 | /* two flavors of same struct with incompatible layout for b.b.b */ |
260 | struct core_reloc_nesting___err_dup_incompat_types__1 { |
261 | struct { |
262 | struct { |
263 | int a; /* offset 0 */ |
264 | } a; |
265 | } a; |
266 | struct { |
267 | struct { |
268 | int b; /* offset 4 */ |
269 | } b; |
270 | } b; |
271 | }; |
272 | |
273 | struct core_reloc_nesting___err_dup_incompat_types__2 { |
274 | struct { |
275 | struct { |
276 | int a; /* offset 0 */ |
277 | } a; |
278 | } a; |
279 | int ; |
280 | struct { |
281 | struct { |
282 | int b; /* offset 8 (!) */ |
283 | } b; |
284 | } b; |
285 | }; |
286 | |
287 | /* two flavors of same struct having one of a.a.a and b.b.b, but not both */ |
288 | struct core_reloc_nesting___err_partial_match_dups__a { |
289 | struct { |
290 | struct { |
291 | int a; |
292 | } a; |
293 | } a; |
294 | }; |
295 | |
296 | struct core_reloc_nesting___err_partial_match_dups__b { |
297 | struct { |
298 | struct { |
299 | int b; |
300 | } b; |
301 | } b; |
302 | }; |
303 | |
304 | struct core_reloc_nesting___err_too_deep { |
305 | struct { |
306 | struct { |
307 | int a; |
308 | } a; |
309 | } a; |
310 | /* 65 levels of nestedness for b.b.b */ |
311 | struct { |
312 | struct { |
313 | struct { struct { struct { struct { struct { |
314 | struct { struct { struct { struct { struct { |
315 | struct { struct { struct { struct { struct { |
316 | struct { struct { struct { struct { struct { |
317 | struct { struct { struct { struct { struct { |
318 | struct { struct { struct { struct { struct { |
319 | struct { struct { struct { struct { struct { |
320 | struct { struct { struct { struct { struct { |
321 | struct { struct { struct { struct { struct { |
322 | struct { struct { struct { struct { struct { |
323 | struct { struct { struct { struct { struct { |
324 | struct { struct { struct { struct { struct { |
325 | /* this one is one too much */ |
326 | struct { |
327 | int b; |
328 | }; |
329 | }; }; }; }; }; |
330 | }; }; }; }; }; |
331 | }; }; }; }; }; |
332 | }; }; }; }; }; |
333 | }; }; }; }; }; |
334 | }; }; }; }; }; |
335 | }; }; }; }; }; |
336 | }; }; }; }; }; |
337 | }; }; }; }; }; |
338 | }; }; }; }; }; |
339 | }; }; }; }; }; |
340 | }; }; }; }; }; |
341 | } b; |
342 | } b; |
343 | }; |
344 | |
345 | /* |
346 | * ARRAYS |
347 | */ |
348 | struct core_reloc_arrays_output { |
349 | int a2; |
350 | char b123; |
351 | int c1c; |
352 | int d00d; |
353 | int f10c; |
354 | }; |
355 | |
356 | struct core_reloc_arrays_substruct { |
357 | int c; |
358 | int d; |
359 | }; |
360 | |
361 | struct core_reloc_arrays { |
362 | int a[5]; |
363 | char b[2][3][4]; |
364 | struct core_reloc_arrays_substruct c[3]; |
365 | struct core_reloc_arrays_substruct d[1][2]; |
366 | struct core_reloc_arrays_substruct f[][2]; |
367 | }; |
368 | |
369 | /* bigger array dimensions */ |
370 | struct core_reloc_arrays___diff_arr_dim { |
371 | int a[7]; |
372 | char b[3][4][5]; |
373 | struct core_reloc_arrays_substruct c[4]; |
374 | struct core_reloc_arrays_substruct d[2][3]; |
375 | struct core_reloc_arrays_substruct f[1][3]; |
376 | }; |
377 | |
378 | /* different size of array's value (struct) */ |
379 | struct core_reloc_arrays___diff_arr_val_sz { |
380 | int a[5]; |
381 | char b[2][3][4]; |
382 | struct { |
383 | int __padding1; |
384 | int c; |
385 | int __padding2; |
386 | } c[3]; |
387 | struct { |
388 | int __padding1; |
389 | int d; |
390 | int __padding2; |
391 | } d[1][2]; |
392 | struct { |
393 | int __padding1; |
394 | int c; |
395 | int __padding2; |
396 | } f[][2]; |
397 | }; |
398 | |
399 | struct core_reloc_arrays___equiv_zero_sz_arr { |
400 | int a[5]; |
401 | char b[2][3][4]; |
402 | struct core_reloc_arrays_substruct c[3]; |
403 | struct core_reloc_arrays_substruct d[1][2]; |
404 | /* equivalent to flexible array */ |
405 | struct core_reloc_arrays_substruct f[][2]; |
406 | }; |
407 | |
408 | struct core_reloc_arrays___fixed_arr { |
409 | int a[5]; |
410 | char b[2][3][4]; |
411 | struct core_reloc_arrays_substruct c[3]; |
412 | struct core_reloc_arrays_substruct d[1][2]; |
413 | /* not a flexible array anymore, but within access bounds */ |
414 | struct core_reloc_arrays_substruct f[1][2]; |
415 | }; |
416 | |
417 | struct core_reloc_arrays___err_too_small { |
418 | int a[2]; /* this one is too small */ |
419 | char b[2][3][4]; |
420 | struct core_reloc_arrays_substruct c[3]; |
421 | struct core_reloc_arrays_substruct d[1][2]; |
422 | struct core_reloc_arrays_substruct f[][2]; |
423 | }; |
424 | |
425 | struct core_reloc_arrays___err_too_shallow { |
426 | int a[5]; |
427 | char b[2][3]; /* this one lacks one dimension */ |
428 | struct core_reloc_arrays_substruct c[3]; |
429 | struct core_reloc_arrays_substruct d[1][2]; |
430 | struct core_reloc_arrays_substruct f[][2]; |
431 | }; |
432 | |
433 | struct core_reloc_arrays___err_non_array { |
434 | int a; /* not an array */ |
435 | char b[2][3][4]; |
436 | struct core_reloc_arrays_substruct c[3]; |
437 | struct core_reloc_arrays_substruct d[1][2]; |
438 | struct core_reloc_arrays_substruct f[][2]; |
439 | }; |
440 | |
441 | struct core_reloc_arrays___err_wrong_val_type { |
442 | int a[5]; |
443 | char b[2][3][4]; |
444 | int c[3]; /* value is not a struct */ |
445 | struct core_reloc_arrays_substruct d[1][2]; |
446 | struct core_reloc_arrays_substruct f[][2]; |
447 | }; |
448 | |
449 | struct core_reloc_arrays___err_bad_zero_sz_arr { |
450 | /* zero-sized array, but not at the end */ |
451 | struct core_reloc_arrays_substruct f[0][2]; |
452 | int a[5]; |
453 | char b[2][3][4]; |
454 | struct core_reloc_arrays_substruct c[3]; |
455 | struct core_reloc_arrays_substruct d[1][2]; |
456 | }; |
457 | |
458 | /* |
459 | * PRIMITIVES |
460 | */ |
461 | enum core_reloc_primitives_enum { |
462 | A = 0, |
463 | B = 1, |
464 | }; |
465 | |
466 | struct core_reloc_primitives { |
467 | char a; |
468 | int b; |
469 | enum core_reloc_primitives_enum c; |
470 | void *d __bpf_aligned; |
471 | int (*f)(const char *) __bpf_aligned; |
472 | }; |
473 | |
474 | struct core_reloc_primitives___diff_enum_def { |
475 | char a; |
476 | int b; |
477 | void *d __bpf_aligned; |
478 | int (*f)(const char *) __bpf_aligned; |
479 | enum { |
480 | X = 100, |
481 | Y = 200, |
482 | } c __bpf_aligned; /* inline enum def with differing set of values */ |
483 | }; |
484 | |
485 | struct core_reloc_primitives___diff_func_proto { |
486 | void (*f)(int) __bpf_aligned; /* incompatible function prototype */ |
487 | void *d __bpf_aligned; |
488 | enum core_reloc_primitives_enum c __bpf_aligned; |
489 | int b; |
490 | char a; |
491 | }; |
492 | |
493 | struct core_reloc_primitives___diff_ptr_type { |
494 | const char * const d __bpf_aligned; /* different pointee type + modifiers */ |
495 | char a __bpf_aligned; |
496 | int b; |
497 | enum core_reloc_primitives_enum c; |
498 | int (*f)(const char *) __bpf_aligned; |
499 | }; |
500 | |
501 | struct core_reloc_primitives___err_non_enum { |
502 | char a[1]; |
503 | int b; |
504 | int c; /* int instead of enum */ |
505 | void *d __bpf_aligned; |
506 | int (*f)(const char *) __bpf_aligned; |
507 | }; |
508 | |
509 | struct core_reloc_primitives___err_non_int { |
510 | char a[1]; |
511 | int *b __bpf_aligned; /* ptr instead of int */ |
512 | enum core_reloc_primitives_enum c __bpf_aligned; |
513 | void *d __bpf_aligned; |
514 | int (*f)(const char *) __bpf_aligned; |
515 | }; |
516 | |
517 | struct core_reloc_primitives___err_non_ptr { |
518 | char a[1]; |
519 | int b; |
520 | enum core_reloc_primitives_enum c; |
521 | int d; /* int instead of ptr */ |
522 | int (*f)(const char *) __bpf_aligned; |
523 | }; |
524 | |
525 | /* |
526 | * MODS |
527 | */ |
528 | struct core_reloc_mods_output { |
529 | int a, b, c, d, e, f, g, h; |
530 | }; |
531 | |
532 | typedef const int int_t; |
533 | typedef const char *char_ptr_t __bpf_aligned; |
534 | typedef const int arr_t[7]; |
535 | |
536 | struct core_reloc_mods_substruct { |
537 | int x; |
538 | int y; |
539 | }; |
540 | |
541 | typedef struct { |
542 | int x; |
543 | int y; |
544 | } core_reloc_mods_substruct_t; |
545 | |
546 | struct core_reloc_mods { |
547 | int a; |
548 | int_t b; |
549 | char *c __bpf_aligned; |
550 | char_ptr_t d; |
551 | int e[3] __bpf_aligned; |
552 | arr_t f; |
553 | struct core_reloc_mods_substruct g; |
554 | core_reloc_mods_substruct_t h; |
555 | }; |
556 | |
557 | /* a/b, c/d, e/f, and g/h pairs are swapped */ |
558 | struct core_reloc_mods___mod_swap { |
559 | int b; |
560 | int_t a; |
561 | char *d __bpf_aligned; |
562 | char_ptr_t c; |
563 | int f[3] __bpf_aligned; |
564 | arr_t e; |
565 | struct { |
566 | int y; |
567 | int x; |
568 | } h; |
569 | core_reloc_mods_substruct_t g; |
570 | }; |
571 | |
572 | typedef int int1_t; |
573 | typedef int1_t int2_t; |
574 | typedef int2_t int3_t; |
575 | |
576 | typedef int arr1_t[5]; |
577 | typedef arr1_t arr2_t; |
578 | typedef arr2_t arr3_t; |
579 | typedef arr3_t arr4_t; |
580 | |
581 | typedef const char * const volatile fancy_char_ptr_t __bpf_aligned; |
582 | |
583 | typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt; |
584 | |
585 | /* we need more typedefs */ |
586 | struct core_reloc_mods___typedefs { |
587 | core_reloc_mods_substruct_tt g; |
588 | core_reloc_mods_substruct_tt h; |
589 | arr4_t f; |
590 | arr4_t e; |
591 | fancy_char_ptr_t d; |
592 | fancy_char_ptr_t c; |
593 | int3_t b __bpf_aligned; |
594 | int3_t a; |
595 | }; |
596 | |
597 | /* |
598 | * PTR_AS_ARR |
599 | */ |
600 | struct core_reloc_ptr_as_arr { |
601 | int a; |
602 | }; |
603 | |
604 | struct core_reloc_ptr_as_arr___diff_sz { |
605 | int :32; /* padding */ |
606 | char __some_more_padding; |
607 | int a; |
608 | }; |
609 | |
610 | /* |
611 | * INTS |
612 | */ |
613 | struct core_reloc_ints { |
614 | uint8_t u8_field; |
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 | /* signed/unsigned types swap */ |
625 | struct core_reloc_ints___reverse_sign { |
626 | int8_t u8_field; |
627 | uint8_t s8_field; |
628 | int16_t u16_field; |
629 | uint16_t s16_field; |
630 | int32_t u32_field; |
631 | uint32_t s32_field; |
632 | int64_t u64_field; |
633 | uint64_t s64_field; |
634 | }; |
635 | |
636 | struct core_reloc_ints___bool { |
637 | bool u8_field; /* bool instead of uint8 */ |
638 | int8_t s8_field; |
639 | uint16_t u16_field; |
640 | int16_t s16_field; |
641 | uint32_t u32_field; |
642 | int32_t s32_field; |
643 | uint64_t u64_field; |
644 | int64_t s64_field; |
645 | }; |
646 | |
647 | /* |
648 | * MISC |
649 | */ |
650 | struct core_reloc_misc_output { |
651 | int a, b, c; |
652 | }; |
653 | |
654 | struct core_reloc_misc___a { |
655 | int a1; |
656 | int a2; |
657 | }; |
658 | |
659 | struct core_reloc_misc___b { |
660 | int b1; |
661 | int b2; |
662 | }; |
663 | |
664 | /* this one extends core_reloc_misc_extensible struct from BPF prog */ |
665 | struct core_reloc_misc_extensible { |
666 | int a; |
667 | int b; |
668 | int c; |
669 | int d; |
670 | }; |
671 | |
672 | /* |
673 | * FIELD EXISTENCE |
674 | */ |
675 | struct core_reloc_existence_output { |
676 | int a_exists; |
677 | int a_value; |
678 | int b_exists; |
679 | int b_value; |
680 | int c_exists; |
681 | int c_value; |
682 | int arr_exists; |
683 | int arr_value; |
684 | int s_exists; |
685 | int s_value; |
686 | }; |
687 | |
688 | struct core_reloc_existence { |
689 | int a; |
690 | struct { |
691 | int b; |
692 | }; |
693 | int c; |
694 | int arr[1]; |
695 | struct { |
696 | int x; |
697 | } s; |
698 | }; |
699 | |
700 | struct core_reloc_existence___minimal { |
701 | int a; |
702 | }; |
703 | |
704 | struct core_reloc_existence___wrong_field_defs { |
705 | void *a; |
706 | int b[1]; |
707 | struct{ int x; } c; |
708 | int arr; |
709 | int s; |
710 | }; |
711 | |
712 | /* |
713 | * BITFIELDS |
714 | */ |
715 | /* bitfield read results, all as plain integers */ |
716 | struct core_reloc_bitfields_output { |
717 | int64_t ub1; |
718 | int64_t ub2; |
719 | int64_t ub7; |
720 | int64_t sb4; |
721 | int64_t sb20; |
722 | int64_t u32; |
723 | int64_t s32; |
724 | }; |
725 | |
726 | struct core_reloc_bitfields { |
727 | /* unsigned bitfields */ |
728 | uint8_t ub1: 1; |
729 | uint8_t ub2: 2; |
730 | uint32_t ub7: 7; |
731 | /* signed bitfields */ |
732 | int8_t sb4: 4; |
733 | int32_t sb20: 20; |
734 | /* non-bitfields */ |
735 | uint32_t u32; |
736 | int32_t s32; |
737 | }; |
738 | |
739 | /* different bit sizes (both up and down) */ |
740 | struct core_reloc_bitfields___bit_sz_change { |
741 | /* unsigned bitfields */ |
742 | uint16_t ub1: 3; /* 1 -> 3 */ |
743 | uint32_t ub2: 20; /* 2 -> 20 */ |
744 | uint8_t ub7: 1; /* 7 -> 1 */ |
745 | /* signed bitfields */ |
746 | int8_t sb4: 1; /* 4 -> 1 */ |
747 | int32_t sb20: 30; /* 20 -> 30 */ |
748 | /* non-bitfields */ |
749 | uint16_t u32; /* 32 -> 16 */ |
750 | int64_t s32 __bpf_aligned; /* 32 -> 64 */ |
751 | }; |
752 | |
753 | /* turn bitfield into non-bitfield and vice versa */ |
754 | struct core_reloc_bitfields___bitfield_vs_int { |
755 | uint64_t ub1; /* 3 -> 64 non-bitfield */ |
756 | uint8_t ub2; /* 20 -> 8 non-bitfield */ |
757 | int64_t ub7 __bpf_aligned; /* 7 -> 64 non-bitfield signed */ |
758 | int64_t sb4 __bpf_aligned; /* 4 -> 64 non-bitfield signed */ |
759 | uint64_t sb20 __bpf_aligned; /* 20 -> 16 non-bitfield unsigned */ |
760 | int32_t u32: 20; /* 32 non-bitfield -> 20 bitfield */ |
761 | uint64_t s32: 60 __bpf_aligned; /* 32 non-bitfield -> 60 bitfield */ |
762 | }; |
763 | |
764 | struct core_reloc_bitfields___just_big_enough { |
765 | uint64_t ub1: 4; |
766 | uint64_t ub2: 60; /* packed tightly */ |
767 | uint32_t ub7; |
768 | uint32_t sb4; |
769 | uint32_t sb20; |
770 | uint32_t u32; |
771 | uint32_t s32; |
772 | } __attribute__((packed)) ; |
773 | |
774 | struct core_reloc_bitfields___err_too_big_bitfield { |
775 | uint64_t ub1: 4; |
776 | uint64_t ub2: 61; /* packed tightly */ |
777 | uint32_t ub7; |
778 | uint32_t sb4; |
779 | uint32_t sb20; |
780 | uint32_t u32; |
781 | uint32_t s32; |
782 | } __attribute__((packed)) ; |
783 | |
784 | /* |
785 | * SIZE |
786 | */ |
787 | struct core_reloc_size_output { |
788 | int int_sz; |
789 | int int_off; |
790 | int struct_sz; |
791 | int struct_off; |
792 | int union_sz; |
793 | int union_off; |
794 | int arr_sz; |
795 | int arr_off; |
796 | int arr_elem_sz; |
797 | int arr_elem_off; |
798 | int ptr_sz; |
799 | int ptr_off; |
800 | int enum_sz; |
801 | int enum_off; |
802 | int float_sz; |
803 | int float_off; |
804 | }; |
805 | |
806 | struct core_reloc_size { |
807 | int int_field; |
808 | struct { int x; } struct_field; |
809 | union { int x; } union_field; |
810 | int arr_field[4]; |
811 | void *ptr_field; |
812 | enum { VALUE = 123 } enum_field; |
813 | float float_field; |
814 | }; |
815 | |
816 | struct core_reloc_size___diff_sz { |
817 | uint64_t int_field; |
818 | struct { int x; int y; int z; } struct_field; |
819 | union { int x; char bla[123]; } union_field; |
820 | char arr_field[10]; |
821 | void *ptr_field; |
822 | enum { OTHER_VALUE = 0xFFFFFFFFFFFFFFFF } enum_field; |
823 | double float_field; |
824 | }; |
825 | |
826 | struct core_reloc_size___diff_offs { |
827 | float float_field; |
828 | enum { YET_OTHER_VALUE = 123 } enum_field; |
829 | void *ptr_field; |
830 | int arr_field[4]; |
831 | union { int x; } union_field; |
832 | struct { int x; } struct_field; |
833 | int int_field; |
834 | }; |
835 | |
836 | /* Error case of two candidates with the fields (int_field) at the same |
837 | * offset, but with differing final relocation values: size 4 vs size 1 |
838 | */ |
839 | struct core_reloc_size___err_ambiguous1 { |
840 | /* int at offset 0 */ |
841 | int int_field; |
842 | |
843 | struct { int x; } struct_field; |
844 | union { int x; } union_field; |
845 | int arr_field[4]; |
846 | void *ptr_field; |
847 | enum { VALUE___1 = 123 } enum_field; |
848 | float float_field; |
849 | }; |
850 | |
851 | struct core_reloc_size___err_ambiguous2 { |
852 | /* char at offset 0 */ |
853 | char int_field; |
854 | |
855 | struct { int x; } struct_field; |
856 | union { int x; } union_field; |
857 | int arr_field[4]; |
858 | void *ptr_field; |
859 | enum { VALUE___2 = 123 } enum_field; |
860 | float float_field; |
861 | }; |
862 | |
863 | /* |
864 | * TYPE EXISTENCE, MATCH & SIZE |
865 | */ |
866 | struct core_reloc_type_based_output { |
867 | bool struct_exists; |
868 | bool complex_struct_exists; |
869 | bool union_exists; |
870 | bool enum_exists; |
871 | bool typedef_named_struct_exists; |
872 | bool typedef_anon_struct_exists; |
873 | bool typedef_struct_ptr_exists; |
874 | bool typedef_int_exists; |
875 | bool typedef_enum_exists; |
876 | bool typedef_void_ptr_exists; |
877 | bool typedef_restrict_ptr_exists; |
878 | bool typedef_func_proto_exists; |
879 | bool typedef_arr_exists; |
880 | |
881 | bool struct_matches; |
882 | bool complex_struct_matches; |
883 | bool union_matches; |
884 | bool enum_matches; |
885 | bool typedef_named_struct_matches; |
886 | bool typedef_anon_struct_matches; |
887 | bool typedef_struct_ptr_matches; |
888 | bool typedef_int_matches; |
889 | bool typedef_enum_matches; |
890 | bool typedef_void_ptr_matches; |
891 | bool typedef_restrict_ptr_matches; |
892 | bool typedef_func_proto_matches; |
893 | bool typedef_arr_matches; |
894 | |
895 | int struct_sz; |
896 | int union_sz; |
897 | int enum_sz; |
898 | int typedef_named_struct_sz; |
899 | int typedef_anon_struct_sz; |
900 | int typedef_struct_ptr_sz; |
901 | int typedef_int_sz; |
902 | int typedef_enum_sz; |
903 | int typedef_void_ptr_sz; |
904 | int typedef_func_proto_sz; |
905 | int typedef_arr_sz; |
906 | }; |
907 | |
908 | struct a_struct { |
909 | int x; |
910 | }; |
911 | |
912 | struct a_complex_struct { |
913 | union { |
914 | struct a_struct * restrict a; |
915 | void *b; |
916 | } x; |
917 | volatile long y; |
918 | }; |
919 | |
920 | union a_union { |
921 | int y; |
922 | int z; |
923 | }; |
924 | |
925 | typedef struct a_struct named_struct_typedef; |
926 | |
927 | typedef struct { int x, y, z; } anon_struct_typedef; |
928 | |
929 | typedef struct { |
930 | int a, b, c; |
931 | } *struct_ptr_typedef; |
932 | |
933 | enum an_enum { |
934 | AN_ENUM_VAL1 = 1, |
935 | AN_ENUM_VAL2 = 2, |
936 | AN_ENUM_VAL3 = 3, |
937 | }; |
938 | |
939 | typedef int int_typedef; |
940 | |
941 | typedef enum { TYPEDEF_ENUM_VAL1, TYPEDEF_ENUM_VAL2 } enum_typedef; |
942 | |
943 | typedef void *void_ptr_typedef; |
944 | typedef int *restrict restrict_ptr_typedef; |
945 | |
946 | typedef int (*func_proto_typedef)(long); |
947 | |
948 | typedef char arr_typedef[20]; |
949 | |
950 | struct core_reloc_type_based { |
951 | struct a_struct f1; |
952 | struct a_complex_struct f2; |
953 | union a_union f3; |
954 | enum an_enum f4; |
955 | named_struct_typedef f5; |
956 | anon_struct_typedef f6; |
957 | struct_ptr_typedef f7; |
958 | int_typedef f8; |
959 | enum_typedef f9; |
960 | void_ptr_typedef f10; |
961 | restrict_ptr_typedef f11; |
962 | func_proto_typedef f12; |
963 | arr_typedef f13; |
964 | }; |
965 | |
966 | /* no types in target */ |
967 | struct core_reloc_type_based___all_missing { |
968 | }; |
969 | |
970 | /* different member orders, enum variant values, signedness, etc */ |
971 | struct a_struct___diff { |
972 | int x; |
973 | int a; |
974 | }; |
975 | |
976 | struct a_struct___forward; |
977 | |
978 | struct a_complex_struct___diff { |
979 | union { |
980 | struct a_struct___forward *a; |
981 | void *b; |
982 | } x; |
983 | volatile long y; |
984 | }; |
985 | |
986 | union a_union___diff { |
987 | int z; |
988 | int y; |
989 | }; |
990 | |
991 | typedef struct a_struct___diff named_struct_typedef___diff; |
992 | |
993 | typedef struct { int z, x, y; } anon_struct_typedef___diff; |
994 | |
995 | typedef struct { |
996 | int c; |
997 | int b; |
998 | int a; |
999 | } *struct_ptr_typedef___diff; |
1000 | |
1001 | enum an_enum___diff { |
1002 | AN_ENUM_VAL2___diff = 0, |
1003 | AN_ENUM_VAL1___diff = 42, |
1004 | AN_ENUM_VAL3___diff = 1, |
1005 | }; |
1006 | |
1007 | typedef unsigned int int_typedef___diff; |
1008 | |
1009 | typedef enum { TYPEDEF_ENUM_VAL2___diff, TYPEDEF_ENUM_VAL1___diff = 50 } enum_typedef___diff; |
1010 | |
1011 | typedef const void *void_ptr_typedef___diff; |
1012 | |
1013 | typedef int_typedef___diff (*func_proto_typedef___diff)(long); |
1014 | |
1015 | typedef char arr_typedef___diff[3]; |
1016 | |
1017 | struct core_reloc_type_based___diff { |
1018 | struct a_struct___diff f1; |
1019 | struct a_complex_struct___diff f2; |
1020 | union a_union___diff f3; |
1021 | enum an_enum___diff f4; |
1022 | named_struct_typedef___diff f5; |
1023 | anon_struct_typedef___diff f6; |
1024 | struct_ptr_typedef___diff f7; |
1025 | int_typedef___diff f8; |
1026 | enum_typedef___diff f9; |
1027 | void_ptr_typedef___diff f10; |
1028 | func_proto_typedef___diff f11; |
1029 | arr_typedef___diff f12; |
1030 | }; |
1031 | |
1032 | /* different type sizes, extra modifiers, anon vs named enums, etc */ |
1033 | struct a_struct___diff_sz { |
1034 | long x; |
1035 | int y; |
1036 | char z; |
1037 | }; |
1038 | |
1039 | union a_union___diff_sz { |
1040 | char yy; |
1041 | char zz; |
1042 | }; |
1043 | |
1044 | typedef struct a_struct___diff_sz named_struct_typedef___diff_sz; |
1045 | |
1046 | typedef struct { long xx, yy, zzz; } anon_struct_typedef___diff_sz; |
1047 | |
1048 | typedef struct { |
1049 | char aa[1], bb[2], cc[3]; |
1050 | } *struct_ptr_typedef___diff_sz; |
1051 | |
1052 | enum an_enum___diff_sz { |
1053 | AN_ENUM_VAL1___diff_sz = 0x123412341234, |
1054 | AN_ENUM_VAL2___diff_sz = 2, |
1055 | }; |
1056 | |
1057 | typedef unsigned long int_typedef___diff_sz; |
1058 | |
1059 | typedef enum an_enum___diff_sz enum_typedef___diff_sz; |
1060 | |
1061 | typedef const void * const void_ptr_typedef___diff_sz; |
1062 | |
1063 | typedef int_typedef___diff_sz (*func_proto_typedef___diff_sz)(char); |
1064 | |
1065 | typedef int arr_typedef___diff_sz[2]; |
1066 | |
1067 | struct core_reloc_type_based___diff_sz { |
1068 | struct a_struct___diff_sz f1; |
1069 | union a_union___diff_sz f2; |
1070 | enum an_enum___diff_sz f3; |
1071 | named_struct_typedef___diff_sz f4; |
1072 | anon_struct_typedef___diff_sz f5; |
1073 | struct_ptr_typedef___diff_sz f6; |
1074 | int_typedef___diff_sz f7; |
1075 | enum_typedef___diff_sz f8; |
1076 | void_ptr_typedef___diff_sz f9; |
1077 | func_proto_typedef___diff_sz f10; |
1078 | arr_typedef___diff_sz f11; |
1079 | }; |
1080 | |
1081 | /* incompatibilities between target and local types */ |
1082 | union a_struct___incompat { /* union instead of struct */ |
1083 | int x; |
1084 | }; |
1085 | |
1086 | struct a_union___incompat { /* struct instead of union */ |
1087 | int y; |
1088 | int z; |
1089 | }; |
1090 | |
1091 | /* typedef to union, not to struct */ |
1092 | typedef union a_struct___incompat named_struct_typedef___incompat; |
1093 | |
1094 | /* typedef to void pointer, instead of struct */ |
1095 | typedef void *anon_struct_typedef___incompat; |
1096 | |
1097 | /* extra pointer indirection */ |
1098 | typedef struct { |
1099 | int a, b, c; |
1100 | } **struct_ptr_typedef___incompat; |
1101 | |
1102 | /* typedef of a struct with int, instead of int */ |
1103 | typedef struct { int x; } int_typedef___incompat; |
1104 | |
1105 | /* typedef to func_proto, instead of enum */ |
1106 | typedef int (*enum_typedef___incompat)(void); |
1107 | |
1108 | /* pointer to char instead of void */ |
1109 | typedef char *void_ptr_typedef___incompat; |
1110 | |
1111 | /* void return type instead of int */ |
1112 | typedef void (*func_proto_typedef___incompat)(long); |
1113 | |
1114 | /* multi-dimensional array instead of a single-dimensional */ |
1115 | typedef int arr_typedef___incompat[20][2]; |
1116 | |
1117 | struct core_reloc_type_based___incompat { |
1118 | union a_struct___incompat f1; |
1119 | struct a_union___incompat f2; |
1120 | /* the only valid one is enum, to check that something still succeeds */ |
1121 | enum an_enum f3; |
1122 | named_struct_typedef___incompat f4; |
1123 | anon_struct_typedef___incompat f5; |
1124 | struct_ptr_typedef___incompat f6; |
1125 | int_typedef___incompat f7; |
1126 | enum_typedef___incompat f8; |
1127 | void_ptr_typedef___incompat f9; |
1128 | func_proto_typedef___incompat f10; |
1129 | arr_typedef___incompat f11; |
1130 | }; |
1131 | |
1132 | /* func_proto with incompatible signature */ |
1133 | typedef void (*func_proto_typedef___fn_wrong_ret1)(long); |
1134 | typedef int * (*func_proto_typedef___fn_wrong_ret2)(long); |
1135 | typedef struct { int x; } int_struct_typedef; |
1136 | typedef int_struct_typedef (*func_proto_typedef___fn_wrong_ret3)(long); |
1137 | typedef int (*func_proto_typedef___fn_wrong_arg)(void *); |
1138 | typedef int (*func_proto_typedef___fn_wrong_arg_cnt1)(long, long); |
1139 | typedef int (*func_proto_typedef___fn_wrong_arg_cnt2)(void); |
1140 | |
1141 | struct core_reloc_type_based___fn_wrong_args { |
1142 | /* one valid type to make sure relos still work */ |
1143 | struct a_struct f1; |
1144 | func_proto_typedef___fn_wrong_ret1 f2; |
1145 | func_proto_typedef___fn_wrong_ret2 f3; |
1146 | func_proto_typedef___fn_wrong_ret3 f4; |
1147 | func_proto_typedef___fn_wrong_arg f5; |
1148 | func_proto_typedef___fn_wrong_arg_cnt1 f6; |
1149 | func_proto_typedef___fn_wrong_arg_cnt2 f7; |
1150 | }; |
1151 | |
1152 | /* |
1153 | * TYPE ID MAPPING (LOCAL AND TARGET) |
1154 | */ |
1155 | struct core_reloc_type_id_output { |
1156 | int local_anon_struct; |
1157 | int local_anon_union; |
1158 | int local_anon_enum; |
1159 | int local_anon_func_proto_ptr; |
1160 | int local_anon_void_ptr; |
1161 | int local_anon_arr; |
1162 | |
1163 | int local_struct; |
1164 | int local_union; |
1165 | int local_enum; |
1166 | int local_int; |
1167 | int local_struct_typedef; |
1168 | int local_func_proto_typedef; |
1169 | int local_arr_typedef; |
1170 | |
1171 | int targ_struct; |
1172 | int targ_union; |
1173 | int targ_enum; |
1174 | int targ_int; |
1175 | int targ_struct_typedef; |
1176 | int targ_func_proto_typedef; |
1177 | int targ_arr_typedef; |
1178 | }; |
1179 | |
1180 | struct core_reloc_type_id { |
1181 | struct a_struct f1; |
1182 | union a_union f2; |
1183 | enum an_enum f3; |
1184 | named_struct_typedef f4; |
1185 | func_proto_typedef f5; |
1186 | arr_typedef f6; |
1187 | }; |
1188 | |
1189 | struct core_reloc_type_id___missing_targets { |
1190 | /* nothing */ |
1191 | }; |
1192 | |
1193 | /* |
1194 | * ENUMERATOR VALUE EXISTENCE AND VALUE RELOCATION |
1195 | */ |
1196 | struct core_reloc_enumval_output { |
1197 | bool named_val1_exists; |
1198 | bool named_val2_exists; |
1199 | bool named_val3_exists; |
1200 | bool anon_val1_exists; |
1201 | bool anon_val2_exists; |
1202 | bool anon_val3_exists; |
1203 | |
1204 | int named_val1; |
1205 | int named_val2; |
1206 | int anon_val1; |
1207 | int anon_val2; |
1208 | }; |
1209 | |
1210 | struct core_reloc_enum64val_output { |
1211 | bool unsigned_val1_exists; |
1212 | bool unsigned_val2_exists; |
1213 | bool unsigned_val3_exists; |
1214 | bool signed_val1_exists; |
1215 | bool signed_val2_exists; |
1216 | bool signed_val3_exists; |
1217 | |
1218 | long unsigned_val1; |
1219 | long unsigned_val2; |
1220 | long signed_val1; |
1221 | long signed_val2; |
1222 | }; |
1223 | |
1224 | enum named_enum { |
1225 | NAMED_ENUM_VAL1 = 1, |
1226 | NAMED_ENUM_VAL2 = 2, |
1227 | NAMED_ENUM_VAL3 = 3, |
1228 | }; |
1229 | |
1230 | typedef enum { |
1231 | ANON_ENUM_VAL1 = 0x10, |
1232 | ANON_ENUM_VAL2 = 0x20, |
1233 | ANON_ENUM_VAL3 = 0x30, |
1234 | } anon_enum; |
1235 | |
1236 | struct core_reloc_enumval { |
1237 | enum named_enum f1; |
1238 | anon_enum f2; |
1239 | }; |
1240 | |
1241 | enum named_unsigned_enum64 { |
1242 | UNSIGNED_ENUM64_VAL1 = 0x1ffffffffULL, |
1243 | UNSIGNED_ENUM64_VAL2 = 0x2, |
1244 | UNSIGNED_ENUM64_VAL3 = 0x3ffffffffULL, |
1245 | }; |
1246 | |
1247 | enum named_signed_enum64 { |
1248 | SIGNED_ENUM64_VAL1 = 0x1ffffffffLL, |
1249 | SIGNED_ENUM64_VAL2 = -2, |
1250 | SIGNED_ENUM64_VAL3 = 0x3ffffffffLL, |
1251 | }; |
1252 | |
1253 | struct core_reloc_enum64val { |
1254 | enum named_unsigned_enum64 f1; |
1255 | enum named_signed_enum64 f2; |
1256 | }; |
1257 | |
1258 | /* differing enumerator values */ |
1259 | enum named_enum___diff { |
1260 | NAMED_ENUM_VAL1___diff = 101, |
1261 | NAMED_ENUM_VAL2___diff = 202, |
1262 | NAMED_ENUM_VAL3___diff = 303, |
1263 | }; |
1264 | |
1265 | typedef enum { |
1266 | ANON_ENUM_VAL1___diff = 0x11, |
1267 | ANON_ENUM_VAL2___diff = 0x22, |
1268 | ANON_ENUM_VAL3___diff = 0x33, |
1269 | } anon_enum___diff; |
1270 | |
1271 | struct core_reloc_enumval___diff { |
1272 | enum named_enum___diff f1; |
1273 | anon_enum___diff f2; |
1274 | }; |
1275 | |
1276 | enum named_unsigned_enum64___diff { |
1277 | UNSIGNED_ENUM64_VAL1___diff = 0x101ffffffffULL, |
1278 | UNSIGNED_ENUM64_VAL2___diff = 0x202ffffffffULL, |
1279 | UNSIGNED_ENUM64_VAL3___diff = 0x303ffffffffULL, |
1280 | }; |
1281 | |
1282 | enum named_signed_enum64___diff { |
1283 | SIGNED_ENUM64_VAL1___diff = -101, |
1284 | SIGNED_ENUM64_VAL2___diff = -202, |
1285 | SIGNED_ENUM64_VAL3___diff = -303, |
1286 | }; |
1287 | |
1288 | struct core_reloc_enum64val___diff { |
1289 | enum named_unsigned_enum64___diff f1; |
1290 | enum named_signed_enum64___diff f2; |
1291 | }; |
1292 | |
1293 | /* missing (optional) third enum value */ |
1294 | enum named_enum___val3_missing { |
1295 | NAMED_ENUM_VAL1___val3_missing = 111, |
1296 | NAMED_ENUM_VAL2___val3_missing = 222, |
1297 | }; |
1298 | |
1299 | typedef enum { |
1300 | ANON_ENUM_VAL1___val3_missing = 0x111, |
1301 | ANON_ENUM_VAL2___val3_missing = 0x222, |
1302 | } anon_enum___val3_missing; |
1303 | |
1304 | struct core_reloc_enumval___val3_missing { |
1305 | enum named_enum___val3_missing f1; |
1306 | anon_enum___val3_missing f2; |
1307 | }; |
1308 | |
1309 | enum named_unsigned_enum64___val3_missing { |
1310 | UNSIGNED_ENUM64_VAL1___val3_missing = 0x111ffffffffULL, |
1311 | UNSIGNED_ENUM64_VAL2___val3_missing = 0x222, |
1312 | }; |
1313 | |
1314 | enum named_signed_enum64___val3_missing { |
1315 | SIGNED_ENUM64_VAL1___val3_missing = 0x111ffffffffLL, |
1316 | SIGNED_ENUM64_VAL2___val3_missing = -222, |
1317 | }; |
1318 | |
1319 | struct core_reloc_enum64val___val3_missing { |
1320 | enum named_unsigned_enum64___val3_missing f1; |
1321 | enum named_signed_enum64___val3_missing f2; |
1322 | }; |
1323 | |
1324 | /* missing (mandatory) second enum value, should fail */ |
1325 | enum named_enum___err_missing { |
1326 | NAMED_ENUM_VAL1___err_missing = 1, |
1327 | NAMED_ENUM_VAL3___err_missing = 3, |
1328 | }; |
1329 | |
1330 | typedef enum { |
1331 | ANON_ENUM_VAL1___err_missing = 0x111, |
1332 | ANON_ENUM_VAL3___err_missing = 0x222, |
1333 | } anon_enum___err_missing; |
1334 | |
1335 | struct core_reloc_enumval___err_missing { |
1336 | enum named_enum___err_missing f1; |
1337 | anon_enum___err_missing f2; |
1338 | }; |
1339 | |
1340 | enum named_unsigned_enum64___err_missing { |
1341 | UNSIGNED_ENUM64_VAL1___err_missing = 0x1ffffffffULL, |
1342 | UNSIGNED_ENUM64_VAL3___err_missing = 0x3ffffffffULL, |
1343 | }; |
1344 | |
1345 | enum named_signed_enum64___err_missing { |
1346 | SIGNED_ENUM64_VAL1___err_missing = 0x1ffffffffLL, |
1347 | SIGNED_ENUM64_VAL3___err_missing = -3, |
1348 | }; |
1349 | |
1350 | struct core_reloc_enum64val___err_missing { |
1351 | enum named_unsigned_enum64___err_missing f1; |
1352 | enum named_signed_enum64___err_missing f2; |
1353 | }; |
1354 | |