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