Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
0002 /* Copyright (c) 2019 Facebook */
0003 
0004 #ifndef __RELO_CORE_H
0005 #define __RELO_CORE_H
0006 
0007 #include <linux/bpf.h>
0008 
0009 struct bpf_core_cand {
0010     const struct btf *btf;
0011     __u32 id;
0012 };
0013 
0014 /* dynamically sized list of type IDs and its associated struct btf */
0015 struct bpf_core_cand_list {
0016     struct bpf_core_cand *cands;
0017     int len;
0018 };
0019 
0020 #define BPF_CORE_SPEC_MAX_LEN 64
0021 
0022 /* represents BPF CO-RE field or array element accessor */
0023 struct bpf_core_accessor {
0024     __u32 type_id;      /* struct/union type or array element type */
0025     __u32 idx;      /* field index or array index */
0026     const char *name;   /* field name or NULL for array accessor */
0027 };
0028 
0029 struct bpf_core_spec {
0030     const struct btf *btf;
0031     /* high-level spec: named fields and array indices only */
0032     struct bpf_core_accessor spec[BPF_CORE_SPEC_MAX_LEN];
0033     /* original unresolved (no skip_mods_or_typedefs) root type ID */
0034     __u32 root_type_id;
0035     /* CO-RE relocation kind */
0036     enum bpf_core_relo_kind relo_kind;
0037     /* high-level spec length */
0038     int len;
0039     /* raw, low-level spec: 1-to-1 with accessor spec string */
0040     int raw_spec[BPF_CORE_SPEC_MAX_LEN];
0041     /* raw spec length */
0042     int raw_len;
0043     /* field bit offset represented by spec */
0044     __u32 bit_offset;
0045 };
0046 
0047 struct bpf_core_relo_res {
0048     /* expected value in the instruction, unless validate == false */
0049     __u64 orig_val;
0050     /* new value that needs to be patched up to */
0051     __u64 new_val;
0052     /* relocation unsuccessful, poison instruction, but don't fail load */
0053     bool poison;
0054     /* some relocations can't be validated against orig_val */
0055     bool validate;
0056     /* for field byte offset relocations or the forms:
0057      *     *(T *)(rX + <off>) = rY
0058      *     rX = *(T *)(rY + <off>),
0059      * we remember original and resolved field size to adjust direct
0060      * memory loads of pointers and integers; this is necessary for 32-bit
0061      * host kernel architectures, but also allows to automatically
0062      * relocate fields that were resized from, e.g., u32 to u64, etc.
0063      */
0064     bool fail_memsz_adjust;
0065     __u32 orig_sz;
0066     __u32 orig_type_id;
0067     __u32 new_sz;
0068     __u32 new_type_id;
0069 };
0070 
0071 int __bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id,
0072                 const struct btf *targ_btf, __u32 targ_id, int level);
0073 int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id,
0074                   const struct btf *targ_btf, __u32 targ_id);
0075 int __bpf_core_types_match(const struct btf *local_btf, __u32 local_id, const struct btf *targ_btf,
0076                __u32 targ_id, bool behind_ptr, int level);
0077 int bpf_core_types_match(const struct btf *local_btf, __u32 local_id, const struct btf *targ_btf,
0078              __u32 targ_id);
0079 
0080 size_t bpf_core_essential_name_len(const char *name);
0081 
0082 int bpf_core_calc_relo_insn(const char *prog_name,
0083                 const struct bpf_core_relo *relo, int relo_idx,
0084                 const struct btf *local_btf,
0085                 struct bpf_core_cand_list *cands,
0086                 struct bpf_core_spec *specs_scratch,
0087                 struct bpf_core_relo_res *targ_res);
0088 
0089 int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
0090             int insn_idx, const struct bpf_core_relo *relo,
0091             int relo_idx, const struct bpf_core_relo_res *res);
0092 
0093 int bpf_core_parse_spec(const char *prog_name, const struct btf *btf,
0094                 const struct bpf_core_relo *relo,
0095                 struct bpf_core_spec *spec);
0096 
0097 int bpf_core_format_spec(char *buf, size_t buf_sz, const struct bpf_core_spec *spec);
0098 
0099 #endif