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