Message ID | 20230616171728.530116-4-alan.maguire@oracle.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | BPF |
Headers | show |
Series | bpf: support BTF kind layout info, CRCs | expand |
On Fri, Jun 16, 2023 at 10:18 AM Alan Maguire <alan.maguire@oracle.com> wrote: > > This allows BTF parsing to proceed even if we do not know the > kind. > > Signed-off-by: Alan Maguire <alan.maguire@oracle.com> > --- > tools/lib/bpf/btf.c | 41 ++++++++++++++++++++++++++++++++++------- > 1 file changed, 34 insertions(+), 7 deletions(-) > > diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c > index f9f919fdc728..457997c2a43c 100644 > --- a/tools/lib/bpf/btf.c > +++ b/tools/lib/bpf/btf.c > @@ -327,7 +327,35 @@ static int btf_parse_kind_layout_sec(struct btf *btf) > return 0; > } > > -static int btf_type_size(const struct btf_type *t) > +/* for unknown kinds, consult kind layout. */ > +static int btf_type_size_unknown(const struct btf *btf, const struct btf_type *t) > +{ > + int size = sizeof(struct btf_type); > + struct btf_kind_layout *k = NULL; > + __u16 vlen = btf_vlen(t); > + __u8 kind = btf_kind(t); > + > + if (btf->kind_layout) > + k = &btf->kind_layout[kind]; see my suggestion on the previous patch. Let's make this layout information mandatory internally and always use it consistently. simpler code, more testing for this new code path > + > + if (!k || (void *)k > ((void *)btf->kind_layout + btf->hdr->kind_layout_len)) { > + pr_debug("Unsupported BTF_KIND: %u\n", btf_kind(t)); > + return -EINVAL; > + } > + > + if (!(k->flags & BTF_KIND_LAYOUT_OPTIONAL)) { > + /* a required kind, and we do not know about it.. */ > + pr_debug("unknown but required kind: %u\n", kind); > + return -EINVAL; > + } > + > + size += k->info_sz; > + size += vlen * k->elem_sz; > + > + return size; > +} > + > +static int btf_type_size(const struct btf *btf, const struct btf_type *t) > { > const int base_size = sizeof(struct btf_type); > __u16 vlen = btf_vlen(t); > @@ -363,8 +391,7 @@ static int btf_type_size(const struct btf_type *t) > case BTF_KIND_DECL_TAG: > return base_size + sizeof(struct btf_decl_tag); > default: > - pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t)); > - return -EINVAL; > + return btf_type_size_unknown(btf, t); > } > } > > @@ -463,7 +490,7 @@ static int btf_parse_type_sec(struct btf *btf) > if (btf->swapped_endian) > btf_bswap_type_base(next_type); > > - type_size = btf_type_size(next_type); > + type_size = btf_type_size(btf, next_type); > if (type_size < 0) > return type_size; > if (next_type + type_size > end_type) { > @@ -1672,7 +1699,7 @@ int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_t > struct btf_type *t; > int sz, err; > > - sz = btf_type_size(src_type); > + sz = btf_type_size(src_btf, src_type); > if (sz < 0) > return libbpf_err(sz); > > @@ -1753,7 +1780,7 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf) > memcpy(t, src_btf->types_data, data_sz); > > for (i = 0; i < cnt; i++) { > - sz = btf_type_size(t); > + sz = btf_type_size(src_btf, t); > if (sz < 0) { > /* unlikely, has to be corrupted src_btf */ > err = sz; > @@ -4749,7 +4776,7 @@ static int btf_dedup_compact_types(struct btf_dedup *d) > continue; > > t = btf__type_by_id(d->btf, id); > - len = btf_type_size(t); > + len = btf_type_size(d->btf, t); > if (len < 0) > return len; > > -- > 2.39.3 >
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index f9f919fdc728..457997c2a43c 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -327,7 +327,35 @@ static int btf_parse_kind_layout_sec(struct btf *btf) return 0; } -static int btf_type_size(const struct btf_type *t) +/* for unknown kinds, consult kind layout. */ +static int btf_type_size_unknown(const struct btf *btf, const struct btf_type *t) +{ + int size = sizeof(struct btf_type); + struct btf_kind_layout *k = NULL; + __u16 vlen = btf_vlen(t); + __u8 kind = btf_kind(t); + + if (btf->kind_layout) + k = &btf->kind_layout[kind]; + + if (!k || (void *)k > ((void *)btf->kind_layout + btf->hdr->kind_layout_len)) { + pr_debug("Unsupported BTF_KIND: %u\n", btf_kind(t)); + return -EINVAL; + } + + if (!(k->flags & BTF_KIND_LAYOUT_OPTIONAL)) { + /* a required kind, and we do not know about it.. */ + pr_debug("unknown but required kind: %u\n", kind); + return -EINVAL; + } + + size += k->info_sz; + size += vlen * k->elem_sz; + + return size; +} + +static int btf_type_size(const struct btf *btf, const struct btf_type *t) { const int base_size = sizeof(struct btf_type); __u16 vlen = btf_vlen(t); @@ -363,8 +391,7 @@ static int btf_type_size(const struct btf_type *t) case BTF_KIND_DECL_TAG: return base_size + sizeof(struct btf_decl_tag); default: - pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t)); - return -EINVAL; + return btf_type_size_unknown(btf, t); } } @@ -463,7 +490,7 @@ static int btf_parse_type_sec(struct btf *btf) if (btf->swapped_endian) btf_bswap_type_base(next_type); - type_size = btf_type_size(next_type); + type_size = btf_type_size(btf, next_type); if (type_size < 0) return type_size; if (next_type + type_size > end_type) { @@ -1672,7 +1699,7 @@ int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_t struct btf_type *t; int sz, err; - sz = btf_type_size(src_type); + sz = btf_type_size(src_btf, src_type); if (sz < 0) return libbpf_err(sz); @@ -1753,7 +1780,7 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf) memcpy(t, src_btf->types_data, data_sz); for (i = 0; i < cnt; i++) { - sz = btf_type_size(t); + sz = btf_type_size(src_btf, t); if (sz < 0) { /* unlikely, has to be corrupted src_btf */ err = sz; @@ -4749,7 +4776,7 @@ static int btf_dedup_compact_types(struct btf_dedup *d) continue; t = btf__type_by_id(d->btf, id); - len = btf_type_size(t); + len = btf_type_size(d->btf, t); if (len < 0) return len;
This allows BTF parsing to proceed even if we do not know the kind. Signed-off-by: Alan Maguire <alan.maguire@oracle.com> --- tools/lib/bpf/btf.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-)