xref: /linux/tools/lib/bpf/gen_loader.c (revision eb63cfcd2ee8ec3805f6881f43341f589c3d2278)
1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2 /* Copyright (c) 2021 Facebook */
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <linux/filter.h>
8 #include <sys/param.h>
9 #include "btf.h"
10 #include "bpf.h"
11 #include "libbpf.h"
12 #include "libbpf_internal.h"
13 #include "hashmap.h"
14 #include "bpf_gen_internal.h"
15 #include "skel_internal.h"
16 
17 #define MAX_USED_MAPS	64
18 #define MAX_USED_PROGS	32
19 #define MAX_KFUNC_DESCS 256
20 #define MAX_FD_ARRAY_SZ (MAX_USED_PROGS + MAX_KFUNC_DESCS)
21 
22 /* The following structure describes the stack layout of the loader program.
23  * In addition R6 contains the pointer to context.
24  * R7 contains the result of the last sys_bpf command (typically error or FD).
25  * R9 contains the result of the last sys_close command.
26  *
27  * Naming convention:
28  * ctx - bpf program context
29  * stack - bpf program stack
30  * blob - bpf_attr-s, strings, insns, map data.
31  *        All the bytes that loader prog will use for read/write.
32  */
33 struct loader_stack {
34 	__u32 btf_fd;
35 	__u32 prog_fd[MAX_USED_PROGS];
36 	__u32 inner_map_fd;
37 };
38 
39 #define stack_off(field) \
40 	(__s16)(-sizeof(struct loader_stack) + offsetof(struct loader_stack, field))
41 
42 #define attr_field(attr, field) (attr + offsetof(union bpf_attr, field))
43 
44 static int realloc_insn_buf(struct bpf_gen *gen, __u32 size)
45 {
46 	size_t off = gen->insn_cur - gen->insn_start;
47 	void *insn_start;
48 
49 	if (gen->error)
50 		return gen->error;
51 	if (size > INT32_MAX || off + size > INT32_MAX) {
52 		gen->error = -ERANGE;
53 		return -ERANGE;
54 	}
55 	insn_start = realloc(gen->insn_start, off + size);
56 	if (!insn_start) {
57 		gen->error = -ENOMEM;
58 		free(gen->insn_start);
59 		gen->insn_start = NULL;
60 		return -ENOMEM;
61 	}
62 	gen->insn_start = insn_start;
63 	gen->insn_cur = insn_start + off;
64 	return 0;
65 }
66 
67 static int realloc_data_buf(struct bpf_gen *gen, __u32 size)
68 {
69 	size_t off = gen->data_cur - gen->data_start;
70 	void *data_start;
71 
72 	if (gen->error)
73 		return gen->error;
74 	if (size > INT32_MAX || off + size > INT32_MAX) {
75 		gen->error = -ERANGE;
76 		return -ERANGE;
77 	}
78 	data_start = realloc(gen->data_start, off + size);
79 	if (!data_start) {
80 		gen->error = -ENOMEM;
81 		free(gen->data_start);
82 		gen->data_start = NULL;
83 		return -ENOMEM;
84 	}
85 	gen->data_start = data_start;
86 	gen->data_cur = data_start + off;
87 	return 0;
88 }
89 
90 static void emit(struct bpf_gen *gen, struct bpf_insn insn)
91 {
92 	if (realloc_insn_buf(gen, sizeof(insn)))
93 		return;
94 	memcpy(gen->insn_cur, &insn, sizeof(insn));
95 	gen->insn_cur += sizeof(insn);
96 }
97 
98 static void emit2(struct bpf_gen *gen, struct bpf_insn insn1, struct bpf_insn insn2)
99 {
100 	emit(gen, insn1);
101 	emit(gen, insn2);
102 }
103 
104 void bpf_gen__init(struct bpf_gen *gen, int log_level)
105 {
106 	size_t stack_sz = sizeof(struct loader_stack);
107 	int i;
108 
109 	gen->log_level = log_level;
110 	/* save ctx pointer into R6 */
111 	emit(gen, BPF_MOV64_REG(BPF_REG_6, BPF_REG_1));
112 
113 	/* bzero stack */
114 	emit(gen, BPF_MOV64_REG(BPF_REG_1, BPF_REG_10));
115 	emit(gen, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -stack_sz));
116 	emit(gen, BPF_MOV64_IMM(BPF_REG_2, stack_sz));
117 	emit(gen, BPF_MOV64_IMM(BPF_REG_3, 0));
118 	emit(gen, BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel));
119 
120 	/* jump over cleanup code */
121 	emit(gen, BPF_JMP_IMM(BPF_JA, 0, 0,
122 			      /* size of cleanup code below */
123 			      (stack_sz / 4) * 3 + 2));
124 
125 	/* remember the label where all error branches will jump to */
126 	gen->cleanup_label = gen->insn_cur - gen->insn_start;
127 	/* emit cleanup code: close all temp FDs */
128 	for (i = 0; i < stack_sz; i += 4) {
129 		emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_10, -stack_sz + i));
130 		emit(gen, BPF_JMP_IMM(BPF_JSLE, BPF_REG_1, 0, 1));
131 		emit(gen, BPF_EMIT_CALL(BPF_FUNC_sys_close));
132 	}
133 	/* R7 contains the error code from sys_bpf. Copy it into R0 and exit. */
134 	emit(gen, BPF_MOV64_REG(BPF_REG_0, BPF_REG_7));
135 	emit(gen, BPF_EXIT_INSN());
136 }
137 
138 static int add_data(struct bpf_gen *gen, const void *data, __u32 size)
139 {
140 	__u32 size8 = roundup(size, 8);
141 	__u64 zero = 0;
142 	void *prev;
143 
144 	if (realloc_data_buf(gen, size8))
145 		return 0;
146 	prev = gen->data_cur;
147 	if (data) {
148 		memcpy(gen->data_cur, data, size);
149 		memcpy(gen->data_cur + size, &zero, size8 - size);
150 	} else {
151 		memset(gen->data_cur, 0, size8);
152 	}
153 	gen->data_cur += size8;
154 	return prev - gen->data_start;
155 }
156 
157 /* Get index for map_fd/btf_fd slot in reserved fd_array, or in data relative
158  * to start of fd_array. Caller can decide if it is usable or not.
159  */
160 static int add_map_fd(struct bpf_gen *gen)
161 {
162 	if (!gen->fd_array)
163 		gen->fd_array = add_data(gen, NULL, MAX_FD_ARRAY_SZ * sizeof(int));
164 	if (gen->nr_maps == MAX_USED_MAPS) {
165 		pr_warn("Total maps exceeds %d\n", MAX_USED_MAPS);
166 		gen->error = -E2BIG;
167 		return 0;
168 	}
169 	return gen->nr_maps++;
170 }
171 
172 static int add_kfunc_btf_fd(struct bpf_gen *gen)
173 {
174 	int cur;
175 
176 	if (!gen->fd_array)
177 		gen->fd_array = add_data(gen, NULL, MAX_FD_ARRAY_SZ * sizeof(int));
178 	if (gen->nr_fd_array == MAX_KFUNC_DESCS) {
179 		cur = add_data(gen, NULL, sizeof(int));
180 		return (cur - gen->fd_array) / sizeof(int);
181 	}
182 	return MAX_USED_MAPS + gen->nr_fd_array++;
183 }
184 
185 static int blob_fd_array_off(struct bpf_gen *gen, int index)
186 {
187 	return gen->fd_array + index * sizeof(int);
188 }
189 
190 static int insn_bytes_to_bpf_size(__u32 sz)
191 {
192 	switch (sz) {
193 	case 8: return BPF_DW;
194 	case 4: return BPF_W;
195 	case 2: return BPF_H;
196 	case 1: return BPF_B;
197 	default: return -1;
198 	}
199 }
200 
201 /* *(u64 *)(blob + off) = (u64)(void *)(blob + data) */
202 static void emit_rel_store(struct bpf_gen *gen, int off, int data)
203 {
204 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_0, BPF_PSEUDO_MAP_IDX_VALUE,
205 					 0, 0, 0, data));
206 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
207 					 0, 0, 0, off));
208 	emit(gen, BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0));
209 }
210 
211 static void move_blob2blob(struct bpf_gen *gen, int off, int size, int blob_off)
212 {
213 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_2, BPF_PSEUDO_MAP_IDX_VALUE,
214 					 0, 0, 0, blob_off));
215 	emit(gen, BPF_LDX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_0, BPF_REG_2, 0));
216 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
217 					 0, 0, 0, off));
218 	emit(gen, BPF_STX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_1, BPF_REG_0, 0));
219 }
220 
221 static void move_blob2ctx(struct bpf_gen *gen, int ctx_off, int size, int blob_off)
222 {
223 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
224 					 0, 0, 0, blob_off));
225 	emit(gen, BPF_LDX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_0, BPF_REG_1, 0));
226 	emit(gen, BPF_STX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_6, BPF_REG_0, ctx_off));
227 }
228 
229 static void move_ctx2blob(struct bpf_gen *gen, int off, int size, int ctx_off,
230 				   bool check_non_zero)
231 {
232 	emit(gen, BPF_LDX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_0, BPF_REG_6, ctx_off));
233 	if (check_non_zero)
234 		/* If value in ctx is zero don't update the blob.
235 		 * For example: when ctx->map.max_entries == 0, keep default max_entries from bpf.c
236 		 */
237 		emit(gen, BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3));
238 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
239 					 0, 0, 0, off));
240 	emit(gen, BPF_STX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_1, BPF_REG_0, 0));
241 }
242 
243 static void move_stack2blob(struct bpf_gen *gen, int off, int size, int stack_off)
244 {
245 	emit(gen, BPF_LDX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_0, BPF_REG_10, stack_off));
246 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
247 					 0, 0, 0, off));
248 	emit(gen, BPF_STX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_1, BPF_REG_0, 0));
249 }
250 
251 static void move_stack2ctx(struct bpf_gen *gen, int ctx_off, int size, int stack_off)
252 {
253 	emit(gen, BPF_LDX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_0, BPF_REG_10, stack_off));
254 	emit(gen, BPF_STX_MEM(insn_bytes_to_bpf_size(size), BPF_REG_6, BPF_REG_0, ctx_off));
255 }
256 
257 static void emit_sys_bpf(struct bpf_gen *gen, int cmd, int attr, int attr_size)
258 {
259 	emit(gen, BPF_MOV64_IMM(BPF_REG_1, cmd));
260 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_2, BPF_PSEUDO_MAP_IDX_VALUE,
261 					 0, 0, 0, attr));
262 	emit(gen, BPF_MOV64_IMM(BPF_REG_3, attr_size));
263 	emit(gen, BPF_EMIT_CALL(BPF_FUNC_sys_bpf));
264 	/* remember the result in R7 */
265 	emit(gen, BPF_MOV64_REG(BPF_REG_7, BPF_REG_0));
266 }
267 
268 static bool is_simm16(__s64 value)
269 {
270 	return value == (__s64)(__s16)value;
271 }
272 
273 static void emit_check_err(struct bpf_gen *gen)
274 {
275 	__s64 off = -(gen->insn_cur - gen->insn_start - gen->cleanup_label) / 8 - 1;
276 
277 	/* R7 contains result of last sys_bpf command.
278 	 * if (R7 < 0) goto cleanup;
279 	 */
280 	if (is_simm16(off)) {
281 		emit(gen, BPF_JMP_IMM(BPF_JSLT, BPF_REG_7, 0, off));
282 	} else {
283 		gen->error = -ERANGE;
284 		emit(gen, BPF_JMP_IMM(BPF_JA, 0, 0, -1));
285 	}
286 }
287 
288 /* reg1 and reg2 should not be R1 - R5. They can be R0, R6 - R10 */
289 static void emit_debug(struct bpf_gen *gen, int reg1, int reg2,
290 		       const char *fmt, va_list args)
291 {
292 	char buf[1024];
293 	int addr, len, ret;
294 
295 	if (!gen->log_level)
296 		return;
297 	ret = vsnprintf(buf, sizeof(buf), fmt, args);
298 	if (ret < 1024 - 7 && reg1 >= 0 && reg2 < 0)
299 		/* The special case to accommodate common debug_ret():
300 		 * to avoid specifying BPF_REG_7 and adding " r=%%d" to
301 		 * prints explicitly.
302 		 */
303 		strcat(buf, " r=%d");
304 	len = strlen(buf) + 1;
305 	addr = add_data(gen, buf, len);
306 
307 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
308 					 0, 0, 0, addr));
309 	emit(gen, BPF_MOV64_IMM(BPF_REG_2, len));
310 	if (reg1 >= 0)
311 		emit(gen, BPF_MOV64_REG(BPF_REG_3, reg1));
312 	if (reg2 >= 0)
313 		emit(gen, BPF_MOV64_REG(BPF_REG_4, reg2));
314 	emit(gen, BPF_EMIT_CALL(BPF_FUNC_trace_printk));
315 }
316 
317 static void debug_regs(struct bpf_gen *gen, int reg1, int reg2, const char *fmt, ...)
318 {
319 	va_list args;
320 
321 	va_start(args, fmt);
322 	emit_debug(gen, reg1, reg2, fmt, args);
323 	va_end(args);
324 }
325 
326 static void debug_ret(struct bpf_gen *gen, const char *fmt, ...)
327 {
328 	va_list args;
329 
330 	va_start(args, fmt);
331 	emit_debug(gen, BPF_REG_7, -1, fmt, args);
332 	va_end(args);
333 }
334 
335 static void __emit_sys_close(struct bpf_gen *gen)
336 {
337 	emit(gen, BPF_JMP_IMM(BPF_JSLE, BPF_REG_1, 0,
338 			      /* 2 is the number of the following insns
339 			       * * 6 is additional insns in debug_regs
340 			       */
341 			      2 + (gen->log_level ? 6 : 0)));
342 	emit(gen, BPF_MOV64_REG(BPF_REG_9, BPF_REG_1));
343 	emit(gen, BPF_EMIT_CALL(BPF_FUNC_sys_close));
344 	debug_regs(gen, BPF_REG_9, BPF_REG_0, "close(%%d) = %%d");
345 }
346 
347 static void emit_sys_close_stack(struct bpf_gen *gen, int stack_off)
348 {
349 	emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_10, stack_off));
350 	__emit_sys_close(gen);
351 }
352 
353 static void emit_sys_close_blob(struct bpf_gen *gen, int blob_off)
354 {
355 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_0, BPF_PSEUDO_MAP_IDX_VALUE,
356 					 0, 0, 0, blob_off));
357 	emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0));
358 	__emit_sys_close(gen);
359 }
360 
361 int bpf_gen__finish(struct bpf_gen *gen)
362 {
363 	int i;
364 
365 	emit_sys_close_stack(gen, stack_off(btf_fd));
366 	for (i = 0; i < gen->nr_progs; i++)
367 		move_stack2ctx(gen,
368 			       sizeof(struct bpf_loader_ctx) +
369 			       sizeof(struct bpf_map_desc) * gen->nr_maps +
370 			       sizeof(struct bpf_prog_desc) * i +
371 			       offsetof(struct bpf_prog_desc, prog_fd), 4,
372 			       stack_off(prog_fd[i]));
373 	for (i = 0; i < gen->nr_maps; i++)
374 		move_blob2ctx(gen,
375 			      sizeof(struct bpf_loader_ctx) +
376 			      sizeof(struct bpf_map_desc) * i +
377 			      offsetof(struct bpf_map_desc, map_fd), 4,
378 			      blob_fd_array_off(gen, i));
379 	emit(gen, BPF_MOV64_IMM(BPF_REG_0, 0));
380 	emit(gen, BPF_EXIT_INSN());
381 	pr_debug("gen: finish %d\n", gen->error);
382 	if (!gen->error) {
383 		struct gen_loader_opts *opts = gen->opts;
384 
385 		opts->insns = gen->insn_start;
386 		opts->insns_sz = gen->insn_cur - gen->insn_start;
387 		opts->data = gen->data_start;
388 		opts->data_sz = gen->data_cur - gen->data_start;
389 	}
390 	return gen->error;
391 }
392 
393 void bpf_gen__free(struct bpf_gen *gen)
394 {
395 	if (!gen)
396 		return;
397 	free(gen->data_start);
398 	free(gen->insn_start);
399 	free(gen);
400 }
401 
402 void bpf_gen__load_btf(struct bpf_gen *gen, const void *btf_raw_data,
403 		       __u32 btf_raw_size)
404 {
405 	int attr_size = offsetofend(union bpf_attr, btf_log_level);
406 	int btf_data, btf_load_attr;
407 	union bpf_attr attr;
408 
409 	memset(&attr, 0, attr_size);
410 	pr_debug("gen: load_btf: size %d\n", btf_raw_size);
411 	btf_data = add_data(gen, btf_raw_data, btf_raw_size);
412 
413 	attr.btf_size = btf_raw_size;
414 	btf_load_attr = add_data(gen, &attr, attr_size);
415 
416 	/* populate union bpf_attr with user provided log details */
417 	move_ctx2blob(gen, attr_field(btf_load_attr, btf_log_level), 4,
418 		      offsetof(struct bpf_loader_ctx, log_level), false);
419 	move_ctx2blob(gen, attr_field(btf_load_attr, btf_log_size), 4,
420 		      offsetof(struct bpf_loader_ctx, log_size), false);
421 	move_ctx2blob(gen, attr_field(btf_load_attr, btf_log_buf), 8,
422 		      offsetof(struct bpf_loader_ctx, log_buf), false);
423 	/* populate union bpf_attr with a pointer to the BTF data */
424 	emit_rel_store(gen, attr_field(btf_load_attr, btf), btf_data);
425 	/* emit BTF_LOAD command */
426 	emit_sys_bpf(gen, BPF_BTF_LOAD, btf_load_attr, attr_size);
427 	debug_ret(gen, "btf_load size %d", btf_raw_size);
428 	emit_check_err(gen);
429 	/* remember btf_fd in the stack, if successful */
430 	emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, stack_off(btf_fd)));
431 }
432 
433 void bpf_gen__map_create(struct bpf_gen *gen,
434 			 struct bpf_create_map_attr *map_attr, int map_idx)
435 {
436 	int attr_size = offsetofend(union bpf_attr, btf_vmlinux_value_type_id);
437 	bool close_inner_map_fd = false;
438 	int map_create_attr, idx;
439 	union bpf_attr attr;
440 
441 	memset(&attr, 0, attr_size);
442 	attr.map_type = map_attr->map_type;
443 	attr.key_size = map_attr->key_size;
444 	attr.value_size = map_attr->value_size;
445 	attr.map_flags = map_attr->map_flags;
446 	memcpy(attr.map_name, map_attr->name,
447 	       min((unsigned)strlen(map_attr->name), BPF_OBJ_NAME_LEN - 1));
448 	attr.numa_node = map_attr->numa_node;
449 	attr.map_ifindex = map_attr->map_ifindex;
450 	attr.max_entries = map_attr->max_entries;
451 	switch (attr.map_type) {
452 	case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
453 	case BPF_MAP_TYPE_CGROUP_ARRAY:
454 	case BPF_MAP_TYPE_STACK_TRACE:
455 	case BPF_MAP_TYPE_ARRAY_OF_MAPS:
456 	case BPF_MAP_TYPE_HASH_OF_MAPS:
457 	case BPF_MAP_TYPE_DEVMAP:
458 	case BPF_MAP_TYPE_DEVMAP_HASH:
459 	case BPF_MAP_TYPE_CPUMAP:
460 	case BPF_MAP_TYPE_XSKMAP:
461 	case BPF_MAP_TYPE_SOCKMAP:
462 	case BPF_MAP_TYPE_SOCKHASH:
463 	case BPF_MAP_TYPE_QUEUE:
464 	case BPF_MAP_TYPE_STACK:
465 	case BPF_MAP_TYPE_RINGBUF:
466 		break;
467 	default:
468 		attr.btf_key_type_id = map_attr->btf_key_type_id;
469 		attr.btf_value_type_id = map_attr->btf_value_type_id;
470 	}
471 
472 	pr_debug("gen: map_create: %s idx %d type %d value_type_id %d\n",
473 		 attr.map_name, map_idx, map_attr->map_type, attr.btf_value_type_id);
474 
475 	map_create_attr = add_data(gen, &attr, attr_size);
476 	if (attr.btf_value_type_id)
477 		/* populate union bpf_attr with btf_fd saved in the stack earlier */
478 		move_stack2blob(gen, attr_field(map_create_attr, btf_fd), 4,
479 				stack_off(btf_fd));
480 	switch (attr.map_type) {
481 	case BPF_MAP_TYPE_ARRAY_OF_MAPS:
482 	case BPF_MAP_TYPE_HASH_OF_MAPS:
483 		move_stack2blob(gen, attr_field(map_create_attr, inner_map_fd), 4,
484 				stack_off(inner_map_fd));
485 		close_inner_map_fd = true;
486 		break;
487 	default:
488 		break;
489 	}
490 	/* conditionally update max_entries */
491 	if (map_idx >= 0)
492 		move_ctx2blob(gen, attr_field(map_create_attr, max_entries), 4,
493 			      sizeof(struct bpf_loader_ctx) +
494 			      sizeof(struct bpf_map_desc) * map_idx +
495 			      offsetof(struct bpf_map_desc, max_entries),
496 			      true /* check that max_entries != 0 */);
497 	/* emit MAP_CREATE command */
498 	emit_sys_bpf(gen, BPF_MAP_CREATE, map_create_attr, attr_size);
499 	debug_ret(gen, "map_create %s idx %d type %d value_size %d value_btf_id %d",
500 		  attr.map_name, map_idx, map_attr->map_type, attr.value_size,
501 		  attr.btf_value_type_id);
502 	emit_check_err(gen);
503 	/* remember map_fd in the stack, if successful */
504 	if (map_idx < 0) {
505 		/* This bpf_gen__map_create() function is called with map_idx >= 0
506 		 * for all maps that libbpf loading logic tracks.
507 		 * It's called with -1 to create an inner map.
508 		 */
509 		emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7,
510 				      stack_off(inner_map_fd)));
511 	} else if (map_idx != gen->nr_maps) {
512 		gen->error = -EDOM; /* internal bug */
513 		return;
514 	} else {
515 		/* add_map_fd does gen->nr_maps++ */
516 		idx = add_map_fd(gen);
517 		emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
518 						 0, 0, 0, blob_fd_array_off(gen, idx)));
519 		emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_7, 0));
520 	}
521 	if (close_inner_map_fd)
522 		emit_sys_close_stack(gen, stack_off(inner_map_fd));
523 }
524 
525 void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *attach_name,
526 				   enum bpf_attach_type type)
527 {
528 	const char *prefix;
529 	int kind, ret;
530 
531 	btf_get_kernel_prefix_kind(type, &prefix, &kind);
532 	gen->attach_kind = kind;
533 	ret = snprintf(gen->attach_target, sizeof(gen->attach_target), "%s%s",
534 		       prefix, attach_name);
535 	if (ret == sizeof(gen->attach_target))
536 		gen->error = -ENOSPC;
537 }
538 
539 static void emit_find_attach_target(struct bpf_gen *gen)
540 {
541 	int name, len = strlen(gen->attach_target) + 1;
542 
543 	pr_debug("gen: find_attach_tgt %s %d\n", gen->attach_target, gen->attach_kind);
544 	name = add_data(gen, gen->attach_target, len);
545 
546 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
547 					 0, 0, 0, name));
548 	emit(gen, BPF_MOV64_IMM(BPF_REG_2, len));
549 	emit(gen, BPF_MOV64_IMM(BPF_REG_3, gen->attach_kind));
550 	emit(gen, BPF_MOV64_IMM(BPF_REG_4, 0));
551 	emit(gen, BPF_EMIT_CALL(BPF_FUNC_btf_find_by_name_kind));
552 	emit(gen, BPF_MOV64_REG(BPF_REG_7, BPF_REG_0));
553 	debug_ret(gen, "find_by_name_kind(%s,%d)",
554 		  gen->attach_target, gen->attach_kind);
555 	emit_check_err(gen);
556 	/* if successful, btf_id is in lower 32-bit of R7 and
557 	 * btf_obj_fd is in upper 32-bit
558 	 */
559 }
560 
561 void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak,
562 			    int kind, int insn_idx)
563 {
564 	struct ksym_relo_desc *relo;
565 
566 	relo = libbpf_reallocarray(gen->relos, gen->relo_cnt + 1, sizeof(*relo));
567 	if (!relo) {
568 		gen->error = -ENOMEM;
569 		return;
570 	}
571 	gen->relos = relo;
572 	relo += gen->relo_cnt;
573 	relo->name = name;
574 	relo->is_weak = is_weak;
575 	relo->kind = kind;
576 	relo->insn_idx = insn_idx;
577 	gen->relo_cnt++;
578 }
579 
580 /* returns existing ksym_desc with ref incremented, or inserts a new one */
581 static struct ksym_desc *get_ksym_desc(struct bpf_gen *gen, struct ksym_relo_desc *relo)
582 {
583 	struct ksym_desc *kdesc;
584 
585 	for (int i = 0; i < gen->nr_ksyms; i++) {
586 		if (!strcmp(gen->ksyms[i].name, relo->name)) {
587 			gen->ksyms[i].ref++;
588 			return &gen->ksyms[i];
589 		}
590 	}
591 	kdesc = libbpf_reallocarray(gen->ksyms, gen->nr_ksyms + 1, sizeof(*kdesc));
592 	if (!kdesc) {
593 		gen->error = -ENOMEM;
594 		return NULL;
595 	}
596 	gen->ksyms = kdesc;
597 	kdesc = &gen->ksyms[gen->nr_ksyms++];
598 	kdesc->name = relo->name;
599 	kdesc->kind = relo->kind;
600 	kdesc->ref = 1;
601 	kdesc->off = 0;
602 	kdesc->insn = 0;
603 	return kdesc;
604 }
605 
606 /* Overwrites BPF_REG_{0, 1, 2, 3, 4, 7}
607  * Returns result in BPF_REG_7
608  */
609 static void emit_bpf_find_by_name_kind(struct bpf_gen *gen, struct ksym_relo_desc *relo)
610 {
611 	int name_off, len = strlen(relo->name) + 1;
612 
613 	name_off = add_data(gen, relo->name, len);
614 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
615 					 0, 0, 0, name_off));
616 	emit(gen, BPF_MOV64_IMM(BPF_REG_2, len));
617 	emit(gen, BPF_MOV64_IMM(BPF_REG_3, relo->kind));
618 	emit(gen, BPF_MOV64_IMM(BPF_REG_4, 0));
619 	emit(gen, BPF_EMIT_CALL(BPF_FUNC_btf_find_by_name_kind));
620 	emit(gen, BPF_MOV64_REG(BPF_REG_7, BPF_REG_0));
621 	debug_ret(gen, "find_by_name_kind(%s,%d)", relo->name, relo->kind);
622 }
623 
624 /* Expects:
625  * BPF_REG_8 - pointer to instruction
626  *
627  * We need to reuse BTF fd for same symbol otherwise each relocation takes a new
628  * index, while kernel limits total kfunc BTFs to 256. For duplicate symbols,
629  * this would mean a new BTF fd index for each entry. By pairing symbol name
630  * with index, we get the insn->imm, insn->off pairing that kernel uses for
631  * kfunc_tab, which becomes the effective limit even though all of them may
632  * share same index in fd_array (such that kfunc_btf_tab has 1 element).
633  */
634 static void emit_relo_kfunc_btf(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insn)
635 {
636 	struct ksym_desc *kdesc;
637 	int btf_fd_idx;
638 
639 	kdesc = get_ksym_desc(gen, relo);
640 	if (!kdesc)
641 		return;
642 	/* try to copy from existing bpf_insn */
643 	if (kdesc->ref > 1) {
644 		move_blob2blob(gen, insn + offsetof(struct bpf_insn, imm), 4,
645 			       kdesc->insn + offsetof(struct bpf_insn, imm));
646 		move_blob2blob(gen, insn + offsetof(struct bpf_insn, off), 2,
647 			       kdesc->insn + offsetof(struct bpf_insn, off));
648 		goto log;
649 	}
650 	/* remember insn offset, so we can copy BTF ID and FD later */
651 	kdesc->insn = insn;
652 	emit_bpf_find_by_name_kind(gen, relo);
653 	if (!relo->is_weak)
654 		emit_check_err(gen);
655 	/* get index in fd_array to store BTF FD at */
656 	btf_fd_idx = add_kfunc_btf_fd(gen);
657 	if (btf_fd_idx > INT16_MAX) {
658 		pr_warn("BTF fd off %d for kfunc %s exceeds INT16_MAX, cannot process relocation\n",
659 			btf_fd_idx, relo->name);
660 		gen->error = -E2BIG;
661 		return;
662 	}
663 	kdesc->off = btf_fd_idx;
664 	/* set a default value for imm */
665 	emit(gen, BPF_ST_MEM(BPF_W, BPF_REG_8, offsetof(struct bpf_insn, imm), 0));
666 	/* skip success case store if ret < 0 */
667 	emit(gen, BPF_JMP_IMM(BPF_JSLT, BPF_REG_7, 0, 1));
668 	/* store btf_id into insn[insn_idx].imm */
669 	emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_7, offsetof(struct bpf_insn, imm)));
670 	/* load fd_array slot pointer */
671 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_0, BPF_PSEUDO_MAP_IDX_VALUE,
672 					 0, 0, 0, blob_fd_array_off(gen, btf_fd_idx)));
673 	/* skip store of BTF fd if ret < 0 */
674 	emit(gen, BPF_JMP_IMM(BPF_JSLT, BPF_REG_7, 0, 3));
675 	/* store BTF fd in slot */
676 	emit(gen, BPF_MOV64_REG(BPF_REG_9, BPF_REG_7));
677 	emit(gen, BPF_ALU64_IMM(BPF_RSH, BPF_REG_9, 32));
678 	emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_9, 0));
679 	/* set a default value for off */
680 	emit(gen, BPF_ST_MEM(BPF_H, BPF_REG_8, offsetof(struct bpf_insn, off), 0));
681 	/* skip insn->off store if ret < 0 */
682 	emit(gen, BPF_JMP_IMM(BPF_JSLT, BPF_REG_7, 0, 2));
683 	/* skip if vmlinux BTF */
684 	emit(gen, BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 0, 1));
685 	/* store index into insn[insn_idx].off */
686 	emit(gen, BPF_ST_MEM(BPF_H, BPF_REG_8, offsetof(struct bpf_insn, off), btf_fd_idx));
687 log:
688 	if (!gen->log_level)
689 		return;
690 	emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_8,
691 			      offsetof(struct bpf_insn, imm)));
692 	emit(gen, BPF_LDX_MEM(BPF_H, BPF_REG_9, BPF_REG_8,
693 			      offsetof(struct bpf_insn, off)));
694 	debug_regs(gen, BPF_REG_7, BPF_REG_9, " func (%s:count=%d): imm: %%d, off: %%d",
695 		   relo->name, kdesc->ref);
696 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_0, BPF_PSEUDO_MAP_IDX_VALUE,
697 					 0, 0, 0, blob_fd_array_off(gen, kdesc->off)));
698 	emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_0, 0));
699 	debug_regs(gen, BPF_REG_9, -1, " func (%s:count=%d): btf_fd",
700 		   relo->name, kdesc->ref);
701 }
702 
703 /* Expects:
704  * BPF_REG_8 - pointer to instruction
705  */
706 static void emit_relo_ksym_btf(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insn)
707 {
708 	struct ksym_desc *kdesc;
709 
710 	kdesc = get_ksym_desc(gen, relo);
711 	if (!kdesc)
712 		return;
713 	/* try to copy from existing ldimm64 insn */
714 	if (kdesc->ref > 1) {
715 		move_blob2blob(gen, insn + offsetof(struct bpf_insn, imm), 4,
716 			       kdesc->insn + offsetof(struct bpf_insn, imm));
717 		move_blob2blob(gen, insn + sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm), 4,
718 			       kdesc->insn + sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm));
719 		goto log;
720 	}
721 	/* remember insn offset, so we can copy BTF ID and FD later */
722 	kdesc->insn = insn;
723 	emit_bpf_find_by_name_kind(gen, relo);
724 	emit_check_err(gen);
725 	/* store btf_id into insn[insn_idx].imm */
726 	emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_7, offsetof(struct bpf_insn, imm)));
727 	/* store btf_obj_fd into insn[insn_idx + 1].imm */
728 	emit(gen, BPF_ALU64_IMM(BPF_RSH, BPF_REG_7, 32));
729 	emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_8, BPF_REG_7,
730 			      sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm)));
731 log:
732 	if (!gen->log_level)
733 		return;
734 	emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_8,
735 			      offsetof(struct bpf_insn, imm)));
736 	emit(gen, BPF_LDX_MEM(BPF_H, BPF_REG_9, BPF_REG_8, sizeof(struct bpf_insn) +
737 			      offsetof(struct bpf_insn, imm)));
738 	debug_regs(gen, BPF_REG_7, BPF_REG_9, " var (%s:count=%d): imm: %%d, fd: %%d",
739 		   relo->name, kdesc->ref);
740 }
741 
742 static void emit_relo(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insns)
743 {
744 	int insn;
745 
746 	pr_debug("gen: emit_relo (%d): %s at %d\n", relo->kind, relo->name, relo->insn_idx);
747 	insn = insns + sizeof(struct bpf_insn) * relo->insn_idx;
748 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_8, BPF_PSEUDO_MAP_IDX_VALUE, 0, 0, 0, insn));
749 	switch (relo->kind) {
750 	case BTF_KIND_VAR:
751 		emit_relo_ksym_btf(gen, relo, insn);
752 		break;
753 	case BTF_KIND_FUNC:
754 		emit_relo_kfunc_btf(gen, relo, insn);
755 		break;
756 	default:
757 		pr_warn("Unknown relocation kind '%d'\n", relo->kind);
758 		gen->error = -EDOM;
759 		return;
760 	}
761 }
762 
763 static void emit_relos(struct bpf_gen *gen, int insns)
764 {
765 	int i;
766 
767 	for (i = 0; i < gen->relo_cnt; i++)
768 		emit_relo(gen, gen->relos + i, insns);
769 }
770 
771 static void cleanup_relos(struct bpf_gen *gen, int insns)
772 {
773 	int i, insn;
774 
775 	for (i = 0; i < gen->nr_ksyms; i++) {
776 		if (gen->ksyms[i].kind == BTF_KIND_VAR) {
777 			/* close fd recorded in insn[insn_idx + 1].imm */
778 			insn = gen->ksyms[i].insn;
779 			insn += sizeof(struct bpf_insn) + offsetof(struct bpf_insn, imm);
780 			emit_sys_close_blob(gen, insn);
781 		} else { /* BTF_KIND_FUNC */
782 			emit_sys_close_blob(gen, blob_fd_array_off(gen, gen->ksyms[i].off));
783 			if (gen->ksyms[i].off < MAX_FD_ARRAY_SZ)
784 				gen->nr_fd_array--;
785 		}
786 	}
787 	if (gen->nr_ksyms) {
788 		free(gen->ksyms);
789 		gen->nr_ksyms = 0;
790 		gen->ksyms = NULL;
791 	}
792 	if (gen->relo_cnt) {
793 		free(gen->relos);
794 		gen->relo_cnt = 0;
795 		gen->relos = NULL;
796 	}
797 }
798 
799 void bpf_gen__prog_load(struct bpf_gen *gen,
800 			struct bpf_prog_load_params *load_attr, int prog_idx)
801 {
802 	int attr_size = offsetofend(union bpf_attr, fd_array);
803 	int prog_load_attr, license, insns, func_info, line_info;
804 	union bpf_attr attr;
805 
806 	memset(&attr, 0, attr_size);
807 	pr_debug("gen: prog_load: type %d insns_cnt %zd\n",
808 		 load_attr->prog_type, load_attr->insn_cnt);
809 	/* add license string to blob of bytes */
810 	license = add_data(gen, load_attr->license, strlen(load_attr->license) + 1);
811 	/* add insns to blob of bytes */
812 	insns = add_data(gen, load_attr->insns,
813 			 load_attr->insn_cnt * sizeof(struct bpf_insn));
814 
815 	attr.prog_type = load_attr->prog_type;
816 	attr.expected_attach_type = load_attr->expected_attach_type;
817 	attr.attach_btf_id = load_attr->attach_btf_id;
818 	attr.prog_ifindex = load_attr->prog_ifindex;
819 	attr.kern_version = 0;
820 	attr.insn_cnt = (__u32)load_attr->insn_cnt;
821 	attr.prog_flags = load_attr->prog_flags;
822 
823 	attr.func_info_rec_size = load_attr->func_info_rec_size;
824 	attr.func_info_cnt = load_attr->func_info_cnt;
825 	func_info = add_data(gen, load_attr->func_info,
826 			     attr.func_info_cnt * attr.func_info_rec_size);
827 
828 	attr.line_info_rec_size = load_attr->line_info_rec_size;
829 	attr.line_info_cnt = load_attr->line_info_cnt;
830 	line_info = add_data(gen, load_attr->line_info,
831 			     attr.line_info_cnt * attr.line_info_rec_size);
832 
833 	memcpy(attr.prog_name, load_attr->name,
834 	       min((unsigned)strlen(load_attr->name), BPF_OBJ_NAME_LEN - 1));
835 	prog_load_attr = add_data(gen, &attr, attr_size);
836 
837 	/* populate union bpf_attr with a pointer to license */
838 	emit_rel_store(gen, attr_field(prog_load_attr, license), license);
839 
840 	/* populate union bpf_attr with a pointer to instructions */
841 	emit_rel_store(gen, attr_field(prog_load_attr, insns), insns);
842 
843 	/* populate union bpf_attr with a pointer to func_info */
844 	emit_rel_store(gen, attr_field(prog_load_attr, func_info), func_info);
845 
846 	/* populate union bpf_attr with a pointer to line_info */
847 	emit_rel_store(gen, attr_field(prog_load_attr, line_info), line_info);
848 
849 	/* populate union bpf_attr fd_array with a pointer to data where map_fds are saved */
850 	emit_rel_store(gen, attr_field(prog_load_attr, fd_array), gen->fd_array);
851 
852 	/* populate union bpf_attr with user provided log details */
853 	move_ctx2blob(gen, attr_field(prog_load_attr, log_level), 4,
854 		      offsetof(struct bpf_loader_ctx, log_level), false);
855 	move_ctx2blob(gen, attr_field(prog_load_attr, log_size), 4,
856 		      offsetof(struct bpf_loader_ctx, log_size), false);
857 	move_ctx2blob(gen, attr_field(prog_load_attr, log_buf), 8,
858 		      offsetof(struct bpf_loader_ctx, log_buf), false);
859 	/* populate union bpf_attr with btf_fd saved in the stack earlier */
860 	move_stack2blob(gen, attr_field(prog_load_attr, prog_btf_fd), 4,
861 			stack_off(btf_fd));
862 	if (gen->attach_kind) {
863 		emit_find_attach_target(gen);
864 		/* populate union bpf_attr with btf_id and btf_obj_fd found by helper */
865 		emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_0, BPF_PSEUDO_MAP_IDX_VALUE,
866 						 0, 0, 0, prog_load_attr));
867 		emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_7,
868 				      offsetof(union bpf_attr, attach_btf_id)));
869 		emit(gen, BPF_ALU64_IMM(BPF_RSH, BPF_REG_7, 32));
870 		emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_7,
871 				      offsetof(union bpf_attr, attach_btf_obj_fd)));
872 	}
873 	emit_relos(gen, insns);
874 	/* emit PROG_LOAD command */
875 	emit_sys_bpf(gen, BPF_PROG_LOAD, prog_load_attr, attr_size);
876 	debug_ret(gen, "prog_load %s insn_cnt %d", attr.prog_name, attr.insn_cnt);
877 	/* successful or not, close btf module FDs used in extern ksyms and attach_btf_obj_fd */
878 	cleanup_relos(gen, insns);
879 	if (gen->attach_kind)
880 		emit_sys_close_blob(gen,
881 				    attr_field(prog_load_attr, attach_btf_obj_fd));
882 	emit_check_err(gen);
883 	/* remember prog_fd in the stack, if successful */
884 	emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7,
885 			      stack_off(prog_fd[gen->nr_progs])));
886 	gen->nr_progs++;
887 }
888 
889 void bpf_gen__map_update_elem(struct bpf_gen *gen, int map_idx, void *pvalue,
890 			      __u32 value_size)
891 {
892 	int attr_size = offsetofend(union bpf_attr, flags);
893 	int map_update_attr, value, key;
894 	union bpf_attr attr;
895 	int zero = 0;
896 
897 	memset(&attr, 0, attr_size);
898 	pr_debug("gen: map_update_elem: idx %d\n", map_idx);
899 
900 	value = add_data(gen, pvalue, value_size);
901 	key = add_data(gen, &zero, sizeof(zero));
902 
903 	/* if (map_desc[map_idx].initial_value)
904 	 *    copy_from_user(value, initial_value, value_size);
905 	 */
906 	emit(gen, BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_6,
907 			      sizeof(struct bpf_loader_ctx) +
908 			      sizeof(struct bpf_map_desc) * map_idx +
909 			      offsetof(struct bpf_map_desc, initial_value)));
910 	emit(gen, BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0, 4));
911 	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
912 					 0, 0, 0, value));
913 	emit(gen, BPF_MOV64_IMM(BPF_REG_2, value_size));
914 	emit(gen, BPF_EMIT_CALL(BPF_FUNC_copy_from_user));
915 
916 	map_update_attr = add_data(gen, &attr, attr_size);
917 	move_blob2blob(gen, attr_field(map_update_attr, map_fd), 4,
918 		       blob_fd_array_off(gen, map_idx));
919 	emit_rel_store(gen, attr_field(map_update_attr, key), key);
920 	emit_rel_store(gen, attr_field(map_update_attr, value), value);
921 	/* emit MAP_UPDATE_ELEM command */
922 	emit_sys_bpf(gen, BPF_MAP_UPDATE_ELEM, map_update_attr, attr_size);
923 	debug_ret(gen, "update_elem idx %d value_size %d", map_idx, value_size);
924 	emit_check_err(gen);
925 }
926 
927 void bpf_gen__map_freeze(struct bpf_gen *gen, int map_idx)
928 {
929 	int attr_size = offsetofend(union bpf_attr, map_fd);
930 	int map_freeze_attr;
931 	union bpf_attr attr;
932 
933 	memset(&attr, 0, attr_size);
934 	pr_debug("gen: map_freeze: idx %d\n", map_idx);
935 	map_freeze_attr = add_data(gen, &attr, attr_size);
936 	move_blob2blob(gen, attr_field(map_freeze_attr, map_fd), 4,
937 		       blob_fd_array_off(gen, map_idx));
938 	/* emit MAP_FREEZE command */
939 	emit_sys_bpf(gen, BPF_MAP_FREEZE, map_freeze_attr, attr_size);
940 	debug_ret(gen, "map_freeze");
941 	emit_check_err(gen);
942 }
943