diff options
Diffstat (limited to 'tools/testing/selftests/bpf/progs/core_reloc_types.h')
-rw-r--r-- | tools/testing/selftests/bpf/progs/core_reloc_types.h | 1145 |
1 files changed, 1145 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h new file mode 100644 index 000000000..af58ef9a2 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -0,0 +1,1145 @@ +#include <stdint.h> +#include <stdbool.h> + +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; +}; + +/* + * 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 struct_sz; + int union_sz; + int arr_sz; + int arr_elem_sz; + int ptr_sz; + int enum_sz; +}; + +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; +}; + +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; +}; + +/* 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; +}; + +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; +}; + +/* + * TYPE EXISTENCE & SIZE + */ +struct core_reloc_type_based_output { + bool 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_func_proto_exists; + bool typedef_arr_exists; + + 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; +}; + +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 (*func_proto_typedef)(long); + +typedef char arr_typedef[20]; + +struct core_reloc_type_based { + struct a_struct f1; + union a_union f2; + enum an_enum f3; + named_struct_typedef f4; + anon_struct_typedef f5; + struct_ptr_typedef f6; + int_typedef f7; + enum_typedef f8; + void_ptr_typedef f9; + func_proto_typedef f10; + arr_typedef f11; +}; + +/* no types in target */ +struct core_reloc_type_based___all_missing { +}; + +/* 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; +}; + +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; +}; + +/* 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; +}; + +/* 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; +}; + +/* 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; +}; |