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 struct a_struct {
19 	int x;
20 };
21 
22 union a_union {
23 	int y;
24 	int z;
25 };
26 
27 typedef struct a_struct named_struct_typedef;
28 
29 typedef struct { int x, y, z; } anon_struct_typedef;
30 
31 typedef struct {
32 	int a, b, c;
33 } *struct_ptr_typedef;
34 
35 enum an_enum {
36 	AN_ENUM_VAL1 = 1,
37 	AN_ENUM_VAL2 = 2,
38 	AN_ENUM_VAL3 = 3,
39 };
40 
41 typedef int int_typedef;
42 
43 typedef enum { TYPEDEF_ENUM_VAL1, TYPEDEF_ENUM_VAL2 } enum_typedef;
44 
45 typedef void *void_ptr_typedef;
46 
47 typedef int (*func_proto_typedef)(long);
48 
49 typedef char arr_typedef[20];
50 
51 struct core_reloc_type_based_output {
52 	bool struct_exists;
53 	bool union_exists;
54 	bool enum_exists;
55 	bool typedef_named_struct_exists;
56 	bool typedef_anon_struct_exists;
57 	bool typedef_struct_ptr_exists;
58 	bool typedef_int_exists;
59 	bool typedef_enum_exists;
60 	bool typedef_void_ptr_exists;
61 	bool typedef_func_proto_exists;
62 	bool typedef_arr_exists;
63 
64 	int struct_sz;
65 	int union_sz;
66 	int enum_sz;
67 	int typedef_named_struct_sz;
68 	int typedef_anon_struct_sz;
69 	int typedef_struct_ptr_sz;
70 	int typedef_int_sz;
71 	int typedef_enum_sz;
72 	int typedef_void_ptr_sz;
73 	int typedef_func_proto_sz;
74 	int typedef_arr_sz;
75 };
76 
77 SEC("raw_tracepoint/sys_enter")
78 int test_core_type_based(void *ctx)
79 {
80 #if __has_builtin(__builtin_preserve_type_info)
81 	struct core_reloc_type_based_output *out = (void *)&data.out;
82 
83 	out->struct_exists = bpf_core_type_exists(struct a_struct);
84 	out->union_exists = bpf_core_type_exists(union a_union);
85 	out->enum_exists = bpf_core_type_exists(enum an_enum);
86 	out->typedef_named_struct_exists = bpf_core_type_exists(named_struct_typedef);
87 	out->typedef_anon_struct_exists = bpf_core_type_exists(anon_struct_typedef);
88 	out->typedef_struct_ptr_exists = bpf_core_type_exists(struct_ptr_typedef);
89 	out->typedef_int_exists = bpf_core_type_exists(int_typedef);
90 	out->typedef_enum_exists = bpf_core_type_exists(enum_typedef);
91 	out->typedef_void_ptr_exists = bpf_core_type_exists(void_ptr_typedef);
92 	out->typedef_func_proto_exists = bpf_core_type_exists(func_proto_typedef);
93 	out->typedef_arr_exists = bpf_core_type_exists(arr_typedef);
94 
95 	out->struct_sz = bpf_core_type_size(struct a_struct);
96 	out->union_sz = bpf_core_type_size(union a_union);
97 	out->enum_sz = bpf_core_type_size(enum an_enum);
98 	out->typedef_named_struct_sz = bpf_core_type_size(named_struct_typedef);
99 	out->typedef_anon_struct_sz = bpf_core_type_size(anon_struct_typedef);
100 	out->typedef_struct_ptr_sz = bpf_core_type_size(struct_ptr_typedef);
101 	out->typedef_int_sz = bpf_core_type_size(int_typedef);
102 	out->typedef_enum_sz = bpf_core_type_size(enum_typedef);
103 	out->typedef_void_ptr_sz = bpf_core_type_size(void_ptr_typedef);
104 	out->typedef_func_proto_sz = bpf_core_type_size(func_proto_typedef);
105 	out->typedef_arr_sz = bpf_core_type_size(arr_typedef);
106 #else
107 	data.skip = true;
108 #endif
109 	return 0;
110 }
111