1 #include <stdint.h>
2 #include <stdbool.h>
3 
preserce_ptr_sz_fn(long x)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 core_reloc_nesting___extra_nesting {
110 	int __padding;
111 	struct {
112 		struct {
113 			struct {
114 				struct {
115 					union {
116 						int a;
117 					} a;
118 				};
119 			};
120 		} a;
121 		int __some_more;
122 		struct {
123 			union {
124 				union {
125 					union {
126 						struct {
127 							int b;
128 						};
129 					} b;
130 				};
131 			} b;
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 __extra_padding;
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 	int a3;
351 	char b123;
352 	int c1c;
353 	int d00d;
354 	int f10c;
355 };
356 
357 struct core_reloc_arrays_substruct {
358 	int c;
359 	int d;
360 };
361 
362 struct core_reloc_arrays {
363 	int a[5];
364 	char b[2][3][4];
365 	struct core_reloc_arrays_substruct c[3];
366 	struct core_reloc_arrays_substruct d[1][2];
367 	struct core_reloc_arrays_substruct f[][2];
368 };
369 
370 /* bigger array dimensions */
371 struct core_reloc_arrays___diff_arr_dim {
372 	int a[7];
373 	char b[3][4][5];
374 	struct core_reloc_arrays_substruct c[4];
375 	struct core_reloc_arrays_substruct d[2][3];
376 	struct core_reloc_arrays_substruct f[1][3];
377 };
378 
379 /* different size of array's value (struct) */
380 struct core_reloc_arrays___diff_arr_val_sz {
381 	int a[5];
382 	char b[2][3][4];
383 	struct {
384 		int __padding1;
385 		int c;
386 		int __padding2;
387 	} c[3];
388 	struct {
389 		int __padding1;
390 		int d;
391 		int __padding2;
392 	} d[1][2];
393 	struct {
394 		int __padding1;
395 		int c;
396 		int __padding2;
397 	} f[][2];
398 };
399 
400 struct core_reloc_arrays___equiv_zero_sz_arr {
401 	int a[5];
402 	char b[2][3][4];
403 	struct core_reloc_arrays_substruct c[3];
404 	struct core_reloc_arrays_substruct d[1][2];
405 	/* equivalent to flexible array */
406 	struct core_reloc_arrays_substruct f[][2];
407 };
408 
409 struct core_reloc_arrays___fixed_arr {
410 	int a[5];
411 	char b[2][3][4];
412 	struct core_reloc_arrays_substruct c[3];
413 	struct core_reloc_arrays_substruct d[1][2];
414 	/* not a flexible array anymore, but within access bounds */
415 	struct core_reloc_arrays_substruct f[1][2];
416 };
417 
418 struct core_reloc_arrays___err_too_small {
419 	int a[2]; /* this one is too small */
420 	char b[2][3][4];
421 	struct core_reloc_arrays_substruct c[3];
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_too_shallow {
427 	int a[5];
428 	char b[2][3]; /* this one lacks one dimension */
429 	struct core_reloc_arrays_substruct c[3];
430 	struct core_reloc_arrays_substruct d[1][2];
431 	struct core_reloc_arrays_substruct f[][2];
432 };
433 
434 struct core_reloc_arrays___err_non_array {
435 	int a; /* not an array */
436 	char b[2][3][4];
437 	struct core_reloc_arrays_substruct c[3];
438 	struct core_reloc_arrays_substruct d[1][2];
439 	struct core_reloc_arrays_substruct f[][2];
440 };
441 
442 struct core_reloc_arrays___err_wrong_val_type {
443 	int a[5];
444 	char b[2][3][4];
445 	int c[3]; /* value is not a struct */
446 	struct core_reloc_arrays_substruct d[1][2];
447 	struct core_reloc_arrays_substruct f[][2];
448 };
449 
450 struct core_reloc_arrays___err_bad_zero_sz_arr {
451 	/* zero-sized array, but not at the end */
452 	struct core_reloc_arrays_substruct f[0][2];
453 	int a[5];
454 	char b[2][3][4];
455 	struct core_reloc_arrays_substruct c[3];
456 	struct core_reloc_arrays_substruct d[1][2];
457 };
458 
459 struct core_reloc_arrays___err_bad_signed_arr_elem_sz {
460 	/* int -> short (signed!): not supported case */
461 	short a[5];
462 	char b[2][3][4];
463 	struct core_reloc_arrays_substruct c[3];
464 	struct core_reloc_arrays_substruct d[1][2];
465 	struct core_reloc_arrays_substruct f[][2];
466 };
467 
468 /*
469  * PRIMITIVES
470  */
471 enum core_reloc_primitives_enum {
472 	A = 0,
473 	B = 1,
474 };
475 
476 struct core_reloc_primitives {
477 	char a;
478 	int b;
479 	enum core_reloc_primitives_enum c;
480 	void *d __bpf_aligned;
481 	int (*f)(const char *) __bpf_aligned;
482 };
483 
484 struct core_reloc_primitives___diff_enum_def {
485 	char a;
486 	int b;
487 	void *d __bpf_aligned;
488 	int (*f)(const char *) __bpf_aligned;
489 	enum {
490 		X = 100,
491 		Y = 200,
492 	} c __bpf_aligned; /* inline enum def with differing set of values */
493 };
494 
495 struct core_reloc_primitives___diff_func_proto {
496 	void (*f)(int) __bpf_aligned; /* incompatible function prototype */
497 	void *d __bpf_aligned;
498 	enum core_reloc_primitives_enum c __bpf_aligned;
499 	int b;
500 	char a;
501 };
502 
503 struct core_reloc_primitives___diff_ptr_type {
504 	const char * const d __bpf_aligned; /* different pointee type + modifiers */
505 	char a __bpf_aligned;
506 	int b;
507 	enum core_reloc_primitives_enum c;
508 	int (*f)(const char *) __bpf_aligned;
509 };
510 
511 struct core_reloc_primitives___err_non_enum {
512 	char a[1];
513 	int b;
514 	int c; /* int instead of enum */
515 	void *d __bpf_aligned;
516 	int (*f)(const char *) __bpf_aligned;
517 };
518 
519 struct core_reloc_primitives___err_non_int {
520 	char a[1];
521 	int *b __bpf_aligned; /* ptr instead of int */
522 	enum core_reloc_primitives_enum c __bpf_aligned;
523 	void *d __bpf_aligned;
524 	int (*f)(const char *) __bpf_aligned;
525 };
526 
527 struct core_reloc_primitives___err_non_ptr {
528 	char a[1];
529 	int b;
530 	enum core_reloc_primitives_enum c;
531 	int d; /* int instead of ptr */
532 	int (*f)(const char *) __bpf_aligned;
533 };
534 
535 /*
536  * MODS
537  */
538 struct core_reloc_mods_output {
539 	int a, b, c, d, e, f, g, h;
540 };
541 
542 typedef const int int_t;
543 typedef const char *char_ptr_t __bpf_aligned;
544 typedef const int arr_t[7];
545 
546 struct core_reloc_mods_substruct {
547 	int x;
548 	int y;
549 };
550 
551 typedef struct {
552 	int x;
553 	int y;
554 } core_reloc_mods_substruct_t;
555 
556 struct core_reloc_mods {
557 	int a;
558 	int_t b;
559 	char *c __bpf_aligned;
560 	char_ptr_t d;
561 	int e[3] __bpf_aligned;
562 	arr_t f;
563 	struct core_reloc_mods_substruct g;
564 	core_reloc_mods_substruct_t h;
565 };
566 
567 /* a/b, c/d, e/f, and g/h pairs are swapped */
568 struct core_reloc_mods___mod_swap {
569 	int b;
570 	int_t a;
571 	char *d __bpf_aligned;
572 	char_ptr_t c;
573 	int f[3] __bpf_aligned;
574 	arr_t e;
575 	struct {
576 		int y;
577 		int x;
578 	} h;
579 	core_reloc_mods_substruct_t g;
580 };
581 
582 typedef int int1_t;
583 typedef int1_t int2_t;
584 typedef int2_t int3_t;
585 
586 typedef int arr1_t[5];
587 typedef arr1_t arr2_t;
588 typedef arr2_t arr3_t;
589 typedef arr3_t arr4_t;
590 
591 typedef const char * const volatile fancy_char_ptr_t __bpf_aligned;
592 
593 typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt;
594 
595 /* we need more typedefs */
596 struct core_reloc_mods___typedefs {
597 	core_reloc_mods_substruct_tt g;
598 	core_reloc_mods_substruct_tt h;
599 	arr4_t f;
600 	arr4_t e;
601 	fancy_char_ptr_t d;
602 	fancy_char_ptr_t c;
603 	int3_t b __bpf_aligned;
604 	int3_t a;
605 };
606 
607 /*
608  * PTR_AS_ARR
609  */
610 struct core_reloc_ptr_as_arr {
611 	int a;
612 };
613 
614 struct core_reloc_ptr_as_arr___diff_sz {
615 	int :32; /* padding */
616 	char __some_more_padding;
617 	int a;
618 };
619 
620 /*
621  * INTS
622  */
623 struct core_reloc_ints {
624 	uint8_t		u8_field;
625 	int8_t		s8_field;
626 	uint16_t	u16_field;
627 	int16_t		s16_field;
628 	uint32_t	u32_field;
629 	int32_t		s32_field;
630 	uint64_t	u64_field;
631 	int64_t		s64_field;
632 };
633 
634 /* signed/unsigned types swap */
635 struct core_reloc_ints___reverse_sign {
636 	int8_t		u8_field;
637 	uint8_t		s8_field;
638 	int16_t		u16_field;
639 	uint16_t	s16_field;
640 	int32_t		u32_field;
641 	uint32_t	s32_field;
642 	int64_t		u64_field;
643 	uint64_t	s64_field;
644 };
645 
646 struct core_reloc_ints___bool {
647 	bool		u8_field; /* bool instead of uint8 */
648 	int8_t		s8_field;
649 	uint16_t	u16_field;
650 	int16_t		s16_field;
651 	uint32_t	u32_field;
652 	int32_t		s32_field;
653 	uint64_t	u64_field;
654 	int64_t		s64_field;
655 };
656 
657 /*
658  * MISC
659  */
660 struct core_reloc_misc_output {
661 	int a, b, c;
662 };
663 
664 struct core_reloc_misc___a {
665 	int a1;
666 	int a2;
667 };
668 
669 struct core_reloc_misc___b {
670 	int b1;
671 	int b2;
672 };
673 
674 /* this one extends core_reloc_misc_extensible struct from BPF prog */
675 struct core_reloc_misc_extensible {
676 	int a;
677 	int b;
678 	int c;
679 	int d;
680 };
681 
682 /*
683  * FIELD EXISTENCE
684  */
685 struct core_reloc_existence_output {
686 	int a_exists;
687 	int a_value;
688 	int b_exists;
689 	int b_value;
690 	int c_exists;
691 	int c_value;
692 	int arr_exists;
693 	int arr_value;
694 	int s_exists;
695 	int s_value;
696 };
697 
698 struct core_reloc_existence {
699 	int a;
700 	struct {
701 		int b;
702 	};
703 	int c;
704 	int arr[1];
705 	struct {
706 		int x;
707 	} s;
708 };
709 
710 struct core_reloc_existence___minimal {
711 	int a;
712 };
713 
714 struct core_reloc_existence___wrong_field_defs {
715 	void *a;
716 	int b[1];
717 	struct{ int x; } c;
718 	int arr;
719 	int s;
720 };
721 
722 /*
723  * BITFIELDS
724  */
725 /* bitfield read results, all as plain integers */
726 struct core_reloc_bitfields_output {
727 	int64_t		ub1;
728 	int64_t		ub2;
729 	int64_t		ub7;
730 	int64_t		sb4;
731 	int64_t		sb20;
732 	int64_t		u32;
733 	int64_t		s32;
734 };
735 
736 struct core_reloc_bitfields {
737 	/* unsigned bitfields */
738 	uint8_t		ub1: 1;
739 	uint8_t		ub2: 2;
740 	uint32_t	ub7: 7;
741 	/* signed bitfields */
742 	int8_t		sb4: 4;
743 	int32_t		sb20: 20;
744 	/* non-bitfields */
745 	uint32_t	u32;
746 	int32_t		s32;
747 };
748 
749 /* different bit sizes (both up and down) */
750 struct core_reloc_bitfields___bit_sz_change {
751 	/* unsigned bitfields */
752 	uint16_t	ub1: 3;		/*  1 ->  3 */
753 	uint32_t	ub2: 20;	/*  2 -> 20 */
754 	uint8_t		ub7: 1;		/*  7 ->  1 */
755 	/* signed bitfields */
756 	int8_t		sb4: 1;		/*  4 ->  1 */
757 	int32_t		sb20: 30;	/* 20 -> 30 */
758 	/* non-bitfields */
759 	uint16_t	u32;			/* 32 -> 16 */
760 	int64_t		s32 __bpf_aligned;	/* 32 -> 64 */
761 };
762 
763 /* turn bitfield into non-bitfield and vice versa */
764 struct core_reloc_bitfields___bitfield_vs_int {
765 	uint64_t	ub1;		/*  3 -> 64 non-bitfield */
766 	uint8_t		ub2;		/* 20 ->  8 non-bitfield */
767 	int64_t		ub7 __bpf_aligned;	/*  7 -> 64 non-bitfield signed */
768 	int64_t		sb4 __bpf_aligned;	/*  4 -> 64 non-bitfield signed */
769 	uint64_t	sb20 __bpf_aligned;	/* 20 -> 16 non-bitfield unsigned */
770 	int32_t		u32: 20;		/* 32 non-bitfield -> 20 bitfield */
771 	uint64_t	s32: 60 __bpf_aligned;	/* 32 non-bitfield -> 60 bitfield */
772 };
773 
774 struct core_reloc_bitfields___just_big_enough {
775 	uint64_t	ub1: 4;
776 	uint64_t	ub2: 60; /* 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 struct core_reloc_bitfields___err_too_big_bitfield {
785 	uint64_t	ub1: 4;
786 	uint64_t	ub2: 61; /* packed tightly */
787 	uint32_t	ub7;
788 	uint32_t	sb4;
789 	uint32_t	sb20;
790 	uint32_t	u32;
791 	uint32_t	s32;
792 } __attribute__((packed)) ;
793 
794 /*
795  * SIZE
796  */
797 struct core_reloc_size_output {
798 	int int_sz;
799 	int int_off;
800 	int struct_sz;
801 	int struct_off;
802 	int union_sz;
803 	int union_off;
804 	int arr_sz;
805 	int arr_off;
806 	int arr_elem_sz;
807 	int arr_elem_off;
808 	int ptr_sz;
809 	int ptr_off;
810 	int enum_sz;
811 	int enum_off;
812 	int float_sz;
813 	int float_off;
814 };
815 
816 struct core_reloc_size {
817 	int int_field;
818 	struct { int x; } struct_field;
819 	union { int x; } union_field;
820 	int arr_field[4];
821 	void *ptr_field;
822 	enum { VALUE = 123 } enum_field;
823 	float float_field;
824 };
825 
826 struct core_reloc_size___diff_sz {
827 	uint64_t int_field;
828 	struct { int x; int y; int z; } struct_field;
829 	union { int x; char bla[123]; } union_field;
830 	char arr_field[10];
831 	void *ptr_field;
832 	enum { OTHER_VALUE = 0xFFFFFFFFFFFFFFFF } enum_field;
833 	double float_field;
834 };
835 
836 struct core_reloc_size___diff_offs {
837 	float float_field;
838 	enum { YET_OTHER_VALUE = 123 } enum_field;
839 	void *ptr_field;
840 	int arr_field[4];
841 	union { int x; } union_field;
842 	struct { int x; } struct_field;
843 	int int_field;
844 };
845 
846 /* Error case of two candidates with the fields (int_field) at the same
847  * offset, but with differing final relocation values: size 4 vs size 1
848  */
849 struct core_reloc_size___err_ambiguous1 {
850 	/* int at offset 0 */
851 	int int_field;
852 
853 	struct { int x; } struct_field;
854 	union { int x; } union_field;
855 	int arr_field[4];
856 	void *ptr_field;
857 	enum { VALUE___1 = 123 } enum_field;
858 	float float_field;
859 };
860 
861 struct core_reloc_size___err_ambiguous2 {
862 	/* char at offset 0 */
863 	char int_field;
864 
865 	struct { int x; } struct_field;
866 	union { int x; } union_field;
867 	int arr_field[4];
868 	void *ptr_field;
869 	enum { VALUE___2 = 123 } enum_field;
870 	float float_field;
871 };
872 
873 /*
874  * TYPE EXISTENCE, MATCH & SIZE
875  */
876 struct core_reloc_type_based_output {
877 	bool struct_exists;
878 	bool complex_struct_exists;
879 	bool union_exists;
880 	bool enum_exists;
881 	bool typedef_named_struct_exists;
882 	bool typedef_anon_struct_exists;
883 	bool typedef_struct_ptr_exists;
884 	bool typedef_int_exists;
885 	bool typedef_enum_exists;
886 	bool typedef_void_ptr_exists;
887 	bool typedef_restrict_ptr_exists;
888 	bool typedef_func_proto_exists;
889 	bool typedef_arr_exists;
890 
891 	bool struct_matches;
892 	bool complex_struct_matches;
893 	bool union_matches;
894 	bool enum_matches;
895 	bool typedef_named_struct_matches;
896 	bool typedef_anon_struct_matches;
897 	bool typedef_struct_ptr_matches;
898 	bool typedef_int_matches;
899 	bool typedef_enum_matches;
900 	bool typedef_void_ptr_matches;
901 	bool typedef_restrict_ptr_matches;
902 	bool typedef_func_proto_matches;
903 	bool typedef_arr_matches;
904 
905 	int struct_sz;
906 	int union_sz;
907 	int enum_sz;
908 	int typedef_named_struct_sz;
909 	int typedef_anon_struct_sz;
910 	int typedef_struct_ptr_sz;
911 	int typedef_int_sz;
912 	int typedef_enum_sz;
913 	int typedef_void_ptr_sz;
914 	int typedef_func_proto_sz;
915 	int typedef_arr_sz;
916 };
917 
918 struct a_struct {
919 	int x;
920 };
921 
922 struct a_complex_struct {
923 	union {
924 		struct a_struct * restrict a;
925 		void *b;
926 	} x;
927 	volatile long y;
928 };
929 
930 union a_union {
931 	int y;
932 	int z;
933 };
934 
935 typedef struct a_struct named_struct_typedef;
936 
937 typedef struct { int x, y, z; } anon_struct_typedef;
938 
939 typedef struct {
940 	int a, b, c;
941 } *struct_ptr_typedef;
942 
943 enum an_enum {
944 	AN_ENUM_VAL1 = 1,
945 	AN_ENUM_VAL2 = 2,
946 	AN_ENUM_VAL3 = 3,
947 };
948 
949 typedef int int_typedef;
950 
951 typedef enum { TYPEDEF_ENUM_VAL1, TYPEDEF_ENUM_VAL2 } enum_typedef;
952 
953 typedef void *void_ptr_typedef;
954 typedef int *restrict restrict_ptr_typedef;
955 
956 typedef int (*func_proto_typedef)(long);
957 
958 typedef char arr_typedef[20];
959 
960 struct core_reloc_type_based {
961 	struct a_struct f1;
962 	struct a_complex_struct f2;
963 	union a_union f3;
964 	enum an_enum f4;
965 	named_struct_typedef f5;
966 	anon_struct_typedef f6;
967 	struct_ptr_typedef f7;
968 	int_typedef f8;
969 	enum_typedef f9;
970 	void_ptr_typedef f10;
971 	restrict_ptr_typedef f11;
972 	func_proto_typedef f12;
973 	arr_typedef f13;
974 };
975 
976 /* no types in target */
977 struct core_reloc_type_based___all_missing {
978 };
979 
980 /* different member orders, enum variant values, signedness, etc */
981 struct a_struct___diff {
982 	int x;
983 	int a;
984 };
985 
986 struct a_struct___forward;
987 
988 struct a_complex_struct___diff {
989 	union {
990 		struct a_struct___forward *a;
991 		void *b;
992 	} x;
993 	volatile long y;
994 };
995 
996 union a_union___diff {
997 	int z;
998 	int y;
999 };
1000 
1001 typedef struct a_struct___diff named_struct_typedef___diff;
1002 
1003 typedef struct { int z, x, y; } anon_struct_typedef___diff;
1004 
1005 typedef struct {
1006 	int c;
1007 	int b;
1008 	int a;
1009 } *struct_ptr_typedef___diff;
1010 
1011 enum an_enum___diff {
1012 	AN_ENUM_VAL2___diff = 0,
1013 	AN_ENUM_VAL1___diff = 42,
1014 	AN_ENUM_VAL3___diff = 1,
1015 };
1016 
1017 typedef unsigned int int_typedef___diff;
1018 
1019 typedef enum { TYPEDEF_ENUM_VAL2___diff, TYPEDEF_ENUM_VAL1___diff = 50 } enum_typedef___diff;
1020 
1021 typedef const void *void_ptr_typedef___diff;
1022 
1023 typedef int_typedef___diff (*func_proto_typedef___diff)(long);
1024 
1025 typedef char arr_typedef___diff[3];
1026 
1027 struct core_reloc_type_based___diff {
1028 	struct a_struct___diff f1;
1029 	struct a_complex_struct___diff f2;
1030 	union a_union___diff f3;
1031 	enum an_enum___diff f4;
1032 	named_struct_typedef___diff f5;
1033 	anon_struct_typedef___diff f6;
1034 	struct_ptr_typedef___diff f7;
1035 	int_typedef___diff f8;
1036 	enum_typedef___diff f9;
1037 	void_ptr_typedef___diff f10;
1038 	func_proto_typedef___diff f11;
1039 	arr_typedef___diff f12;
1040 };
1041 
1042 /* different type sizes, extra modifiers, anon vs named enums, etc */
1043 struct a_struct___diff_sz {
1044 	long x;
1045 	int y;
1046 	char z;
1047 };
1048 
1049 union a_union___diff_sz {
1050 	char yy;
1051 	char zz;
1052 };
1053 
1054 typedef struct a_struct___diff_sz named_struct_typedef___diff_sz;
1055 
1056 typedef struct { long xx, yy, zzz; } anon_struct_typedef___diff_sz;
1057 
1058 typedef struct {
1059 	char aa[1], bb[2], cc[3];
1060 } *struct_ptr_typedef___diff_sz;
1061 
1062 enum an_enum___diff_sz {
1063 	AN_ENUM_VAL1___diff_sz = 0x123412341234,
1064 	AN_ENUM_VAL2___diff_sz = 2,
1065 };
1066 
1067 typedef unsigned long int_typedef___diff_sz;
1068 
1069 typedef enum an_enum___diff_sz enum_typedef___diff_sz;
1070 
1071 typedef const void * const void_ptr_typedef___diff_sz;
1072 
1073 typedef int_typedef___diff_sz (*func_proto_typedef___diff_sz)(char);
1074 
1075 typedef int arr_typedef___diff_sz[2];
1076 
1077 struct core_reloc_type_based___diff_sz {
1078 	struct a_struct___diff_sz f1;
1079 	union a_union___diff_sz f2;
1080 	enum an_enum___diff_sz f3;
1081 	named_struct_typedef___diff_sz f4;
1082 	anon_struct_typedef___diff_sz f5;
1083 	struct_ptr_typedef___diff_sz f6;
1084 	int_typedef___diff_sz f7;
1085 	enum_typedef___diff_sz f8;
1086 	void_ptr_typedef___diff_sz f9;
1087 	func_proto_typedef___diff_sz f10;
1088 	arr_typedef___diff_sz f11;
1089 };
1090 
1091 /* incompatibilities between target and local types */
1092 union a_struct___incompat { /* union instead of struct */
1093 	int x;
1094 };
1095 
1096 struct a_union___incompat { /* struct instead of union */
1097 	int y;
1098 	int z;
1099 };
1100 
1101 /* typedef to union, not to struct */
1102 typedef union a_struct___incompat named_struct_typedef___incompat;
1103 
1104 /* typedef to void pointer, instead of struct */
1105 typedef void *anon_struct_typedef___incompat;
1106 
1107 /* extra pointer indirection */
1108 typedef struct {
1109 	int a, b, c;
1110 } **struct_ptr_typedef___incompat;
1111 
1112 /* typedef of a struct with int, instead of int */
1113 typedef struct { int x; } int_typedef___incompat;
1114 
1115 /* typedef to func_proto, instead of enum */
1116 typedef int (*enum_typedef___incompat)(void);
1117 
1118 /* pointer to char instead of void */
1119 typedef char *void_ptr_typedef___incompat;
1120 
1121 /* void return type instead of int */
1122 typedef void (*func_proto_typedef___incompat)(long);
1123 
1124 /* multi-dimensional array instead of a single-dimensional */
1125 typedef int arr_typedef___incompat[20][2];
1126 
1127 struct core_reloc_type_based___incompat {
1128 	union a_struct___incompat f1;
1129 	struct a_union___incompat f2;
1130 	/* the only valid one is enum, to check that something still succeeds */
1131 	enum an_enum f3;
1132 	named_struct_typedef___incompat f4;
1133 	anon_struct_typedef___incompat f5;
1134 	struct_ptr_typedef___incompat f6;
1135 	int_typedef___incompat f7;
1136 	enum_typedef___incompat f8;
1137 	void_ptr_typedef___incompat f9;
1138 	func_proto_typedef___incompat f10;
1139 	arr_typedef___incompat f11;
1140 };
1141 
1142 /* func_proto with incompatible signature */
1143 typedef void (*func_proto_typedef___fn_wrong_ret1)(long);
1144 typedef int * (*func_proto_typedef___fn_wrong_ret2)(long);
1145 typedef struct { int x; } int_struct_typedef;
1146 typedef int_struct_typedef (*func_proto_typedef___fn_wrong_ret3)(long);
1147 typedef int (*func_proto_typedef___fn_wrong_arg)(void *);
1148 typedef int (*func_proto_typedef___fn_wrong_arg_cnt1)(long, long);
1149 typedef int (*func_proto_typedef___fn_wrong_arg_cnt2)(void);
1150 
1151 struct core_reloc_type_based___fn_wrong_args {
1152 	/* one valid type to make sure relos still work */
1153 	struct a_struct f1;
1154 	func_proto_typedef___fn_wrong_ret1 f2;
1155 	func_proto_typedef___fn_wrong_ret2 f3;
1156 	func_proto_typedef___fn_wrong_ret3 f4;
1157 	func_proto_typedef___fn_wrong_arg f5;
1158 	func_proto_typedef___fn_wrong_arg_cnt1 f6;
1159 	func_proto_typedef___fn_wrong_arg_cnt2 f7;
1160 };
1161 
1162 /*
1163  * TYPE ID MAPPING (LOCAL AND TARGET)
1164  */
1165 struct core_reloc_type_id_output {
1166 	int local_anon_struct;
1167 	int local_anon_union;
1168 	int local_anon_enum;
1169 	int local_anon_func_proto_ptr;
1170 	int local_anon_void_ptr;
1171 	int local_anon_arr;
1172 
1173 	int local_struct;
1174 	int local_union;
1175 	int local_enum;
1176 	int local_int;
1177 	int local_struct_typedef;
1178 	int local_func_proto_typedef;
1179 	int local_arr_typedef;
1180 
1181 	int targ_struct;
1182 	int targ_union;
1183 	int targ_enum;
1184 	int targ_int;
1185 	int targ_struct_typedef;
1186 	int targ_func_proto_typedef;
1187 	int targ_arr_typedef;
1188 };
1189 
1190 struct core_reloc_type_id {
1191 	struct a_struct f1;
1192 	union a_union f2;
1193 	enum an_enum f3;
1194 	named_struct_typedef f4;
1195 	func_proto_typedef f5;
1196 	arr_typedef f6;
1197 };
1198 
1199 struct core_reloc_type_id___missing_targets {
1200 	/* nothing */
1201 };
1202 
1203 /*
1204  * ENUMERATOR VALUE EXISTENCE AND VALUE RELOCATION
1205  */
1206 struct core_reloc_enumval_output {
1207 	bool named_val1_exists;
1208 	bool named_val2_exists;
1209 	bool named_val3_exists;
1210 	bool anon_val1_exists;
1211 	bool anon_val2_exists;
1212 	bool anon_val3_exists;
1213 
1214 	int named_val1;
1215 	int named_val2;
1216 	int anon_val1;
1217 	int anon_val2;
1218 };
1219 
1220 struct core_reloc_enum64val_output {
1221 	bool unsigned_val1_exists;
1222 	bool unsigned_val2_exists;
1223 	bool unsigned_val3_exists;
1224 	bool signed_val1_exists;
1225 	bool signed_val2_exists;
1226 	bool signed_val3_exists;
1227 
1228 	long unsigned_val1;
1229 	long unsigned_val2;
1230 	long signed_val1;
1231 	long signed_val2;
1232 };
1233 
1234 enum named_enum {
1235 	NAMED_ENUM_VAL1 = 1,
1236 	NAMED_ENUM_VAL2 = 2,
1237 	NAMED_ENUM_VAL3 = 3,
1238 };
1239 
1240 typedef enum {
1241 	ANON_ENUM_VAL1 = 0x10,
1242 	ANON_ENUM_VAL2 = 0x20,
1243 	ANON_ENUM_VAL3 = 0x30,
1244 } anon_enum;
1245 
1246 struct core_reloc_enumval {
1247 	enum named_enum f1;
1248 	anon_enum f2;
1249 };
1250 
1251 enum named_unsigned_enum64 {
1252 	UNSIGNED_ENUM64_VAL1 = 0x1ffffffffULL,
1253 	UNSIGNED_ENUM64_VAL2 = 0x2,
1254 	UNSIGNED_ENUM64_VAL3 = 0x3ffffffffULL,
1255 };
1256 
1257 enum named_signed_enum64 {
1258 	SIGNED_ENUM64_VAL1 = 0x1ffffffffLL,
1259 	SIGNED_ENUM64_VAL2 = -2,
1260 	SIGNED_ENUM64_VAL3 = 0x3ffffffffLL,
1261 };
1262 
1263 struct core_reloc_enum64val {
1264 	enum named_unsigned_enum64 f1;
1265 	enum named_signed_enum64 f2;
1266 };
1267 
1268 /* differing enumerator values */
1269 enum named_enum___diff {
1270 	NAMED_ENUM_VAL1___diff = 101,
1271 	NAMED_ENUM_VAL2___diff = 202,
1272 	NAMED_ENUM_VAL3___diff = 303,
1273 };
1274 
1275 typedef enum {
1276 	ANON_ENUM_VAL1___diff = 0x11,
1277 	ANON_ENUM_VAL2___diff = 0x22,
1278 	ANON_ENUM_VAL3___diff = 0x33,
1279 } anon_enum___diff;
1280 
1281 struct core_reloc_enumval___diff {
1282 	enum named_enum___diff f1;
1283 	anon_enum___diff f2;
1284 };
1285 
1286 enum named_unsigned_enum64___diff {
1287 	UNSIGNED_ENUM64_VAL1___diff = 0x101ffffffffULL,
1288 	UNSIGNED_ENUM64_VAL2___diff = 0x202ffffffffULL,
1289 	UNSIGNED_ENUM64_VAL3___diff = 0x303ffffffffULL,
1290 };
1291 
1292 enum named_signed_enum64___diff {
1293 	SIGNED_ENUM64_VAL1___diff = -101,
1294 	SIGNED_ENUM64_VAL2___diff = -202,
1295 	SIGNED_ENUM64_VAL3___diff = -303,
1296 };
1297 
1298 struct core_reloc_enum64val___diff {
1299 	enum named_unsigned_enum64___diff f1;
1300 	enum named_signed_enum64___diff f2;
1301 };
1302 
1303 /* missing (optional) third enum value */
1304 enum named_enum___val3_missing {
1305 	NAMED_ENUM_VAL1___val3_missing = 111,
1306 	NAMED_ENUM_VAL2___val3_missing = 222,
1307 };
1308 
1309 typedef enum {
1310 	ANON_ENUM_VAL1___val3_missing = 0x111,
1311 	ANON_ENUM_VAL2___val3_missing = 0x222,
1312 } anon_enum___val3_missing;
1313 
1314 struct core_reloc_enumval___val3_missing {
1315 	enum named_enum___val3_missing f1;
1316 	anon_enum___val3_missing f2;
1317 };
1318 
1319 enum named_unsigned_enum64___val3_missing {
1320 	UNSIGNED_ENUM64_VAL1___val3_missing = 0x111ffffffffULL,
1321 	UNSIGNED_ENUM64_VAL2___val3_missing = 0x222,
1322 };
1323 
1324 enum named_signed_enum64___val3_missing {
1325 	SIGNED_ENUM64_VAL1___val3_missing = 0x111ffffffffLL,
1326 	SIGNED_ENUM64_VAL2___val3_missing = -222,
1327 };
1328 
1329 struct core_reloc_enum64val___val3_missing {
1330 	enum named_unsigned_enum64___val3_missing f1;
1331 	enum named_signed_enum64___val3_missing f2;
1332 };
1333 
1334 /* missing (mandatory) second enum value, should fail */
1335 enum named_enum___err_missing {
1336 	NAMED_ENUM_VAL1___err_missing = 1,
1337 	NAMED_ENUM_VAL3___err_missing = 3,
1338 };
1339 
1340 typedef enum {
1341 	ANON_ENUM_VAL1___err_missing = 0x111,
1342 	ANON_ENUM_VAL3___err_missing = 0x222,
1343 } anon_enum___err_missing;
1344 
1345 struct core_reloc_enumval___err_missing {
1346 	enum named_enum___err_missing f1;
1347 	anon_enum___err_missing f2;
1348 };
1349 
1350 enum named_unsigned_enum64___err_missing {
1351 	UNSIGNED_ENUM64_VAL1___err_missing = 0x1ffffffffULL,
1352 	UNSIGNED_ENUM64_VAL3___err_missing = 0x3ffffffffULL,
1353 };
1354 
1355 enum named_signed_enum64___err_missing {
1356 	SIGNED_ENUM64_VAL1___err_missing = 0x1ffffffffLL,
1357 	SIGNED_ENUM64_VAL3___err_missing = -3,
1358 };
1359 
1360 struct core_reloc_enum64val___err_missing {
1361 	enum named_unsigned_enum64___err_missing f1;
1362 	enum named_signed_enum64___err_missing f2;
1363 };
1364