xref: /aosp_15_r20/external/strace/bpf.c (revision cf84ac9a129d8ea9952db616b4e9b904c4bdde56)
1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2015-2017 Dmitry V. Levin <[email protected]>
3*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2017 Quentin Monnet <[email protected]>
4*cf84ac9aSAndroid Build Coastguard Worker  * Copyright (c) 2015-2018 The strace developers.
5*cf84ac9aSAndroid Build Coastguard Worker  * All rights reserved.
6*cf84ac9aSAndroid Build Coastguard Worker  *
7*cf84ac9aSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
8*cf84ac9aSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
9*cf84ac9aSAndroid Build Coastguard Worker  * are met:
10*cf84ac9aSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
11*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
12*cf84ac9aSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
13*cf84ac9aSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
14*cf84ac9aSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
15*cf84ac9aSAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
16*cf84ac9aSAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
17*cf84ac9aSAndroid Build Coastguard Worker  *
18*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19*cf84ac9aSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20*cf84ac9aSAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21*cf84ac9aSAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22*cf84ac9aSAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23*cf84ac9aSAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*cf84ac9aSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*cf84ac9aSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*cf84ac9aSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27*cf84ac9aSAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*cf84ac9aSAndroid Build Coastguard Worker  */
29*cf84ac9aSAndroid Build Coastguard Worker 
30*cf84ac9aSAndroid Build Coastguard Worker #include "defs.h"
31*cf84ac9aSAndroid Build Coastguard Worker #include "print_fields.h"
32*cf84ac9aSAndroid Build Coastguard Worker 
33*cf84ac9aSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_BPF_H
34*cf84ac9aSAndroid Build Coastguard Worker # include <linux/bpf.h>
35*cf84ac9aSAndroid Build Coastguard Worker #endif
36*cf84ac9aSAndroid Build Coastguard Worker #include <linux/filter.h>
37*cf84ac9aSAndroid Build Coastguard Worker 
38*cf84ac9aSAndroid Build Coastguard Worker #include "bpf_attr.h"
39*cf84ac9aSAndroid Build Coastguard Worker 
40*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_commands.h"
41*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_file_mode_flags.h"
42*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_map_types.h"
43*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_map_flags.h"
44*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_prog_types.h"
45*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_prog_flags.h"
46*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_map_update_elem_flags.h"
47*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_attach_type.h"
48*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_attach_flags.h"
49*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/bpf_query_flags.h"
50*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/ebpf_regs.h"
51*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/numa_node.h"
52*cf84ac9aSAndroid Build Coastguard Worker 
53*cf84ac9aSAndroid Build Coastguard Worker #define DECL_BPF_CMD_DECODER(bpf_cmd_decoder)				\
54*cf84ac9aSAndroid Build Coastguard Worker int									\
55*cf84ac9aSAndroid Build Coastguard Worker bpf_cmd_decoder(struct tcb *const tcp,					\
56*cf84ac9aSAndroid Build Coastguard Worker 		const kernel_ulong_t addr,				\
57*cf84ac9aSAndroid Build Coastguard Worker 		const unsigned int size,				\
58*cf84ac9aSAndroid Build Coastguard Worker 		void *const data)					\
59*cf84ac9aSAndroid Build Coastguard Worker /* End of DECL_BPF_CMD_DECODER definition. */
60*cf84ac9aSAndroid Build Coastguard Worker 
61*cf84ac9aSAndroid Build Coastguard Worker #define BEGIN_BPF_CMD_DECODER(bpf_cmd)					\
62*cf84ac9aSAndroid Build Coastguard Worker 	static DECL_BPF_CMD_DECODER(decode_ ## bpf_cmd)			\
63*cf84ac9aSAndroid Build Coastguard Worker 	{								\
64*cf84ac9aSAndroid Build Coastguard Worker 		struct bpf_cmd ## _struct attr = {};			\
65*cf84ac9aSAndroid Build Coastguard Worker 		const size_t attr_size = bpf_cmd ## _struct_size;	\
66*cf84ac9aSAndroid Build Coastguard Worker 		const unsigned int len = MIN(size, attr_size);		\
67*cf84ac9aSAndroid Build Coastguard Worker 		memcpy(&attr, data, len);				\
68*cf84ac9aSAndroid Build Coastguard Worker 		do {							\
69*cf84ac9aSAndroid Build Coastguard Worker /* End of BEGIN_BPF_CMD_DECODER definition. */
70*cf84ac9aSAndroid Build Coastguard Worker 
71*cf84ac9aSAndroid Build Coastguard Worker #define END_BPF_CMD_DECODER(rval)					\
72*cf84ac9aSAndroid Build Coastguard Worker 			decode_attr_extra_data(tcp, data, size, attr_size); \
73*cf84ac9aSAndroid Build Coastguard Worker 		} while (0);						\
74*cf84ac9aSAndroid Build Coastguard Worker 		tprints("}");						\
75*cf84ac9aSAndroid Build Coastguard Worker 		return (rval);						\
76*cf84ac9aSAndroid Build Coastguard Worker 	}								\
77*cf84ac9aSAndroid Build Coastguard Worker /* End of END_BPF_CMD_DECODER definition. */
78*cf84ac9aSAndroid Build Coastguard Worker 
79*cf84ac9aSAndroid Build Coastguard Worker #define BPF_CMD_ENTRY(bpf_cmd)						\
80*cf84ac9aSAndroid Build Coastguard Worker 	[bpf_cmd] = decode_ ## bpf_cmd
81*cf84ac9aSAndroid Build Coastguard Worker 
82*cf84ac9aSAndroid Build Coastguard Worker typedef DECL_BPF_CMD_DECODER((*bpf_cmd_decoder_t));
83*cf84ac9aSAndroid Build Coastguard Worker 
84*cf84ac9aSAndroid Build Coastguard Worker /*
85*cf84ac9aSAndroid Build Coastguard Worker  * A note about bpf syscall decoder: it doesn't perform any size sanity checks,
86*cf84ac9aSAndroid Build Coastguard Worker  * so even if it leads to partial copying of one of the fields, the command
87*cf84ac9aSAndroid Build Coastguard Worker  * handler will still use the (partially-copied-from-userspace, partially
88*cf84ac9aSAndroid Build Coastguard Worker  * zeroed) field value.  That's why we stop decoding and check for known sizes
89*cf84ac9aSAndroid Build Coastguard Worker  * that correspond to released versions of the structure used by the specific
90*cf84ac9aSAndroid Build Coastguard Worker  * command - it looks like the most sensible way to parse this insanity.
91*cf84ac9aSAndroid Build Coastguard Worker  */
92*cf84ac9aSAndroid Build Coastguard Worker 
93*cf84ac9aSAndroid Build Coastguard Worker static int
decode_attr_extra_data(struct tcb * const tcp,const char * data,unsigned int size,const size_t attr_size)94*cf84ac9aSAndroid Build Coastguard Worker decode_attr_extra_data(struct tcb *const tcp,
95*cf84ac9aSAndroid Build Coastguard Worker 		       const char *data,
96*cf84ac9aSAndroid Build Coastguard Worker 		       unsigned int size,
97*cf84ac9aSAndroid Build Coastguard Worker 		       const size_t attr_size)
98*cf84ac9aSAndroid Build Coastguard Worker {
99*cf84ac9aSAndroid Build Coastguard Worker 	if (size <= attr_size)
100*cf84ac9aSAndroid Build Coastguard Worker 		return 0;
101*cf84ac9aSAndroid Build Coastguard Worker 
102*cf84ac9aSAndroid Build Coastguard Worker 	data += attr_size;
103*cf84ac9aSAndroid Build Coastguard Worker 	size -= attr_size;
104*cf84ac9aSAndroid Build Coastguard Worker 
105*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int i;
106*cf84ac9aSAndroid Build Coastguard Worker 	for (i = 0; i < size; ++i) {
107*cf84ac9aSAndroid Build Coastguard Worker 		if (data[i]) {
108*cf84ac9aSAndroid Build Coastguard Worker 			tprints(", ");
109*cf84ac9aSAndroid Build Coastguard Worker 			if (abbrev(tcp)) {
110*cf84ac9aSAndroid Build Coastguard Worker 				tprints("...");
111*cf84ac9aSAndroid Build Coastguard Worker 			} else {
112*cf84ac9aSAndroid Build Coastguard Worker 				tprintf("/* bytes %zu..%zu */ ",
113*cf84ac9aSAndroid Build Coastguard Worker 					attr_size, attr_size + size - 1);
114*cf84ac9aSAndroid Build Coastguard Worker 				print_quoted_string(data, size,
115*cf84ac9aSAndroid Build Coastguard Worker 						    QUOTE_FORCE_HEX);
116*cf84ac9aSAndroid Build Coastguard Worker 			}
117*cf84ac9aSAndroid Build Coastguard Worker 			return RVAL_DECODED;
118*cf84ac9aSAndroid Build Coastguard Worker 		}
119*cf84ac9aSAndroid Build Coastguard Worker 	}
120*cf84ac9aSAndroid Build Coastguard Worker 
121*cf84ac9aSAndroid Build Coastguard Worker 	return 0;
122*cf84ac9aSAndroid Build Coastguard Worker }
123*cf84ac9aSAndroid Build Coastguard Worker 
124*cf84ac9aSAndroid Build Coastguard Worker struct ebpf_insn {
125*cf84ac9aSAndroid Build Coastguard Worker 	uint8_t code;
126*cf84ac9aSAndroid Build Coastguard Worker 	uint8_t dst_reg:4;
127*cf84ac9aSAndroid Build Coastguard Worker 	uint8_t src_reg:4;
128*cf84ac9aSAndroid Build Coastguard Worker 	int16_t off;
129*cf84ac9aSAndroid Build Coastguard Worker 	int32_t imm;
130*cf84ac9aSAndroid Build Coastguard Worker };
131*cf84ac9aSAndroid Build Coastguard Worker 
132*cf84ac9aSAndroid Build Coastguard Worker struct ebpf_insns_data {
133*cf84ac9aSAndroid Build Coastguard Worker 	unsigned int count;
134*cf84ac9aSAndroid Build Coastguard Worker };
135*cf84ac9aSAndroid Build Coastguard Worker 
136*cf84ac9aSAndroid Build Coastguard Worker static bool
print_ebpf_insn(struct tcb * const tcp,void * const elem_buf,const size_t elem_size,void * const data)137*cf84ac9aSAndroid Build Coastguard Worker print_ebpf_insn(struct tcb * const tcp, void * const elem_buf,
138*cf84ac9aSAndroid Build Coastguard Worker 		const size_t elem_size, void * const data)
139*cf84ac9aSAndroid Build Coastguard Worker {
140*cf84ac9aSAndroid Build Coastguard Worker 	struct ebpf_insns_data *eid = data;
141*cf84ac9aSAndroid Build Coastguard Worker 	struct ebpf_insn *insn = elem_buf;
142*cf84ac9aSAndroid Build Coastguard Worker 
143*cf84ac9aSAndroid Build Coastguard Worker 	if (eid->count++ >= BPF_MAXINSNS) {
144*cf84ac9aSAndroid Build Coastguard Worker 		tprints("...");
145*cf84ac9aSAndroid Build Coastguard Worker 		return false;
146*cf84ac9aSAndroid Build Coastguard Worker 	}
147*cf84ac9aSAndroid Build Coastguard Worker 
148*cf84ac9aSAndroid Build Coastguard Worker 	tprints("{code=");
149*cf84ac9aSAndroid Build Coastguard Worker 	print_bpf_filter_code(insn->code, true);
150*cf84ac9aSAndroid Build Coastguard Worker 
151*cf84ac9aSAndroid Build Coastguard Worker 	/* We can't use PRINT_FIELD_XVAL on bit fields */
152*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", dst_reg=");
153*cf84ac9aSAndroid Build Coastguard Worker 	printxval_index(ebpf_regs, insn->dst_reg, "BPF_REG_???");
154*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", src_reg=");
155*cf84ac9aSAndroid Build Coastguard Worker 	printxval_index(ebpf_regs, insn->src_reg, "BPF_REG_???");
156*cf84ac9aSAndroid Build Coastguard Worker 
157*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_D(", ", *insn, off);
158*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_X(", ", *insn, imm);
159*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
160*cf84ac9aSAndroid Build Coastguard Worker 
161*cf84ac9aSAndroid Build Coastguard Worker 	return true;
162*cf84ac9aSAndroid Build Coastguard Worker }
163*cf84ac9aSAndroid Build Coastguard Worker 
164*cf84ac9aSAndroid Build Coastguard Worker static void
print_ebpf_prog(struct tcb * const tcp,const uint64_t addr,const uint32_t len)165*cf84ac9aSAndroid Build Coastguard Worker print_ebpf_prog(struct tcb *const tcp, const uint64_t addr, const uint32_t len)
166*cf84ac9aSAndroid Build Coastguard Worker {
167*cf84ac9aSAndroid Build Coastguard Worker 	print_big_u64_addr(addr);
168*cf84ac9aSAndroid Build Coastguard Worker 	if (abbrev(tcp)) {
169*cf84ac9aSAndroid Build Coastguard Worker 		printaddr(addr);
170*cf84ac9aSAndroid Build Coastguard Worker 	} else {
171*cf84ac9aSAndroid Build Coastguard Worker 		struct ebpf_insns_data eid = {};
172*cf84ac9aSAndroid Build Coastguard Worker 		struct ebpf_insn insn;
173*cf84ac9aSAndroid Build Coastguard Worker 
174*cf84ac9aSAndroid Build Coastguard Worker 		print_array(tcp, addr, len, &insn, sizeof(insn),
175*cf84ac9aSAndroid Build Coastguard Worker 			    tfetch_mem, print_ebpf_insn, &eid);
176*cf84ac9aSAndroid Build Coastguard Worker 	}
177*cf84ac9aSAndroid Build Coastguard Worker }
178*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_MAP_CREATE)179*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_MAP_CREATE)
180*cf84ac9aSAndroid Build Coastguard Worker {
181*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_XVAL_INDEX("{", attr, map_type, bpf_map_types,
182*cf84ac9aSAndroid Build Coastguard Worker 			       "BPF_MAP_TYPE_???");
183*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, key_size);
184*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, value_size);
185*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, max_entries);
186*cf84ac9aSAndroid Build Coastguard Worker 
187*cf84ac9aSAndroid Build Coastguard Worker 	/* map_flags field was added in Linux commit v4.6-rc1~91^2~108^2~6. */
188*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_MAP_CREATE_struct, map_flags))
189*cf84ac9aSAndroid Build Coastguard Worker 		break;
190*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FLAGS(", ", attr, map_flags, bpf_map_flags, "BPF_F_???");
191*cf84ac9aSAndroid Build Coastguard Worker 
192*cf84ac9aSAndroid Build Coastguard Worker 	/*
193*cf84ac9aSAndroid Build Coastguard Worker 	 * inner_map_fd field was added in Linux commit
194*cf84ac9aSAndroid Build Coastguard Worker 	 * v4.12-rc1~64^3~373^2~2.
195*cf84ac9aSAndroid Build Coastguard Worker 	 */
196*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_MAP_CREATE_struct, inner_map_fd))
197*cf84ac9aSAndroid Build Coastguard Worker 		break;
198*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD(", ", attr, inner_map_fd, tcp);
199*cf84ac9aSAndroid Build Coastguard Worker 
200*cf84ac9aSAndroid Build Coastguard Worker 	/* numa_node field was added in Linux commit v4.14-rc1~130^2~196^2~1. */
201*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_MAP_CREATE_struct, numa_node))
202*cf84ac9aSAndroid Build Coastguard Worker 		break;
203*cf84ac9aSAndroid Build Coastguard Worker 	if (attr.map_flags & BPF_F_NUMA_NODE) {
204*cf84ac9aSAndroid Build Coastguard Worker 		/*
205*cf84ac9aSAndroid Build Coastguard Worker 		 * Kernel uses the value of -1 as a designation for "no NUMA
206*cf84ac9aSAndroid Build Coastguard Worker 		 * node specified", and even uses NUMA_NO_NODE constant;
207*cf84ac9aSAndroid Build Coastguard Worker 		 * however, the constant definition is not a part of UAPI
208*cf84ac9aSAndroid Build Coastguard Worker 		 * headers, thus we can't simply print this named constant
209*cf84ac9aSAndroid Build Coastguard Worker 		 * instead of the value. Let's force verbose xlat style instead
210*cf84ac9aSAndroid Build Coastguard Worker 		 * in order to provide the information for the user while
211*cf84ac9aSAndroid Build Coastguard Worker 		 * not hampering the availability to derive the actual value
212*cf84ac9aSAndroid Build Coastguard Worker 		 * without the access to the kernel headers.
213*cf84ac9aSAndroid Build Coastguard Worker 		 */
214*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", numa_node=");
215*cf84ac9aSAndroid Build Coastguard Worker 		printxvals_ex(attr.numa_node, NULL,
216*cf84ac9aSAndroid Build Coastguard Worker 			      XLAT_STYLE_FMT_U | XLAT_STYLE_VERBOSE,
217*cf84ac9aSAndroid Build Coastguard Worker 			      numa_node, NULL);
218*cf84ac9aSAndroid Build Coastguard Worker 	}
219*cf84ac9aSAndroid Build Coastguard Worker 
220*cf84ac9aSAndroid Build Coastguard Worker 	/* map_name field was added in Linux commit v4.15-rc1~84^2~605^2~3. */
221*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_MAP_CREATE_struct, map_name))
222*cf84ac9aSAndroid Build Coastguard Worker 		break;
223*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_CSTRING_SZ(", ", attr, map_name,
224*cf84ac9aSAndroid Build Coastguard Worker 			       MIN(sizeof(attr.map_name),
225*cf84ac9aSAndroid Build Coastguard Worker 				   len - offsetof(struct BPF_MAP_CREATE_struct,
226*cf84ac9aSAndroid Build Coastguard Worker 						  map_name)));
227*cf84ac9aSAndroid Build Coastguard Worker 
228*cf84ac9aSAndroid Build Coastguard Worker 	/*
229*cf84ac9aSAndroid Build Coastguard Worker 	 * map_ifindex field was added in Linux commit
230*cf84ac9aSAndroid Build Coastguard Worker 	 * v4.16-rc1~123^2~145^2~5^2~8.
231*cf84ac9aSAndroid Build Coastguard Worker 	 */
232*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_MAP_CREATE_struct, map_ifindex))
233*cf84ac9aSAndroid Build Coastguard Worker 		break;
234*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_IFINDEX(", ", attr, map_ifindex);
235*cf84ac9aSAndroid Build Coastguard Worker }
236*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
237*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_MAP_LOOKUP_ELEM)238*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_MAP_LOOKUP_ELEM)
239*cf84ac9aSAndroid Build Coastguard Worker {
240*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD("{", attr, map_fd, tcp);
241*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, key);
242*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, value);
243*cf84ac9aSAndroid Build Coastguard Worker }
244*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
245*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_ELEM)246*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_ELEM)
247*cf84ac9aSAndroid Build Coastguard Worker {
248*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD("{", attr, map_fd, tcp);
249*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, key);
250*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, value);
251*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_XVAL_INDEX(", ", attr, flags, bpf_map_update_elem_flags,
252*cf84ac9aSAndroid Build Coastguard Worker 			       "BPF_???");
253*cf84ac9aSAndroid Build Coastguard Worker }
254*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
255*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_MAP_DELETE_ELEM)256*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_MAP_DELETE_ELEM)
257*cf84ac9aSAndroid Build Coastguard Worker {
258*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD("{", attr, map_fd, tcp);
259*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, key);
260*cf84ac9aSAndroid Build Coastguard Worker }
261*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
262*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_MAP_GET_NEXT_KEY)263*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_MAP_GET_NEXT_KEY)
264*cf84ac9aSAndroid Build Coastguard Worker {
265*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD("{", attr, map_fd, tcp);
266*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, key);
267*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, next_key);
268*cf84ac9aSAndroid Build Coastguard Worker }
269*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
270*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_PROG_LOAD)271*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_PROG_LOAD)
272*cf84ac9aSAndroid Build Coastguard Worker {
273*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_XVAL_INDEX("{", attr, prog_type, bpf_prog_types,
274*cf84ac9aSAndroid Build Coastguard Worker 			       "BPF_PROG_TYPE_???");
275*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, insn_cnt);
276*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", insns=");
277*cf84ac9aSAndroid Build Coastguard Worker 	print_ebpf_prog(tcp, attr.insns, attr.insn_cnt);
278*cf84ac9aSAndroid Build Coastguard Worker 
279*cf84ac9aSAndroid Build Coastguard Worker 	tprintf(", license=");
280*cf84ac9aSAndroid Build Coastguard Worker 	print_big_u64_addr(attr.license);
281*cf84ac9aSAndroid Build Coastguard Worker 	printstr(tcp, attr.license);
282*cf84ac9aSAndroid Build Coastguard Worker 
283*cf84ac9aSAndroid Build Coastguard Worker 	/* log_* fields were added in Linux commit v3.18-rc1~52^2~1^2~4.  */
284*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_PROG_LOAD_struct, log_level))
285*cf84ac9aSAndroid Build Coastguard Worker 		break;
286*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, log_level);
287*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, log_size);
288*cf84ac9aSAndroid Build Coastguard Worker 	tprintf(", log_buf=");
289*cf84ac9aSAndroid Build Coastguard Worker 	print_big_u64_addr(attr.log_buf);
290*cf84ac9aSAndroid Build Coastguard Worker 	printstr_ex(tcp, attr.log_buf, attr.log_size, QUOTE_0_TERMINATED);
291*cf84ac9aSAndroid Build Coastguard Worker 
292*cf84ac9aSAndroid Build Coastguard Worker 	/* kern_version field was added in Linux commit v4.1-rc1~84^2~50.  */
293*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_PROG_LOAD_struct, kern_version))
294*cf84ac9aSAndroid Build Coastguard Worker 		break;
295*cf84ac9aSAndroid Build Coastguard Worker 	tprintf(", kern_version=KERNEL_VERSION(%u, %u, %u)",
296*cf84ac9aSAndroid Build Coastguard Worker 		attr.kern_version >> 16,
297*cf84ac9aSAndroid Build Coastguard Worker 		(attr.kern_version >> 8) & 0xFF,
298*cf84ac9aSAndroid Build Coastguard Worker 		attr.kern_version & 0xFF);
299*cf84ac9aSAndroid Build Coastguard Worker 
300*cf84ac9aSAndroid Build Coastguard Worker 	/* prog_flags field was added in Linux commit v4.12-rc2~34^2~29^2~2.  */
301*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_PROG_LOAD_struct, prog_flags))
302*cf84ac9aSAndroid Build Coastguard Worker 		break;
303*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FLAGS(", ", attr, prog_flags, bpf_prog_flags, "BPF_F_???");
304*cf84ac9aSAndroid Build Coastguard Worker 
305*cf84ac9aSAndroid Build Coastguard Worker 	/* prog_name field was added in Linux commit v4.15-rc1~84^2~605^2~4. */
306*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_PROG_LOAD_struct, prog_name))
307*cf84ac9aSAndroid Build Coastguard Worker 		break;
308*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_CSTRING_SZ(", ", attr, prog_name,
309*cf84ac9aSAndroid Build Coastguard Worker 			       MIN(sizeof(attr.prog_name),
310*cf84ac9aSAndroid Build Coastguard Worker 				   len - offsetof(struct BPF_PROG_LOAD_struct,
311*cf84ac9aSAndroid Build Coastguard Worker 						   prog_name)));
312*cf84ac9aSAndroid Build Coastguard Worker 
313*cf84ac9aSAndroid Build Coastguard Worker 	/*
314*cf84ac9aSAndroid Build Coastguard Worker 	 * prog_ifindex field was added as prog_target_ifindex in Linux commit
315*cf84ac9aSAndroid Build Coastguard Worker 	 * v4.15-rc1~84^2~127^2~13 and renamed to its current name in
316*cf84ac9aSAndroid Build Coastguard Worker 	 * v4.15-rc1~15^2~5^2~3^2~7.
317*cf84ac9aSAndroid Build Coastguard Worker 	 */
318*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_PROG_LOAD_struct, prog_ifindex))
319*cf84ac9aSAndroid Build Coastguard Worker 		break;
320*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_IFINDEX(", ", attr, prog_ifindex);
321*cf84ac9aSAndroid Build Coastguard Worker 
322*cf84ac9aSAndroid Build Coastguard Worker 	/*
323*cf84ac9aSAndroid Build Coastguard Worker 	 * expected_attach_type was added in Linux commit
324*cf84ac9aSAndroid Build Coastguard Worker 	 * v4.17-rc1~148^2~19^2^2~8.
325*cf84ac9aSAndroid Build Coastguard Worker 	 */
326*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_PROG_LOAD_struct, expected_attach_type))
327*cf84ac9aSAndroid Build Coastguard Worker 		break;
328*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_XVAL(", ", attr, expected_attach_type, bpf_attach_type,
329*cf84ac9aSAndroid Build Coastguard Worker 			 "BPF_???");
330*cf84ac9aSAndroid Build Coastguard Worker }
331*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
332*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_OBJ_PIN)333*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_OBJ_PIN)
334*cf84ac9aSAndroid Build Coastguard Worker {
335*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("{pathname=");
336*cf84ac9aSAndroid Build Coastguard Worker 	print_big_u64_addr(attr.pathname);
337*cf84ac9aSAndroid Build Coastguard Worker 	printpath(tcp, attr.pathname);
338*cf84ac9aSAndroid Build Coastguard Worker 
339*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD(", ", attr, bpf_fd, tcp);
340*cf84ac9aSAndroid Build Coastguard Worker 
341*cf84ac9aSAndroid Build Coastguard Worker 	/* file_flags field was added in Linux v4.15-rc1~84^2~384^2~4 */
342*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_OBJ_PIN_struct, file_flags))
343*cf84ac9aSAndroid Build Coastguard Worker 		break;
344*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FLAGS(", ", attr, file_flags, bpf_file_mode_flags,
345*cf84ac9aSAndroid Build Coastguard Worker 			  "BPF_F_???");
346*cf84ac9aSAndroid Build Coastguard Worker }
347*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
348*cf84ac9aSAndroid Build Coastguard Worker 
349*cf84ac9aSAndroid Build Coastguard Worker #define decode_BPF_OBJ_GET decode_BPF_OBJ_PIN
350*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_PROG_ATTACH)351*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_PROG_ATTACH)
352*cf84ac9aSAndroid Build Coastguard Worker {
353*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD("{", attr, target_fd, tcp);
354*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD(", ", attr, attach_bpf_fd, tcp);
355*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
356*cf84ac9aSAndroid Build Coastguard Worker 			       "BPF_???");
357*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
358*cf84ac9aSAndroid Build Coastguard Worker 			  "BPF_F_???");
359*cf84ac9aSAndroid Build Coastguard Worker }
360*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
361*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_PROG_DETACH)362*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_PROG_DETACH)
363*cf84ac9aSAndroid Build Coastguard Worker {
364*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD("{", attr, target_fd, tcp);
365*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
366*cf84ac9aSAndroid Build Coastguard Worker 			       "BPF_???");
367*cf84ac9aSAndroid Build Coastguard Worker }
368*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
369*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_PROG_TEST_RUN)370*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_PROG_TEST_RUN)
371*cf84ac9aSAndroid Build Coastguard Worker {
372*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD("{test={", attr, prog_fd, tcp);
373*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, retval);
374*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, data_size_in);
375*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, data_size_out);
376*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, data_in);
377*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_ADDR64(", ", attr, data_out);
378*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, repeat);
379*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, duration);
380*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
381*cf84ac9aSAndroid Build Coastguard Worker }
382*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
383*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_PROG_GET_NEXT_ID)384*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_PROG_GET_NEXT_ID)
385*cf84ac9aSAndroid Build Coastguard Worker {
386*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U("{", attr, start_id);
387*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, next_id);
388*cf84ac9aSAndroid Build Coastguard Worker 
389*cf84ac9aSAndroid Build Coastguard Worker 	/* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
390*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_PROG_GET_NEXT_ID_struct, open_flags))
391*cf84ac9aSAndroid Build Coastguard Worker 		break;
392*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FLAGS(", ", attr, open_flags, bpf_file_mode_flags,
393*cf84ac9aSAndroid Build Coastguard Worker 			  "BPF_F_???");
394*cf84ac9aSAndroid Build Coastguard Worker }
395*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
396*cf84ac9aSAndroid Build Coastguard Worker 
397*cf84ac9aSAndroid Build Coastguard Worker #define decode_BPF_MAP_GET_NEXT_ID decode_BPF_PROG_GET_NEXT_ID
398*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_PROG_GET_FD_BY_ID)399*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_PROG_GET_FD_BY_ID)
400*cf84ac9aSAndroid Build Coastguard Worker {
401*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U("{", attr, prog_id);
402*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, next_id);
403*cf84ac9aSAndroid Build Coastguard Worker 
404*cf84ac9aSAndroid Build Coastguard Worker 	/* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
405*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_PROG_GET_FD_BY_ID_struct, open_flags))
406*cf84ac9aSAndroid Build Coastguard Worker 		break;
407*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FLAGS(", ", attr, open_flags, bpf_file_mode_flags,
408*cf84ac9aSAndroid Build Coastguard Worker 			  "BPF_F_???");
409*cf84ac9aSAndroid Build Coastguard Worker }
410*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
411*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_MAP_GET_FD_BY_ID)412*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_MAP_GET_FD_BY_ID)
413*cf84ac9aSAndroid Build Coastguard Worker {
414*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U("{", attr, map_id);
415*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", attr, next_id);
416*cf84ac9aSAndroid Build Coastguard Worker 
417*cf84ac9aSAndroid Build Coastguard Worker 	/* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
418*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct BPF_MAP_GET_FD_BY_ID_struct, open_flags))
419*cf84ac9aSAndroid Build Coastguard Worker 		break;
420*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FLAGS(", ", attr, open_flags, bpf_file_mode_flags,
421*cf84ac9aSAndroid Build Coastguard Worker 			  "BPF_F_???");
422*cf84ac9aSAndroid Build Coastguard Worker }
423*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
424*cf84ac9aSAndroid Build Coastguard Worker 
425*cf84ac9aSAndroid Build Coastguard Worker struct obj_get_info_saved;
426*cf84ac9aSAndroid Build Coastguard Worker typedef void (*print_bpf_obj_info_fn)(struct tcb *,
427*cf84ac9aSAndroid Build Coastguard Worker 				      uint32_t bpf_fd,
428*cf84ac9aSAndroid Build Coastguard Worker 				      const char *info_buf,
429*cf84ac9aSAndroid Build Coastguard Worker 				      uint32_t size,
430*cf84ac9aSAndroid Build Coastguard Worker 				      struct obj_get_info_saved *saved);
431*cf84ac9aSAndroid Build Coastguard Worker 
432*cf84ac9aSAndroid Build Coastguard Worker struct obj_get_info_saved {
433*cf84ac9aSAndroid Build Coastguard Worker 	print_bpf_obj_info_fn print_fn;
434*cf84ac9aSAndroid Build Coastguard Worker 
435*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t info_len;
436*cf84ac9aSAndroid Build Coastguard Worker 
437*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t jited_prog_len;
438*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t xlated_prog_len;
439*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t nr_map_ids;
440*cf84ac9aSAndroid Build Coastguard Worker };
441*cf84ac9aSAndroid Build Coastguard Worker 
442*cf84ac9aSAndroid Build Coastguard Worker static void
print_bpf_map_info(struct tcb * const tcp,uint32_t bpf_fd,const char * info_buf,uint32_t size,struct obj_get_info_saved * saved)443*cf84ac9aSAndroid Build Coastguard Worker print_bpf_map_info(struct tcb * const tcp, uint32_t bpf_fd,
444*cf84ac9aSAndroid Build Coastguard Worker 		   const char *info_buf, uint32_t size,
445*cf84ac9aSAndroid Build Coastguard Worker 		   struct obj_get_info_saved *saved)
446*cf84ac9aSAndroid Build Coastguard Worker {
447*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp))
448*cf84ac9aSAndroid Build Coastguard Worker 		return;
449*cf84ac9aSAndroid Build Coastguard Worker 
450*cf84ac9aSAndroid Build Coastguard Worker 	struct bpf_map_info_struct info = { 0 };
451*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int len = MIN(size, bpf_map_info_struct_size);
452*cf84ac9aSAndroid Build Coastguard Worker 
453*cf84ac9aSAndroid Build Coastguard Worker 	memcpy(&info, info_buf, len);
454*cf84ac9aSAndroid Build Coastguard Worker 
455*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_XVAL("{", info, type, bpf_map_types, "BPF_MAP_TYPE_???");
456*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", info, id);
457*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", info, key_size);
458*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", info, value_size);
459*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", info, max_entries);
460*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FLAGS(", ", info, map_flags, bpf_map_flags, "BPF_F_???");
461*cf84ac9aSAndroid Build Coastguard Worker 
462*cf84ac9aSAndroid Build Coastguard Worker 	/*
463*cf84ac9aSAndroid Build Coastguard Worker 	 * "name" field was introduced by Linux commit v4.15-rc1~84^2~605^2~3.
464*cf84ac9aSAndroid Build Coastguard Worker 	 */
465*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct bpf_map_info_struct, name))
466*cf84ac9aSAndroid Build Coastguard Worker 		goto print_bpf_map_info_end;
467*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_CSTRING(", ", info, name);
468*cf84ac9aSAndroid Build Coastguard Worker 
469*cf84ac9aSAndroid Build Coastguard Worker 	/*
470*cf84ac9aSAndroid Build Coastguard Worker 	 * ifindex, netns_dev, and netns_ino fields were introduced
471*cf84ac9aSAndroid Build Coastguard Worker 	 * by Linux commit v4.16-rc1~123^2~109^2~5^2~4.
472*cf84ac9aSAndroid Build Coastguard Worker 	 */
473*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct bpf_map_info_struct, ifindex))
474*cf84ac9aSAndroid Build Coastguard Worker 		goto print_bpf_map_info_end;
475*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_IFINDEX(", ", info, ifindex);
476*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_DEV(", ", info, netns_dev);
477*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", info, netns_ino);
478*cf84ac9aSAndroid Build Coastguard Worker 
479*cf84ac9aSAndroid Build Coastguard Worker 	decode_attr_extra_data(tcp, info_buf, size, bpf_map_info_struct_size);
480*cf84ac9aSAndroid Build Coastguard Worker 
481*cf84ac9aSAndroid Build Coastguard Worker print_bpf_map_info_end:
482*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
483*cf84ac9aSAndroid Build Coastguard Worker }
484*cf84ac9aSAndroid Build Coastguard Worker 
485*cf84ac9aSAndroid Build Coastguard Worker static void
print_bpf_prog_info(struct tcb * const tcp,uint32_t bpf_fd,const char * info_buf,uint32_t size,struct obj_get_info_saved * saved)486*cf84ac9aSAndroid Build Coastguard Worker print_bpf_prog_info(struct tcb * const tcp, uint32_t bpf_fd,
487*cf84ac9aSAndroid Build Coastguard Worker 		    const char *info_buf, uint32_t size,
488*cf84ac9aSAndroid Build Coastguard Worker 		    struct obj_get_info_saved *saved)
489*cf84ac9aSAndroid Build Coastguard Worker {
490*cf84ac9aSAndroid Build Coastguard Worker 	struct bpf_prog_info_struct info = { 0 };
491*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int len = MIN(size, bpf_prog_info_struct_size);
492*cf84ac9aSAndroid Build Coastguard Worker 	uint64_t map_id_buf;
493*cf84ac9aSAndroid Build Coastguard Worker 
494*cf84ac9aSAndroid Build Coastguard Worker 	memcpy(&info, info_buf, len);
495*cf84ac9aSAndroid Build Coastguard Worker 
496*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
497*cf84ac9aSAndroid Build Coastguard Worker 		saved->jited_prog_len = info.jited_prog_len;
498*cf84ac9aSAndroid Build Coastguard Worker 		saved->xlated_prog_len = info.xlated_prog_len;
499*cf84ac9aSAndroid Build Coastguard Worker 		saved->nr_map_ids = info.nr_map_ids;
500*cf84ac9aSAndroid Build Coastguard Worker 
501*cf84ac9aSAndroid Build Coastguard Worker 		return;
502*cf84ac9aSAndroid Build Coastguard Worker 	}
503*cf84ac9aSAndroid Build Coastguard Worker 
504*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_XVAL("{", info, type, bpf_prog_types, "BPF_PROG_TYPE_???");
505*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", info, id);
506*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_HEX_ARRAY(", ", info, tag);
507*cf84ac9aSAndroid Build Coastguard Worker 
508*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", jited_prog_len=");
509*cf84ac9aSAndroid Build Coastguard Worker 	if (saved->jited_prog_len != info.jited_prog_len)
510*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("%" PRIu32 " => ", saved->jited_prog_len);
511*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("%" PRIu32, info.jited_prog_len);
512*cf84ac9aSAndroid Build Coastguard Worker 
513*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", jited_prog_insns=");
514*cf84ac9aSAndroid Build Coastguard Worker 	print_big_u64_addr(info.jited_prog_insns);
515*cf84ac9aSAndroid Build Coastguard Worker 	printstr_ex(tcp, info.jited_prog_insns, info.jited_prog_len,
516*cf84ac9aSAndroid Build Coastguard Worker 		    QUOTE_FORCE_HEX);
517*cf84ac9aSAndroid Build Coastguard Worker 
518*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", xlated_prog_len=");
519*cf84ac9aSAndroid Build Coastguard Worker 	if (saved->xlated_prog_len != info.xlated_prog_len)
520*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("%" PRIu32 " => ", saved->xlated_prog_len);
521*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("%" PRIu32, info.xlated_prog_len);
522*cf84ac9aSAndroid Build Coastguard Worker 
523*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", xlated_prog_insns=");
524*cf84ac9aSAndroid Build Coastguard Worker 	print_ebpf_prog(tcp, info.xlated_prog_insns,
525*cf84ac9aSAndroid Build Coastguard Worker 			MIN(saved->xlated_prog_len, info.xlated_prog_len) / 8);
526*cf84ac9aSAndroid Build Coastguard Worker 
527*cf84ac9aSAndroid Build Coastguard Worker 	/*
528*cf84ac9aSAndroid Build Coastguard Worker 	 * load_time, created_by_uid, nr_map_ids, map_ids, and name fields
529*cf84ac9aSAndroid Build Coastguard Worker 	 * were introduced by Linux commit v4.15-rc1~84^2~605^2~4.
530*cf84ac9aSAndroid Build Coastguard Worker 	 */
531*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct bpf_prog_info_struct, load_time))
532*cf84ac9aSAndroid Build Coastguard Worker 		goto print_bpf_prog_info_end;
533*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", info, load_time);
534*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_UID(", ", info, created_by_uid);
535*cf84ac9aSAndroid Build Coastguard Worker 
536*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", nr_map_ids=");
537*cf84ac9aSAndroid Build Coastguard Worker 	if (saved->nr_map_ids != info.nr_map_ids)
538*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("%" PRIu32 " => ", saved->nr_map_ids);
539*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("%" PRIu32, info.nr_map_ids);
540*cf84ac9aSAndroid Build Coastguard Worker 
541*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", map_ids=");
542*cf84ac9aSAndroid Build Coastguard Worker 	print_big_u64_addr(info.map_ids);
543*cf84ac9aSAndroid Build Coastguard Worker 	print_array(tcp, info.map_ids, MIN(saved->nr_map_ids, info.nr_map_ids),
544*cf84ac9aSAndroid Build Coastguard Worker 		    &map_id_buf, sizeof(map_id_buf),
545*cf84ac9aSAndroid Build Coastguard Worker 		    tfetch_mem, print_uint32_array_member, 0);
546*cf84ac9aSAndroid Build Coastguard Worker 
547*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_CSTRING(", ", info, name);
548*cf84ac9aSAndroid Build Coastguard Worker 
549*cf84ac9aSAndroid Build Coastguard Worker 	/*
550*cf84ac9aSAndroid Build Coastguard Worker 	 * ifindex, netns_dev, and netns_ino fields were introduced
551*cf84ac9aSAndroid Build Coastguard Worker 	 * by Linux commit v4.16-rc1~123^2~227^2~5^2~2.
552*cf84ac9aSAndroid Build Coastguard Worker 	 */
553*cf84ac9aSAndroid Build Coastguard Worker 	if (len <= offsetof(struct bpf_prog_info_struct, ifindex))
554*cf84ac9aSAndroid Build Coastguard Worker 		goto print_bpf_prog_info_end;
555*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_IFINDEX(", ", info, ifindex);
556*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_DEV(", ", info, netns_dev);
557*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_U(", ", info, netns_ino);
558*cf84ac9aSAndroid Build Coastguard Worker 
559*cf84ac9aSAndroid Build Coastguard Worker 	decode_attr_extra_data(tcp, info_buf, size, bpf_prog_info_struct_size);
560*cf84ac9aSAndroid Build Coastguard Worker 
561*cf84ac9aSAndroid Build Coastguard Worker print_bpf_prog_info_end:
562*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
563*cf84ac9aSAndroid Build Coastguard Worker }
564*cf84ac9aSAndroid Build Coastguard Worker 
565*cf84ac9aSAndroid Build Coastguard Worker static const char *
fetch_bpf_obj_info(struct tcb * const tcp,uint64_t info,uint32_t size)566*cf84ac9aSAndroid Build Coastguard Worker fetch_bpf_obj_info(struct tcb * const tcp, uint64_t info, uint32_t size)
567*cf84ac9aSAndroid Build Coastguard Worker {
568*cf84ac9aSAndroid Build Coastguard Worker 	static char *info_buf;
569*cf84ac9aSAndroid Build Coastguard Worker 
570*cf84ac9aSAndroid Build Coastguard Worker 	if (!info_buf)
571*cf84ac9aSAndroid Build Coastguard Worker 		info_buf = xmalloc(get_pagesize());
572*cf84ac9aSAndroid Build Coastguard Worker 
573*cf84ac9aSAndroid Build Coastguard Worker 	memset(info_buf, 0, get_pagesize());
574*cf84ac9aSAndroid Build Coastguard Worker 
575*cf84ac9aSAndroid Build Coastguard Worker 	if (size > 0 && size <= get_pagesize()
576*cf84ac9aSAndroid Build Coastguard Worker 	    && !umoven(tcp, info, size, info_buf))
577*cf84ac9aSAndroid Build Coastguard Worker 		return info_buf;
578*cf84ac9aSAndroid Build Coastguard Worker 
579*cf84ac9aSAndroid Build Coastguard Worker 	return NULL;
580*cf84ac9aSAndroid Build Coastguard Worker }
581*cf84ac9aSAndroid Build Coastguard Worker 
582*cf84ac9aSAndroid Build Coastguard Worker static void
print_bpf_obj_info_addr(struct tcb * const tcp,uint64_t addr)583*cf84ac9aSAndroid Build Coastguard Worker print_bpf_obj_info_addr(struct tcb * const tcp, uint64_t addr)
584*cf84ac9aSAndroid Build Coastguard Worker {
585*cf84ac9aSAndroid Build Coastguard Worker 	if (exiting(tcp))
586*cf84ac9aSAndroid Build Coastguard Worker 		printaddr64(addr);
587*cf84ac9aSAndroid Build Coastguard Worker }
588*cf84ac9aSAndroid Build Coastguard Worker 
589*cf84ac9aSAndroid Build Coastguard Worker static void
print_bpf_obj_info(struct tcb * const tcp,uint32_t bpf_fd,uint64_t info,uint32_t size,struct obj_get_info_saved * saved)590*cf84ac9aSAndroid Build Coastguard Worker print_bpf_obj_info(struct tcb * const tcp, uint32_t bpf_fd, uint64_t info,
591*cf84ac9aSAndroid Build Coastguard Worker 		   uint32_t size, struct obj_get_info_saved *saved)
592*cf84ac9aSAndroid Build Coastguard Worker {
593*cf84ac9aSAndroid Build Coastguard Worker 	if (abbrev(tcp)) {
594*cf84ac9aSAndroid Build Coastguard Worker 		print_bpf_obj_info_addr(tcp, info);
595*cf84ac9aSAndroid Build Coastguard Worker 		return;
596*cf84ac9aSAndroid Build Coastguard Worker 	}
597*cf84ac9aSAndroid Build Coastguard Worker 
598*cf84ac9aSAndroid Build Coastguard Worker 	static struct {
599*cf84ac9aSAndroid Build Coastguard Worker 		const char *id;
600*cf84ac9aSAndroid Build Coastguard Worker 		print_bpf_obj_info_fn print_fn;
601*cf84ac9aSAndroid Build Coastguard Worker 	} obj_printers[] = {
602*cf84ac9aSAndroid Build Coastguard Worker 		{ "anon_inode:bpf-map", print_bpf_map_info },
603*cf84ac9aSAndroid Build Coastguard Worker 		{ "anon_inode:bpf-prog", print_bpf_prog_info }
604*cf84ac9aSAndroid Build Coastguard Worker 	};
605*cf84ac9aSAndroid Build Coastguard Worker 
606*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
607*cf84ac9aSAndroid Build Coastguard Worker 		char path[PATH_MAX + 1];
608*cf84ac9aSAndroid Build Coastguard Worker 
609*cf84ac9aSAndroid Build Coastguard Worker 		if (getfdpath(tcp, bpf_fd, path, sizeof(path)) > 0) {
610*cf84ac9aSAndroid Build Coastguard Worker 			for (size_t i = 0; i < ARRAY_SIZE(obj_printers); ++i) {
611*cf84ac9aSAndroid Build Coastguard Worker 				if (!strcmp(path, obj_printers[i].id)) {
612*cf84ac9aSAndroid Build Coastguard Worker 					saved->print_fn =
613*cf84ac9aSAndroid Build Coastguard Worker 						obj_printers[i].print_fn;
614*cf84ac9aSAndroid Build Coastguard Worker 					break;
615*cf84ac9aSAndroid Build Coastguard Worker 				}
616*cf84ac9aSAndroid Build Coastguard Worker 			}
617*cf84ac9aSAndroid Build Coastguard Worker 		}
618*cf84ac9aSAndroid Build Coastguard Worker 	}
619*cf84ac9aSAndroid Build Coastguard Worker 
620*cf84ac9aSAndroid Build Coastguard Worker 	if (!saved || !saved->print_fn) {
621*cf84ac9aSAndroid Build Coastguard Worker 		print_bpf_obj_info_addr(tcp, info);
622*cf84ac9aSAndroid Build Coastguard Worker 		return;
623*cf84ac9aSAndroid Build Coastguard Worker 	}
624*cf84ac9aSAndroid Build Coastguard Worker 
625*cf84ac9aSAndroid Build Coastguard Worker 	const char *info_buf = fetch_bpf_obj_info(tcp, info, size);
626*cf84ac9aSAndroid Build Coastguard Worker 
627*cf84ac9aSAndroid Build Coastguard Worker 	if (info_buf)
628*cf84ac9aSAndroid Build Coastguard Worker 		saved->print_fn(tcp, bpf_fd, info_buf, size, saved);
629*cf84ac9aSAndroid Build Coastguard Worker 	else
630*cf84ac9aSAndroid Build Coastguard Worker 		print_bpf_obj_info_addr(tcp, info);
631*cf84ac9aSAndroid Build Coastguard Worker }
632*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_OBJ_GET_INFO_BY_FD)633*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_OBJ_GET_INFO_BY_FD)
634*cf84ac9aSAndroid Build Coastguard Worker {
635*cf84ac9aSAndroid Build Coastguard Worker 	struct obj_get_info_saved *saved;
636*cf84ac9aSAndroid Build Coastguard Worker 
637*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
638*cf84ac9aSAndroid Build Coastguard Worker 		saved = xcalloc(1, sizeof(*saved));
639*cf84ac9aSAndroid Build Coastguard Worker 		saved->info_len = attr.info_len;
640*cf84ac9aSAndroid Build Coastguard Worker 		set_tcb_priv_data(tcp, saved, free);
641*cf84ac9aSAndroid Build Coastguard Worker 
642*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_FD("{info={", attr, bpf_fd, tcp);
643*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_U(", ", attr, info_len);
644*cf84ac9aSAndroid Build Coastguard Worker 	} else {
645*cf84ac9aSAndroid Build Coastguard Worker 		saved = get_tcb_priv_data(tcp);
646*cf84ac9aSAndroid Build Coastguard Worker 
647*cf84ac9aSAndroid Build Coastguard Worker 		if (saved && (saved->info_len != attr.info_len))
648*cf84ac9aSAndroid Build Coastguard Worker 			tprintf(" => %u", attr.info_len);
649*cf84ac9aSAndroid Build Coastguard Worker 
650*cf84ac9aSAndroid Build Coastguard Worker 		tprintf(", info=");
651*cf84ac9aSAndroid Build Coastguard Worker 	}
652*cf84ac9aSAndroid Build Coastguard Worker 
653*cf84ac9aSAndroid Build Coastguard Worker 	print_bpf_obj_info(tcp, attr.bpf_fd, attr.info, attr.info_len, saved);
654*cf84ac9aSAndroid Build Coastguard Worker 
655*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp))
656*cf84ac9aSAndroid Build Coastguard Worker 		return 0;
657*cf84ac9aSAndroid Build Coastguard Worker 
658*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
659*cf84ac9aSAndroid Build Coastguard Worker }
660*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
661*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)662*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)
663*cf84ac9aSAndroid Build Coastguard Worker {
664*cf84ac9aSAndroid Build Coastguard Worker 	uint32_t prog_id_buf;
665*cf84ac9aSAndroid Build Coastguard Worker 
666*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
667*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_FD("{query={", attr, target_fd, tcp);
668*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
669*cf84ac9aSAndroid Build Coastguard Worker 				       "BPF_???");
670*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_FLAGS(", ", attr, query_flags, bpf_query_flags,
671*cf84ac9aSAndroid Build Coastguard Worker 				  "BPF_F_QUERY_???");
672*cf84ac9aSAndroid Build Coastguard Worker 		PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
673*cf84ac9aSAndroid Build Coastguard Worker 				  "BPF_F_???");
674*cf84ac9aSAndroid Build Coastguard Worker 
675*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", prog_ids=");
676*cf84ac9aSAndroid Build Coastguard Worker 
677*cf84ac9aSAndroid Build Coastguard Worker 		set_tcb_priv_ulong(tcp, attr.prog_cnt);
678*cf84ac9aSAndroid Build Coastguard Worker 
679*cf84ac9aSAndroid Build Coastguard Worker 		return 0;
680*cf84ac9aSAndroid Build Coastguard Worker 	}
681*cf84ac9aSAndroid Build Coastguard Worker 
682*cf84ac9aSAndroid Build Coastguard Worker 	print_big_u64_addr(attr.prog_ids);
683*cf84ac9aSAndroid Build Coastguard Worker 	print_array(tcp, attr.prog_ids, attr.prog_cnt, &prog_id_buf,
684*cf84ac9aSAndroid Build Coastguard Worker 		    sizeof(prog_id_buf), tfetch_mem,
685*cf84ac9aSAndroid Build Coastguard Worker 		    print_uint32_array_member, 0);
686*cf84ac9aSAndroid Build Coastguard Worker 
687*cf84ac9aSAndroid Build Coastguard Worker 	tprints(", prog_cnt=");
688*cf84ac9aSAndroid Build Coastguard Worker 	const uint32_t prog_cnt_entering = get_tcb_priv_ulong(tcp);
689*cf84ac9aSAndroid Build Coastguard Worker 	if (prog_cnt_entering != attr.prog_cnt)
690*cf84ac9aSAndroid Build Coastguard Worker 		tprintf("%" PRIu32 " => ", prog_cnt_entering);
691*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("%" PRIu32, attr.prog_cnt);
692*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
693*cf84ac9aSAndroid Build Coastguard Worker }
694*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
695*cf84ac9aSAndroid Build Coastguard Worker 
BEGIN_BPF_CMD_DECODER(BPF_RAW_TRACEPOINT_OPEN)696*cf84ac9aSAndroid Build Coastguard Worker BEGIN_BPF_CMD_DECODER(BPF_RAW_TRACEPOINT_OPEN)
697*cf84ac9aSAndroid Build Coastguard Worker {
698*cf84ac9aSAndroid Build Coastguard Worker 	enum { TP_NAME_SIZE = 128 };
699*cf84ac9aSAndroid Build Coastguard Worker 
700*cf84ac9aSAndroid Build Coastguard Worker 	tprintf("{raw_tracepoint={name=");
701*cf84ac9aSAndroid Build Coastguard Worker 	print_big_u64_addr(attr.name);
702*cf84ac9aSAndroid Build Coastguard Worker 	printstr_ex(tcp, attr.name, TP_NAME_SIZE, QUOTE_0_TERMINATED);
703*cf84ac9aSAndroid Build Coastguard Worker 
704*cf84ac9aSAndroid Build Coastguard Worker 	PRINT_FIELD_FD(", ", attr, prog_fd, tcp);
705*cf84ac9aSAndroid Build Coastguard Worker 
706*cf84ac9aSAndroid Build Coastguard Worker 	tprints("}");
707*cf84ac9aSAndroid Build Coastguard Worker }
708*cf84ac9aSAndroid Build Coastguard Worker END_BPF_CMD_DECODER(RVAL_DECODED)
709*cf84ac9aSAndroid Build Coastguard Worker 
SYS_FUNC(bpf)710*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(bpf)
711*cf84ac9aSAndroid Build Coastguard Worker {
712*cf84ac9aSAndroid Build Coastguard Worker 	static const bpf_cmd_decoder_t bpf_cmd_decoders[] = {
713*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_MAP_CREATE),
714*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_MAP_LOOKUP_ELEM),
715*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_MAP_UPDATE_ELEM),
716*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_MAP_DELETE_ELEM),
717*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_MAP_GET_NEXT_KEY),
718*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_PROG_LOAD),
719*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_OBJ_PIN),
720*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_OBJ_GET),
721*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_PROG_ATTACH),
722*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_PROG_DETACH),
723*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_PROG_TEST_RUN),
724*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_PROG_GET_NEXT_ID),
725*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_MAP_GET_NEXT_ID),
726*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_PROG_GET_FD_BY_ID),
727*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_MAP_GET_FD_BY_ID),
728*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_OBJ_GET_INFO_BY_FD),
729*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_PROG_QUERY),
730*cf84ac9aSAndroid Build Coastguard Worker 		BPF_CMD_ENTRY(BPF_RAW_TRACEPOINT_OPEN),
731*cf84ac9aSAndroid Build Coastguard Worker 	};
732*cf84ac9aSAndroid Build Coastguard Worker 
733*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int cmd = tcp->u_arg[0];
734*cf84ac9aSAndroid Build Coastguard Worker 	const kernel_ulong_t addr = tcp->u_arg[1];
735*cf84ac9aSAndroid Build Coastguard Worker 	const unsigned int size = tcp->u_arg[2];
736*cf84ac9aSAndroid Build Coastguard Worker 	int rc = RVAL_DECODED;
737*cf84ac9aSAndroid Build Coastguard Worker 
738*cf84ac9aSAndroid Build Coastguard Worker 	if (entering(tcp)) {
739*cf84ac9aSAndroid Build Coastguard Worker 		printxval_index(bpf_commands, cmd, "BPF_???");
740*cf84ac9aSAndroid Build Coastguard Worker 		tprints(", ");
741*cf84ac9aSAndroid Build Coastguard Worker 	}
742*cf84ac9aSAndroid Build Coastguard Worker 
743*cf84ac9aSAndroid Build Coastguard Worker 	if (size > 0
744*cf84ac9aSAndroid Build Coastguard Worker 	    && size <= get_pagesize()
745*cf84ac9aSAndroid Build Coastguard Worker 	    && cmd < ARRAY_SIZE(bpf_cmd_decoders)
746*cf84ac9aSAndroid Build Coastguard Worker 	    && bpf_cmd_decoders[cmd]) {
747*cf84ac9aSAndroid Build Coastguard Worker 		static char *buf;
748*cf84ac9aSAndroid Build Coastguard Worker 
749*cf84ac9aSAndroid Build Coastguard Worker 		if (!buf)
750*cf84ac9aSAndroid Build Coastguard Worker 			buf = xmalloc(get_pagesize());
751*cf84ac9aSAndroid Build Coastguard Worker 
752*cf84ac9aSAndroid Build Coastguard Worker 		if (!umoven_or_printaddr_ignore_syserror(tcp, addr, size, buf))
753*cf84ac9aSAndroid Build Coastguard Worker 			rc = bpf_cmd_decoders[cmd](tcp, addr, size, buf);
754*cf84ac9aSAndroid Build Coastguard Worker 	} else {
755*cf84ac9aSAndroid Build Coastguard Worker 		printaddr(addr);
756*cf84ac9aSAndroid Build Coastguard Worker 	}
757*cf84ac9aSAndroid Build Coastguard Worker 
758*cf84ac9aSAndroid Build Coastguard Worker 	if (exiting(tcp) || (rc & RVAL_DECODED))
759*cf84ac9aSAndroid Build Coastguard Worker 		tprintf(", %u", size);
760*cf84ac9aSAndroid Build Coastguard Worker 
761*cf84ac9aSAndroid Build Coastguard Worker 	return rc;
762*cf84ac9aSAndroid Build Coastguard Worker }
763