linux/tools/lib/bpf/bpf_tracing.h
<<
>>
Prefs
   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
  52#if defined(__KERNEL__) || defined(__VMLINUX_H__)
  53
  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)
  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
  76#else
  77
  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)
  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
 102#else
 103
 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)
 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
 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 */
 132struct 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
 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])
 151#define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[14])
 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])
 155#define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), psw.addr)
 156
 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
 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
 181#elif defined(bpf_target_arm64)
 182
 183/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
 184struct 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
 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
 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[2])
 219#define PT_REGS_SP(x) ((x)->regs[29])
 220#define PT_REGS_IP(x) ((x)->cp0_epc)
 221
 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[2])
 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
 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
 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
 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
 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
 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)
 276#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), tpc)
 277#else
 278#define PT_REGS_IP(x) ((x)->pc)
 279#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), pc)
 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_kernel(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
 293#define BPF_KRETPROBE_READ_RET_IP(ip, ctx)                                  \
 294        ({ bpf_probe_read_kernel(&(ip), sizeof(ip),                         \
 295                          (void *)(PT_REGS_FP(ctx) + sizeof(ip))); })
 296#endif
 297
 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...)                                             \
 338name(unsigned long long *ctx);                                              \
 339static __attribute__((always_inline)) typeof(name(0))                       \
 340____##name(unsigned long long *ctx, ##args);                                \
 341typeof(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}                                                                           \
 348static __attribute__((always_inline)) typeof(name(0))                       \
 349____##name(unsigned long long *ctx, ##args)
 350
 351struct 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...)                                           \
 378name(struct pt_regs *ctx);                                                  \
 379static __attribute__((always_inline)) typeof(name(0))                       \
 380____##name(struct pt_regs *ctx, ##args);                                    \
 381typeof(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}                                                                           \
 388static __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) \
 393        ___bpf_kretprobe_args0(), (void *)PT_REGS_RC(ctx)
 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...)                                        \
 404name(struct pt_regs *ctx);                                                  \
 405static __attribute__((always_inline)) typeof(name(0))                       \
 406____##name(struct pt_regs *ctx, ##args);                                    \
 407typeof(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}                                                                           \
 414static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
 415
 416/*
 417 * BPF_SEQ_PRINTF to wrap bpf_seq_printf to-be-printed values
 418 * in a structure.
 419 */
 420#define BPF_SEQ_PRINTF(seq, fmt, args...)                                   \
 421        ({                                                                  \
 422                _Pragma("GCC diagnostic push")                              \
 423                _Pragma("GCC diagnostic ignored \"-Wint-conversion\"")      \
 424                static const char ___fmt[] = fmt;                           \
 425                unsigned long long ___param[] = { args };                   \
 426                _Pragma("GCC diagnostic pop")                               \
 427                int ___ret = bpf_seq_printf(seq, ___fmt, sizeof(___fmt),    \
 428                                            ___param, sizeof(___param));    \
 429                ___ret;                                                     \
 430        })
 431
 432#endif
 433