1 | /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ |
2 | /* Copyright (c) 2019 Facebook */ |
3 | |
4 | #ifndef __RELO_CORE_H |
5 | #define __RELO_CORE_H |
6 | |
7 | #include <linux/bpf.h> |
8 | |
9 | struct bpf_core_cand { |
10 | const struct btf *btf; |
11 | __u32 id; |
12 | }; |
13 | |
14 | /* dynamically sized list of type IDs and its associated struct btf */ |
15 | struct bpf_core_cand_list { |
16 | struct bpf_core_cand *cands; |
17 | int len; |
18 | }; |
19 | |
20 | #define BPF_CORE_SPEC_MAX_LEN 64 |
21 | |
22 | /* represents BPF CO-RE field or array element accessor */ |
23 | struct bpf_core_accessor { |
24 | __u32 type_id; /* struct/union type or array element type */ |
25 | __u32 idx; /* field index or array index */ |
26 | const char *name; /* field name or NULL for array accessor */ |
27 | }; |
28 | |
29 | struct bpf_core_spec { |
30 | const struct btf *btf; |
31 | /* high-level spec: named fields and array indices only */ |
32 | struct bpf_core_accessor spec[BPF_CORE_SPEC_MAX_LEN]; |
33 | /* original unresolved (no skip_mods_or_typedefs) root type ID */ |
34 | __u32 root_type_id; |
35 | /* CO-RE relocation kind */ |
36 | enum bpf_core_relo_kind relo_kind; |
37 | /* high-level spec length */ |
38 | int len; |
39 | /* raw, low-level spec: 1-to-1 with accessor spec string */ |
40 | int raw_spec[BPF_CORE_SPEC_MAX_LEN]; |
41 | /* raw spec length */ |
42 | int raw_len; |
43 | /* field bit offset represented by spec */ |
44 | __u32 bit_offset; |
45 | }; |
46 | |
47 | struct bpf_core_relo_res { |
48 | /* expected value in the instruction, unless validate == false */ |
49 | __u64 orig_val; |
50 | /* new value that needs to be patched up to */ |
51 | __u64 new_val; |
52 | /* relocation unsuccessful, poison instruction, but don't fail load */ |
53 | bool poison; |
54 | /* some relocations can't be validated against orig_val */ |
55 | bool validate; |
56 | /* for field byte offset relocations or the forms: |
57 | * *(T *)(rX + <off>) = rY |
58 | * rX = *(T *)(rY + <off>), |
59 | * we remember original and resolved field size to adjust direct |
60 | * memory loads of pointers and integers; this is necessary for 32-bit |
61 | * host kernel architectures, but also allows to automatically |
62 | * relocate fields that were resized from, e.g., u32 to u64, etc. |
63 | */ |
64 | bool fail_memsz_adjust; |
65 | __u32 orig_sz; |
66 | __u32 orig_type_id; |
67 | __u32 new_sz; |
68 | __u32 new_type_id; |
69 | }; |
70 | |
71 | int __bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id, |
72 | const struct btf *targ_btf, __u32 targ_id, int level); |
73 | int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id, |
74 | const struct btf *targ_btf, __u32 targ_id); |
75 | int __bpf_core_types_match(const struct btf *local_btf, __u32 local_id, const struct btf *targ_btf, |
76 | __u32 targ_id, bool behind_ptr, int level); |
77 | int bpf_core_types_match(const struct btf *local_btf, __u32 local_id, const struct btf *targ_btf, |
78 | __u32 targ_id); |
79 | |
80 | size_t bpf_core_essential_name_len(const char *name); |
81 | |
82 | int bpf_core_calc_relo_insn(const char *prog_name, |
83 | const struct bpf_core_relo *relo, int relo_idx, |
84 | const struct btf *local_btf, |
85 | struct bpf_core_cand_list *cands, |
86 | struct bpf_core_spec *specs_scratch, |
87 | struct bpf_core_relo_res *targ_res); |
88 | |
89 | int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn, |
90 | int insn_idx, const struct bpf_core_relo *relo, |
91 | int relo_idx, const struct bpf_core_relo_res *res); |
92 | |
93 | int bpf_core_parse_spec(const char *prog_name, const struct btf *btf, |
94 | const struct bpf_core_relo *relo, |
95 | struct bpf_core_spec *spec); |
96 | |
97 | int bpf_core_format_spec(char *buf, size_t buf_sz, const struct bpf_core_spec *spec); |
98 | |
99 | #endif |
100 | |