| // SPDX-License-Identifier: GPL-2.0 |
| // Copyright (c) 2020 Facebook |
| |
| #include <linux/bpf.h> |
| #include <stdint.h> |
| #include <stdbool.h> |
| #include <bpf/bpf_helpers.h> |
| #include <bpf/bpf_core_read.h> |
| |
| char _license[] SEC("license") = "GPL"; |
| |
| struct { |
| char in[256]; |
| char out[256]; |
| bool skip; |
| } data = {}; |
| |
| /* some types are shared with test_core_reloc_type_based.c */ |
| struct a_struct { |
| int x; |
| }; |
| |
| union a_union { |
| int y; |
| int z; |
| }; |
| |
| enum an_enum { |
| AN_ENUM_VAL1 = 1, |
| AN_ENUM_VAL2 = 2, |
| AN_ENUM_VAL3 = 3, |
| }; |
| |
| typedef struct a_struct named_struct_typedef; |
| |
| typedef int (*func_proto_typedef)(long); |
| |
| typedef char arr_typedef[20]; |
| |
| 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; |
| }; |
| |
| /* preserve types even if Clang doesn't support built-in */ |
| struct a_struct t1 = {}; |
| union a_union t2 = {}; |
| enum an_enum t3 = 0; |
| named_struct_typedef t4 = {}; |
| func_proto_typedef t5 = 0; |
| arr_typedef t6 = {}; |
| |
| SEC("raw_tracepoint/sys_enter") |
| int test_core_type_id(void *ctx) |
| { |
| /* We use __builtin_btf_type_id() in this tests, but up until the time |
| * __builtin_preserve_type_info() was added it contained a bug that |
| * would make this test fail. The bug was fixed ([0]) with addition of |
| * __builtin_preserve_type_info(), though, so that's what we are using |
| * to detect whether this test has to be executed, however strange |
| * that might look like. |
| * |
| * [0] https://github.com/llvm/llvm-project/commit/00602ee7ef0bf6c68d690a2bd729c12b95c95c99 |
| */ |
| #if __has_builtin(__builtin_preserve_type_info) |
| struct core_reloc_type_id_output *out = (void *)&data.out; |
| |
| out->local_anon_struct = bpf_core_type_id_local(struct { int marker_field; }); |
| out->local_anon_union = bpf_core_type_id_local(union { int marker_field; }); |
| out->local_anon_enum = bpf_core_type_id_local(enum { MARKER_ENUM_VAL = 123 }); |
| out->local_anon_func_proto_ptr = bpf_core_type_id_local(_Bool(*)(int)); |
| out->local_anon_void_ptr = bpf_core_type_id_local(void *); |
| out->local_anon_arr = bpf_core_type_id_local(_Bool[47]); |
| |
| out->local_struct = bpf_core_type_id_local(struct a_struct); |
| out->local_union = bpf_core_type_id_local(union a_union); |
| out->local_enum = bpf_core_type_id_local(enum an_enum); |
| out->local_int = bpf_core_type_id_local(int); |
| out->local_struct_typedef = bpf_core_type_id_local(named_struct_typedef); |
| out->local_func_proto_typedef = bpf_core_type_id_local(func_proto_typedef); |
| out->local_arr_typedef = bpf_core_type_id_local(arr_typedef); |
| |
| out->targ_struct = bpf_core_type_id_kernel(struct a_struct); |
| out->targ_union = bpf_core_type_id_kernel(union a_union); |
| out->targ_enum = bpf_core_type_id_kernel(enum an_enum); |
| out->targ_int = bpf_core_type_id_kernel(int); |
| out->targ_struct_typedef = bpf_core_type_id_kernel(named_struct_typedef); |
| out->targ_func_proto_typedef = bpf_core_type_id_kernel(func_proto_typedef); |
| out->targ_arr_typedef = bpf_core_type_id_kernel(arr_typedef); |
| #else |
| data.skip = true; |
| #endif |
| |
| return 0; |
| } |