On Fri, Sep 17, 2021 at 2:57 PM Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> wrote: > > From: Alexei Starovoitov <ast@xxxxxxxxxx> > > Make relo_core.c to be compiled with kernel and with libbpf. > > Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx> > --- > include/linux/btf.h | 89 +++++++++++++++++++++++++++++++++++++++ > kernel/bpf/Makefile | 4 ++ > kernel/bpf/btf.c | 26 ++++++++++++ > tools/lib/bpf/relo_core.c | 72 ++++++++++++++++++++++++++++++- > 4 files changed, 189 insertions(+), 2 deletions(-) > [...] > static inline u16 btf_func_linkage(const struct btf_type *t) > { > return BTF_INFO_VLEN(t->info); > @@ -193,6 +245,27 @@ static inline bool btf_type_kflag(const struct btf_type *t) > return BTF_INFO_KFLAG(t->info); > } > > +static inline struct btf_member *btf_members(const struct btf_type *t) > +{ > + return (struct btf_member *)(t + 1); > +} > +#ifdef RELO_CORE ugh... seems like in most (if not all) cases kernel has member_idx available, so it will be a simple and mechanical change to use libbpf's member_idx implementation everywhere. Would allow #define RELO_CORE, unless you think it's useful for something else? > +static inline u32 btf_member_bit_offset(const struct btf_type *t, u32 member_idx) > +{ > + const struct btf_member *m = btf_members(t) + member_idx; > + bool kflag = btf_type_kflag(t); > + > + return kflag ? BTF_MEMBER_BIT_OFFSET(m->offset) : m->offset; > +} > + [...] > static inline const struct btf_var_secinfo *btf_type_var_secinfo( > const struct btf_type *t) > { > @@ -222,6 +307,10 @@ static inline const struct btf_var_secinfo *btf_type_var_secinfo( > struct bpf_prog; > > const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id); > +static inline const struct btf_type *btf__type_by_id(const struct btf *btf, u32 type_id) > +{ > + return btf_type_by_id(btf, type_id); > +} There is just one place in relo_core.c where btf__type_by_id() behavior matters, that's in bpf_core_apply_relo_insn() which validates that relocation info is valid. But we've already done that in bpf_core_apply_relo() anyways, so I think all relo_core.c uses can be just switched to btf_type_by_id(). So you don't need to add this tiny wrapper. > const char *btf_name_by_offset(const struct btf *btf, u32 offset); > struct btf *btf_parse_vmlinux(void); > struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog); > diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile > index 7f33098ca63f..3d5370c876b5 100644 > --- a/kernel/bpf/Makefile > +++ b/kernel/bpf/Makefile > @@ -36,3 +36,7 @@ obj-$(CONFIG_BPF_SYSCALL) += bpf_struct_ops.o > obj-${CONFIG_BPF_LSM} += bpf_lsm.o > endif > obj-$(CONFIG_BPF_PRELOAD) += preload/ > + > +obj-$(CONFIG_BPF_SYSCALL) += relo_core.o > +$(obj)/relo_core.o: $(srctree)/tools/lib/bpf/relo_core.c FORCE > + $(call if_changed_rule,cc_o_c) > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > index c3d605b22473..fa2c88f6ac4a 100644 > --- a/kernel/bpf/btf.c > +++ b/kernel/bpf/btf.c > @@ -6343,3 +6343,29 @@ const struct bpf_func_proto bpf_btf_find_by_name_kind_proto = { > }; > > BTF_ID_LIST_GLOBAL_SINGLE(btf_task_struct_ids, struct, task_struct) > + > +int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id, > + const struct btf *targ_btf, __u32 targ_id) > +{ We chatted offline about bpf_core_types_are_compat() and how it's used in only one place. It's because fields have dedicated bpf_core_fields_are_compat(), which is non-recursive. > + return -EOPNOTSUPP; > +} > + > +static bool bpf_core_is_flavor_sep(const char *s) > +{ > + /* check X___Y name pattern, where X and Y are not underscores */ > + return s[0] != '_' && /* X */ > + s[1] == '_' && s[2] == '_' && s[3] == '_' && /* ___ */ > + s[4] != '_'; /* Y */ > +} > + [...]