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