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".
Showing the changes to include/uapi (1 of 7 files). Show all
Unified · Split
| @@ -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 | */ | ||
| 6446 | struct 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__ */ |