1e01a75c1SAndrii Nakryiko /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 2e01a75c1SAndrii Nakryiko #ifndef __BPF_TRACING_H__ 3e01a75c1SAndrii Nakryiko #define __BPF_TRACING_H__ 4e01a75c1SAndrii Nakryiko 5*dde3979bSSergey Kacheev #include "bpf_helpers.h" 66f5d467dSAndrii Nakryiko 7e01a75c1SAndrii Nakryiko /* Scan the ARCH passed in from ARCH env variable (see Makefile) */ 8e01a75c1SAndrii Nakryiko #if defined(__TARGET_ARCH_x86) 9e01a75c1SAndrii Nakryiko #define bpf_target_x86 10e01a75c1SAndrii Nakryiko #define bpf_target_defined 11e01a75c1SAndrii Nakryiko #elif defined(__TARGET_ARCH_s390) 12e01a75c1SAndrii Nakryiko #define bpf_target_s390 13e01a75c1SAndrii Nakryiko #define bpf_target_defined 14e01a75c1SAndrii Nakryiko #elif defined(__TARGET_ARCH_arm) 15e01a75c1SAndrii Nakryiko #define bpf_target_arm 16e01a75c1SAndrii Nakryiko #define bpf_target_defined 17e01a75c1SAndrii Nakryiko #elif defined(__TARGET_ARCH_arm64) 18e01a75c1SAndrii Nakryiko #define bpf_target_arm64 19e01a75c1SAndrii Nakryiko #define bpf_target_defined 20e01a75c1SAndrii Nakryiko #elif defined(__TARGET_ARCH_mips) 21e01a75c1SAndrii Nakryiko #define bpf_target_mips 22e01a75c1SAndrii Nakryiko #define bpf_target_defined 23e01a75c1SAndrii Nakryiko #elif defined(__TARGET_ARCH_powerpc) 24e01a75c1SAndrii Nakryiko #define bpf_target_powerpc 25e01a75c1SAndrii Nakryiko #define bpf_target_defined 26e01a75c1SAndrii Nakryiko #elif defined(__TARGET_ARCH_sparc) 27e01a75c1SAndrii Nakryiko #define bpf_target_sparc 28e01a75c1SAndrii Nakryiko #define bpf_target_defined 29589fed47SBjörn Töpel #elif defined(__TARGET_ARCH_riscv) 30589fed47SBjörn Töpel #define bpf_target_riscv 31589fed47SBjörn Töpel #define bpf_target_defined 3207385998SVladimir Isaev #elif defined(__TARGET_ARCH_arc) 3307385998SVladimir Isaev #define bpf_target_arc 3407385998SVladimir Isaev #define bpf_target_defined 3500883922SHengqi Chen #elif defined(__TARGET_ARCH_loongarch) 3600883922SHengqi Chen #define bpf_target_loongarch 3700883922SHengqi Chen #define bpf_target_defined 38e01a75c1SAndrii Nakryiko #else 39e01a75c1SAndrii Nakryiko 40e01a75c1SAndrii Nakryiko /* Fall back to what the compiler says */ 41e01a75c1SAndrii Nakryiko #if defined(__x86_64__) 42e01a75c1SAndrii Nakryiko #define bpf_target_x86 434a638d58SLorenz Bauer #define bpf_target_defined 44e01a75c1SAndrii Nakryiko #elif defined(__s390__) 45e01a75c1SAndrii Nakryiko #define bpf_target_s390 464a638d58SLorenz Bauer #define bpf_target_defined 47e01a75c1SAndrii Nakryiko #elif defined(__arm__) 48e01a75c1SAndrii Nakryiko #define bpf_target_arm 494a638d58SLorenz Bauer #define bpf_target_defined 50e01a75c1SAndrii Nakryiko #elif defined(__aarch64__) 51e01a75c1SAndrii Nakryiko #define bpf_target_arm64 524a638d58SLorenz Bauer #define bpf_target_defined 53e01a75c1SAndrii Nakryiko #elif defined(__mips__) 54e01a75c1SAndrii Nakryiko #define bpf_target_mips 554a638d58SLorenz Bauer #define bpf_target_defined 56e01a75c1SAndrii Nakryiko #elif defined(__powerpc__) 57e01a75c1SAndrii Nakryiko #define bpf_target_powerpc 584a638d58SLorenz Bauer #define bpf_target_defined 59e01a75c1SAndrii Nakryiko #elif defined(__sparc__) 60e01a75c1SAndrii Nakryiko #define bpf_target_sparc 614a638d58SLorenz Bauer #define bpf_target_defined 62589fed47SBjörn Töpel #elif defined(__riscv) && __riscv_xlen == 64 63589fed47SBjörn Töpel #define bpf_target_riscv 64589fed47SBjörn Töpel #define bpf_target_defined 6507385998SVladimir Isaev #elif defined(__arc__) 6607385998SVladimir Isaev #define bpf_target_arc 6707385998SVladimir Isaev #define bpf_target_defined 6800883922SHengqi Chen #elif defined(__loongarch__) 6900883922SHengqi Chen #define bpf_target_loongarch 7000883922SHengqi Chen #define bpf_target_defined 714a638d58SLorenz Bauer #endif /* no compiler target */ 724a638d58SLorenz Bauer 73e01a75c1SAndrii Nakryiko #endif 744a638d58SLorenz Bauer 754a638d58SLorenz Bauer #ifndef __BPF_TARGET_MISSING 764a638d58SLorenz Bauer #define __BPF_TARGET_MISSING "GCC error \"Must specify a BPF target arch via __TARGET_ARCH_xxx\"" 77e01a75c1SAndrii Nakryiko #endif 78e01a75c1SAndrii Nakryiko 79e01a75c1SAndrii Nakryiko #if defined(bpf_target_x86) 80e01a75c1SAndrii Nakryiko 8101329032SAndrii Nakryiko /* 8201329032SAndrii Nakryiko * https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI 8301329032SAndrii Nakryiko */ 8401329032SAndrii Nakryiko 85fd56e005SAndrii Nakryiko #if defined(__KERNEL__) || defined(__VMLINUX_H__) 86b8ebce86SAndrii Nakryiko 873cc31d79SAndrii Nakryiko #define __PT_PARM1_REG di 883cc31d79SAndrii Nakryiko #define __PT_PARM2_REG si 893cc31d79SAndrii Nakryiko #define __PT_PARM3_REG dx 903cc31d79SAndrii Nakryiko #define __PT_PARM4_REG cx 913cc31d79SAndrii Nakryiko #define __PT_PARM5_REG r8 9201329032SAndrii Nakryiko #define __PT_PARM6_REG r9 93d21fbceeSAndrii Nakryiko /* 94d21fbceeSAndrii Nakryiko * Syscall uses r10 for PARM4. See arch/x86/entry/entry_64.S:entry_SYSCALL_64 95d21fbceeSAndrii Nakryiko * comments in Linux sources. And refer to syscall(2) manpage. 96d21fbceeSAndrii Nakryiko */ 97d21fbceeSAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG 98d21fbceeSAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 99d21fbceeSAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 100d21fbceeSAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG r10 101d21fbceeSAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 102d21fbceeSAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG 103d21fbceeSAndrii Nakryiko 1043cc31d79SAndrii Nakryiko #define __PT_RET_REG sp 1053cc31d79SAndrii Nakryiko #define __PT_FP_REG bp 1063cc31d79SAndrii Nakryiko #define __PT_RC_REG ax 1073cc31d79SAndrii Nakryiko #define __PT_SP_REG sp 1083cc31d79SAndrii Nakryiko #define __PT_IP_REG ip 109b8ebce86SAndrii Nakryiko 110e01a75c1SAndrii Nakryiko #else 111b8ebce86SAndrii Nakryiko 112e01a75c1SAndrii Nakryiko #ifdef __i386__ 1133cc31d79SAndrii Nakryiko 1143c59623dSAndrii Nakryiko /* i386 kernel is built with -mregparm=3 */ 1153cc31d79SAndrii Nakryiko #define __PT_PARM1_REG eax 1163cc31d79SAndrii Nakryiko #define __PT_PARM2_REG edx 1173cc31d79SAndrii Nakryiko #define __PT_PARM3_REG ecx 118ff00f9cbSAndrii Nakryiko /* i386 syscall ABI is very different, refer to syscall(2) manpage */ 119ff00f9cbSAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG ebx 120ff00f9cbSAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG ecx 121ff00f9cbSAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG edx 122ff00f9cbSAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG esi 123ff00f9cbSAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG edi 124ff00f9cbSAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG ebp 125ff00f9cbSAndrii Nakryiko 1263cc31d79SAndrii Nakryiko #define __PT_RET_REG esp 1273cc31d79SAndrii Nakryiko #define __PT_FP_REG ebp 1283cc31d79SAndrii Nakryiko #define __PT_RC_REG eax 1293cc31d79SAndrii Nakryiko #define __PT_SP_REG esp 1303cc31d79SAndrii Nakryiko #define __PT_IP_REG eip 131b8ebce86SAndrii Nakryiko 1323cc31d79SAndrii Nakryiko #else /* __i386__ */ 133b8ebce86SAndrii Nakryiko 1343cc31d79SAndrii Nakryiko #define __PT_PARM1_REG rdi 1353cc31d79SAndrii Nakryiko #define __PT_PARM2_REG rsi 1363cc31d79SAndrii Nakryiko #define __PT_PARM3_REG rdx 1373cc31d79SAndrii Nakryiko #define __PT_PARM4_REG rcx 1383cc31d79SAndrii Nakryiko #define __PT_PARM5_REG r8 13901329032SAndrii Nakryiko #define __PT_PARM6_REG r9 140d21fbceeSAndrii Nakryiko 141d21fbceeSAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG 142d21fbceeSAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 143d21fbceeSAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 144d21fbceeSAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG r10 145d21fbceeSAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 146d21fbceeSAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG 147d21fbceeSAndrii Nakryiko 1483cc31d79SAndrii Nakryiko #define __PT_RET_REG rsp 1493cc31d79SAndrii Nakryiko #define __PT_FP_REG rbp 1503cc31d79SAndrii Nakryiko #define __PT_RC_REG rax 1513cc31d79SAndrii Nakryiko #define __PT_SP_REG rsp 1523cc31d79SAndrii Nakryiko #define __PT_IP_REG rip 153b8ebce86SAndrii Nakryiko 1543cc31d79SAndrii Nakryiko #endif /* __i386__ */ 155b8ebce86SAndrii Nakryiko 1563cc31d79SAndrii Nakryiko #endif /* __KERNEL__ || __VMLINUX_H__ */ 157e01a75c1SAndrii Nakryiko 158e01a75c1SAndrii Nakryiko #elif defined(bpf_target_s390) 159e01a75c1SAndrii Nakryiko 160e82b96a3SAndrii Nakryiko /* 161e82b96a3SAndrii Nakryiko * https://github.com/IBM/s390x-abi/releases/download/v1.6/lzsabi_s390x.pdf 162e82b96a3SAndrii Nakryiko */ 163e82b96a3SAndrii Nakryiko 1641f22a6f9SIlya Leoshkevich struct pt_regs___s390 { 1651f22a6f9SIlya Leoshkevich unsigned long orig_gpr2; 1661f22a6f9SIlya Leoshkevich }; 1671f22a6f9SIlya Leoshkevich 168e01a75c1SAndrii Nakryiko /* s390 provides user_pt_regs instead of struct pt_regs to userspace */ 1693cc31d79SAndrii Nakryiko #define __PT_REGS_CAST(x) ((const user_pt_regs *)(x)) 1703cc31d79SAndrii Nakryiko #define __PT_PARM1_REG gprs[2] 1713cc31d79SAndrii Nakryiko #define __PT_PARM2_REG gprs[3] 1723cc31d79SAndrii Nakryiko #define __PT_PARM3_REG gprs[4] 1733cc31d79SAndrii Nakryiko #define __PT_PARM4_REG gprs[5] 1743cc31d79SAndrii Nakryiko #define __PT_PARM5_REG gprs[6] 175e82b96a3SAndrii Nakryiko 176e82b96a3SAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG orig_gpr2 177e82b96a3SAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 178e82b96a3SAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 179e82b96a3SAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 180e82b96a3SAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 181e82b96a3SAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG gprs[7] 182e82b96a3SAndrii Nakryiko #define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1_CORE_SYSCALL(x) 183e82b96a3SAndrii Nakryiko #define PT_REGS_PARM1_CORE_SYSCALL(x) \ 184e82b96a3SAndrii Nakryiko BPF_CORE_READ((const struct pt_regs___s390 *)(x), __PT_PARM1_SYSCALL_REG) 185e82b96a3SAndrii Nakryiko 1867244eb66SDaniel T. Lee #define __PT_RET_REG gprs[14] 1873cc31d79SAndrii Nakryiko #define __PT_FP_REG gprs[11] /* Works only with CONFIG_FRAME_POINTER */ 1883cc31d79SAndrii Nakryiko #define __PT_RC_REG gprs[2] 1893cc31d79SAndrii Nakryiko #define __PT_SP_REG gprs[15] 1903cc31d79SAndrii Nakryiko #define __PT_IP_REG psw.addr 191b8ebce86SAndrii Nakryiko 192e01a75c1SAndrii Nakryiko #elif defined(bpf_target_arm) 193e01a75c1SAndrii Nakryiko 1941dac40acSAndrii Nakryiko /* 1951dac40acSAndrii Nakryiko * https://github.com/ARM-software/abi-aa/blob/main/aapcs32/aapcs32.rst#machine-registers 1961dac40acSAndrii Nakryiko */ 1971dac40acSAndrii Nakryiko 1983cc31d79SAndrii Nakryiko #define __PT_PARM1_REG uregs[0] 1993cc31d79SAndrii Nakryiko #define __PT_PARM2_REG uregs[1] 2003cc31d79SAndrii Nakryiko #define __PT_PARM3_REG uregs[2] 2013cc31d79SAndrii Nakryiko #define __PT_PARM4_REG uregs[3] 2023a95c42dSAndrii Nakryiko 2033a95c42dSAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG 2043a95c42dSAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 2053a95c42dSAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 2063a95c42dSAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 20706943ae6SPuranjay Mohan #define __PT_PARM5_SYSCALL_REG uregs[4] 2083a95c42dSAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG uregs[5] 2093a95c42dSAndrii Nakryiko #define __PT_PARM7_SYSCALL_REG uregs[6] 2103a95c42dSAndrii Nakryiko 2113cc31d79SAndrii Nakryiko #define __PT_RET_REG uregs[14] 2123cc31d79SAndrii Nakryiko #define __PT_FP_REG uregs[11] /* Works only with CONFIG_FRAME_POINTER */ 2133cc31d79SAndrii Nakryiko #define __PT_RC_REG uregs[0] 2143cc31d79SAndrii Nakryiko #define __PT_SP_REG uregs[13] 2153cc31d79SAndrii Nakryiko #define __PT_IP_REG uregs[12] 216b8ebce86SAndrii Nakryiko 217e01a75c1SAndrii Nakryiko #elif defined(bpf_target_arm64) 218e01a75c1SAndrii Nakryiko 2191dac40acSAndrii Nakryiko /* 2201dac40acSAndrii Nakryiko * https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#machine-registers 2211dac40acSAndrii Nakryiko */ 2221dac40acSAndrii Nakryiko 223fbca4a2fSIlya Leoshkevich struct pt_regs___arm64 { 224fbca4a2fSIlya Leoshkevich unsigned long orig_x0; 225fbca4a2fSIlya Leoshkevich }; 226fbca4a2fSIlya Leoshkevich 227e01a75c1SAndrii Nakryiko /* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */ 2283cc31d79SAndrii Nakryiko #define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x)) 2293cc31d79SAndrii Nakryiko #define __PT_PARM1_REG regs[0] 2303cc31d79SAndrii Nakryiko #define __PT_PARM2_REG regs[1] 2313cc31d79SAndrii Nakryiko #define __PT_PARM3_REG regs[2] 2323cc31d79SAndrii Nakryiko #define __PT_PARM4_REG regs[3] 2333cc31d79SAndrii Nakryiko #define __PT_PARM5_REG regs[4] 2341dac40acSAndrii Nakryiko #define __PT_PARM6_REG regs[5] 2351dac40acSAndrii Nakryiko #define __PT_PARM7_REG regs[6] 2361dac40acSAndrii Nakryiko #define __PT_PARM8_REG regs[7] 2373488ea05SAndrii Nakryiko 2383488ea05SAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG orig_x0 2393488ea05SAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 2403488ea05SAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 2413488ea05SAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 2423488ea05SAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 2433488ea05SAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG 2443488ea05SAndrii Nakryiko #define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1_CORE_SYSCALL(x) 2453488ea05SAndrii Nakryiko #define PT_REGS_PARM1_CORE_SYSCALL(x) \ 2463488ea05SAndrii Nakryiko BPF_CORE_READ((const struct pt_regs___arm64 *)(x), __PT_PARM1_SYSCALL_REG) 2473488ea05SAndrii Nakryiko 2483cc31d79SAndrii Nakryiko #define __PT_RET_REG regs[30] 2493cc31d79SAndrii Nakryiko #define __PT_FP_REG regs[29] /* Works only with CONFIG_FRAME_POINTER */ 2503cc31d79SAndrii Nakryiko #define __PT_RC_REG regs[0] 2513cc31d79SAndrii Nakryiko #define __PT_SP_REG sp 2523cc31d79SAndrii Nakryiko #define __PT_IP_REG pc 253b8ebce86SAndrii Nakryiko 254e01a75c1SAndrii Nakryiko #elif defined(bpf_target_mips) 255e01a75c1SAndrii Nakryiko 2561222445aSAndrii Nakryiko /* 2571222445aSAndrii Nakryiko * N64 ABI is assumed right now. 2581222445aSAndrii Nakryiko * https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions 2591222445aSAndrii Nakryiko */ 2601222445aSAndrii Nakryiko 2613cc31d79SAndrii Nakryiko #define __PT_PARM1_REG regs[4] 2623cc31d79SAndrii Nakryiko #define __PT_PARM2_REG regs[5] 2633cc31d79SAndrii Nakryiko #define __PT_PARM3_REG regs[6] 2643cc31d79SAndrii Nakryiko #define __PT_PARM4_REG regs[7] 2653cc31d79SAndrii Nakryiko #define __PT_PARM5_REG regs[8] 2661222445aSAndrii Nakryiko #define __PT_PARM6_REG regs[9] 2671222445aSAndrii Nakryiko #define __PT_PARM7_REG regs[10] 2681222445aSAndrii Nakryiko #define __PT_PARM8_REG regs[11] 269cfd0bbe9SAndrii Nakryiko 270cfd0bbe9SAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG 271cfd0bbe9SAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 272cfd0bbe9SAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 273cfd0bbe9SAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 274cfd0bbe9SAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG /* only N32/N64 */ 275cfd0bbe9SAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG /* only N32/N64 */ 276cfd0bbe9SAndrii Nakryiko 2773cc31d79SAndrii Nakryiko #define __PT_RET_REG regs[31] 2783cc31d79SAndrii Nakryiko #define __PT_FP_REG regs[30] /* Works only with CONFIG_FRAME_POINTER */ 2793cc31d79SAndrii Nakryiko #define __PT_RC_REG regs[2] 2803cc31d79SAndrii Nakryiko #define __PT_SP_REG regs[29] 2813cc31d79SAndrii Nakryiko #define __PT_IP_REG cp0_epc 282b8ebce86SAndrii Nakryiko 283e01a75c1SAndrii Nakryiko #elif defined(bpf_target_powerpc) 284e01a75c1SAndrii Nakryiko 2852eb2be30SAndrii Nakryiko /* 2862eb2be30SAndrii Nakryiko * http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf (page 3-14, 2872eb2be30SAndrii Nakryiko * section "Function Calling Sequence") 2882eb2be30SAndrii Nakryiko */ 2892eb2be30SAndrii Nakryiko 2903cc31d79SAndrii Nakryiko #define __PT_PARM1_REG gpr[3] 2913cc31d79SAndrii Nakryiko #define __PT_PARM2_REG gpr[4] 2923cc31d79SAndrii Nakryiko #define __PT_PARM3_REG gpr[5] 2933cc31d79SAndrii Nakryiko #define __PT_PARM4_REG gpr[6] 2943cc31d79SAndrii Nakryiko #define __PT_PARM5_REG gpr[7] 2952eb2be30SAndrii Nakryiko #define __PT_PARM6_REG gpr[8] 2962eb2be30SAndrii Nakryiko #define __PT_PARM7_REG gpr[9] 2972eb2be30SAndrii Nakryiko #define __PT_PARM8_REG gpr[10] 298c1cc01a2SAndrii Nakryiko 299c1cc01a2SAndrii Nakryiko /* powerpc does not select ARCH_HAS_SYSCALL_WRAPPER. */ 300c1cc01a2SAndrii Nakryiko #define PT_REGS_SYSCALL_REGS(ctx) ctx 301c1cc01a2SAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG orig_gpr3 302c1cc01a2SAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 303c1cc01a2SAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 304c1cc01a2SAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 305c1cc01a2SAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 306c1cc01a2SAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG 307c1cc01a2SAndrii Nakryiko #if !defined(__arch64__) 308c1cc01a2SAndrii Nakryiko #define __PT_PARM7_SYSCALL_REG __PT_PARM7_REG /* only powerpc (not powerpc64) */ 309c1cc01a2SAndrii Nakryiko #endif 310c1cc01a2SAndrii Nakryiko 3113cc31d79SAndrii Nakryiko #define __PT_RET_REG regs[31] 3123cc31d79SAndrii Nakryiko #define __PT_FP_REG __unsupported__ 3133cc31d79SAndrii Nakryiko #define __PT_RC_REG gpr[3] 3143cc31d79SAndrii Nakryiko #define __PT_SP_REG sp 3153cc31d79SAndrii Nakryiko #define __PT_IP_REG nip 316b8ebce86SAndrii Nakryiko 317e01a75c1SAndrii Nakryiko #elif defined(bpf_target_sparc) 318e01a75c1SAndrii Nakryiko 3197f60f5d8SAndrii Nakryiko /* 3207f60f5d8SAndrii Nakryiko * https://en.wikipedia.org/wiki/Calling_convention#SPARC 3217f60f5d8SAndrii Nakryiko */ 3227f60f5d8SAndrii Nakryiko 3233cc31d79SAndrii Nakryiko #define __PT_PARM1_REG u_regs[UREG_I0] 3243cc31d79SAndrii Nakryiko #define __PT_PARM2_REG u_regs[UREG_I1] 3253cc31d79SAndrii Nakryiko #define __PT_PARM3_REG u_regs[UREG_I2] 3263cc31d79SAndrii Nakryiko #define __PT_PARM4_REG u_regs[UREG_I3] 3273cc31d79SAndrii Nakryiko #define __PT_PARM5_REG u_regs[UREG_I4] 3287f60f5d8SAndrii Nakryiko #define __PT_PARM6_REG u_regs[UREG_I5] 329377c15b1SAndrii Nakryiko 330377c15b1SAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG 331377c15b1SAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 332377c15b1SAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 333377c15b1SAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 334377c15b1SAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 335377c15b1SAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG 336377c15b1SAndrii Nakryiko 3373cc31d79SAndrii Nakryiko #define __PT_RET_REG u_regs[UREG_I7] 3383cc31d79SAndrii Nakryiko #define __PT_FP_REG __unsupported__ 3393cc31d79SAndrii Nakryiko #define __PT_RC_REG u_regs[UREG_I0] 3403cc31d79SAndrii Nakryiko #define __PT_SP_REG u_regs[UREG_FP] 341e01a75c1SAndrii Nakryiko /* Should this also be a bpf_target check for the sparc case? */ 342e01a75c1SAndrii Nakryiko #if defined(__arch64__) 3433cc31d79SAndrii Nakryiko #define __PT_IP_REG tpc 344e01a75c1SAndrii Nakryiko #else 3453cc31d79SAndrii Nakryiko #define __PT_IP_REG pc 346e01a75c1SAndrii Nakryiko #endif 347e01a75c1SAndrii Nakryiko 348589fed47SBjörn Töpel #elif defined(bpf_target_riscv) 349589fed47SBjörn Töpel 350b13ed8caSAndrii Nakryiko /* 351b13ed8caSAndrii Nakryiko * https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#risc-v-calling-conventions 352b13ed8caSAndrii Nakryiko */ 353b13ed8caSAndrii Nakryiko 3547866fc6aSKenjiro Nakayama /* riscv provides struct user_regs_struct instead of struct pt_regs to userspace */ 3553cc31d79SAndrii Nakryiko #define __PT_REGS_CAST(x) ((const struct user_regs_struct *)(x)) 3563cc31d79SAndrii Nakryiko #define __PT_PARM1_REG a0 3573cc31d79SAndrii Nakryiko #define __PT_PARM2_REG a1 3583cc31d79SAndrii Nakryiko #define __PT_PARM3_REG a2 3593cc31d79SAndrii Nakryiko #define __PT_PARM4_REG a3 3603cc31d79SAndrii Nakryiko #define __PT_PARM5_REG a4 361b13ed8caSAndrii Nakryiko #define __PT_PARM6_REG a5 362b13ed8caSAndrii Nakryiko #define __PT_PARM7_REG a6 363b13ed8caSAndrii Nakryiko #define __PT_PARM8_REG a7 364a0426216SAndrii Nakryiko 365a0426216SAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG 366a0426216SAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 367a0426216SAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 368a0426216SAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 369a0426216SAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 370a0426216SAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG 371a0426216SAndrii Nakryiko 3723cc31d79SAndrii Nakryiko #define __PT_RET_REG ra 3735c101153SIlya Leoshkevich #define __PT_FP_REG s0 374935dc35cSYixun Lan #define __PT_RC_REG a0 3753cc31d79SAndrii Nakryiko #define __PT_SP_REG sp 3765c101153SIlya Leoshkevich #define __PT_IP_REG pc 377589fed47SBjörn Töpel 37807385998SVladimir Isaev #elif defined(bpf_target_arc) 37907385998SVladimir Isaev 3800ac08656SAndrii Nakryiko /* 3810ac08656SAndrii Nakryiko * Section "Function Calling Sequence" (page 24): 3820ac08656SAndrii Nakryiko * https://raw.githubusercontent.com/wiki/foss-for-synopsys-dwc-arc-processors/toolchain/files/ARCv2_ABI.pdf 3830ac08656SAndrii Nakryiko */ 3840ac08656SAndrii Nakryiko 3857866fc6aSKenjiro Nakayama /* arc provides struct user_regs_struct instead of struct pt_regs to userspace */ 38607385998SVladimir Isaev #define __PT_REGS_CAST(x) ((const struct user_regs_struct *)(x)) 38707385998SVladimir Isaev #define __PT_PARM1_REG scratch.r0 38807385998SVladimir Isaev #define __PT_PARM2_REG scratch.r1 38907385998SVladimir Isaev #define __PT_PARM3_REG scratch.r2 39007385998SVladimir Isaev #define __PT_PARM4_REG scratch.r3 39107385998SVladimir Isaev #define __PT_PARM5_REG scratch.r4 3920ac08656SAndrii Nakryiko #define __PT_PARM6_REG scratch.r5 3930ac08656SAndrii Nakryiko #define __PT_PARM7_REG scratch.r6 3940ac08656SAndrii Nakryiko #define __PT_PARM8_REG scratch.r7 3952cf80273SAndrii Nakryiko 3962cf80273SAndrii Nakryiko /* arc does not select ARCH_HAS_SYSCALL_WRAPPER. */ 3972cf80273SAndrii Nakryiko #define PT_REGS_SYSCALL_REGS(ctx) ctx 3982cf80273SAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG 3992cf80273SAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 4002cf80273SAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 4012cf80273SAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 4022cf80273SAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 4032cf80273SAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG 4042cf80273SAndrii Nakryiko 40507385998SVladimir Isaev #define __PT_RET_REG scratch.blink 4060ac08656SAndrii Nakryiko #define __PT_FP_REG scratch.fp 40707385998SVladimir Isaev #define __PT_RC_REG scratch.r0 40807385998SVladimir Isaev #define __PT_SP_REG scratch.sp 40907385998SVladimir Isaev #define __PT_IP_REG scratch.ret 41007385998SVladimir Isaev 41100883922SHengqi Chen #elif defined(bpf_target_loongarch) 41200883922SHengqi Chen 41355ff00d5SAndrii Nakryiko /* 41455ff00d5SAndrii Nakryiko * https://docs.kernel.org/loongarch/introduction.html 41555ff00d5SAndrii Nakryiko * https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html 41655ff00d5SAndrii Nakryiko */ 41700883922SHengqi Chen 41829c66ad1STiezhu Yang /* loongarch provides struct user_pt_regs instead of struct pt_regs to userspace */ 41929c66ad1STiezhu Yang #define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x)) 42000883922SHengqi Chen #define __PT_PARM1_REG regs[4] 42100883922SHengqi Chen #define __PT_PARM2_REG regs[5] 42200883922SHengqi Chen #define __PT_PARM3_REG regs[6] 42300883922SHengqi Chen #define __PT_PARM4_REG regs[7] 42400883922SHengqi Chen #define __PT_PARM5_REG regs[8] 42555ff00d5SAndrii Nakryiko #define __PT_PARM6_REG regs[9] 42655ff00d5SAndrii Nakryiko #define __PT_PARM7_REG regs[10] 42755ff00d5SAndrii Nakryiko #define __PT_PARM8_REG regs[11] 42812a299f0SAndrii Nakryiko 42912a299f0SAndrii Nakryiko /* loongarch does not select ARCH_HAS_SYSCALL_WRAPPER. */ 43012a299f0SAndrii Nakryiko #define PT_REGS_SYSCALL_REGS(ctx) ctx 43112a299f0SAndrii Nakryiko #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG 43212a299f0SAndrii Nakryiko #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG 43312a299f0SAndrii Nakryiko #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG 43412a299f0SAndrii Nakryiko #define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG 43512a299f0SAndrii Nakryiko #define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG 43612a299f0SAndrii Nakryiko #define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG 43712a299f0SAndrii Nakryiko 43800883922SHengqi Chen #define __PT_RET_REG regs[1] 43900883922SHengqi Chen #define __PT_FP_REG regs[22] 44000883922SHengqi Chen #define __PT_RC_REG regs[4] 44100883922SHengqi Chen #define __PT_SP_REG regs[3] 44200883922SHengqi Chen #define __PT_IP_REG csr_era 44300883922SHengqi Chen 444e01a75c1SAndrii Nakryiko #endif 445e01a75c1SAndrii Nakryiko 4463cc31d79SAndrii Nakryiko #if defined(bpf_target_defined) 4473cc31d79SAndrii Nakryiko 4483cc31d79SAndrii Nakryiko struct pt_regs; 4493cc31d79SAndrii Nakryiko 4503c59623dSAndrii Nakryiko /* allow some architectures to override `struct pt_regs` */ 4513cc31d79SAndrii Nakryiko #ifndef __PT_REGS_CAST 4523cc31d79SAndrii Nakryiko #define __PT_REGS_CAST(x) (x) 4533cc31d79SAndrii Nakryiko #endif 4543cc31d79SAndrii Nakryiko 4553c59623dSAndrii Nakryiko /* 4563c59623dSAndrii Nakryiko * Different architectures support different number of arguments passed 4573c59623dSAndrii Nakryiko * through registers. i386 supports just 3, some arches support up to 8. 4583c59623dSAndrii Nakryiko */ 4593c59623dSAndrii Nakryiko #ifndef __PT_PARM4_REG 4603c59623dSAndrii Nakryiko #define __PT_PARM4_REG __unsupported__ 4613c59623dSAndrii Nakryiko #endif 4623c59623dSAndrii Nakryiko #ifndef __PT_PARM5_REG 4633c59623dSAndrii Nakryiko #define __PT_PARM5_REG __unsupported__ 4643c59623dSAndrii Nakryiko #endif 4653c59623dSAndrii Nakryiko #ifndef __PT_PARM6_REG 4663c59623dSAndrii Nakryiko #define __PT_PARM6_REG __unsupported__ 4673c59623dSAndrii Nakryiko #endif 4683c59623dSAndrii Nakryiko #ifndef __PT_PARM7_REG 4693c59623dSAndrii Nakryiko #define __PT_PARM7_REG __unsupported__ 4703c59623dSAndrii Nakryiko #endif 4713c59623dSAndrii Nakryiko #ifndef __PT_PARM8_REG 4723c59623dSAndrii Nakryiko #define __PT_PARM8_REG __unsupported__ 4733c59623dSAndrii Nakryiko #endif 4748ccabeefSAndrii Nakryiko /* 4758ccabeefSAndrii Nakryiko * Similarly, syscall-specific conventions might differ between function call 4768ccabeefSAndrii Nakryiko * conventions within each architecutre. All supported architectures pass 4778ccabeefSAndrii Nakryiko * either 6 or 7 syscall arguments in registers. 4788ccabeefSAndrii Nakryiko * 4798ccabeefSAndrii Nakryiko * See syscall(2) manpage for succinct table with information on each arch. 4808ccabeefSAndrii Nakryiko */ 4818ccabeefSAndrii Nakryiko #ifndef __PT_PARM7_SYSCALL_REG 4828ccabeefSAndrii Nakryiko #define __PT_PARM7_SYSCALL_REG __unsupported__ 4838ccabeefSAndrii Nakryiko #endif 4843c59623dSAndrii Nakryiko 4853cc31d79SAndrii Nakryiko #define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG) 4863cc31d79SAndrii Nakryiko #define PT_REGS_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG) 4873cc31d79SAndrii Nakryiko #define PT_REGS_PARM3(x) (__PT_REGS_CAST(x)->__PT_PARM3_REG) 4883cc31d79SAndrii Nakryiko #define PT_REGS_PARM4(x) (__PT_REGS_CAST(x)->__PT_PARM4_REG) 4893cc31d79SAndrii Nakryiko #define PT_REGS_PARM5(x) (__PT_REGS_CAST(x)->__PT_PARM5_REG) 4903c59623dSAndrii Nakryiko #define PT_REGS_PARM6(x) (__PT_REGS_CAST(x)->__PT_PARM6_REG) 4913c59623dSAndrii Nakryiko #define PT_REGS_PARM7(x) (__PT_REGS_CAST(x)->__PT_PARM7_REG) 4923c59623dSAndrii Nakryiko #define PT_REGS_PARM8(x) (__PT_REGS_CAST(x)->__PT_PARM8_REG) 4933cc31d79SAndrii Nakryiko #define PT_REGS_RET(x) (__PT_REGS_CAST(x)->__PT_RET_REG) 4943cc31d79SAndrii Nakryiko #define PT_REGS_FP(x) (__PT_REGS_CAST(x)->__PT_FP_REG) 4953cc31d79SAndrii Nakryiko #define PT_REGS_RC(x) (__PT_REGS_CAST(x)->__PT_RC_REG) 4963cc31d79SAndrii Nakryiko #define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG) 4973cc31d79SAndrii Nakryiko #define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG) 4983cc31d79SAndrii Nakryiko 4993cc31d79SAndrii Nakryiko #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM1_REG) 5003cc31d79SAndrii Nakryiko #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM2_REG) 5013cc31d79SAndrii Nakryiko #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM3_REG) 5023cc31d79SAndrii Nakryiko #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM4_REG) 5033cc31d79SAndrii Nakryiko #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM5_REG) 5043c59623dSAndrii Nakryiko #define PT_REGS_PARM6_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM6_REG) 5053c59623dSAndrii Nakryiko #define PT_REGS_PARM7_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM7_REG) 5063c59623dSAndrii Nakryiko #define PT_REGS_PARM8_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM8_REG) 5073cc31d79SAndrii Nakryiko #define PT_REGS_RET_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_RET_REG) 5083cc31d79SAndrii Nakryiko #define PT_REGS_FP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_FP_REG) 5093cc31d79SAndrii Nakryiko #define PT_REGS_RC_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_RC_REG) 5103cc31d79SAndrii Nakryiko #define PT_REGS_SP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_SP_REG) 5113cc31d79SAndrii Nakryiko #define PT_REGS_IP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_IP_REG) 5123cc31d79SAndrii Nakryiko 513e01a75c1SAndrii Nakryiko #if defined(bpf_target_powerpc) 5143cc31d79SAndrii Nakryiko 515e01a75c1SAndrii Nakryiko #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; }) 516e01a75c1SAndrii Nakryiko #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP 5173cc31d79SAndrii Nakryiko 518e01a75c1SAndrii Nakryiko #elif defined(bpf_target_sparc) 5193cc31d79SAndrii Nakryiko 520e01a75c1SAndrii Nakryiko #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = PT_REGS_RET(ctx); }) 521e01a75c1SAndrii Nakryiko #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP 5223cc31d79SAndrii Nakryiko 5233cc31d79SAndrii Nakryiko #else 5243cc31d79SAndrii Nakryiko 525e01a75c1SAndrii Nakryiko #define BPF_KPROBE_READ_RET_IP(ip, ctx) \ 52670785cfbSAndrii Nakryiko ({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); }) 527e01a75c1SAndrii Nakryiko #define BPF_KRETPROBE_READ_RET_IP(ip, ctx) \ 5283cc31d79SAndrii Nakryiko ({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)(PT_REGS_FP(ctx) + sizeof(ip))); }) 5293cc31d79SAndrii Nakryiko 530e01a75c1SAndrii Nakryiko #endif 531e01a75c1SAndrii Nakryiko 53260d16c5cSIlya Leoshkevich #ifndef PT_REGS_PARM1_SYSCALL 5338ccabeefSAndrii Nakryiko #define PT_REGS_PARM1_SYSCALL(x) (__PT_REGS_CAST(x)->__PT_PARM1_SYSCALL_REG) 5348ccabeefSAndrii Nakryiko #define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM1_SYSCALL_REG) 53560d16c5cSIlya Leoshkevich #endif 5368ccabeefSAndrii Nakryiko #ifndef PT_REGS_PARM2_SYSCALL 5378ccabeefSAndrii Nakryiko #define PT_REGS_PARM2_SYSCALL(x) (__PT_REGS_CAST(x)->__PT_PARM2_SYSCALL_REG) 5388ccabeefSAndrii Nakryiko #define PT_REGS_PARM2_CORE_SYSCALL(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM2_SYSCALL_REG) 5398ccabeefSAndrii Nakryiko #endif 5408ccabeefSAndrii Nakryiko #ifndef PT_REGS_PARM3_SYSCALL 5418ccabeefSAndrii Nakryiko #define PT_REGS_PARM3_SYSCALL(x) (__PT_REGS_CAST(x)->__PT_PARM3_SYSCALL_REG) 5428ccabeefSAndrii Nakryiko #define PT_REGS_PARM3_CORE_SYSCALL(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM3_SYSCALL_REG) 5438ccabeefSAndrii Nakryiko #endif 54460d16c5cSIlya Leoshkevich #ifndef PT_REGS_PARM4_SYSCALL 5458ccabeefSAndrii Nakryiko #define PT_REGS_PARM4_SYSCALL(x) (__PT_REGS_CAST(x)->__PT_PARM4_SYSCALL_REG) 5468ccabeefSAndrii Nakryiko #define PT_REGS_PARM4_CORE_SYSCALL(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM4_SYSCALL_REG) 547d084df3bSKenta Tada #endif 5488ccabeefSAndrii Nakryiko #ifndef PT_REGS_PARM5_SYSCALL 5498ccabeefSAndrii Nakryiko #define PT_REGS_PARM5_SYSCALL(x) (__PT_REGS_CAST(x)->__PT_PARM5_SYSCALL_REG) 5508ccabeefSAndrii Nakryiko #define PT_REGS_PARM5_CORE_SYSCALL(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM5_SYSCALL_REG) 55160d16c5cSIlya Leoshkevich #endif 5528ccabeefSAndrii Nakryiko #ifndef PT_REGS_PARM6_SYSCALL 5538ccabeefSAndrii Nakryiko #define PT_REGS_PARM6_SYSCALL(x) (__PT_REGS_CAST(x)->__PT_PARM6_SYSCALL_REG) 5548ccabeefSAndrii Nakryiko #define PT_REGS_PARM6_CORE_SYSCALL(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM6_SYSCALL_REG) 555d084df3bSKenta Tada #endif 5568ccabeefSAndrii Nakryiko #ifndef PT_REGS_PARM7_SYSCALL 5578ccabeefSAndrii Nakryiko #define PT_REGS_PARM7_SYSCALL(x) (__PT_REGS_CAST(x)->__PT_PARM7_SYSCALL_REG) 5588ccabeefSAndrii Nakryiko #define PT_REGS_PARM7_CORE_SYSCALL(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM7_SYSCALL_REG) 5598ccabeefSAndrii Nakryiko #endif 560d084df3bSKenta Tada 5613cc31d79SAndrii Nakryiko #else /* defined(bpf_target_defined) */ 5624a638d58SLorenz Bauer 5634a638d58SLorenz Bauer #define PT_REGS_PARM1(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5644a638d58SLorenz Bauer #define PT_REGS_PARM2(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5654a638d58SLorenz Bauer #define PT_REGS_PARM3(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5664a638d58SLorenz Bauer #define PT_REGS_PARM4(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5674a638d58SLorenz Bauer #define PT_REGS_PARM5(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5683c59623dSAndrii Nakryiko #define PT_REGS_PARM6(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5693c59623dSAndrii Nakryiko #define PT_REGS_PARM7(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5703c59623dSAndrii Nakryiko #define PT_REGS_PARM8(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5714a638d58SLorenz Bauer #define PT_REGS_RET(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5724a638d58SLorenz Bauer #define PT_REGS_FP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5734a638d58SLorenz Bauer #define PT_REGS_RC(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5744a638d58SLorenz Bauer #define PT_REGS_SP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5754a638d58SLorenz Bauer #define PT_REGS_IP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5764a638d58SLorenz Bauer 5774a638d58SLorenz Bauer #define PT_REGS_PARM1_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5784a638d58SLorenz Bauer #define PT_REGS_PARM2_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5794a638d58SLorenz Bauer #define PT_REGS_PARM3_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5804a638d58SLorenz Bauer #define PT_REGS_PARM4_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5814a638d58SLorenz Bauer #define PT_REGS_PARM5_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5823c59623dSAndrii Nakryiko #define PT_REGS_PARM6_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5833c59623dSAndrii Nakryiko #define PT_REGS_PARM7_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5843c59623dSAndrii Nakryiko #define PT_REGS_PARM8_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5854a638d58SLorenz Bauer #define PT_REGS_RET_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5864a638d58SLorenz Bauer #define PT_REGS_FP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5874a638d58SLorenz Bauer #define PT_REGS_RC_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5884a638d58SLorenz Bauer #define PT_REGS_SP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5894a638d58SLorenz Bauer #define PT_REGS_IP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5904a638d58SLorenz Bauer 5914a638d58SLorenz Bauer #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5924a638d58SLorenz Bauer #define BPF_KRETPROBE_READ_RET_IP(ip, ctx) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5934a638d58SLorenz Bauer 594d084df3bSKenta Tada #define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 595d084df3bSKenta Tada #define PT_REGS_PARM2_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 596d084df3bSKenta Tada #define PT_REGS_PARM3_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 597d084df3bSKenta Tada #define PT_REGS_PARM4_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 598d084df3bSKenta Tada #define PT_REGS_PARM5_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 5998ccabeefSAndrii Nakryiko #define PT_REGS_PARM6_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 6008ccabeefSAndrii Nakryiko #define PT_REGS_PARM7_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 601d084df3bSKenta Tada 602d084df3bSKenta Tada #define PT_REGS_PARM1_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 603d084df3bSKenta Tada #define PT_REGS_PARM2_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 604d084df3bSKenta Tada #define PT_REGS_PARM3_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 605d084df3bSKenta Tada #define PT_REGS_PARM4_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 606d084df3bSKenta Tada #define PT_REGS_PARM5_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 6078ccabeefSAndrii Nakryiko #define PT_REGS_PARM6_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 6088ccabeefSAndrii Nakryiko #define PT_REGS_PARM7_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 609d084df3bSKenta Tada 6103cc31d79SAndrii Nakryiko #endif /* defined(bpf_target_defined) */ 6114a638d58SLorenz Bauer 612c5a1ffa0SIlya Leoshkevich /* 613c5a1ffa0SIlya Leoshkevich * When invoked from a syscall handler kprobe, returns a pointer to a 614c5a1ffa0SIlya Leoshkevich * struct pt_regs containing syscall arguments and suitable for passing to 615c5a1ffa0SIlya Leoshkevich * PT_REGS_PARMn_SYSCALL() and PT_REGS_PARMn_CORE_SYSCALL(). 616c5a1ffa0SIlya Leoshkevich */ 617c5a1ffa0SIlya Leoshkevich #ifndef PT_REGS_SYSCALL_REGS 618c5a1ffa0SIlya Leoshkevich /* By default, assume that the arch selects ARCH_HAS_SYSCALL_WRAPPER. */ 619c5a1ffa0SIlya Leoshkevich #define PT_REGS_SYSCALL_REGS(ctx) ((struct pt_regs *)PT_REGS_PARM1(ctx)) 620c5a1ffa0SIlya Leoshkevich #endif 621c5a1ffa0SIlya Leoshkevich 622d6a6a555SFlorent Revest #ifndef ___bpf_concat 623df8ff353SAndrii Nakryiko #define ___bpf_concat(a, b) a ## b 624d6a6a555SFlorent Revest #endif 625d6a6a555SFlorent Revest #ifndef ___bpf_apply 626df8ff353SAndrii Nakryiko #define ___bpf_apply(fn, n) ___bpf_concat(fn, n) 627d6a6a555SFlorent Revest #endif 628d6a6a555SFlorent Revest #ifndef ___bpf_nth 629df8ff353SAndrii Nakryiko #define ___bpf_nth(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, N, ...) N 630d6a6a555SFlorent Revest #endif 631d6a6a555SFlorent Revest #ifndef ___bpf_narg 632f60edf5bSAndrii Nakryiko #define ___bpf_narg(...) ___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 633d6a6a555SFlorent Revest #endif 634df8ff353SAndrii Nakryiko 635df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast0() ctx 636df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast1(x) ___bpf_ctx_cast0(), (void *)ctx[0] 637df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast2(x, args...) ___bpf_ctx_cast1(args), (void *)ctx[1] 638df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast3(x, args...) ___bpf_ctx_cast2(args), (void *)ctx[2] 639df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast4(x, args...) ___bpf_ctx_cast3(args), (void *)ctx[3] 640df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast5(x, args...) ___bpf_ctx_cast4(args), (void *)ctx[4] 641df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast6(x, args...) ___bpf_ctx_cast5(args), (void *)ctx[5] 642df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast7(x, args...) ___bpf_ctx_cast6(args), (void *)ctx[6] 643df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast8(x, args...) ___bpf_ctx_cast7(args), (void *)ctx[7] 644df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast9(x, args...) ___bpf_ctx_cast8(args), (void *)ctx[8] 645df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast10(x, args...) ___bpf_ctx_cast9(args), (void *)ctx[9] 646df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast11(x, args...) ___bpf_ctx_cast10(args), (void *)ctx[10] 647df8ff353SAndrii Nakryiko #define ___bpf_ctx_cast12(x, args...) ___bpf_ctx_cast11(args), (void *)ctx[11] 648f60edf5bSAndrii Nakryiko #define ___bpf_ctx_cast(args...) ___bpf_apply(___bpf_ctx_cast, ___bpf_narg(args))(args) 649df8ff353SAndrii Nakryiko 650df8ff353SAndrii Nakryiko /* 651df8ff353SAndrii Nakryiko * BPF_PROG is a convenience wrapper for generic tp_btf/fentry/fexit and 652df8ff353SAndrii Nakryiko * similar kinds of BPF programs, that accept input arguments as a single 653df8ff353SAndrii Nakryiko * pointer to untyped u64 array, where each u64 can actually be a typed 654df8ff353SAndrii Nakryiko * pointer or integer of different size. Instead of requring user to write 655df8ff353SAndrii Nakryiko * manual casts and work with array elements by index, BPF_PROG macro 656df8ff353SAndrii Nakryiko * allows user to declare a list of named and typed input arguments in the 657df8ff353SAndrii Nakryiko * same syntax as for normal C function. All the casting is hidden and 658df8ff353SAndrii Nakryiko * performed transparently, while user code can just assume working with 659df8ff353SAndrii Nakryiko * function arguments of specified type and name. 660df8ff353SAndrii Nakryiko * 661df8ff353SAndrii Nakryiko * Original raw context argument is preserved as well as 'ctx' argument. 662df8ff353SAndrii Nakryiko * This is useful when using BPF helpers that expect original context 663df8ff353SAndrii Nakryiko * as one of the parameters (e.g., for bpf_perf_event_output()). 664df8ff353SAndrii Nakryiko */ 665df8ff353SAndrii Nakryiko #define BPF_PROG(name, args...) \ 666df8ff353SAndrii Nakryiko name(unsigned long long *ctx); \ 667d25f40ffSJames Hilliard static __always_inline typeof(name(0)) \ 668df8ff353SAndrii Nakryiko ____##name(unsigned long long *ctx, ##args); \ 669df8ff353SAndrii Nakryiko typeof(name(0)) name(unsigned long long *ctx) \ 670df8ff353SAndrii Nakryiko { \ 671df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic push") \ 672df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ 673df8ff353SAndrii Nakryiko return ____##name(___bpf_ctx_cast(args)); \ 674df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic pop") \ 675df8ff353SAndrii Nakryiko } \ 676d25f40ffSJames Hilliard static __always_inline typeof(name(0)) \ 677df8ff353SAndrii Nakryiko ____##name(unsigned long long *ctx, ##args) 678df8ff353SAndrii Nakryiko 6799f2f5d78SYonghong Song #ifndef ___bpf_nth2 6809f2f5d78SYonghong Song #define ___bpf_nth2(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ 6819f2f5d78SYonghong Song _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, N, ...) N 68234586d29SYonghong Song #endif 6839f2f5d78SYonghong Song #ifndef ___bpf_narg2 6849f2f5d78SYonghong Song #define ___bpf_narg2(...) \ 6859f2f5d78SYonghong Song ___bpf_nth2(_, ##__VA_ARGS__, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, \ 6869f2f5d78SYonghong Song 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0) 68734586d29SYonghong Song #endif 68834586d29SYonghong Song 6899f2f5d78SYonghong Song #define ___bpf_treg_cnt(t) \ 6909f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 1, 1, \ 6919f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 2, 1, \ 6929f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 4, 1, \ 6939f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 8, 1, \ 69434586d29SYonghong Song __builtin_choose_expr(sizeof(t) == 16, 2, \ 69534586d29SYonghong Song (void)0))))) 69634586d29SYonghong Song 6979f2f5d78SYonghong Song #define ___bpf_reg_cnt0() (0) 6989f2f5d78SYonghong Song #define ___bpf_reg_cnt1(t, x) (___bpf_reg_cnt0() + ___bpf_treg_cnt(t)) 6999f2f5d78SYonghong Song #define ___bpf_reg_cnt2(t, x, args...) (___bpf_reg_cnt1(args) + ___bpf_treg_cnt(t)) 7009f2f5d78SYonghong Song #define ___bpf_reg_cnt3(t, x, args...) (___bpf_reg_cnt2(args) + ___bpf_treg_cnt(t)) 7019f2f5d78SYonghong Song #define ___bpf_reg_cnt4(t, x, args...) (___bpf_reg_cnt3(args) + ___bpf_treg_cnt(t)) 7029f2f5d78SYonghong Song #define ___bpf_reg_cnt5(t, x, args...) (___bpf_reg_cnt4(args) + ___bpf_treg_cnt(t)) 7039f2f5d78SYonghong Song #define ___bpf_reg_cnt6(t, x, args...) (___bpf_reg_cnt5(args) + ___bpf_treg_cnt(t)) 7049f2f5d78SYonghong Song #define ___bpf_reg_cnt7(t, x, args...) (___bpf_reg_cnt6(args) + ___bpf_treg_cnt(t)) 7059f2f5d78SYonghong Song #define ___bpf_reg_cnt8(t, x, args...) (___bpf_reg_cnt7(args) + ___bpf_treg_cnt(t)) 7069f2f5d78SYonghong Song #define ___bpf_reg_cnt9(t, x, args...) (___bpf_reg_cnt8(args) + ___bpf_treg_cnt(t)) 7079f2f5d78SYonghong Song #define ___bpf_reg_cnt10(t, x, args...) (___bpf_reg_cnt9(args) + ___bpf_treg_cnt(t)) 7089f2f5d78SYonghong Song #define ___bpf_reg_cnt11(t, x, args...) (___bpf_reg_cnt10(args) + ___bpf_treg_cnt(t)) 7099f2f5d78SYonghong Song #define ___bpf_reg_cnt12(t, x, args...) (___bpf_reg_cnt11(args) + ___bpf_treg_cnt(t)) 7109f2f5d78SYonghong Song #define ___bpf_reg_cnt(args...) ___bpf_apply(___bpf_reg_cnt, ___bpf_narg2(args))(args) 71134586d29SYonghong Song 7129f2f5d78SYonghong Song #define ___bpf_union_arg(t, x, n) \ 7139f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 1, ({ union { __u8 z[1]; t x; } ___t = { .z = {ctx[n]}}; ___t.x; }), \ 7149f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 2, ({ union { __u16 z[1]; t x; } ___t = { .z = {ctx[n]} }; ___t.x; }), \ 7159f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 4, ({ union { __u32 z[1]; t x; } ___t = { .z = {ctx[n]} }; ___t.x; }), \ 7169f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 8, ({ union { __u64 z[1]; t x; } ___t = {.z = {ctx[n]} }; ___t.x; }), \ 7179f2f5d78SYonghong Song __builtin_choose_expr(sizeof(t) == 16, ({ union { __u64 z[2]; t x; } ___t = {.z = {ctx[n], ctx[n + 1]} }; ___t.x; }), \ 7189f2f5d78SYonghong Song (void)0))))) 7199f2f5d78SYonghong Song 7209f2f5d78SYonghong Song #define ___bpf_ctx_arg0(n, args...) 7219f2f5d78SYonghong Song #define ___bpf_ctx_arg1(n, t, x) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt1(t, x)) 7229f2f5d78SYonghong Song #define ___bpf_ctx_arg2(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt2(t, x, args)) ___bpf_ctx_arg1(n, args) 7239f2f5d78SYonghong Song #define ___bpf_ctx_arg3(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt3(t, x, args)) ___bpf_ctx_arg2(n, args) 7249f2f5d78SYonghong Song #define ___bpf_ctx_arg4(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt4(t, x, args)) ___bpf_ctx_arg3(n, args) 7259f2f5d78SYonghong Song #define ___bpf_ctx_arg5(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt5(t, x, args)) ___bpf_ctx_arg4(n, args) 7269f2f5d78SYonghong Song #define ___bpf_ctx_arg6(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt6(t, x, args)) ___bpf_ctx_arg5(n, args) 7279f2f5d78SYonghong Song #define ___bpf_ctx_arg7(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt7(t, x, args)) ___bpf_ctx_arg6(n, args) 7289f2f5d78SYonghong Song #define ___bpf_ctx_arg8(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt8(t, x, args)) ___bpf_ctx_arg7(n, args) 7299f2f5d78SYonghong Song #define ___bpf_ctx_arg9(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt9(t, x, args)) ___bpf_ctx_arg8(n, args) 7309f2f5d78SYonghong Song #define ___bpf_ctx_arg10(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt10(t, x, args)) ___bpf_ctx_arg9(n, args) 7319f2f5d78SYonghong Song #define ___bpf_ctx_arg11(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt11(t, x, args)) ___bpf_ctx_arg10(n, args) 7329f2f5d78SYonghong Song #define ___bpf_ctx_arg12(n, t, x, args...) , ___bpf_union_arg(t, x, n - ___bpf_reg_cnt12(t, x, args)) ___bpf_ctx_arg11(n, args) 7339f2f5d78SYonghong Song #define ___bpf_ctx_arg(args...) ___bpf_apply(___bpf_ctx_arg, ___bpf_narg2(args))(___bpf_reg_cnt(args), args) 7349f2f5d78SYonghong Song 7359f2f5d78SYonghong Song #define ___bpf_ctx_decl0() 7369f2f5d78SYonghong Song #define ___bpf_ctx_decl1(t, x) , t x 7379f2f5d78SYonghong Song #define ___bpf_ctx_decl2(t, x, args...) , t x ___bpf_ctx_decl1(args) 7389f2f5d78SYonghong Song #define ___bpf_ctx_decl3(t, x, args...) , t x ___bpf_ctx_decl2(args) 7399f2f5d78SYonghong Song #define ___bpf_ctx_decl4(t, x, args...) , t x ___bpf_ctx_decl3(args) 7409f2f5d78SYonghong Song #define ___bpf_ctx_decl5(t, x, args...) , t x ___bpf_ctx_decl4(args) 7419f2f5d78SYonghong Song #define ___bpf_ctx_decl6(t, x, args...) , t x ___bpf_ctx_decl5(args) 7429f2f5d78SYonghong Song #define ___bpf_ctx_decl7(t, x, args...) , t x ___bpf_ctx_decl6(args) 7439f2f5d78SYonghong Song #define ___bpf_ctx_decl8(t, x, args...) , t x ___bpf_ctx_decl7(args) 7449f2f5d78SYonghong Song #define ___bpf_ctx_decl9(t, x, args...) , t x ___bpf_ctx_decl8(args) 7459f2f5d78SYonghong Song #define ___bpf_ctx_decl10(t, x, args...) , t x ___bpf_ctx_decl9(args) 7469f2f5d78SYonghong Song #define ___bpf_ctx_decl11(t, x, args...) , t x ___bpf_ctx_decl10(args) 7479f2f5d78SYonghong Song #define ___bpf_ctx_decl12(t, x, args...) , t x ___bpf_ctx_decl11(args) 7489f2f5d78SYonghong Song #define ___bpf_ctx_decl(args...) ___bpf_apply(___bpf_ctx_decl, ___bpf_narg2(args))(args) 74934586d29SYonghong Song 75034586d29SYonghong Song /* 7519f2f5d78SYonghong Song * BPF_PROG2 is an enhanced version of BPF_PROG in order to handle struct 7529f2f5d78SYonghong Song * arguments. Since each struct argument might take one or two u64 values 7539f2f5d78SYonghong Song * in the trampoline stack, argument type size is needed to place proper number 7549f2f5d78SYonghong Song * of u64 values for each argument. Therefore, BPF_PROG2 has different 7559f2f5d78SYonghong Song * syntax from BPF_PROG. For example, for the following BPF_PROG syntax: 7569f2f5d78SYonghong Song * 7579f2f5d78SYonghong Song * int BPF_PROG(test2, int a, int b) { ... } 7589f2f5d78SYonghong Song * 7599f2f5d78SYonghong Song * the corresponding BPF_PROG2 syntax is: 7609f2f5d78SYonghong Song * 7619f2f5d78SYonghong Song * int BPF_PROG2(test2, int, a, int, b) { ... } 7629f2f5d78SYonghong Song * 7639f2f5d78SYonghong Song * where type and the corresponding argument name are separated by comma. 7649f2f5d78SYonghong Song * 7659f2f5d78SYonghong Song * Use BPF_PROG2 macro if one of the arguments might be a struct/union larger 7669f2f5d78SYonghong Song * than 8 bytes: 7679f2f5d78SYonghong Song * 7689f2f5d78SYonghong Song * int BPF_PROG2(test_struct_arg, struct bpf_testmod_struct_arg_1, a, int, b, 7699f2f5d78SYonghong Song * int, c, int, d, struct bpf_testmod_struct_arg_2, e, int, ret) 7709f2f5d78SYonghong Song * { 7719f2f5d78SYonghong Song * // access a, b, c, d, e, and ret directly 7729f2f5d78SYonghong Song * ... 7739f2f5d78SYonghong Song * } 77434586d29SYonghong Song */ 77534586d29SYonghong Song #define BPF_PROG2(name, args...) \ 77634586d29SYonghong Song name(unsigned long long *ctx); \ 77734586d29SYonghong Song static __always_inline typeof(name(0)) \ 7789f2f5d78SYonghong Song ____##name(unsigned long long *ctx ___bpf_ctx_decl(args)); \ 77934586d29SYonghong Song typeof(name(0)) name(unsigned long long *ctx) \ 78034586d29SYonghong Song { \ 7819f2f5d78SYonghong Song return ____##name(ctx ___bpf_ctx_arg(args)); \ 78234586d29SYonghong Song } \ 78334586d29SYonghong Song static __always_inline typeof(name(0)) \ 7849f2f5d78SYonghong Song ____##name(unsigned long long *ctx ___bpf_ctx_decl(args)) 78534586d29SYonghong Song 786df8ff353SAndrii Nakryiko struct pt_regs; 787df8ff353SAndrii Nakryiko 788df8ff353SAndrii Nakryiko #define ___bpf_kprobe_args0() ctx 789f60edf5bSAndrii Nakryiko #define ___bpf_kprobe_args1(x) ___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx) 790f60edf5bSAndrii Nakryiko #define ___bpf_kprobe_args2(x, args...) ___bpf_kprobe_args1(args), (void *)PT_REGS_PARM2(ctx) 791f60edf5bSAndrii Nakryiko #define ___bpf_kprobe_args3(x, args...) ___bpf_kprobe_args2(args), (void *)PT_REGS_PARM3(ctx) 792f60edf5bSAndrii Nakryiko #define ___bpf_kprobe_args4(x, args...) ___bpf_kprobe_args3(args), (void *)PT_REGS_PARM4(ctx) 793f60edf5bSAndrii Nakryiko #define ___bpf_kprobe_args5(x, args...) ___bpf_kprobe_args4(args), (void *)PT_REGS_PARM5(ctx) 7943c59623dSAndrii Nakryiko #define ___bpf_kprobe_args6(x, args...) ___bpf_kprobe_args5(args), (void *)PT_REGS_PARM6(ctx) 7953c59623dSAndrii Nakryiko #define ___bpf_kprobe_args7(x, args...) ___bpf_kprobe_args6(args), (void *)PT_REGS_PARM7(ctx) 7963c59623dSAndrii Nakryiko #define ___bpf_kprobe_args8(x, args...) ___bpf_kprobe_args7(args), (void *)PT_REGS_PARM8(ctx) 797f60edf5bSAndrii Nakryiko #define ___bpf_kprobe_args(args...) ___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args) 798df8ff353SAndrii Nakryiko 799df8ff353SAndrii Nakryiko /* 800df8ff353SAndrii Nakryiko * BPF_KPROBE serves the same purpose for kprobes as BPF_PROG for 801df8ff353SAndrii Nakryiko * tp_btf/fentry/fexit BPF programs. It hides the underlying platform-specific 802df8ff353SAndrii Nakryiko * low-level way of getting kprobe input arguments from struct pt_regs, and 803df8ff353SAndrii Nakryiko * provides a familiar typed and named function arguments syntax and 804df8ff353SAndrii Nakryiko * semantics of accessing kprobe input paremeters. 805df8ff353SAndrii Nakryiko * 806df8ff353SAndrii Nakryiko * Original struct pt_regs* context is preserved as 'ctx' argument. This might 807df8ff353SAndrii Nakryiko * be necessary when using BPF helpers like bpf_perf_event_output(). 808df8ff353SAndrii Nakryiko */ 809df8ff353SAndrii Nakryiko #define BPF_KPROBE(name, args...) \ 810df8ff353SAndrii Nakryiko name(struct pt_regs *ctx); \ 811d25f40ffSJames Hilliard static __always_inline typeof(name(0)) \ 812df8ff353SAndrii Nakryiko ____##name(struct pt_regs *ctx, ##args); \ 813df8ff353SAndrii Nakryiko typeof(name(0)) name(struct pt_regs *ctx) \ 814df8ff353SAndrii Nakryiko { \ 815df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic push") \ 816df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ 817df8ff353SAndrii Nakryiko return ____##name(___bpf_kprobe_args(args)); \ 818df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic pop") \ 819df8ff353SAndrii Nakryiko } \ 820d25f40ffSJames Hilliard static __always_inline typeof(name(0)) \ 821df8ff353SAndrii Nakryiko ____##name(struct pt_regs *ctx, ##args) 822df8ff353SAndrii Nakryiko 823df8ff353SAndrii Nakryiko #define ___bpf_kretprobe_args0() ctx 824f60edf5bSAndrii Nakryiko #define ___bpf_kretprobe_args1(x) ___bpf_kretprobe_args0(), (void *)PT_REGS_RC(ctx) 825f60edf5bSAndrii Nakryiko #define ___bpf_kretprobe_args(args...) ___bpf_apply(___bpf_kretprobe_args, ___bpf_narg(args))(args) 826df8ff353SAndrii Nakryiko 827df8ff353SAndrii Nakryiko /* 828df8ff353SAndrii Nakryiko * BPF_KRETPROBE is similar to BPF_KPROBE, except, it only provides optional 829df8ff353SAndrii Nakryiko * return value (in addition to `struct pt_regs *ctx`), but no input 830df8ff353SAndrii Nakryiko * arguments, because they will be clobbered by the time probed function 831df8ff353SAndrii Nakryiko * returns. 832df8ff353SAndrii Nakryiko */ 833df8ff353SAndrii Nakryiko #define BPF_KRETPROBE(name, args...) \ 834df8ff353SAndrii Nakryiko name(struct pt_regs *ctx); \ 835d25f40ffSJames Hilliard static __always_inline typeof(name(0)) \ 836df8ff353SAndrii Nakryiko ____##name(struct pt_regs *ctx, ##args); \ 837df8ff353SAndrii Nakryiko typeof(name(0)) name(struct pt_regs *ctx) \ 838df8ff353SAndrii Nakryiko { \ 839df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic push") \ 840df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ 841df8ff353SAndrii Nakryiko return ____##name(___bpf_kretprobe_args(args)); \ 842df8ff353SAndrii Nakryiko _Pragma("GCC diagnostic pop") \ 843df8ff353SAndrii Nakryiko } \ 844df8ff353SAndrii Nakryiko static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args) 845df8ff353SAndrii Nakryiko 8466f5d467dSAndrii Nakryiko /* If kernel has CONFIG_ARCH_HAS_SYSCALL_WRAPPER, read pt_regs directly */ 847816ae109SHengqi Chen #define ___bpf_syscall_args0() ctx 8486f5d467dSAndrii Nakryiko #define ___bpf_syscall_args1(x) ___bpf_syscall_args0(), (void *)PT_REGS_PARM1_SYSCALL(regs) 8496f5d467dSAndrii Nakryiko #define ___bpf_syscall_args2(x, args...) ___bpf_syscall_args1(args), (void *)PT_REGS_PARM2_SYSCALL(regs) 8506f5d467dSAndrii Nakryiko #define ___bpf_syscall_args3(x, args...) ___bpf_syscall_args2(args), (void *)PT_REGS_PARM3_SYSCALL(regs) 8516f5d467dSAndrii Nakryiko #define ___bpf_syscall_args4(x, args...) ___bpf_syscall_args3(args), (void *)PT_REGS_PARM4_SYSCALL(regs) 8526f5d467dSAndrii Nakryiko #define ___bpf_syscall_args5(x, args...) ___bpf_syscall_args4(args), (void *)PT_REGS_PARM5_SYSCALL(regs) 8538ccabeefSAndrii Nakryiko #define ___bpf_syscall_args6(x, args...) ___bpf_syscall_args5(args), (void *)PT_REGS_PARM6_SYSCALL(regs) 8548ccabeefSAndrii Nakryiko #define ___bpf_syscall_args7(x, args...) ___bpf_syscall_args6(args), (void *)PT_REGS_PARM7_SYSCALL(regs) 855816ae109SHengqi Chen #define ___bpf_syscall_args(args...) ___bpf_apply(___bpf_syscall_args, ___bpf_narg(args))(args) 856816ae109SHengqi Chen 8576f5d467dSAndrii Nakryiko /* If kernel doesn't have CONFIG_ARCH_HAS_SYSCALL_WRAPPER, we have to BPF_CORE_READ from pt_regs */ 8586f5d467dSAndrii Nakryiko #define ___bpf_syswrap_args0() ctx 8596f5d467dSAndrii Nakryiko #define ___bpf_syswrap_args1(x) ___bpf_syswrap_args0(), (void *)PT_REGS_PARM1_CORE_SYSCALL(regs) 8606f5d467dSAndrii Nakryiko #define ___bpf_syswrap_args2(x, args...) ___bpf_syswrap_args1(args), (void *)PT_REGS_PARM2_CORE_SYSCALL(regs) 8616f5d467dSAndrii Nakryiko #define ___bpf_syswrap_args3(x, args...) ___bpf_syswrap_args2(args), (void *)PT_REGS_PARM3_CORE_SYSCALL(regs) 8626f5d467dSAndrii Nakryiko #define ___bpf_syswrap_args4(x, args...) ___bpf_syswrap_args3(args), (void *)PT_REGS_PARM4_CORE_SYSCALL(regs) 8636f5d467dSAndrii Nakryiko #define ___bpf_syswrap_args5(x, args...) ___bpf_syswrap_args4(args), (void *)PT_REGS_PARM5_CORE_SYSCALL(regs) 8648ccabeefSAndrii Nakryiko #define ___bpf_syswrap_args6(x, args...) ___bpf_syswrap_args5(args), (void *)PT_REGS_PARM6_CORE_SYSCALL(regs) 8658ccabeefSAndrii Nakryiko #define ___bpf_syswrap_args7(x, args...) ___bpf_syswrap_args6(args), (void *)PT_REGS_PARM7_CORE_SYSCALL(regs) 8666f5d467dSAndrii Nakryiko #define ___bpf_syswrap_args(args...) ___bpf_apply(___bpf_syswrap_args, ___bpf_narg(args))(args) 8676f5d467dSAndrii Nakryiko 868816ae109SHengqi Chen /* 8696f5d467dSAndrii Nakryiko * BPF_KSYSCALL is a variant of BPF_KPROBE, which is intended for 870816ae109SHengqi Chen * tracing syscall functions, like __x64_sys_close. It hides the underlying 871816ae109SHengqi Chen * platform-specific low-level way of getting syscall input arguments from 872816ae109SHengqi Chen * struct pt_regs, and provides a familiar typed and named function arguments 873816ae109SHengqi Chen * syntax and semantics of accessing syscall input parameters. 874816ae109SHengqi Chen * 875816ae109SHengqi Chen * Original struct pt_regs * context is preserved as 'ctx' argument. This might 876816ae109SHengqi Chen * be necessary when using BPF helpers like bpf_perf_event_output(). 877816ae109SHengqi Chen * 8782d369b4bSIlya Leoshkevich * At the moment BPF_KSYSCALL does not transparently handle all the calling 8792d369b4bSIlya Leoshkevich * convention quirks for the following syscalls: 8802d369b4bSIlya Leoshkevich * 8812d369b4bSIlya Leoshkevich * - mmap(): __ARCH_WANT_SYS_OLD_MMAP. 8822d369b4bSIlya Leoshkevich * - clone(): CONFIG_CLONE_BACKWARDS, CONFIG_CLONE_BACKWARDS2 and 8832d369b4bSIlya Leoshkevich * CONFIG_CLONE_BACKWARDS3. 8842d369b4bSIlya Leoshkevich * - socket-related syscalls: __ARCH_WANT_SYS_SOCKETCALL. 8852d369b4bSIlya Leoshkevich * - compat syscalls. 8862d369b4bSIlya Leoshkevich * 8872d369b4bSIlya Leoshkevich * This may or may not change in the future. User needs to take extra measures 8882d369b4bSIlya Leoshkevich * to handle such quirks explicitly, if necessary. 8896f5d467dSAndrii Nakryiko * 8906f5d467dSAndrii Nakryiko * This macro relies on BPF CO-RE support and virtual __kconfig externs. 891816ae109SHengqi Chen */ 8926f5d467dSAndrii Nakryiko #define BPF_KSYSCALL(name, args...) \ 893816ae109SHengqi Chen name(struct pt_regs *ctx); \ 8946f5d467dSAndrii Nakryiko extern _Bool LINUX_HAS_SYSCALL_WRAPPER __kconfig; \ 895d25f40ffSJames Hilliard static __always_inline typeof(name(0)) \ 896816ae109SHengqi Chen ____##name(struct pt_regs *ctx, ##args); \ 897816ae109SHengqi Chen typeof(name(0)) name(struct pt_regs *ctx) \ 898816ae109SHengqi Chen { \ 8996f5d467dSAndrii Nakryiko struct pt_regs *regs = LINUX_HAS_SYSCALL_WRAPPER \ 9006f5d467dSAndrii Nakryiko ? (struct pt_regs *)PT_REGS_PARM1(ctx) \ 9016f5d467dSAndrii Nakryiko : ctx; \ 902816ae109SHengqi Chen _Pragma("GCC diagnostic push") \ 903816ae109SHengqi Chen _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ 9046f5d467dSAndrii Nakryiko if (LINUX_HAS_SYSCALL_WRAPPER) \ 9056f5d467dSAndrii Nakryiko return ____##name(___bpf_syswrap_args(args)); \ 9066f5d467dSAndrii Nakryiko else \ 907816ae109SHengqi Chen return ____##name(___bpf_syscall_args(args)); \ 908816ae109SHengqi Chen _Pragma("GCC diagnostic pop") \ 909816ae109SHengqi Chen } \ 910d25f40ffSJames Hilliard static __always_inline typeof(name(0)) \ 911816ae109SHengqi Chen ____##name(struct pt_regs *ctx, ##args) 912816ae109SHengqi Chen 9136f5d467dSAndrii Nakryiko #define BPF_KPROBE_SYSCALL BPF_KSYSCALL 9146f5d467dSAndrii Nakryiko 915ac4afd6eSAndrii Nakryiko /* BPF_UPROBE and BPF_URETPROBE are identical to BPF_KPROBE and BPF_KRETPROBE, 916ac4afd6eSAndrii Nakryiko * but are named way less confusingly for SEC("uprobe") and SEC("uretprobe") 917ac4afd6eSAndrii Nakryiko * use cases. 918ac4afd6eSAndrii Nakryiko */ 919ac4afd6eSAndrii Nakryiko #define BPF_UPROBE(name, args...) BPF_KPROBE(name, ##args) 920ac4afd6eSAndrii Nakryiko #define BPF_URETPROBE(name, args...) BPF_KRETPROBE(name, ##args) 921ac4afd6eSAndrii Nakryiko 922e01a75c1SAndrii Nakryiko #endif 923