On Mon, Jun 10, 2019 at 9:49 PM Andrii Nakryiko <andriin@xxxxxx> wrote: > > Libbpf does sanitization of BTF before loading it into kernel, if kernel > doesn't support some of newer BTF features. This removes some of the > important information from BTF (e.g., DATASEC and VAR description), > which will be used for map construction. This patch splits BTF > processing into initialization step, in which BTF is initialized from > ELF and all the original data is still preserved; and > sanitization/loading step, which ensures that BTF is safe to load into > kernel. This allows to use full BTF information to construct maps, while > still loading valid BTF into older kernels. > > Signed-off-by: Andrii Nakryiko <andriin@xxxxxx> Acked-by: Song Liu <songliubraving@xxxxxx> > --- > tools/lib/bpf/libbpf.c | 34 ++++++++++++++++++++++++---------- > 1 file changed, 24 insertions(+), 10 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index 5e7ea7dac958..79a8143240d7 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -1118,7 +1118,7 @@ static void bpf_object__sanitize_btf_ext(struct bpf_object *obj) > } > } > > -static int bpf_object__load_btf(struct bpf_object *obj, > +static int bpf_object__init_btf(struct bpf_object *obj, > Elf_Data *btf_data, > Elf_Data *btf_ext_data) > { > @@ -1137,13 +1137,6 @@ static int bpf_object__load_btf(struct bpf_object *obj, > BTF_ELF_SEC, err); > goto out; > } > - bpf_object__sanitize_btf(obj); > - err = btf__load(obj->btf); > - if (err) { > - pr_warning("Error loading %s into kernel: %d.\n", > - BTF_ELF_SEC, err); > - goto out; > - } > } > if (btf_ext_data) { > if (!obj->btf) { > @@ -1159,7 +1152,6 @@ static int bpf_object__load_btf(struct bpf_object *obj, > obj->btf_ext = NULL; > goto out; > } > - bpf_object__sanitize_btf_ext(obj); > } > out: > if (err || IS_ERR(obj->btf)) { > @@ -1170,6 +1162,26 @@ static int bpf_object__load_btf(struct bpf_object *obj, > return 0; > } > > +static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj) > +{ > + int err = 0; > + > + if (!obj->btf) > + return 0; > + > + bpf_object__sanitize_btf(obj); > + bpf_object__sanitize_btf_ext(obj); > + > + err = btf__load(obj->btf); > + if (err) { > + pr_warning("Error loading %s into kernel: %d.\n", > + BTF_ELF_SEC, err); > + btf__free(obj->btf); > + obj->btf = NULL; > + } > + return 0; > +} > + > static int bpf_object__elf_collect(struct bpf_object *obj, int flags) > { > Elf *elf = obj->efile.elf; > @@ -1301,9 +1313,11 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) > pr_warning("Corrupted ELF file: index of strtab invalid\n"); > return -LIBBPF_ERRNO__FORMAT; > } > - err = bpf_object__load_btf(obj, btf_data, btf_ext_data); > + err = bpf_object__init_btf(obj, btf_data, btf_ext_data); > if (!err) > err = bpf_object__init_maps(obj, flags); > + if (!err) > + err = bpf_object__sanitize_and_load_btf(obj); > if (!err) > err = bpf_object__init_prog_names(obj); > return err; > -- > 2.17.1 >