1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (c) 2020 Facebook |
3 | |
4 | #include <linux/bpf.h> |
5 | #include <stdint.h> |
6 | #include <stdbool.h> |
7 | #include <bpf/bpf_helpers.h> |
8 | #include <bpf/bpf_core_read.h> |
9 | |
10 | char _license[] SEC("license" ) = "GPL" ; |
11 | |
12 | struct { |
13 | char in[256]; |
14 | char out[256]; |
15 | bool skip; |
16 | } data = {}; |
17 | |
18 | /* some types are shared with test_core_reloc_type_based.c */ |
19 | struct a_struct { |
20 | int x; |
21 | }; |
22 | |
23 | union a_union { |
24 | int y; |
25 | int z; |
26 | }; |
27 | |
28 | enum an_enum { |
29 | AN_ENUM_VAL1 = 1, |
30 | AN_ENUM_VAL2 = 2, |
31 | AN_ENUM_VAL3 = 3, |
32 | }; |
33 | |
34 | typedef struct a_struct named_struct_typedef; |
35 | |
36 | typedef int (*func_proto_typedef)(long); |
37 | |
38 | typedef char arr_typedef[20]; |
39 | |
40 | struct core_reloc_type_id_output { |
41 | int local_anon_struct; |
42 | int local_anon_union; |
43 | int local_anon_enum; |
44 | int local_anon_func_proto_ptr; |
45 | int local_anon_void_ptr; |
46 | int local_anon_arr; |
47 | |
48 | int local_struct; |
49 | int local_union; |
50 | int local_enum; |
51 | int local_int; |
52 | int local_struct_typedef; |
53 | int local_func_proto_typedef; |
54 | int local_arr_typedef; |
55 | |
56 | int targ_struct; |
57 | int targ_union; |
58 | int targ_enum; |
59 | int targ_int; |
60 | int targ_struct_typedef; |
61 | int targ_func_proto_typedef; |
62 | int targ_arr_typedef; |
63 | }; |
64 | |
65 | /* preserve types even if Clang doesn't support built-in */ |
66 | struct a_struct t1 = {}; |
67 | union a_union t2 = {}; |
68 | enum an_enum t3 = 0; |
69 | named_struct_typedef t4 = {}; |
70 | func_proto_typedef t5 = 0; |
71 | arr_typedef t6 = {}; |
72 | |
73 | SEC("raw_tracepoint/sys_enter" ) |
74 | int test_core_type_id(void *ctx) |
75 | { |
76 | /* We use __builtin_btf_type_id() in this tests, but up until the time |
77 | * __builtin_preserve_type_info() was added it contained a bug that |
78 | * would make this test fail. The bug was fixed ([0]) with addition of |
79 | * __builtin_preserve_type_info(), though, so that's what we are using |
80 | * to detect whether this test has to be executed, however strange |
81 | * that might look like. |
82 | * |
83 | * [0] https://github.com/llvm/llvm-project/commit/00602ee7ef0bf6c68d690a2bd729c12b95c95c99 |
84 | */ |
85 | #if __has_builtin(__builtin_preserve_type_info) |
86 | struct core_reloc_type_id_output *out = (void *)&data.out; |
87 | |
88 | out->local_anon_struct = bpf_core_type_id_local(struct { int marker_field; }); |
89 | out->local_anon_union = bpf_core_type_id_local(union { int marker_field; }); |
90 | out->local_anon_enum = bpf_core_type_id_local(enum { MARKER_ENUM_VAL = 123 }); |
91 | out->local_anon_func_proto_ptr = bpf_core_type_id_local(_Bool(*)(int)); |
92 | out->local_anon_void_ptr = bpf_core_type_id_local(void *); |
93 | out->local_anon_arr = bpf_core_type_id_local(_Bool[47]); |
94 | |
95 | out->local_struct = bpf_core_type_id_local(struct a_struct); |
96 | out->local_union = bpf_core_type_id_local(union a_union); |
97 | out->local_enum = bpf_core_type_id_local(enum an_enum); |
98 | out->local_int = bpf_core_type_id_local(int); |
99 | out->local_struct_typedef = bpf_core_type_id_local(named_struct_typedef); |
100 | out->local_func_proto_typedef = bpf_core_type_id_local(func_proto_typedef); |
101 | out->local_arr_typedef = bpf_core_type_id_local(arr_typedef); |
102 | |
103 | out->targ_struct = bpf_core_type_id_kernel(struct a_struct); |
104 | out->targ_union = bpf_core_type_id_kernel(union a_union); |
105 | out->targ_enum = bpf_core_type_id_kernel(enum an_enum); |
106 | out->targ_int = bpf_core_type_id_kernel(int); |
107 | out->targ_struct_typedef = bpf_core_type_id_kernel(named_struct_typedef); |
108 | out->targ_func_proto_typedef = bpf_core_type_id_kernel(func_proto_typedef); |
109 | out->targ_arr_typedef = bpf_core_type_id_kernel(arr_typedef); |
110 | #else |
111 | data.skip = true; |
112 | #endif |
113 | |
114 | return 0; |
115 | } |
116 | |