On Tue, Feb 27, 2024 at 10:45:49PM +0200, Eduard Zingerman wrote: > E.g. allow the following struct_ops definitions: > > struct bpf_testmod_ops___v1 { int (*test)(void); }; > struct bpf_testmod_ops___v2 { int (*test)(void); }; > > SEC(".struct_ops.link") > struct bpf_testmod_ops___v1 a = { .test = ... } > SEC(".struct_ops.link") > struct bpf_testmod_ops___v2 b = { .test = ... } > > Where both bpf_testmod_ops__v1 and bpf_testmod_ops__v2 would be > resolved as 'struct bpf_testmod_ops' from kernel BTF. > > Signed-off-by: Eduard Zingerman <eddyz87@xxxxxxxxx> Acked-by: David Vernet <void@xxxxxxxxxxxxx> Modulo the leak pointed out by Kui-Feng in another thread. It would be nice if we could just do this on the stack, but I guess there's no static max size for a tname. > --- > tools/lib/bpf/libbpf.c | 22 +++++++++++++++++----- > 1 file changed, 17 insertions(+), 5 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index 01f407591a92..abe663927013 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -948,7 +948,7 @@ static int find_btf_by_prefix_kind(const struct btf *btf, const char *prefix, > const char *name, __u32 kind); > > static int > -find_struct_ops_kern_types(struct bpf_object *obj, const char *tname, > +find_struct_ops_kern_types(struct bpf_object *obj, const char *tname_raw, > struct module_btf **mod_btf, > const struct btf_type **type, __u32 *type_id, > const struct btf_type **vtype, __u32 *vtype_id, > @@ -957,15 +957,21 @@ find_struct_ops_kern_types(struct bpf_object *obj, const char *tname, > const struct btf_type *kern_type, *kern_vtype; > const struct btf_member *kern_data_member; > struct btf *btf; > - __s32 kern_vtype_id, kern_type_id; > + __s32 kern_vtype_id, kern_type_id, err; > + char *tname; > __u32 i; > > + tname = strndup(tname_raw, bpf_core_essential_name_len(tname_raw)); > + if (!tname) > + return -ENOMEM; > + > kern_type_id = find_ksym_btf_id(obj, tname, BTF_KIND_STRUCT, > &btf, mod_btf); > if (kern_type_id < 0) { > pr_warn("struct_ops init_kern: struct %s is not found in kernel BTF\n", > tname); > - return kern_type_id; > + err = kern_type_id; > + goto err_out; > } > kern_type = btf__type_by_id(btf, kern_type_id); > > @@ -979,7 +985,8 @@ find_struct_ops_kern_types(struct bpf_object *obj, const char *tname, > if (kern_vtype_id < 0) { > pr_warn("struct_ops init_kern: struct %s%s is not found in kernel BTF\n", > STRUCT_OPS_VALUE_PREFIX, tname); > - return kern_vtype_id; > + err = kern_vtype_id; > + goto err_out; > } > kern_vtype = btf__type_by_id(btf, kern_vtype_id); > > @@ -997,7 +1004,8 @@ find_struct_ops_kern_types(struct bpf_object *obj, const char *tname, > if (i == btf_vlen(kern_vtype)) { > pr_warn("struct_ops init_kern: struct %s data is not found in struct %s%s\n", > tname, STRUCT_OPS_VALUE_PREFIX, tname); > - return -EINVAL; > + err = -EINVAL; > + goto err_out; > } > > *type = kern_type; > @@ -1007,6 +1015,10 @@ find_struct_ops_kern_types(struct bpf_object *obj, const char *tname, > *data_member = kern_data_member; > > return 0; > + > +err_out: > + free(tname); > + return err; > } > > static bool bpf_map__is_struct_ops(const struct bpf_map *map) > -- > 2.43.0 >
Attachment:
signature.asc
Description: PGP signature