From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> As defined by being a series of BTF raw_data concatenated that then are combined using btf__add_btf() to then be passed to btf__dedup(). This is a simpler interface, a more involved one, maybe for pahole would involve doing the same approach as for encoding BTF from DWARF: create a series of threads that would load the BTF archive in parallel to then dedup it. Cc: Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> Cc: Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> Cc: Jiri Olsa <jolsa@xxxxxxxxxx> Cc: "Jose E. Marchesi" <jose.marchesi@xxxxxxxxxx> Cc: Namhyung Kim <namhyung@xxxxxxxxxx> Cc: Nick Alcock <nick.alcock@xxxxxxxxxx> Cc: Yonghong Song <yonghong.song@xxxxxxxxx> Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> --- tools/lib/bpf/btf.c | 38 ++++++++++++++++++++++++++++++++++++++ tools/lib/bpf/btf.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index ee45d461d53bea9a..73a6d94eeda125e1 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -1127,6 +1127,44 @@ struct btf *btf__new(const void *data, __u32 size) return libbpf_ptr(btf_new(data, size, NULL, false)); } +bool btf__is_archive(const struct btf *btf) +{ + return btf->extra_raw_data; +} + +int btf__dedup_archive(struct btf *btf, const void *data, __u32 size, const struct btf_dedup_opts *opts) +{ + __u32 raw_size = btf->raw_size; + struct btf *brother; + int err = 0; + + while (size > raw_size) { + data += raw_size; + size -= raw_size; + brother = btf_new(data, size, btf->base_btf, btf->raw_data_is_mmap); + + if (IS_ERR(brother)) { + err = PTR_ERR(brother); + pr_debug("%s: __btf_new() failed! %d\n", __func__, err); + goto out; + } + + if (btf__add_btf(btf, brother) < 0) { + err = -errno; + pr_debug("%s: btf__add_btf() failed: %d(%s)!\n", __func__, errno, strerror(errno)); + btf__free(brother); + goto out; + } + + raw_size = brother->raw_size; + btf__free(brother); + } + + err = btf__dedup(btf, opts); +out: + return libbpf_err(err); +} + struct btf *btf__new_split(const void *data, __u32 size, struct btf *base_btf) { return libbpf_ptr(btf_new(data, size, base_btf, false)); diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index ccfd905f03dfe7b6..71a6b8e037f5c98b 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h @@ -258,6 +258,9 @@ struct btf_dedup_opts { #define btf_dedup_opts__last_field force_collisions LIBBPF_API int btf__dedup(struct btf *btf, const struct btf_dedup_opts *opts); +LIBBPF_API int btf__dedup_archive(struct btf *btf, const void *data, __u32 size, + const struct btf_dedup_opts *opts); +LIBBPF_API bool btf__is_archive(const struct btf *btf); /** * @brief **btf__relocate()** will check the split BTF *btf* for references -- 2.50.1