xref: /aosp_15_r20/external/libbpf/src/usdt.bpf.h (revision f7c14bbac8cf49633f2740db462ea43457973ec4)
1*f7c14bbaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2*f7c14bbaSAndroid Build Coastguard Worker /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3*f7c14bbaSAndroid Build Coastguard Worker #ifndef __USDT_BPF_H__
4*f7c14bbaSAndroid Build Coastguard Worker #define __USDT_BPF_H__
5*f7c14bbaSAndroid Build Coastguard Worker 
6*f7c14bbaSAndroid Build Coastguard Worker #include <linux/errno.h>
7*f7c14bbaSAndroid Build Coastguard Worker #include "bpf_helpers.h"
8*f7c14bbaSAndroid Build Coastguard Worker #include "bpf_tracing.h"
9*f7c14bbaSAndroid Build Coastguard Worker 
10*f7c14bbaSAndroid Build Coastguard Worker /* Below types and maps are internal implementation details of libbpf's USDT
11*f7c14bbaSAndroid Build Coastguard Worker  * support and are subjects to change. Also, bpf_usdt_xxx() API helpers should
12*f7c14bbaSAndroid Build Coastguard Worker  * be considered an unstable API as well and might be adjusted based on user
13*f7c14bbaSAndroid Build Coastguard Worker  * feedback from using libbpf's USDT support in production.
14*f7c14bbaSAndroid Build Coastguard Worker  */
15*f7c14bbaSAndroid Build Coastguard Worker 
16*f7c14bbaSAndroid Build Coastguard Worker /* User can override BPF_USDT_MAX_SPEC_CNT to change default size of internal
17*f7c14bbaSAndroid Build Coastguard Worker  * map that keeps track of USDT argument specifications. This might be
18*f7c14bbaSAndroid Build Coastguard Worker  * necessary if there are a lot of USDT attachments.
19*f7c14bbaSAndroid Build Coastguard Worker  */
20*f7c14bbaSAndroid Build Coastguard Worker #ifndef BPF_USDT_MAX_SPEC_CNT
21*f7c14bbaSAndroid Build Coastguard Worker #define BPF_USDT_MAX_SPEC_CNT 256
22*f7c14bbaSAndroid Build Coastguard Worker #endif
23*f7c14bbaSAndroid Build Coastguard Worker /* User can override BPF_USDT_MAX_IP_CNT to change default size of internal
24*f7c14bbaSAndroid Build Coastguard Worker  * map that keeps track of IP (memory address) mapping to USDT argument
25*f7c14bbaSAndroid Build Coastguard Worker  * specification.
26*f7c14bbaSAndroid Build Coastguard Worker  * Note, if kernel supports BPF cookies, this map is not used and could be
27*f7c14bbaSAndroid Build Coastguard Worker  * resized all the way to 1 to save a bit of memory.
28*f7c14bbaSAndroid Build Coastguard Worker  */
29*f7c14bbaSAndroid Build Coastguard Worker #ifndef BPF_USDT_MAX_IP_CNT
30*f7c14bbaSAndroid Build Coastguard Worker #define BPF_USDT_MAX_IP_CNT (4 * BPF_USDT_MAX_SPEC_CNT)
31*f7c14bbaSAndroid Build Coastguard Worker #endif
32*f7c14bbaSAndroid Build Coastguard Worker 
33*f7c14bbaSAndroid Build Coastguard Worker enum __bpf_usdt_arg_type {
34*f7c14bbaSAndroid Build Coastguard Worker 	BPF_USDT_ARG_CONST,
35*f7c14bbaSAndroid Build Coastguard Worker 	BPF_USDT_ARG_REG,
36*f7c14bbaSAndroid Build Coastguard Worker 	BPF_USDT_ARG_REG_DEREF,
37*f7c14bbaSAndroid Build Coastguard Worker };
38*f7c14bbaSAndroid Build Coastguard Worker 
39*f7c14bbaSAndroid Build Coastguard Worker struct __bpf_usdt_arg_spec {
40*f7c14bbaSAndroid Build Coastguard Worker 	/* u64 scalar interpreted depending on arg_type, see below */
41*f7c14bbaSAndroid Build Coastguard Worker 	__u64 val_off;
42*f7c14bbaSAndroid Build Coastguard Worker 	/* arg location case, see bpf_udst_arg() for details */
43*f7c14bbaSAndroid Build Coastguard Worker 	enum __bpf_usdt_arg_type arg_type;
44*f7c14bbaSAndroid Build Coastguard Worker 	/* offset of referenced register within struct pt_regs */
45*f7c14bbaSAndroid Build Coastguard Worker 	short reg_off;
46*f7c14bbaSAndroid Build Coastguard Worker 	/* whether arg should be interpreted as signed value */
47*f7c14bbaSAndroid Build Coastguard Worker 	bool arg_signed;
48*f7c14bbaSAndroid Build Coastguard Worker 	/* number of bits that need to be cleared and, optionally,
49*f7c14bbaSAndroid Build Coastguard Worker 	 * sign-extended to cast arguments that are 1, 2, or 4 bytes
50*f7c14bbaSAndroid Build Coastguard Worker 	 * long into final 8-byte u64/s64 value returned to user
51*f7c14bbaSAndroid Build Coastguard Worker 	 */
52*f7c14bbaSAndroid Build Coastguard Worker 	char arg_bitshift;
53*f7c14bbaSAndroid Build Coastguard Worker };
54*f7c14bbaSAndroid Build Coastguard Worker 
55*f7c14bbaSAndroid Build Coastguard Worker /* should match USDT_MAX_ARG_CNT in usdt.c exactly */
56*f7c14bbaSAndroid Build Coastguard Worker #define BPF_USDT_MAX_ARG_CNT 12
57*f7c14bbaSAndroid Build Coastguard Worker struct __bpf_usdt_spec {
58*f7c14bbaSAndroid Build Coastguard Worker 	struct __bpf_usdt_arg_spec args[BPF_USDT_MAX_ARG_CNT];
59*f7c14bbaSAndroid Build Coastguard Worker 	__u64 usdt_cookie;
60*f7c14bbaSAndroid Build Coastguard Worker 	short arg_cnt;
61*f7c14bbaSAndroid Build Coastguard Worker };
62*f7c14bbaSAndroid Build Coastguard Worker 
63*f7c14bbaSAndroid Build Coastguard Worker struct {
64*f7c14bbaSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_ARRAY);
65*f7c14bbaSAndroid Build Coastguard Worker 	__uint(max_entries, BPF_USDT_MAX_SPEC_CNT);
66*f7c14bbaSAndroid Build Coastguard Worker 	__type(key, int);
67*f7c14bbaSAndroid Build Coastguard Worker 	__type(value, struct __bpf_usdt_spec);
68*f7c14bbaSAndroid Build Coastguard Worker } __bpf_usdt_specs SEC(".maps") __weak;
69*f7c14bbaSAndroid Build Coastguard Worker 
70*f7c14bbaSAndroid Build Coastguard Worker struct {
71*f7c14bbaSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
72*f7c14bbaSAndroid Build Coastguard Worker 	__uint(max_entries, BPF_USDT_MAX_IP_CNT);
73*f7c14bbaSAndroid Build Coastguard Worker 	__type(key, long);
74*f7c14bbaSAndroid Build Coastguard Worker 	__type(value, __u32);
75*f7c14bbaSAndroid Build Coastguard Worker } __bpf_usdt_ip_to_spec_id SEC(".maps") __weak;
76*f7c14bbaSAndroid Build Coastguard Worker 
77*f7c14bbaSAndroid Build Coastguard Worker extern const _Bool LINUX_HAS_BPF_COOKIE __kconfig;
78*f7c14bbaSAndroid Build Coastguard Worker 
79*f7c14bbaSAndroid Build Coastguard Worker static __always_inline
__bpf_usdt_spec_id(struct pt_regs * ctx)80*f7c14bbaSAndroid Build Coastguard Worker int __bpf_usdt_spec_id(struct pt_regs *ctx)
81*f7c14bbaSAndroid Build Coastguard Worker {
82*f7c14bbaSAndroid Build Coastguard Worker 	if (!LINUX_HAS_BPF_COOKIE) {
83*f7c14bbaSAndroid Build Coastguard Worker 		long ip = PT_REGS_IP(ctx);
84*f7c14bbaSAndroid Build Coastguard Worker 		int *spec_id_ptr;
85*f7c14bbaSAndroid Build Coastguard Worker 
86*f7c14bbaSAndroid Build Coastguard Worker 		spec_id_ptr = bpf_map_lookup_elem(&__bpf_usdt_ip_to_spec_id, &ip);
87*f7c14bbaSAndroid Build Coastguard Worker 		return spec_id_ptr ? *spec_id_ptr : -ESRCH;
88*f7c14bbaSAndroid Build Coastguard Worker 	}
89*f7c14bbaSAndroid Build Coastguard Worker 
90*f7c14bbaSAndroid Build Coastguard Worker 	return bpf_get_attach_cookie(ctx);
91*f7c14bbaSAndroid Build Coastguard Worker }
92*f7c14bbaSAndroid Build Coastguard Worker 
93*f7c14bbaSAndroid Build Coastguard Worker /* Return number of USDT arguments defined for currently traced USDT. */
94*f7c14bbaSAndroid Build Coastguard Worker __weak __hidden
bpf_usdt_arg_cnt(struct pt_regs * ctx)95*f7c14bbaSAndroid Build Coastguard Worker int bpf_usdt_arg_cnt(struct pt_regs *ctx)
96*f7c14bbaSAndroid Build Coastguard Worker {
97*f7c14bbaSAndroid Build Coastguard Worker 	struct __bpf_usdt_spec *spec;
98*f7c14bbaSAndroid Build Coastguard Worker 	int spec_id;
99*f7c14bbaSAndroid Build Coastguard Worker 
100*f7c14bbaSAndroid Build Coastguard Worker 	spec_id = __bpf_usdt_spec_id(ctx);
101*f7c14bbaSAndroid Build Coastguard Worker 	if (spec_id < 0)
102*f7c14bbaSAndroid Build Coastguard Worker 		return -ESRCH;
103*f7c14bbaSAndroid Build Coastguard Worker 
104*f7c14bbaSAndroid Build Coastguard Worker 	spec = bpf_map_lookup_elem(&__bpf_usdt_specs, &spec_id);
105*f7c14bbaSAndroid Build Coastguard Worker 	if (!spec)
106*f7c14bbaSAndroid Build Coastguard Worker 		return -ESRCH;
107*f7c14bbaSAndroid Build Coastguard Worker 
108*f7c14bbaSAndroid Build Coastguard Worker 	return spec->arg_cnt;
109*f7c14bbaSAndroid Build Coastguard Worker }
110*f7c14bbaSAndroid Build Coastguard Worker 
111*f7c14bbaSAndroid Build Coastguard Worker /* Fetch USDT argument #*arg_num* (zero-indexed) and put its value into *res.
112*f7c14bbaSAndroid Build Coastguard Worker  * Returns 0 on success; negative error, otherwise.
113*f7c14bbaSAndroid Build Coastguard Worker  * On error *res is guaranteed to be set to zero.
114*f7c14bbaSAndroid Build Coastguard Worker  */
115*f7c14bbaSAndroid Build Coastguard Worker __weak __hidden
bpf_usdt_arg(struct pt_regs * ctx,__u64 arg_num,long * res)116*f7c14bbaSAndroid Build Coastguard Worker int bpf_usdt_arg(struct pt_regs *ctx, __u64 arg_num, long *res)
117*f7c14bbaSAndroid Build Coastguard Worker {
118*f7c14bbaSAndroid Build Coastguard Worker 	struct __bpf_usdt_spec *spec;
119*f7c14bbaSAndroid Build Coastguard Worker 	struct __bpf_usdt_arg_spec *arg_spec;
120*f7c14bbaSAndroid Build Coastguard Worker 	unsigned long val;
121*f7c14bbaSAndroid Build Coastguard Worker 	int err, spec_id;
122*f7c14bbaSAndroid Build Coastguard Worker 
123*f7c14bbaSAndroid Build Coastguard Worker 	*res = 0;
124*f7c14bbaSAndroid Build Coastguard Worker 
125*f7c14bbaSAndroid Build Coastguard Worker 	spec_id = __bpf_usdt_spec_id(ctx);
126*f7c14bbaSAndroid Build Coastguard Worker 	if (spec_id < 0)
127*f7c14bbaSAndroid Build Coastguard Worker 		return -ESRCH;
128*f7c14bbaSAndroid Build Coastguard Worker 
129*f7c14bbaSAndroid Build Coastguard Worker 	spec = bpf_map_lookup_elem(&__bpf_usdt_specs, &spec_id);
130*f7c14bbaSAndroid Build Coastguard Worker 	if (!spec)
131*f7c14bbaSAndroid Build Coastguard Worker 		return -ESRCH;
132*f7c14bbaSAndroid Build Coastguard Worker 
133*f7c14bbaSAndroid Build Coastguard Worker 	if (arg_num >= BPF_USDT_MAX_ARG_CNT)
134*f7c14bbaSAndroid Build Coastguard Worker 		return -ENOENT;
135*f7c14bbaSAndroid Build Coastguard Worker 	barrier_var(arg_num);
136*f7c14bbaSAndroid Build Coastguard Worker 	if (arg_num >= spec->arg_cnt)
137*f7c14bbaSAndroid Build Coastguard Worker 		return -ENOENT;
138*f7c14bbaSAndroid Build Coastguard Worker 
139*f7c14bbaSAndroid Build Coastguard Worker 	arg_spec = &spec->args[arg_num];
140*f7c14bbaSAndroid Build Coastguard Worker 	switch (arg_spec->arg_type) {
141*f7c14bbaSAndroid Build Coastguard Worker 	case BPF_USDT_ARG_CONST:
142*f7c14bbaSAndroid Build Coastguard Worker 		/* Arg is just a constant ("-4@$-9" in USDT arg spec).
143*f7c14bbaSAndroid Build Coastguard Worker 		 * value is recorded in arg_spec->val_off directly.
144*f7c14bbaSAndroid Build Coastguard Worker 		 */
145*f7c14bbaSAndroid Build Coastguard Worker 		val = arg_spec->val_off;
146*f7c14bbaSAndroid Build Coastguard Worker 		break;
147*f7c14bbaSAndroid Build Coastguard Worker 	case BPF_USDT_ARG_REG:
148*f7c14bbaSAndroid Build Coastguard Worker 		/* Arg is in a register (e.g, "8@%rax" in USDT arg spec),
149*f7c14bbaSAndroid Build Coastguard Worker 		 * so we read the contents of that register directly from
150*f7c14bbaSAndroid Build Coastguard Worker 		 * struct pt_regs. To keep things simple user-space parts
151*f7c14bbaSAndroid Build Coastguard Worker 		 * record offsetof(struct pt_regs, <regname>) in arg_spec->reg_off.
152*f7c14bbaSAndroid Build Coastguard Worker 		 */
153*f7c14bbaSAndroid Build Coastguard Worker 		err = bpf_probe_read_kernel(&val, sizeof(val), (void *)ctx + arg_spec->reg_off);
154*f7c14bbaSAndroid Build Coastguard Worker 		if (err)
155*f7c14bbaSAndroid Build Coastguard Worker 			return err;
156*f7c14bbaSAndroid Build Coastguard Worker 		break;
157*f7c14bbaSAndroid Build Coastguard Worker 	case BPF_USDT_ARG_REG_DEREF:
158*f7c14bbaSAndroid Build Coastguard Worker 		/* Arg is in memory addressed by register, plus some offset
159*f7c14bbaSAndroid Build Coastguard Worker 		 * (e.g., "-4@-1204(%rbp)" in USDT arg spec). Register is
160*f7c14bbaSAndroid Build Coastguard Worker 		 * identified like with BPF_USDT_ARG_REG case, and the offset
161*f7c14bbaSAndroid Build Coastguard Worker 		 * is in arg_spec->val_off. We first fetch register contents
162*f7c14bbaSAndroid Build Coastguard Worker 		 * from pt_regs, then do another user-space probe read to
163*f7c14bbaSAndroid Build Coastguard Worker 		 * fetch argument value itself.
164*f7c14bbaSAndroid Build Coastguard Worker 		 */
165*f7c14bbaSAndroid Build Coastguard Worker 		err = bpf_probe_read_kernel(&val, sizeof(val), (void *)ctx + arg_spec->reg_off);
166*f7c14bbaSAndroid Build Coastguard Worker 		if (err)
167*f7c14bbaSAndroid Build Coastguard Worker 			return err;
168*f7c14bbaSAndroid Build Coastguard Worker 		err = bpf_probe_read_user(&val, sizeof(val), (void *)val + arg_spec->val_off);
169*f7c14bbaSAndroid Build Coastguard Worker 		if (err)
170*f7c14bbaSAndroid Build Coastguard Worker 			return err;
171*f7c14bbaSAndroid Build Coastguard Worker #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
172*f7c14bbaSAndroid Build Coastguard Worker 		val >>= arg_spec->arg_bitshift;
173*f7c14bbaSAndroid Build Coastguard Worker #endif
174*f7c14bbaSAndroid Build Coastguard Worker 		break;
175*f7c14bbaSAndroid Build Coastguard Worker 	default:
176*f7c14bbaSAndroid Build Coastguard Worker 		return -EINVAL;
177*f7c14bbaSAndroid Build Coastguard Worker 	}
178*f7c14bbaSAndroid Build Coastguard Worker 
179*f7c14bbaSAndroid Build Coastguard Worker 	/* cast arg from 1, 2, or 4 bytes to final 8 byte size clearing
180*f7c14bbaSAndroid Build Coastguard Worker 	 * necessary upper arg_bitshift bits, with sign extension if argument
181*f7c14bbaSAndroid Build Coastguard Worker 	 * is signed
182*f7c14bbaSAndroid Build Coastguard Worker 	 */
183*f7c14bbaSAndroid Build Coastguard Worker 	val <<= arg_spec->arg_bitshift;
184*f7c14bbaSAndroid Build Coastguard Worker 	if (arg_spec->arg_signed)
185*f7c14bbaSAndroid Build Coastguard Worker 		val = ((long)val) >> arg_spec->arg_bitshift;
186*f7c14bbaSAndroid Build Coastguard Worker 	else
187*f7c14bbaSAndroid Build Coastguard Worker 		val = val >> arg_spec->arg_bitshift;
188*f7c14bbaSAndroid Build Coastguard Worker 	*res = val;
189*f7c14bbaSAndroid Build Coastguard Worker 	return 0;
190*f7c14bbaSAndroid Build Coastguard Worker }
191*f7c14bbaSAndroid Build Coastguard Worker 
192*f7c14bbaSAndroid Build Coastguard Worker /* Retrieve user-specified cookie value provided during attach as
193*f7c14bbaSAndroid Build Coastguard Worker  * bpf_usdt_opts.usdt_cookie. This serves the same purpose as BPF cookie
194*f7c14bbaSAndroid Build Coastguard Worker  * returned by bpf_get_attach_cookie(). Libbpf's support for USDT is itself
195*f7c14bbaSAndroid Build Coastguard Worker  * utilizing BPF cookies internally, so user can't use BPF cookie directly
196*f7c14bbaSAndroid Build Coastguard Worker  * for USDT programs and has to use bpf_usdt_cookie() API instead.
197*f7c14bbaSAndroid Build Coastguard Worker  */
198*f7c14bbaSAndroid Build Coastguard Worker __weak __hidden
bpf_usdt_cookie(struct pt_regs * ctx)199*f7c14bbaSAndroid Build Coastguard Worker long bpf_usdt_cookie(struct pt_regs *ctx)
200*f7c14bbaSAndroid Build Coastguard Worker {
201*f7c14bbaSAndroid Build Coastguard Worker 	struct __bpf_usdt_spec *spec;
202*f7c14bbaSAndroid Build Coastguard Worker 	int spec_id;
203*f7c14bbaSAndroid Build Coastguard Worker 
204*f7c14bbaSAndroid Build Coastguard Worker 	spec_id = __bpf_usdt_spec_id(ctx);
205*f7c14bbaSAndroid Build Coastguard Worker 	if (spec_id < 0)
206*f7c14bbaSAndroid Build Coastguard Worker 		return 0;
207*f7c14bbaSAndroid Build Coastguard Worker 
208*f7c14bbaSAndroid Build Coastguard Worker 	spec = bpf_map_lookup_elem(&__bpf_usdt_specs, &spec_id);
209*f7c14bbaSAndroid Build Coastguard Worker 	if (!spec)
210*f7c14bbaSAndroid Build Coastguard Worker 		return 0;
211*f7c14bbaSAndroid Build Coastguard Worker 
212*f7c14bbaSAndroid Build Coastguard Worker 	return spec->usdt_cookie;
213*f7c14bbaSAndroid Build Coastguard Worker }
214*f7c14bbaSAndroid Build Coastguard Worker 
215*f7c14bbaSAndroid Build Coastguard Worker /* we rely on ___bpf_apply() and ___bpf_narg() macros already defined in bpf_tracing.h */
216*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args0() ctx
217*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args1(x) ___bpf_usdt_args0(), ({ long _x; bpf_usdt_arg(ctx, 0, &_x); (void *)_x; })
218*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args2(x, args...) ___bpf_usdt_args1(args), ({ long _x; bpf_usdt_arg(ctx, 1, &_x); (void *)_x; })
219*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args3(x, args...) ___bpf_usdt_args2(args), ({ long _x; bpf_usdt_arg(ctx, 2, &_x); (void *)_x; })
220*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args4(x, args...) ___bpf_usdt_args3(args), ({ long _x; bpf_usdt_arg(ctx, 3, &_x); (void *)_x; })
221*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args5(x, args...) ___bpf_usdt_args4(args), ({ long _x; bpf_usdt_arg(ctx, 4, &_x); (void *)_x; })
222*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args6(x, args...) ___bpf_usdt_args5(args), ({ long _x; bpf_usdt_arg(ctx, 5, &_x); (void *)_x; })
223*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args7(x, args...) ___bpf_usdt_args6(args), ({ long _x; bpf_usdt_arg(ctx, 6, &_x); (void *)_x; })
224*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args8(x, args...) ___bpf_usdt_args7(args), ({ long _x; bpf_usdt_arg(ctx, 7, &_x); (void *)_x; })
225*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args9(x, args...) ___bpf_usdt_args8(args), ({ long _x; bpf_usdt_arg(ctx, 8, &_x); (void *)_x; })
226*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args10(x, args...) ___bpf_usdt_args9(args), ({ long _x; bpf_usdt_arg(ctx, 9, &_x); (void *)_x; })
227*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args11(x, args...) ___bpf_usdt_args10(args), ({ long _x; bpf_usdt_arg(ctx, 10, &_x); (void *)_x; })
228*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args12(x, args...) ___bpf_usdt_args11(args), ({ long _x; bpf_usdt_arg(ctx, 11, &_x); (void *)_x; })
229*f7c14bbaSAndroid Build Coastguard Worker #define ___bpf_usdt_args(args...) ___bpf_apply(___bpf_usdt_args, ___bpf_narg(args))(args)
230*f7c14bbaSAndroid Build Coastguard Worker 
231*f7c14bbaSAndroid Build Coastguard Worker /*
232*f7c14bbaSAndroid Build Coastguard Worker  * BPF_USDT serves the same purpose for USDT handlers as BPF_PROG for
233*f7c14bbaSAndroid Build Coastguard Worker  * tp_btf/fentry/fexit BPF programs and BPF_KPROBE for kprobes.
234*f7c14bbaSAndroid Build Coastguard Worker  * Original struct pt_regs * context is preserved as 'ctx' argument.
235*f7c14bbaSAndroid Build Coastguard Worker  */
236*f7c14bbaSAndroid Build Coastguard Worker #define BPF_USDT(name, args...)						    \
237*f7c14bbaSAndroid Build Coastguard Worker name(struct pt_regs *ctx);						    \
238*f7c14bbaSAndroid Build Coastguard Worker static __always_inline typeof(name(0))					    \
239*f7c14bbaSAndroid Build Coastguard Worker ____##name(struct pt_regs *ctx, ##args);				    \
240*f7c14bbaSAndroid Build Coastguard Worker typeof(name(0)) name(struct pt_regs *ctx)				    \
241*f7c14bbaSAndroid Build Coastguard Worker {									    \
242*f7c14bbaSAndroid Build Coastguard Worker         _Pragma("GCC diagnostic push")					    \
243*f7c14bbaSAndroid Build Coastguard Worker         _Pragma("GCC diagnostic ignored \"-Wint-conversion\"")		    \
244*f7c14bbaSAndroid Build Coastguard Worker         return ____##name(___bpf_usdt_args(args));			    \
245*f7c14bbaSAndroid Build Coastguard Worker         _Pragma("GCC diagnostic pop")					    \
246*f7c14bbaSAndroid Build Coastguard Worker }									    \
247*f7c14bbaSAndroid Build Coastguard Worker static __always_inline typeof(name(0))					    \
248*f7c14bbaSAndroid Build Coastguard Worker ____##name(struct pt_regs *ctx, ##args)
249*f7c14bbaSAndroid Build Coastguard Worker 
250*f7c14bbaSAndroid Build Coastguard Worker #endif /* __USDT_BPF_H__ */
251