1#include <stdint.h>
2#include <stdbool.h>
3
4void preserce_ptr_sz_fn(long x) {}
5
6#define __bpf_aligned __attribute__((aligned(8)))
7
8/*
9 * KERNEL
10 */
11
12struct 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
23struct 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 */
39struct 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 */
46struct 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 */
56struct core_reloc_nesting_substruct {
57	int a;
58};
59
60union core_reloc_nesting_subunion {
61	int b;
62};
63
64struct 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 */
74struct 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 */
89struct 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 */
109struct 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 */
138struct 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
154struct 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
176struct 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 */
192struct 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 */
206struct 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 */
220struct 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 */
232struct 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 */
246struct 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 */
260struct 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
273struct 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 */
288struct core_reloc_nesting___err_partial_match_dups__a {
289	struct {
290		struct {
291			int a;
292		} a;
293	} a;
294};
295
296struct core_reloc_nesting___err_partial_match_dups__b {
297	struct {
298		struct {
299			int b;
300		} b;
301	} b;
302};
303
304struct 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 */
348struct core_reloc_arrays_output {
349	int a2;
350	char b123;
351	int c1c;
352	int d00d;
353	int f10c;
354};
355
356struct core_reloc_arrays_substruct {
357	int c;
358	int d;
359};
360
361struct 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 */
370struct 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) */
379struct 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
399struct 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
408struct 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
417struct 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
425struct 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
433struct 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
441struct 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
449struct 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 */
461enum core_reloc_primitives_enum {
462	A = 0,
463	B = 1,
464};
465
466struct 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
474struct 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
485struct 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
493struct 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
501struct 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
509struct 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
517struct 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 */
528struct core_reloc_mods_output {
529	int a, b, c, d, e, f, g, h;
530};
531
532typedef const int int_t;
533typedef const char *char_ptr_t __bpf_aligned;
534typedef const int arr_t[7];
535
536struct core_reloc_mods_substruct {
537	int x;
538	int y;
539};
540
541typedef struct {
542	int x;
543	int y;
544} core_reloc_mods_substruct_t;
545
546struct 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 */
558struct 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
572typedef int int1_t;
573typedef int1_t int2_t;
574typedef int2_t int3_t;
575
576typedef int arr1_t[5];
577typedef arr1_t arr2_t;
578typedef arr2_t arr3_t;
579typedef arr3_t arr4_t;
580
581typedef const char * const volatile fancy_char_ptr_t __bpf_aligned;
582
583typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt;
584
585/* we need more typedefs */
586struct 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 */
600struct core_reloc_ptr_as_arr {
601	int a;
602};
603
604struct 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 */
613struct 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 */
625struct 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
636struct 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 */
650struct core_reloc_misc_output {
651	int a, b, c;
652};
653
654struct core_reloc_misc___a {
655	int a1;
656	int a2;
657};
658
659struct core_reloc_misc___b {
660	int b1;
661	int b2;
662};
663
664/* this one extends core_reloc_misc_extensible struct from BPF prog */
665struct core_reloc_misc_extensible {
666	int a;
667	int b;
668	int c;
669	int d;
670};
671
672/*
673 * FIELD EXISTENCE
674 */
675struct 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
688struct 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
700struct core_reloc_existence___minimal {
701	int a;
702};
703
704struct 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 */
716struct 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
726struct 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) */
740struct 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 */
754struct 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
764struct 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
774struct 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 */
787struct 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
806struct 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
816struct 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
826struct 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 */
839struct 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
851struct 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 */
866struct 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
908struct a_struct {
909	int x;
910};
911
912struct a_complex_struct {
913	union {
914		struct a_struct * restrict a;
915		void *b;
916	} x;
917	volatile long y;
918};
919
920union a_union {
921	int y;
922	int z;
923};
924
925typedef struct a_struct named_struct_typedef;
926
927typedef struct { int x, y, z; } anon_struct_typedef;
928
929typedef struct {
930	int a, b, c;
931} *struct_ptr_typedef;
932
933enum an_enum {
934	AN_ENUM_VAL1 = 1,
935	AN_ENUM_VAL2 = 2,
936	AN_ENUM_VAL3 = 3,
937};
938
939typedef int int_typedef;
940
941typedef enum { TYPEDEF_ENUM_VAL1, TYPEDEF_ENUM_VAL2 } enum_typedef;
942
943typedef void *void_ptr_typedef;
944typedef int *restrict restrict_ptr_typedef;
945
946typedef int (*func_proto_typedef)(long);
947
948typedef char arr_typedef[20];
949
950struct 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 */
967struct core_reloc_type_based___all_missing {
968};
969
970/* different member orders, enum variant values, signedness, etc */
971struct a_struct___diff {
972	int x;
973	int a;
974};
975
976struct a_struct___forward;
977
978struct a_complex_struct___diff {
979	union {
980		struct a_struct___forward *a;
981		void *b;
982	} x;
983	volatile long y;
984};
985
986union a_union___diff {
987	int z;
988	int y;
989};
990
991typedef struct a_struct___diff named_struct_typedef___diff;
992
993typedef struct { int z, x, y; } anon_struct_typedef___diff;
994
995typedef struct {
996	int c;
997	int b;
998	int a;
999} *struct_ptr_typedef___diff;
1000
1001enum an_enum___diff {
1002	AN_ENUM_VAL2___diff = 0,
1003	AN_ENUM_VAL1___diff = 42,
1004	AN_ENUM_VAL3___diff = 1,
1005};
1006
1007typedef unsigned int int_typedef___diff;
1008
1009typedef enum { TYPEDEF_ENUM_VAL2___diff, TYPEDEF_ENUM_VAL1___diff = 50 } enum_typedef___diff;
1010
1011typedef const void *void_ptr_typedef___diff;
1012
1013typedef int_typedef___diff (*func_proto_typedef___diff)(long);
1014
1015typedef char arr_typedef___diff[3];
1016
1017struct 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 */
1033struct a_struct___diff_sz {
1034	long x;
1035	int y;
1036	char z;
1037};
1038
1039union a_union___diff_sz {
1040	char yy;
1041	char zz;
1042};
1043
1044typedef struct a_struct___diff_sz named_struct_typedef___diff_sz;
1045
1046typedef struct { long xx, yy, zzz; } anon_struct_typedef___diff_sz;
1047
1048typedef struct {
1049	char aa[1], bb[2], cc[3];
1050} *struct_ptr_typedef___diff_sz;
1051
1052enum an_enum___diff_sz {
1053	AN_ENUM_VAL1___diff_sz = 0x123412341234,
1054	AN_ENUM_VAL2___diff_sz = 2,
1055};
1056
1057typedef unsigned long int_typedef___diff_sz;
1058
1059typedef enum an_enum___diff_sz enum_typedef___diff_sz;
1060
1061typedef const void * const void_ptr_typedef___diff_sz;
1062
1063typedef int_typedef___diff_sz (*func_proto_typedef___diff_sz)(char);
1064
1065typedef int arr_typedef___diff_sz[2];
1066
1067struct 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 */
1082union a_struct___incompat { /* union instead of struct */
1083	int x;
1084};
1085
1086struct a_union___incompat { /* struct instead of union */
1087	int y;
1088	int z;
1089};
1090
1091/* typedef to union, not to struct */
1092typedef union a_struct___incompat named_struct_typedef___incompat;
1093
1094/* typedef to void pointer, instead of struct */
1095typedef void *anon_struct_typedef___incompat;
1096
1097/* extra pointer indirection */
1098typedef struct {
1099	int a, b, c;
1100} **struct_ptr_typedef___incompat;
1101
1102/* typedef of a struct with int, instead of int */
1103typedef struct { int x; } int_typedef___incompat;
1104
1105/* typedef to func_proto, instead of enum */
1106typedef int (*enum_typedef___incompat)(void);
1107
1108/* pointer to char instead of void */
1109typedef char *void_ptr_typedef___incompat;
1110
1111/* void return type instead of int */
1112typedef void (*func_proto_typedef___incompat)(long);
1113
1114/* multi-dimensional array instead of a single-dimensional */
1115typedef int arr_typedef___incompat[20][2];
1116
1117struct 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 */
1133typedef void (*func_proto_typedef___fn_wrong_ret1)(long);
1134typedef int * (*func_proto_typedef___fn_wrong_ret2)(long);
1135typedef struct { int x; } int_struct_typedef;
1136typedef int_struct_typedef (*func_proto_typedef___fn_wrong_ret3)(long);
1137typedef int (*func_proto_typedef___fn_wrong_arg)(void *);
1138typedef int (*func_proto_typedef___fn_wrong_arg_cnt1)(long, long);
1139typedef int (*func_proto_typedef___fn_wrong_arg_cnt2)(void);
1140
1141struct 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 */
1155struct 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
1180struct 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
1189struct core_reloc_type_id___missing_targets {
1190	/* nothing */
1191};
1192
1193/*
1194 * ENUMERATOR VALUE EXISTENCE AND VALUE RELOCATION
1195 */
1196struct 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
1210struct 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
1224enum named_enum {
1225	NAMED_ENUM_VAL1 = 1,
1226	NAMED_ENUM_VAL2 = 2,
1227	NAMED_ENUM_VAL3 = 3,
1228};
1229
1230typedef enum {
1231	ANON_ENUM_VAL1 = 0x10,
1232	ANON_ENUM_VAL2 = 0x20,
1233	ANON_ENUM_VAL3 = 0x30,
1234} anon_enum;
1235
1236struct core_reloc_enumval {
1237	enum named_enum f1;
1238	anon_enum f2;
1239};
1240
1241enum named_unsigned_enum64 {
1242	UNSIGNED_ENUM64_VAL1 = 0x1ffffffffULL,
1243	UNSIGNED_ENUM64_VAL2 = 0x2,
1244	UNSIGNED_ENUM64_VAL3 = 0x3ffffffffULL,
1245};
1246
1247enum named_signed_enum64 {
1248	SIGNED_ENUM64_VAL1 = 0x1ffffffffLL,
1249	SIGNED_ENUM64_VAL2 = -2,
1250	SIGNED_ENUM64_VAL3 = 0x3ffffffffLL,
1251};
1252
1253struct core_reloc_enum64val {
1254	enum named_unsigned_enum64 f1;
1255	enum named_signed_enum64 f2;
1256};
1257
1258/* differing enumerator values */
1259enum named_enum___diff {
1260	NAMED_ENUM_VAL1___diff = 101,
1261	NAMED_ENUM_VAL2___diff = 202,
1262	NAMED_ENUM_VAL3___diff = 303,
1263};
1264
1265typedef enum {
1266	ANON_ENUM_VAL1___diff = 0x11,
1267	ANON_ENUM_VAL2___diff = 0x22,
1268	ANON_ENUM_VAL3___diff = 0x33,
1269} anon_enum___diff;
1270
1271struct core_reloc_enumval___diff {
1272	enum named_enum___diff f1;
1273	anon_enum___diff f2;
1274};
1275
1276enum named_unsigned_enum64___diff {
1277	UNSIGNED_ENUM64_VAL1___diff = 0x101ffffffffULL,
1278	UNSIGNED_ENUM64_VAL2___diff = 0x202ffffffffULL,
1279	UNSIGNED_ENUM64_VAL3___diff = 0x303ffffffffULL,
1280};
1281
1282enum named_signed_enum64___diff {
1283	SIGNED_ENUM64_VAL1___diff = -101,
1284	SIGNED_ENUM64_VAL2___diff = -202,
1285	SIGNED_ENUM64_VAL3___diff = -303,
1286};
1287
1288struct 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 */
1294enum named_enum___val3_missing {
1295	NAMED_ENUM_VAL1___val3_missing = 111,
1296	NAMED_ENUM_VAL2___val3_missing = 222,
1297};
1298
1299typedef enum {
1300	ANON_ENUM_VAL1___val3_missing = 0x111,
1301	ANON_ENUM_VAL2___val3_missing = 0x222,
1302} anon_enum___val3_missing;
1303
1304struct core_reloc_enumval___val3_missing {
1305	enum named_enum___val3_missing f1;
1306	anon_enum___val3_missing f2;
1307};
1308
1309enum named_unsigned_enum64___val3_missing {
1310	UNSIGNED_ENUM64_VAL1___val3_missing = 0x111ffffffffULL,
1311	UNSIGNED_ENUM64_VAL2___val3_missing = 0x222,
1312};
1313
1314enum named_signed_enum64___val3_missing {
1315	SIGNED_ENUM64_VAL1___val3_missing = 0x111ffffffffLL,
1316	SIGNED_ENUM64_VAL2___val3_missing = -222,
1317};
1318
1319struct 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 */
1325enum named_enum___err_missing {
1326	NAMED_ENUM_VAL1___err_missing = 1,
1327	NAMED_ENUM_VAL3___err_missing = 3,
1328};
1329
1330typedef enum {
1331	ANON_ENUM_VAL1___err_missing = 0x111,
1332	ANON_ENUM_VAL3___err_missing = 0x222,
1333} anon_enum___err_missing;
1334
1335struct core_reloc_enumval___err_missing {
1336	enum named_enum___err_missing f1;
1337	anon_enum___err_missing f2;
1338};
1339
1340enum named_unsigned_enum64___err_missing {
1341	UNSIGNED_ENUM64_VAL1___err_missing = 0x1ffffffffULL,
1342	UNSIGNED_ENUM64_VAL3___err_missing = 0x3ffffffffULL,
1343};
1344
1345enum named_signed_enum64___err_missing {
1346	SIGNED_ENUM64_VAL1___err_missing = 0x1ffffffffLL,
1347	SIGNED_ENUM64_VAL3___err_missing = -3,
1348};
1349
1350struct core_reloc_enum64val___err_missing {
1351	enum named_unsigned_enum64___err_missing f1;
1352	enum named_signed_enum64___err_missing f2;
1353};
1354