On Wed, Oct 27, 2021 at 1:37 PM Mauricio Vásquez <mauricio@xxxxxxxxxx> wrote: > > Implement helper function to save the contents of a BTF object to a > file. > > Signed-off-by: Mauricio Vásquez <mauricio@xxxxxxxxxx> > Signed-off-by: Rafael David Tinoco <rafael.tinoco@xxxxxxxxxxx> > Signed-off-by: Lorenzo Fontana <lorenzo.fontana@xxxxxxxxxx> > --- > tools/lib/bpf/btf.c | 22 ++++++++++++++++++++++ > tools/lib/bpf/btf.h | 2 ++ > tools/lib/bpf/libbpf.map | 1 + > 3 files changed, 25 insertions(+) > > diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c > index 0c628c33e23b..087035574dba 100644 > --- a/tools/lib/bpf/btf.c > +++ b/tools/lib/bpf/btf.c > @@ -4773,3 +4773,25 @@ int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void > > return 0; > } > + > +int btf__save_to_file(struct btf *btf, const char *path) given we have its loading counterpart as btf__parse_raw(), let's call this one btf__save_raw()? > +{ > + const void *data; > + __u32 data_sz; > + FILE *file; > + > + data = btf_get_raw_data(btf, &data_sz, btf->swapped_endian); use btf__raw_data() instead? no need to think about btf->swapped_endian here > + if (!data) > + return -ENOMEM; please use libbpf_err() helper for returning errors, see other use cases > + > + file = fopen(path, "wb"); > + if (!file) > + return -errno; > + > + if (fwrite(data, 1, data_sz, file) != data_sz) { > + fclose(file); > + return -EIO; why not propagating original errno? make sure you save it before fclose(), though > + } > + > + return fclose(file); hm... I'd just do fclose(file) separately and return 0 (because success). If file closing fails, there isn't anything that can be done (but it also shouldn't fail in any normal situation). > +} > diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h > index bc005ba3ceec..300ad498c615 100644 > --- a/tools/lib/bpf/btf.h > +++ b/tools/lib/bpf/btf.h > @@ -114,6 +114,8 @@ LIBBPF_API struct btf *btf__parse_elf_split(const char *path, struct btf *base_b > LIBBPF_API struct btf *btf__parse_raw(const char *path); > LIBBPF_API struct btf *btf__parse_raw_split(const char *path, struct btf *base_btf); > > +LIBBPF_API int btf__save_to_file(struct btf *btf, const char *path); const struct btf? btf__raw_data() (even though it internally modifies btf) accepts `const struct btf*`, because this is conceptually read-only operation > + > LIBBPF_API struct btf *btf__load_vmlinux_btf(void); > LIBBPF_API struct btf *btf__load_module_btf(const char *module_name, struct btf *vmlinux_btf); > LIBBPF_API struct btf *libbpf_find_kernel_btf(void); > diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map > index 15239c05659c..0e9bed7c9b9e 100644 > --- a/tools/lib/bpf/libbpf.map > +++ b/tools/lib/bpf/libbpf.map > @@ -399,4 +399,5 @@ LIBBPF_0.6.0 { > btf__add_decl_tag; > btf__raw_data; > btf__type_cnt; > + btf__save_to_file; > } LIBBPF_0.5.0; > -- > 2.25.1 >