]>
Commit | Line | Data |
---|---|---|
3ac4dbe3 AN |
1 | /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ |
2 | #ifndef __BPF_TRACING_H__ | |
3 | #define __BPF_TRACING_H__ | |
4 | ||
5 | /* Scan the ARCH passed in from ARCH env variable (see Makefile) */ | |
6 | #if defined(__TARGET_ARCH_x86) | |
7 | #define bpf_target_x86 | |
8 | #define bpf_target_defined | |
9 | #elif defined(__TARGET_ARCH_s390) | |
10 | #define bpf_target_s390 | |
11 | #define bpf_target_defined | |
12 | #elif defined(__TARGET_ARCH_arm) | |
13 | #define bpf_target_arm | |
14 | #define bpf_target_defined | |
15 | #elif defined(__TARGET_ARCH_arm64) | |
16 | #define bpf_target_arm64 | |
17 | #define bpf_target_defined | |
18 | #elif defined(__TARGET_ARCH_mips) | |
19 | #define bpf_target_mips | |
20 | #define bpf_target_defined | |
21 | #elif defined(__TARGET_ARCH_powerpc) | |
22 | #define bpf_target_powerpc | |
23 | #define bpf_target_defined | |
24 | #elif defined(__TARGET_ARCH_sparc) | |
25 | #define bpf_target_sparc | |
26 | #define bpf_target_defined | |
27 | #else | |
28 | #undef bpf_target_defined | |
29 | #endif | |
30 | ||
31 | /* Fall back to what the compiler says */ | |
32 | #ifndef bpf_target_defined | |
33 | #if defined(__x86_64__) | |
34 | #define bpf_target_x86 | |
35 | #elif defined(__s390__) | |
36 | #define bpf_target_s390 | |
37 | #elif defined(__arm__) | |
38 | #define bpf_target_arm | |
39 | #elif defined(__aarch64__) | |
40 | #define bpf_target_arm64 | |
41 | #elif defined(__mips__) | |
42 | #define bpf_target_mips | |
43 | #elif defined(__powerpc__) | |
44 | #define bpf_target_powerpc | |
45 | #elif defined(__sparc__) | |
46 | #define bpf_target_sparc | |
47 | #endif | |
48 | #endif | |
49 | ||
50 | #if defined(bpf_target_x86) | |
51 | ||
fd56e005 | 52 | #if defined(__KERNEL__) || defined(__VMLINUX_H__) |
b8ebce86 | 53 | |
3ac4dbe3 AN |
54 | #define PT_REGS_PARM1(x) ((x)->di) |
55 | #define PT_REGS_PARM2(x) ((x)->si) | |
56 | #define PT_REGS_PARM3(x) ((x)->dx) | |
57 | #define PT_REGS_PARM4(x) ((x)->cx) | |
58 | #define PT_REGS_PARM5(x) ((x)->r8) | |
59 | #define PT_REGS_RET(x) ((x)->sp) | |
60 | #define PT_REGS_FP(x) ((x)->bp) | |
61 | #define PT_REGS_RC(x) ((x)->ax) | |
62 | #define PT_REGS_SP(x) ((x)->sp) | |
63 | #define PT_REGS_IP(x) ((x)->ip) | |
b8ebce86 AN |
64 | |
65 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), di) | |
66 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), si) | |
67 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), dx) | |
68 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), cx) | |
69 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), r8) | |
70 | #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), sp) | |
71 | #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), bp) | |
72 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), ax) | |
73 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), sp) | |
74 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), ip) | |
75 | ||
3ac4dbe3 | 76 | #else |
b8ebce86 | 77 | |
3ac4dbe3 AN |
78 | #ifdef __i386__ |
79 | /* i386 kernel is built with -mregparm=3 */ | |
80 | #define PT_REGS_PARM1(x) ((x)->eax) | |
81 | #define PT_REGS_PARM2(x) ((x)->edx) | |
82 | #define PT_REGS_PARM3(x) ((x)->ecx) | |
83 | #define PT_REGS_PARM4(x) 0 | |
84 | #define PT_REGS_PARM5(x) 0 | |
85 | #define PT_REGS_RET(x) ((x)->esp) | |
86 | #define PT_REGS_FP(x) ((x)->ebp) | |
87 | #define PT_REGS_RC(x) ((x)->eax) | |
88 | #define PT_REGS_SP(x) ((x)->esp) | |
89 | #define PT_REGS_IP(x) ((x)->eip) | |
b8ebce86 AN |
90 | |
91 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), eax) | |
92 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), edx) | |
93 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), ecx) | |
94 | #define PT_REGS_PARM4_CORE(x) 0 | |
95 | #define PT_REGS_PARM5_CORE(x) 0 | |
96 | #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), esp) | |
97 | #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), ebp) | |
98 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), eax) | |
99 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), esp) | |
100 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), eip) | |
101 | ||
3ac4dbe3 | 102 | #else |
b8ebce86 | 103 | |
3ac4dbe3 AN |
104 | #define PT_REGS_PARM1(x) ((x)->rdi) |
105 | #define PT_REGS_PARM2(x) ((x)->rsi) | |
106 | #define PT_REGS_PARM3(x) ((x)->rdx) | |
107 | #define PT_REGS_PARM4(x) ((x)->rcx) | |
108 | #define PT_REGS_PARM5(x) ((x)->r8) | |
109 | #define PT_REGS_RET(x) ((x)->rsp) | |
110 | #define PT_REGS_FP(x) ((x)->rbp) | |
111 | #define PT_REGS_RC(x) ((x)->rax) | |
112 | #define PT_REGS_SP(x) ((x)->rsp) | |
113 | #define PT_REGS_IP(x) ((x)->rip) | |
b8ebce86 AN |
114 | |
115 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), rdi) | |
116 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), rsi) | |
117 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), rdx) | |
118 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), rcx) | |
119 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), r8) | |
120 | #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), rsp) | |
121 | #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), rbp) | |
122 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), rax) | |
123 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), rsp) | |
124 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), rip) | |
125 | ||
3ac4dbe3 AN |
126 | #endif |
127 | #endif | |
128 | ||
129 | #elif defined(bpf_target_s390) | |
130 | ||
131 | /* s390 provides user_pt_regs instead of struct pt_regs to userspace */ | |
132 | struct pt_regs; | |
133 | #define PT_REGS_S390 const volatile user_pt_regs | |
134 | #define PT_REGS_PARM1(x) (((PT_REGS_S390 *)(x))->gprs[2]) | |
135 | #define PT_REGS_PARM2(x) (((PT_REGS_S390 *)(x))->gprs[3]) | |
136 | #define PT_REGS_PARM3(x) (((PT_REGS_S390 *)(x))->gprs[4]) | |
137 | #define PT_REGS_PARM4(x) (((PT_REGS_S390 *)(x))->gprs[5]) | |
138 | #define PT_REGS_PARM5(x) (((PT_REGS_S390 *)(x))->gprs[6]) | |
139 | #define PT_REGS_RET(x) (((PT_REGS_S390 *)(x))->gprs[14]) | |
140 | /* Works only with CONFIG_FRAME_POINTER */ | |
141 | #define PT_REGS_FP(x) (((PT_REGS_S390 *)(x))->gprs[11]) | |
142 | #define PT_REGS_RC(x) (((PT_REGS_S390 *)(x))->gprs[2]) | |
143 | #define PT_REGS_SP(x) (((PT_REGS_S390 *)(x))->gprs[15]) | |
144 | #define PT_REGS_IP(x) (((PT_REGS_S390 *)(x))->psw.addr) | |
145 | ||
b8ebce86 AN |
146 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[2]) |
147 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[3]) | |
148 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[4]) | |
149 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[5]) | |
150 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[6]) | |
516d8d49 | 151 | #define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[14]) |
b8ebce86 AN |
152 | #define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[11]) |
153 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[2]) | |
154 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[15]) | |
516d8d49 | 155 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), psw.addr) |
b8ebce86 | 156 | |
3ac4dbe3 AN |
157 | #elif defined(bpf_target_arm) |
158 | ||
159 | #define PT_REGS_PARM1(x) ((x)->uregs[0]) | |
160 | #define PT_REGS_PARM2(x) ((x)->uregs[1]) | |
161 | #define PT_REGS_PARM3(x) ((x)->uregs[2]) | |
162 | #define PT_REGS_PARM4(x) ((x)->uregs[3]) | |
163 | #define PT_REGS_PARM5(x) ((x)->uregs[4]) | |
164 | #define PT_REGS_RET(x) ((x)->uregs[14]) | |
165 | #define PT_REGS_FP(x) ((x)->uregs[11]) /* Works only with CONFIG_FRAME_POINTER */ | |
166 | #define PT_REGS_RC(x) ((x)->uregs[0]) | |
167 | #define PT_REGS_SP(x) ((x)->uregs[13]) | |
168 | #define PT_REGS_IP(x) ((x)->uregs[12]) | |
169 | ||
b8ebce86 AN |
170 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), uregs[0]) |
171 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), uregs[1]) | |
172 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), uregs[2]) | |
173 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), uregs[3]) | |
174 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), uregs[4]) | |
175 | #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), uregs[14]) | |
176 | #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), uregs[11]) | |
177 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), uregs[0]) | |
178 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), uregs[13]) | |
179 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), uregs[12]) | |
180 | ||
3ac4dbe3 AN |
181 | #elif defined(bpf_target_arm64) |
182 | ||
183 | /* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */ | |
184 | struct pt_regs; | |
185 | #define PT_REGS_ARM64 const volatile struct user_pt_regs | |
186 | #define PT_REGS_PARM1(x) (((PT_REGS_ARM64 *)(x))->regs[0]) | |
187 | #define PT_REGS_PARM2(x) (((PT_REGS_ARM64 *)(x))->regs[1]) | |
188 | #define PT_REGS_PARM3(x) (((PT_REGS_ARM64 *)(x))->regs[2]) | |
189 | #define PT_REGS_PARM4(x) (((PT_REGS_ARM64 *)(x))->regs[3]) | |
190 | #define PT_REGS_PARM5(x) (((PT_REGS_ARM64 *)(x))->regs[4]) | |
191 | #define PT_REGS_RET(x) (((PT_REGS_ARM64 *)(x))->regs[30]) | |
192 | /* Works only with CONFIG_FRAME_POINTER */ | |
193 | #define PT_REGS_FP(x) (((PT_REGS_ARM64 *)(x))->regs[29]) | |
194 | #define PT_REGS_RC(x) (((PT_REGS_ARM64 *)(x))->regs[0]) | |
195 | #define PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp) | |
196 | #define PT_REGS_IP(x) (((PT_REGS_ARM64 *)(x))->pc) | |
197 | ||
b8ebce86 AN |
198 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[0]) |
199 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[1]) | |
200 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[2]) | |
201 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[3]) | |
202 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[4]) | |
203 | #define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[30]) | |
204 | #define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[29]) | |
205 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[0]) | |
206 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), sp) | |
207 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), pc) | |
208 | ||
3ac4dbe3 AN |
209 | #elif defined(bpf_target_mips) |
210 | ||
211 | #define PT_REGS_PARM1(x) ((x)->regs[4]) | |
212 | #define PT_REGS_PARM2(x) ((x)->regs[5]) | |
213 | #define PT_REGS_PARM3(x) ((x)->regs[6]) | |
214 | #define PT_REGS_PARM4(x) ((x)->regs[7]) | |
215 | #define PT_REGS_PARM5(x) ((x)->regs[8]) | |
216 | #define PT_REGS_RET(x) ((x)->regs[31]) | |
217 | #define PT_REGS_FP(x) ((x)->regs[30]) /* Works only with CONFIG_FRAME_POINTER */ | |
218 | #define PT_REGS_RC(x) ((x)->regs[1]) | |
219 | #define PT_REGS_SP(x) ((x)->regs[29]) | |
220 | #define PT_REGS_IP(x) ((x)->cp0_epc) | |
221 | ||
b8ebce86 AN |
222 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), regs[4]) |
223 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), regs[5]) | |
224 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), regs[6]) | |
225 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), regs[7]) | |
226 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), regs[8]) | |
227 | #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), regs[31]) | |
228 | #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), regs[30]) | |
229 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), regs[1]) | |
230 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), regs[29]) | |
231 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), cp0_epc) | |
232 | ||
3ac4dbe3 AN |
233 | #elif defined(bpf_target_powerpc) |
234 | ||
235 | #define PT_REGS_PARM1(x) ((x)->gpr[3]) | |
236 | #define PT_REGS_PARM2(x) ((x)->gpr[4]) | |
237 | #define PT_REGS_PARM3(x) ((x)->gpr[5]) | |
238 | #define PT_REGS_PARM4(x) ((x)->gpr[6]) | |
239 | #define PT_REGS_PARM5(x) ((x)->gpr[7]) | |
240 | #define PT_REGS_RC(x) ((x)->gpr[3]) | |
241 | #define PT_REGS_SP(x) ((x)->sp) | |
242 | #define PT_REGS_IP(x) ((x)->nip) | |
243 | ||
b8ebce86 AN |
244 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), gpr[3]) |
245 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), gpr[4]) | |
246 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), gpr[5]) | |
247 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), gpr[6]) | |
248 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), gpr[7]) | |
249 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), gpr[3]) | |
250 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), sp) | |
251 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), nip) | |
252 | ||
3ac4dbe3 AN |
253 | #elif defined(bpf_target_sparc) |
254 | ||
255 | #define PT_REGS_PARM1(x) ((x)->u_regs[UREG_I0]) | |
256 | #define PT_REGS_PARM2(x) ((x)->u_regs[UREG_I1]) | |
257 | #define PT_REGS_PARM3(x) ((x)->u_regs[UREG_I2]) | |
258 | #define PT_REGS_PARM4(x) ((x)->u_regs[UREG_I3]) | |
259 | #define PT_REGS_PARM5(x) ((x)->u_regs[UREG_I4]) | |
260 | #define PT_REGS_RET(x) ((x)->u_regs[UREG_I7]) | |
261 | #define PT_REGS_RC(x) ((x)->u_regs[UREG_I0]) | |
262 | #define PT_REGS_SP(x) ((x)->u_regs[UREG_FP]) | |
263 | ||
b8ebce86 AN |
264 | #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I0]) |
265 | #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I1]) | |
266 | #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I2]) | |
267 | #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I3]) | |
268 | #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I4]) | |
269 | #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I7]) | |
270 | #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I0]) | |
271 | #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), u_regs[UREG_FP]) | |
272 | ||
3ac4dbe3 AN |
273 | /* Should this also be a bpf_target check for the sparc case? */ |
274 | #if defined(__arch64__) | |
275 | #define PT_REGS_IP(x) ((x)->tpc) | |
b8ebce86 | 276 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), tpc) |
3ac4dbe3 AN |
277 | #else |
278 | #define PT_REGS_IP(x) ((x)->pc) | |
b8ebce86 | 279 | #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), pc) |
3ac4dbe3 AN |
280 | #endif |
281 | ||
282 | #endif | |
283 | ||
284 | #if defined(bpf_target_powerpc) | |
285 | #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; }) | |
286 | #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP | |
287 | #elif defined(bpf_target_sparc) | |
288 | #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = PT_REGS_RET(ctx); }) | |
289 | #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP | |
290 | #else | |
291 | #define BPF_KPROBE_READ_RET_IP(ip, ctx) \ | |
292 | ({ bpf_probe_read(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); }) | |
293 | #define BPF_KRETPROBE_READ_RET_IP(ip, ctx) \ | |
294 | ({ bpf_probe_read(&(ip), sizeof(ip), \ | |
295 | (void *)(PT_REGS_FP(ctx) + sizeof(ip))); }) | |
296 | #endif | |
297 | ||
df8ff353 AN |
298 | #define ___bpf_concat(a, b) a ## b |
299 | #define ___bpf_apply(fn, n) ___bpf_concat(fn, n) | |
300 | #define ___bpf_nth(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, N, ...) N | |
301 | #define ___bpf_narg(...) \ | |
302 | ___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) | |
303 | #define ___bpf_empty(...) \ | |
304 | ___bpf_nth(_, ##__VA_ARGS__, N, N, N, N, N, N, N, N, N, N, 0) | |
305 | ||
306 | #define ___bpf_ctx_cast0() ctx | |
307 | #define ___bpf_ctx_cast1(x) ___bpf_ctx_cast0(), (void *)ctx[0] | |
308 | #define ___bpf_ctx_cast2(x, args...) ___bpf_ctx_cast1(args), (void *)ctx[1] | |
309 | #define ___bpf_ctx_cast3(x, args...) ___bpf_ctx_cast2(args), (void *)ctx[2] | |
310 | #define ___bpf_ctx_cast4(x, args...) ___bpf_ctx_cast3(args), (void *)ctx[3] | |
311 | #define ___bpf_ctx_cast5(x, args...) ___bpf_ctx_cast4(args), (void *)ctx[4] | |
312 | #define ___bpf_ctx_cast6(x, args...) ___bpf_ctx_cast5(args), (void *)ctx[5] | |
313 | #define ___bpf_ctx_cast7(x, args...) ___bpf_ctx_cast6(args), (void *)ctx[6] | |
314 | #define ___bpf_ctx_cast8(x, args...) ___bpf_ctx_cast7(args), (void *)ctx[7] | |
315 | #define ___bpf_ctx_cast9(x, args...) ___bpf_ctx_cast8(args), (void *)ctx[8] | |
316 | #define ___bpf_ctx_cast10(x, args...) ___bpf_ctx_cast9(args), (void *)ctx[9] | |
317 | #define ___bpf_ctx_cast11(x, args...) ___bpf_ctx_cast10(args), (void *)ctx[10] | |
318 | #define ___bpf_ctx_cast12(x, args...) ___bpf_ctx_cast11(args), (void *)ctx[11] | |
319 | #define ___bpf_ctx_cast(args...) \ | |
320 | ___bpf_apply(___bpf_ctx_cast, ___bpf_narg(args))(args) | |
321 | ||
322 | /* | |
323 | * BPF_PROG is a convenience wrapper for generic tp_btf/fentry/fexit and | |
324 | * similar kinds of BPF programs, that accept input arguments as a single | |
325 | * pointer to untyped u64 array, where each u64 can actually be a typed | |
326 | * pointer or integer of different size. Instead of requring user to write | |
327 | * manual casts and work with array elements by index, BPF_PROG macro | |
328 | * allows user to declare a list of named and typed input arguments in the | |
329 | * same syntax as for normal C function. All the casting is hidden and | |
330 | * performed transparently, while user code can just assume working with | |
331 | * function arguments of specified type and name. | |
332 | * | |
333 | * Original raw context argument is preserved as well as 'ctx' argument. | |
334 | * This is useful when using BPF helpers that expect original context | |
335 | * as one of the parameters (e.g., for bpf_perf_event_output()). | |
336 | */ | |
337 | #define BPF_PROG(name, args...) \ | |
338 | name(unsigned long long *ctx); \ | |
339 | static __attribute__((always_inline)) typeof(name(0)) \ | |
340 | ____##name(unsigned long long *ctx, ##args); \ | |
341 | typeof(name(0)) name(unsigned long long *ctx) \ | |
342 | { \ | |
343 | _Pragma("GCC diagnostic push") \ | |
344 | _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ | |
345 | return ____##name(___bpf_ctx_cast(args)); \ | |
346 | _Pragma("GCC diagnostic pop") \ | |
347 | } \ | |
348 | static __attribute__((always_inline)) typeof(name(0)) \ | |
349 | ____##name(unsigned long long *ctx, ##args) | |
350 | ||
351 | struct pt_regs; | |
352 | ||
353 | #define ___bpf_kprobe_args0() ctx | |
354 | #define ___bpf_kprobe_args1(x) \ | |
355 | ___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx) | |
356 | #define ___bpf_kprobe_args2(x, args...) \ | |
357 | ___bpf_kprobe_args1(args), (void *)PT_REGS_PARM2(ctx) | |
358 | #define ___bpf_kprobe_args3(x, args...) \ | |
359 | ___bpf_kprobe_args2(args), (void *)PT_REGS_PARM3(ctx) | |
360 | #define ___bpf_kprobe_args4(x, args...) \ | |
361 | ___bpf_kprobe_args3(args), (void *)PT_REGS_PARM4(ctx) | |
362 | #define ___bpf_kprobe_args5(x, args...) \ | |
363 | ___bpf_kprobe_args4(args), (void *)PT_REGS_PARM5(ctx) | |
364 | #define ___bpf_kprobe_args(args...) \ | |
365 | ___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args) | |
366 | ||
367 | /* | |
368 | * BPF_KPROBE serves the same purpose for kprobes as BPF_PROG for | |
369 | * tp_btf/fentry/fexit BPF programs. It hides the underlying platform-specific | |
370 | * low-level way of getting kprobe input arguments from struct pt_regs, and | |
371 | * provides a familiar typed and named function arguments syntax and | |
372 | * semantics of accessing kprobe input paremeters. | |
373 | * | |
374 | * Original struct pt_regs* context is preserved as 'ctx' argument. This might | |
375 | * be necessary when using BPF helpers like bpf_perf_event_output(). | |
376 | */ | |
377 | #define BPF_KPROBE(name, args...) \ | |
378 | name(struct pt_regs *ctx); \ | |
379 | static __attribute__((always_inline)) typeof(name(0)) \ | |
380 | ____##name(struct pt_regs *ctx, ##args); \ | |
381 | typeof(name(0)) name(struct pt_regs *ctx) \ | |
382 | { \ | |
383 | _Pragma("GCC diagnostic push") \ | |
384 | _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ | |
385 | return ____##name(___bpf_kprobe_args(args)); \ | |
386 | _Pragma("GCC diagnostic pop") \ | |
387 | } \ | |
388 | static __attribute__((always_inline)) typeof(name(0)) \ | |
389 | ____##name(struct pt_regs *ctx, ##args) | |
390 | ||
391 | #define ___bpf_kretprobe_args0() ctx | |
392 | #define ___bpf_kretprobe_args1(x) \ | |
483d7a30 | 393 | ___bpf_kretprobe_args0(), (void *)PT_REGS_RC(ctx) |
df8ff353 AN |
394 | #define ___bpf_kretprobe_args(args...) \ |
395 | ___bpf_apply(___bpf_kretprobe_args, ___bpf_narg(args))(args) | |
396 | ||
397 | /* | |
398 | * BPF_KRETPROBE is similar to BPF_KPROBE, except, it only provides optional | |
399 | * return value (in addition to `struct pt_regs *ctx`), but no input | |
400 | * arguments, because they will be clobbered by the time probed function | |
401 | * returns. | |
402 | */ | |
403 | #define BPF_KRETPROBE(name, args...) \ | |
404 | name(struct pt_regs *ctx); \ | |
405 | static __attribute__((always_inline)) typeof(name(0)) \ | |
406 | ____##name(struct pt_regs *ctx, ##args); \ | |
407 | typeof(name(0)) name(struct pt_regs *ctx) \ | |
408 | { \ | |
409 | _Pragma("GCC diagnostic push") \ | |
410 | _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ | |
411 | return ____##name(___bpf_kretprobe_args(args)); \ | |
412 | _Pragma("GCC diagnostic pop") \ | |
413 | } \ | |
414 | static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args) | |
415 | ||
3ac4dbe3 | 416 | #endif |