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
9struct 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 */
15struct 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 */
23struct 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
29struct 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
47struct 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
71int __bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id,
72				const struct btf *targ_btf, __u32 targ_id, int level);
73int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id,
74			      const struct btf *targ_btf, __u32 targ_id);
75int __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);
77int bpf_core_types_match(const struct btf *local_btf, __u32 local_id, const struct btf *targ_btf,
78			 __u32 targ_id);
79
80size_t bpf_core_essential_name_len(const char *name);
81
82int 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
89int 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
93int 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
97int bpf_core_format_spec(char *buf, size_t buf_sz, const struct bpf_core_spec *spec);
98
99#endif
100