#include #include void preserce_ptr_sz_fn(long x) {} #define __bpf_aligned __attribute__((aligned(8))) /* * KERNEL */ struct core_reloc_kernel_output { int valid[10]; char comm[sizeof("test_progs")]; int comm_len; bool local_task_struct_matches; }; /* * MODULE */ struct core_reloc_module_output { long long len; long long off; int read_ctx_sz; bool read_ctx_exists; bool buf_exists; bool len_exists; bool off_exists; /* we have test_progs[-flavor], so cut flavor part */ char comm[sizeof("test_progs")]; int comm_len; }; /* * FLAVORS */ struct core_reloc_flavors { int a; int b; int c; }; /* this is not a flavor, as it doesn't have triple underscore */ struct core_reloc_flavors__err_wrong_name { int a; int b; int c; }; /* * NESTING */ /* original set up, used to record relocations in BPF program */ struct core_reloc_nesting_substruct { int a; }; union core_reloc_nesting_subunion { int b; }; struct core_reloc_nesting { union { struct core_reloc_nesting_substruct a; } a; struct { union core_reloc_nesting_subunion b; } b; }; /* inlined anonymous struct/union instead of named structs in original */ struct core_reloc_nesting___anon_embed { int __just_for_padding; union { struct { int a; } a; } a; struct { union { int b; } b; } b; }; /* different mix of nested structs/unions than in original */ struct core_reloc_nesting___struct_union_mixup { int __a; struct { int __a; union { char __a; int a; } a; } a; int __b; union { int __b; union { char __b; int b; } b; } b; }; /* extra anon structs/unions, but still valid a.a.a and b.b.b accessors */ struct core_reloc_nesting___extra_nesting { int __padding; struct { struct { struct { struct { union { int a; } a; }; }; } a; int __some_more; struct { union { union { union { struct { int b; }; } b; }; } b; }; }; }; /* three flavors of same struct with different structure but same layout for * a.a.a and b.b.b, thus successfully resolved and relocatable */ struct core_reloc_nesting___dup_compat_types { char __just_for_padding; /* 3 more bytes of padding */ struct { struct { int a; /* offset 4 */ } a; } a; long long __more_padding; struct { struct { int b; /* offset 16 */ } b; } b; }; struct core_reloc_nesting___dup_compat_types__2 { int __aligned_padding; struct { int __trickier_noop[0]; struct { char __some_more_noops[0]; int a; /* offset 4 */ } a; } a; int __more_padding; struct { struct { struct { int __critical_padding; int b; /* offset 16 */ } b; int __does_not_matter; }; } b; int __more_irrelevant_stuff; }; struct core_reloc_nesting___dup_compat_types__3 { char __correct_padding[4]; struct { struct { int a; /* offset 4 */ } a; } a; /* 8 byte padding due to next struct's alignment */ struct { struct { int b; } b; } b __attribute__((aligned(16))); }; /* b.b.b field is missing */ struct core_reloc_nesting___err_missing_field { struct { struct { int a; } a; } a; struct { struct { int x; } b; } b; }; /* b.b.b field is an array of integers instead of plain int */ struct core_reloc_nesting___err_array_field { struct { struct { int a; } a; } a; struct { struct { int b[1]; } b; } b; }; /* middle b container is missing */ struct core_reloc_nesting___err_missing_container { struct { struct { int a; } a; } a; struct { int x; } b; }; /* middle b container is referenced through pointer instead of being embedded */ struct core_reloc_nesting___err_nonstruct_container { struct { struct { int a; } a; } a; struct { struct { int b; } *b; } b; }; /* middle b container is an array of structs instead of plain struct */ struct core_reloc_nesting___err_array_container { struct { struct { int a; } a; } a; struct { struct { int b; } b[1]; } b; }; /* two flavors of same struct with incompatible layout for b.b.b */ struct core_reloc_nesting___err_dup_incompat_types__1 { struct { struct { int a; /* offset 0 */ } a; } a; struct { struct { int b; /* offset 4 */ } b; } b; }; struct core_reloc_nesting___err_dup_incompat_types__2 { struct { struct { int a; /* offset 0 */ } a; } a; int __extra_padding; struct { struct { int b; /* offset 8 (!) */ } b; } b; }; /* two flavors of same struct having one of a.a.a and b.b.b, but not both */ struct core_reloc_nesting___err_partial_match_dups__a { struct { struct { int a; } a; } a; }; struct core_reloc_nesting___err_partial_match_dups__b { struct { struct { int b; } b; } b; }; struct core_reloc_nesting___err_too_deep { struct { struct { int a; } a; } a; /* 65 levels of nestedness for b.b.b */ struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { struct { /* this one is one too much */ struct { int b; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; } b; } b; }; /* * ARRAYS */ struct core_reloc_arrays_output { int a2; char b123; int c1c; int d00d; int f10c; }; struct core_reloc_arrays_substruct { int c; int d; }; struct core_reloc_arrays { int a[5]; char b[2][3][4]; struct core_reloc_arrays_substruct c[3]; struct core_reloc_arrays_substruct d[1][2]; struct core_reloc_arrays_substruct f[][2]; }; /* bigger array dimensions */ struct core_reloc_arrays___diff_arr_dim { int a[7]; char b[3][4][5]; struct core_reloc_arrays_substruct c[4]; struct core_reloc_arrays_substruct d[2][3]; struct core_reloc_arrays_substruct f[1][3]; }; /* different size of array's value (struct) */ struct core_reloc_arrays___diff_arr_val_sz { int a[5]; char b[2][3][4]; struct { int __padding1; int c; int __padding2; } c[3]; struct { int __padding1; int d; int __padding2; } d[1][2]; struct { int __padding1; int c; int __padding2; } f[][2]; }; struct core_reloc_arrays___equiv_zero_sz_arr { int a[5]; char b[2][3][4]; struct core_reloc_arrays_substruct c[3]; struct core_reloc_arrays_substruct d[1][2]; /* equivalent to flexible array */ struct core_reloc_arrays_substruct f[][2]; }; struct core_reloc_arrays___fixed_arr { int a[5]; char b[2][3][4]; struct core_reloc_arrays_substruct c[3]; struct core_reloc_arrays_substruct d[1][2]; /* not a flexible array anymore, but within access bounds */ struct core_reloc_arrays_substruct f[1][2]; }; struct core_reloc_arrays___err_too_small { int a[2]; /* this one is too small */ char b[2][3][4]; struct core_reloc_arrays_substruct c[3]; struct core_reloc_arrays_substruct d[1][2]; struct core_reloc_arrays_substruct f[][2]; }; struct core_reloc_arrays___err_too_shallow { int a[5]; char b[2][3]; /* this one lacks one dimension */ struct core_reloc_arrays_substruct c[3]; struct core_reloc_arrays_substruct d[1][2]; struct core_reloc_arrays_substruct f[][2]; }; struct core_reloc_arrays___err_non_array { int a; /* not an array */ char b[2][3][4]; struct core_reloc_arrays_substruct c[3]; struct core_reloc_arrays_substruct d[1][2]; struct core_reloc_arrays_substruct f[][2]; }; struct core_reloc_arrays___err_wrong_val_type { int a[5]; char b[2][3][4]; int c[3]; /* value is not a struct */ struct core_reloc_arrays_substruct d[1][2]; struct core_reloc_arrays_substruct f[][2]; }; struct core_reloc_arrays___err_bad_zero_sz_arr { /* zero-sized array, but not at the end */ struct core_reloc_arrays_substruct f[0][2]; int a[5]; char b[2][3][4]; struct core_reloc_arrays_substruct c[3]; struct core_reloc_arrays_substruct d[1][2]; }; /* * PRIMITIVES */ enum core_reloc_primitives_enum { A = 0, B = 1, }; struct core_reloc_primitives { char a; int b; enum core_reloc_primitives_enum c; void *d __bpf_aligned; int (*f)(const char *) __bpf_aligned; }; struct core_reloc_primitives___diff_enum_def { char a; int b; void *d __bpf_aligned; int (*f)(const char *) __bpf_aligned; enum { X = 100, Y = 200, } c __bpf_aligned; /* inline enum def with differing set of values */ }; struct core_reloc_primitives___diff_func_proto { void (*f)(int) __bpf_aligned; /* incompatible function prototype */ void *d __bpf_aligned; enum core_reloc_primitives_enum c __bpf_aligned; int b; char a; }; struct core_reloc_primitives___diff_ptr_type { const char * const d __bpf_aligned; /* different pointee type + modifiers */ char a __bpf_aligned; int b; enum core_reloc_primitives_enum c; int (*f)(const char *) __bpf_aligned; }; struct core_reloc_primitives___err_non_enum { char a[1]; int b; int c; /* int instead of enum */ void *d __bpf_aligned; int (*f)(const char *) __bpf_aligned; }; struct core_reloc_primitives___err_non_int { char a[1]; int *b __bpf_aligned; /* ptr instead of int */ enum core_reloc_primitives_enum c __bpf_aligned; void *d __bpf_aligned; int (*f)(const char *) __bpf_aligned; }; struct core_reloc_primitives___err_non_ptr { char a[1]; int b; enum core_reloc_primitives_enum c; int d; /* int instead of ptr */ int (*f)(const char *) __bpf_aligned; }; /* * MODS */ struct core_reloc_mods_output { int a, b, c, d, e, f, g, h; }; typedef const int int_t; typedef const char *char_ptr_t __bpf_aligned; typedef const int arr_t[7]; struct core_reloc_mods_substruct { int x; int y; }; typedef struct { int x; int y; } core_reloc_mods_substruct_t; struct core_reloc_mods { int a; int_t b; char *c __bpf_aligned; char_ptr_t d; int e[3] __bpf_aligned; arr_t f; struct core_reloc_mods_substruct g; core_reloc_mods_substruct_t h; }; /* a/b, c/d, e/f, and g/h pairs are swapped */ struct core_reloc_mods___mod_swap { int b; int_t a; char *d __bpf_aligned; char_ptr_t c; int f[3] __bpf_aligned; arr_t e; struct { int y; int x; } h; core_reloc_mods_substruct_t g; }; typedef int int1_t; typedef int1_t int2_t; typedef int2_t int3_t; typedef int arr1_t[5]; typedef arr1_t arr2_t; typedef arr2_t arr3_t; typedef arr3_t arr4_t; typedef const char * const volatile fancy_char_ptr_t __bpf_aligned; typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt; /* we need more typedefs */ struct core_reloc_mods___typedefs { core_reloc_mods_substruct_tt g; core_reloc_mods_substruct_tt h; arr4_t f; arr4_t e; fancy_char_ptr_t d; fancy_char_ptr_t c; int3_t b __bpf_aligned; int3_t a; }; /* * PTR_AS_ARR */ struct core_reloc_ptr_as_arr { int a; }; struct core_reloc_ptr_as_arr___diff_sz { int :32; /* padding */ char __some_more_padding; int a; }; /* * INTS */ struct core_reloc_ints { uint8_t u8_field; int8_t s8_field; uint16_t u16_field; int16_t s16_field; uint32_t u32_field; int32_t s32_field; uint64_t u64_field; int64_t s64_field; }; /* signed/unsigned types swap */ struct core_reloc_ints___reverse_sign { int8_t u8_field; uint8_t s8_field; int16_t u16_field; uint16_t s16_field; int32_t u32_field; uint32_t s32_field; int64_t u64_field; uint64_t s64_field; }; struct core_reloc_ints___bool { bool u8_field; /* bool instead of uint8 */ int8_t s8_field; uint16_t u16_field; int16_t s16_field; uint32_t u32_field; int32_t s32_field; uint64_t u64_field; int64_t s64_field; }; /* * MISC */ struct core_reloc_misc_output { int a, b, c; }; struct core_reloc_misc___a { int a1; int a2; }; struct core_reloc_misc___b { int b1; int b2; }; /* this one extends core_reloc_misc_extensible struct from BPF prog */ struct core_reloc_misc_extensible { int a; int b; int c; int d; }; /* * FIELD EXISTENCE */ struct core_reloc_existence_output { int a_exists; int a_value; int b_exists; int b_value; int c_exists; int c_value; int arr_exists; int arr_value; int s_exists; int s_value; }; struct core_reloc_existence { int a; struct { int b; }; int c; int arr[1]; struct { int x; } s; }; struct core_reloc_existence___minimal { int a; }; struct core_reloc_existence___wrong_field_defs { void *a; int b[1]; struct{ int x; } c; int arr; int s; }; /* * BITFIELDS */ /* bitfield read results, all as plain integers */ struct core_reloc_bitfields_output { int64_t ub1; int64_t ub2; int64_t ub7; int64_t sb4; int64_t sb20; int64_t u32; int64_t s32; }; struct core_reloc_bitfields { /* unsigned bitfields */ uint8_t ub1: 1; uint8_t ub2: 2; uint32_t ub7: 7; /* signed bitfields */ int8_t sb4: 4; int32_t sb20: 20; /* non-bitfields */ uint32_t u32; int32_t s32; }; /* different bit sizes (both up and down) */ struct core_reloc_bitfields___bit_sz_change { /* unsigned bitfields */ uint16_t ub1: 3; /* 1 -> 3 */ uint32_t ub2: 20; /* 2 -> 20 */ uint8_t ub7: 1; /* 7 -> 1 */ /* signed bitfields */ int8_t sb4: 1; /* 4 -> 1 */ int32_t sb20: 30; /* 20 -> 30 */ /* non-bitfields */ uint16_t u32; /* 32 -> 16 */ int64_t s32 __bpf_aligned; /* 32 -> 64 */ }; /* turn bitfield into non-bitfield and vice versa */ struct core_reloc_bitfields___bitfield_vs_int { uint64_t ub1; /* 3 -> 64 non-bitfield */ uint8_t ub2; /* 20 -> 8 non-bitfield */ int64_t ub7 __bpf_aligned; /* 7 -> 64 non-bitfield signed */ int64_t sb4 __bpf_aligned; /* 4 -> 64 non-bitfield signed */ uint64_t sb20 __bpf_aligned; /* 20 -> 16 non-bitfield unsigned */ int32_t u32: 20; /* 32 non-bitfield -> 20 bitfield */ uint64_t s32: 60 __bpf_aligned; /* 32 non-bitfield -> 60 bitfield */ }; struct core_reloc_bitfields___just_big_enough { uint64_t ub1: 4; uint64_t ub2: 60; /* packed tightly */ uint32_t ub7; uint32_t sb4; uint32_t sb20; uint32_t u32; uint32_t s32; } __attribute__((packed)) ; struct core_reloc_bitfields___err_too_big_bitfield { uint64_t ub1: 4; uint64_t ub2: 61; /* packed tightly */ uint32_t ub7; uint32_t sb4; uint32_t sb20; uint32_t u32; uint32_t s32; } __attribute__((packed)) ; /* * SIZE */ struct core_reloc_size_output { int int_sz; int int_off; int struct_sz; int struct_off; int union_sz; int union_off; int arr_sz; int arr_off; int arr_elem_sz; int arr_elem_off; int ptr_sz; int ptr_off; int enum_sz; int enum_off; int float_sz; int float_off; }; struct core_reloc_size { int int_field; struct { int x; } struct_field; union { int x; } union_field; int arr_field[4]; void *ptr_field; enum { VALUE = 123 } enum_field; float float_field; }; struct core_reloc_size___diff_sz { uint64_t int_field; struct { int x; int y; int z; } struct_field; union { int x; char bla[123]; } union_field; char arr_field[10]; void *ptr_field; enum { OTHER_VALUE = 0xFFFFFFFFFFFFFFFF } enum_field; double float_field; }; struct core_reloc_size___diff_offs { float float_field; enum { YET_OTHER_VALUE = 123 } enum_field; void *ptr_field; int arr_field[4]; union { int x; } union_field; struct { int x; } struct_field; int int_field; }; /* Error case of two candidates with the fields (int_field) at the same * offset, but with differing final relocation values: size 4 vs size 1 */ struct core_reloc_size___err_ambiguous1 { /* int at offset 0 */ int int_field; struct { int x; } struct_field; union { int x; } union_field; int arr_field[4]; void *ptr_field; enum { VALUE___1 = 123 } enum_field; float float_field; }; struct core_reloc_size___err_ambiguous2 { /* char at offset 0 */ char int_field; struct { int x; } struct_field; union { int x; } union_field; int arr_field[4]; void *ptr_field; enum { VALUE___2 = 123 } enum_field; float float_field; }; /* * TYPE EXISTENCE, MATCH & SIZE */ struct core_reloc_type_based_output { bool struct_exists; bool complex_struct_exists; bool union_exists; bool enum_exists; bool typedef_named_struct_exists; bool typedef_anon_struct_exists; bool typedef_struct_ptr_exists; bool typedef_int_exists; bool typedef_enum_exists; bool typedef_void_ptr_exists; bool typedef_restrict_ptr_exists; bool typedef_func_proto_exists; bool typedef_arr_exists; bool struct_matches; bool complex_struct_matches; bool union_matches; bool enum_matches; bool typedef_named_struct_matches; bool typedef_anon_struct_matches; bool typedef_struct_ptr_matches; bool typedef_int_matches; bool typedef_enum_matches; bool typedef_void_ptr_matches; bool typedef_restrict_ptr_matches; bool typedef_func_proto_matches; bool typedef_arr_matches; int struct_sz; int union_sz; int enum_sz; int typedef_named_struct_sz; int typedef_anon_struct_sz; int typedef_struct_ptr_sz; int typedef_int_sz; int typedef_enum_sz; int typedef_void_ptr_sz; int typedef_func_proto_sz; int typedef_arr_sz; }; struct a_struct { int x; }; struct a_complex_struct { union { struct a_struct * restrict a; void *b; } x; volatile long y; }; union a_union { int y; int z; }; typedef struct a_struct named_struct_typedef; typedef struct { int x, y, z; } anon_struct_typedef; typedef struct { int a, b, c; } *struct_ptr_typedef; enum an_enum { AN_ENUM_VAL1 = 1, AN_ENUM_VAL2 = 2, AN_ENUM_VAL3 = 3, }; typedef int int_typedef; typedef enum { TYPEDEF_ENUM_VAL1, TYPEDEF_ENUM_VAL2 } enum_typedef; typedef void *void_ptr_typedef; typedef int *restrict restrict_ptr_typedef; typedef int (*func_proto_typedef)(long); typedef char arr_typedef[20]; struct core_reloc_type_based { struct a_struct f1; struct a_complex_struct f2; union a_union f3; enum an_enum f4; named_struct_typedef f5; anon_struct_typedef f6; struct_ptr_typedef f7; int_typedef f8; enum_typedef f9; void_ptr_typedef f10; restrict_ptr_typedef f11; func_proto_typedef f12; arr_typedef f13; }; /* no types in target */ struct core_reloc_type_based___all_missing { }; /* different member orders, enum variant values, signedness, etc */ struct a_struct___diff { int x; int a; }; struct a_struct___forward; struct a_complex_struct___diff { union { struct a_struct___forward *a; void *b; } x; volatile long y; }; union a_union___diff { int z; int y; }; typedef struct a_struct___diff named_struct_typedef___diff; typedef struct { int z, x, y; } anon_struct_typedef___diff; typedef struct { int c; int b; int a; } *struct_ptr_typedef___diff; enum an_enum___diff { AN_ENUM_VAL2___diff = 0, AN_ENUM_VAL1___diff = 42, AN_ENUM_VAL3___diff = 1, }; typedef unsigned int int_typedef___diff; typedef enum { TYPEDEF_ENUM_VAL2___diff, TYPEDEF_ENUM_VAL1___diff = 50 } enum_typedef___diff; typedef const void *void_ptr_typedef___diff; typedef int_typedef___diff (*func_proto_typedef___diff)(long); typedef char arr_typedef___diff[3]; struct core_reloc_type_based___diff { struct a_struct___diff f1; struct a_complex_struct___diff f2; union a_union___diff f3; enum an_enum___diff f4; named_struct_typedef___diff f5; anon_struct_typedef___diff f6; struct_ptr_typedef___diff f7; int_typedef___diff f8; enum_typedef___diff f9; void_ptr_typedef___diff f10; func_proto_typedef___diff f11; arr_typedef___diff f12; }; /* different type sizes, extra modifiers, anon vs named enums, etc */ struct a_struct___diff_sz { long x; int y; char z; }; union a_union___diff_sz { char yy; char zz; }; typedef struct a_struct___diff_sz named_struct_typedef___diff_sz; typedef struct { long xx, yy, zzz; } anon_struct_typedef___diff_sz; typedef struct { char aa[1], bb[2], cc[3]; } *struct_ptr_typedef___diff_sz; enum an_enum___diff_sz { AN_ENUM_VAL1___diff_sz = 0x123412341234, AN_ENUM_VAL2___diff_sz = 2, }; typedef unsigned long int_typedef___diff_sz; typedef enum an_enum___diff_sz enum_typedef___diff_sz; typedef const void * const void_ptr_typedef___diff_sz; typedef int_typedef___diff_sz (*func_proto_typedef___diff_sz)(char); typedef int arr_typedef___diff_sz[2]; struct core_reloc_type_based___diff_sz { struct a_struct___diff_sz f1; union a_union___diff_sz f2; enum an_enum___diff_sz f3; named_struct_typedef___diff_sz f4; anon_struct_typedef___diff_sz f5; struct_ptr_typedef___diff_sz f6; int_typedef___diff_sz f7; enum_typedef___diff_sz f8; void_ptr_typedef___diff_sz f9; func_proto_typedef___diff_sz f10; arr_typedef___diff_sz f11; }; /* incompatibilities between target and local types */ union a_struct___incompat { /* union instead of struct */ int x; }; struct a_union___incompat { /* struct instead of union */ int y; int z; }; /* typedef to union, not to struct */ typedef union a_struct___incompat named_struct_typedef___incompat; /* typedef to void pointer, instead of struct */ typedef void *anon_struct_typedef___incompat; /* extra pointer indirection */ typedef struct { int a, b, c; } **struct_ptr_typedef___incompat; /* typedef of a struct with int, instead of int */ typedef struct { int x; } int_typedef___incompat; /* typedef to func_proto, instead of enum */ typedef int (*enum_typedef___incompat)(void); /* pointer to char instead of void */ typedef char *void_ptr_typedef___incompat; /* void return type instead of int */ typedef void (*func_proto_typedef___incompat)(long); /* multi-dimensional array instead of a single-dimensional */ typedef int arr_typedef___incompat[20][2]; struct core_reloc_type_based___incompat { union a_struct___incompat f1; struct a_union___incompat f2; /* the only valid one is enum, to check that something still succeeds */ enum an_enum f3; named_struct_typedef___incompat f4; anon_struct_typedef___incompat f5; struct_ptr_typedef___incompat f6; int_typedef___incompat f7; enum_typedef___incompat f8; void_ptr_typedef___incompat f9; func_proto_typedef___incompat f10; arr_typedef___incompat f11; }; /* func_proto with incompatible signature */ typedef void (*func_proto_typedef___fn_wrong_ret1)(long); typedef int * (*func_proto_typedef___fn_wrong_ret2)(long); typedef struct { int x; } int_struct_typedef; typedef int_struct_typedef (*func_proto_typedef___fn_wrong_ret3)(long); typedef int (*func_proto_typedef___fn_wrong_arg)(void *); typedef int (*func_proto_typedef___fn_wrong_arg_cnt1)(long, long); typedef int (*func_proto_typedef___fn_wrong_arg_cnt2)(void); struct core_reloc_type_based___fn_wrong_args { /* one valid type to make sure relos still work */ struct a_struct f1; func_proto_typedef___fn_wrong_ret1 f2; func_proto_typedef___fn_wrong_ret2 f3; func_proto_typedef___fn_wrong_ret3 f4; func_proto_typedef___fn_wrong_arg f5; func_proto_typedef___fn_wrong_arg_cnt1 f6; func_proto_typedef___fn_wrong_arg_cnt2 f7; }; /* * TYPE ID MAPPING (LOCAL AND TARGET) */ struct core_reloc_type_id_output { int local_anon_struct; int local_anon_union; int local_anon_enum; int local_anon_func_proto_ptr; int local_anon_void_ptr; int local_anon_arr; int local_struct; int local_union; int local_enum; int local_int; int local_struct_typedef; int local_func_proto_typedef; int local_arr_typedef; int targ_struct; int targ_union; int targ_enum; int targ_int; int targ_struct_typedef; int targ_func_proto_typedef; int targ_arr_typedef; }; struct core_reloc_type_id { struct a_struct f1; union a_union f2; enum an_enum f3; named_struct_typedef f4; func_proto_typedef f5; arr_typedef f6; }; struct core_reloc_type_id___missing_targets { /* nothing */ }; /* * ENUMERATOR VALUE EXISTENCE AND VALUE RELOCATION */ struct core_reloc_enumval_output { bool named_val1_exists; bool named_val2_exists; bool named_val3_exists; bool anon_val1_exists; bool anon_val2_exists; bool anon_val3_exists; int named_val1; int named_val2; int anon_val1; int anon_val2; }; struct core_reloc_enum64val_output { bool unsigned_val1_exists; bool unsigned_val2_exists; bool unsigned_val3_exists; bool signed_val1_exists; bool signed_val2_exists; bool signed_val3_exists; long unsigned_val1; long unsigned_val2; long signed_val1; long signed_val2; }; enum named_enum { NAMED_ENUM_VAL1 = 1, NAMED_ENUM_VAL2 = 2, NAMED_ENUM_VAL3 = 3, }; typedef enum { ANON_ENUM_VAL1 = 0x10, ANON_ENUM_VAL2 = 0x20, ANON_ENUM_VAL3 = 0x30, } anon_enum; struct core_reloc_enumval { enum named_enum f1; anon_enum f2; }; enum named_unsigned_enum64 { UNSIGNED_ENUM64_VAL1 = 0x1ffffffffULL, UNSIGNED_ENUM64_VAL2 = 0x2, UNSIGNED_ENUM64_VAL3 = 0x3ffffffffULL, }; enum named_signed_enum64 { SIGNED_ENUM64_VAL1 = 0x1ffffffffLL, SIGNED_ENUM64_VAL2 = -2, SIGNED_ENUM64_VAL3 = 0x3ffffffffLL, }; struct core_reloc_enum64val { enum named_unsigned_enum64 f1; enum named_signed_enum64 f2; }; /* differing enumerator values */ enum named_enum___diff { NAMED_ENUM_VAL1___diff = 101, NAMED_ENUM_VAL2___diff = 202, NAMED_ENUM_VAL3___diff = 303, }; typedef enum { ANON_ENUM_VAL1___diff = 0x11, ANON_ENUM_VAL2___diff = 0x22, ANON_ENUM_VAL3___diff = 0x33, } anon_enum___diff; struct core_reloc_enumval___diff { enum named_enum___diff f1; anon_enum___diff f2; }; enum named_unsigned_enum64___diff { UNSIGNED_ENUM64_VAL1___diff = 0x101ffffffffULL, UNSIGNED_ENUM64_VAL2___diff = 0x202ffffffffULL, UNSIGNED_ENUM64_VAL3___diff = 0x303ffffffffULL, }; enum named_signed_enum64___diff { SIGNED_ENUM64_VAL1___diff = -101, SIGNED_ENUM64_VAL2___diff = -202, SIGNED_ENUM64_VAL3___diff = -303, }; struct core_reloc_enum64val___diff { enum named_unsigned_enum64___diff f1; enum named_signed_enum64___diff f2; }; /* missing (optional) third enum value */ enum named_enum___val3_missing { NAMED_ENUM_VAL1___val3_missing = 111, NAMED_ENUM_VAL2___val3_missing = 222, }; typedef enum { ANON_ENUM_VAL1___val3_missing = 0x111, ANON_ENUM_VAL2___val3_missing = 0x222, } anon_enum___val3_missing; struct core_reloc_enumval___val3_missing { enum named_enum___val3_missing f1; anon_enum___val3_missing f2; }; enum named_unsigned_enum64___val3_missing { UNSIGNED_ENUM64_VAL1___val3_missing = 0x111ffffffffULL, UNSIGNED_ENUM64_VAL2___val3_missing = 0x222, }; enum named_signed_enum64___val3_missing { SIGNED_ENUM64_VAL1___val3_missing = 0x111ffffffffLL, SIGNED_ENUM64_VAL2___val3_missing = -222, }; struct core_reloc_enum64val___val3_missing { enum named_unsigned_enum64___val3_missing f1; enum named_signed_enum64___val3_missing f2; }; /* missing (mandatory) second enum value, should fail */ enum named_enum___err_missing { NAMED_ENUM_VAL1___err_missing = 1, NAMED_ENUM_VAL3___err_missing = 3, }; typedef enum { ANON_ENUM_VAL1___err_missing = 0x111, ANON_ENUM_VAL3___err_missing = 0x222, } anon_enum___err_missing; struct core_reloc_enumval___err_missing { enum named_enum___err_missing f1; anon_enum___err_missing f2; }; enum named_unsigned_enum64___err_missing { UNSIGNED_ENUM64_VAL1___err_missing = 0x1ffffffffULL, UNSIGNED_ENUM64_VAL3___err_missing = 0x3ffffffffULL, }; enum named_signed_enum64___err_missing { SIGNED_ENUM64_VAL1___err_missing = 0x1ffffffffLL, SIGNED_ENUM64_VAL3___err_missing = -3, }; struct core_reloc_enum64val___err_missing { enum named_unsigned_enum64___err_missing f1; enum named_signed_enum64___err_missing f2; };