History

bpf: Pass a set of bpf_core_relo-s to prog_load command.

struct bpf_core_relo is generated by llvm and processed by libbpf. It's a de-facto uapi. With CO-RE in the kernel the struct bpf_core_relo becomes uapi de-jure. Add an ability to pass a set of 'struct bpf_core_relo' to prog_load command and let the kernel perform CO-RE relocations. Note the struct bpf_line_info and struct bpf_func_info have the same layout when passed from LLVM to libbpf and from libbpf to the kernel except "insn_off" fields means "byte offset" when LLVM generates it. Then libbpf converts it to "insn index" to pass to the kernel. The struct bpf_core_relo's "insn_off" field is always "byte offset".

Alexei Starovoitov committed 4 years ago

Commit fbd94c71 parent 46334a07 files · +207 −56Browse files

Showing the changes to include/uapi (1 of 7 files). Show all

Unified · Split

include/uapi/linux/bpf.h+58−1
@@ -1342,8 +1342,10 @@ union bpf_attr { · 1341 unmodified lines
1342 /* or valid module BTF object fd or 0 to attach to vmlinux */1342 /* or valid module BTF object fd or 0 to attach to vmlinux */
1343 __u32 attach_btf_obj_fd;1343 __u32 attach_btf_obj_fd;
1344 };1344 };
1345 __u32 :32; /* pad */1345 __u32 core_relo_cnt; /* number of bpf_core_relo */
1346 __aligned_u64 fd_array; /* array of FDs */1346 __aligned_u64 fd_array; /* array of FDs */
1347 __aligned_u64 core_relos;
1348 __u32 core_relo_rec_size; /* sizeof(struct bpf_core_relo) */
1347 };1349 };
1348 1350
1349 struct { /* anonymous struct used by BPF_OBJ_* commands */1351 struct { /* anonymous struct used by BPF_OBJ_* commands */
@@ -6393,4 +6395,59 @@ enum bpf_core_relo_kind { · 5043 unmodified lines
6393 BPF_CORE_ENUMVAL_VALUE = 11, /* enum value integer value */6395 BPF_CORE_ENUMVAL_VALUE = 11, /* enum value integer value */
6394};6396};
6395 6397
6398/*
6399 * "struct bpf_core_relo" is used to pass relocation data form LLVM to libbpf
6400 * and from libbpf to the kernel.
6401 *
6402 * CO-RE relocation captures the following data:
6403 * - insn_off - instruction offset (in bytes) within a BPF program that needs
6404 * its insn->imm field to be relocated with actual field info;
6405 * - type_id - BTF type ID of the "root" (containing) entity of a relocatable
6406 * type or field;
6407 * - access_str_off - offset into corresponding .BTF string section. String
6408 * interpretation depends on specific relocation kind:
6409 * - for field-based relocations, string encodes an accessed field using
6410 * a sequence of field and array indices, separated by colon (:). It's
6411 * conceptually very close to LLVM's getelementptr ([0]) instruction's
6412 * arguments for identifying offset to a field.
6413 * - for type-based relocations, strings is expected to be just "0";
6414 * - for enum value-based relocations, string contains an index of enum
6415 * value within its enum type;
6416 * - kind - one of enum bpf_core_relo_kind;
6417 *
6418 * Example:
6419 * struct sample {
6420 * int a;
6421 * struct {
6422 * int b[10];
6423 * };
6424 * };
6425 *
6426 * struct sample *s = ...;
6427 * int *x = &s->a; // encoded as "0:0" (a is field #0)
6428 * int *y = &s->b[5]; // encoded as "0:1:0:5" (anon struct is field #1,
6429 * // b is field #0 inside anon struct, accessing elem #5)
6430 * int *z = &s[10]->b; // encoded as "10:1" (ptr is used as an array)
6431 *
6432 * type_id for all relocs in this example will capture BTF type id of
6433 * `struct sample`.
6434 *
6435 * Such relocation is emitted when using __builtin_preserve_access_index()
6436 * Clang built-in, passing expression that captures field address, e.g.:
6437 *
6438 * bpf_probe_read(&dst, sizeof(dst),
6439 * __builtin_preserve_access_index(&src->a.b.c));
6440 *
6441 * In this case Clang will emit field relocation recording necessary data to
6442 * be able to find offset of embedded `a.b.c` field within `src` struct.
6443 *
6444 * [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction
6445 */
6446struct bpf_core_relo {
6447 __u32 insn_off;
6448 __u32 type_id;
6449 __u32 access_str_off;
6450 enum bpf_core_relo_kind kind;
6451};
6452
6396#endif /* _UAPI__LINUX_BPF_H__ */6453#endif /* _UAPI__LINUX_BPF_H__ */