Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

libbpf: Use layout to compute an unknown kind size

This allows BTF parsing to proceed even if we do not know the
kind. Fall back to base BTF layout if layout information is
not in split BTF.

Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260326145444.2076244-4-alan.maguire@oracle.com

authored by

Alan Maguire and committed by
Andrii Nakryiko
2ecbe53e 087f3964

+43 -9
+43 -9
tools/lib/bpf/btf.c
··· 386 386 return 0; 387 387 } 388 388 389 - static int btf_type_size(const struct btf_type *t) 389 + /* for unknown kinds, consult kind layout. */ 390 + static int btf_type_size_unknown(const struct btf *btf, const struct btf_type *t) 391 + { 392 + __u32 l_cnt = btf->hdr.layout_len / sizeof(struct btf_layout); 393 + struct btf_layout *l = btf->layout; 394 + __u16 vlen = btf_vlen(t); 395 + __u32 kind = btf_kind(t); 396 + 397 + /* Fall back to base BTF if needed as they share layout information */ 398 + if (!l) { 399 + struct btf *base_btf = btf->base_btf; 400 + 401 + if (base_btf) { 402 + l = base_btf->layout; 403 + l_cnt = base_btf->hdr.layout_len / sizeof(struct btf_layout); 404 + } 405 + } 406 + if (!l || kind >= l_cnt) { 407 + pr_debug("Unsupported BTF_KIND: %u\n", btf_kind(t)); 408 + return -EINVAL; 409 + } 410 + if (l[kind].info_sz % 4) { 411 + pr_debug("Unsupported info_sz %u for kind %u\n", 412 + l[kind].info_sz, kind); 413 + return -EINVAL; 414 + } 415 + if (l[kind].elem_sz % 4) { 416 + pr_debug("Unsupported elem_sz %u for kind %u\n", 417 + l[kind].elem_sz, kind); 418 + return -EINVAL; 419 + } 420 + 421 + return sizeof(struct btf_type) + l[kind].info_sz + vlen * l[kind].elem_sz; 422 + } 423 + 424 + static int btf_type_size(const struct btf *btf, const struct btf_type *t) 390 425 { 391 426 const int base_size = sizeof(struct btf_type); 392 427 __u16 vlen = btf_vlen(t); ··· 457 422 case BTF_KIND_DECL_TAG: 458 423 return base_size + sizeof(struct btf_decl_tag); 459 424 default: 460 - pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t)); 461 - return -EINVAL; 425 + return btf_type_size_unknown(btf, t); 462 426 } 463 427 } 464 428 ··· 555 521 if (btf->swapped_endian) 556 522 btf_bswap_type_base(next_type); 557 523 558 - type_size = btf_type_size(next_type); 524 + type_size = btf_type_size(btf, next_type); 559 525 if (type_size < 0) 560 526 return type_size; 561 527 if (next_type + type_size > end_type) { ··· 2136 2102 __u32 *str_off; 2137 2103 int sz, err; 2138 2104 2139 - sz = btf_type_size(src_type); 2105 + sz = btf_type_size(p->src, src_type); 2140 2106 if (sz < 0) 2141 2107 return libbpf_err(sz); 2142 2108 ··· 2226 2192 struct btf_field_iter it; 2227 2193 __u32 *type_id, *str_off; 2228 2194 2229 - sz = btf_type_size(t); 2195 + sz = btf_type_size(src_btf, t); 2230 2196 if (sz < 0) { 2231 2197 /* unlikely, has to be corrupted src_btf */ 2232 2198 err = sz; ··· 5594 5560 continue; 5595 5561 5596 5562 t = btf__type_by_id(d->btf, id); 5597 - len = btf_type_size(t); 5563 + len = btf_type_size(d->btf, t); 5598 5564 if (len < 0) 5599 5565 return len; 5600 5566 ··· 6256 6222 6257 6223 id = order_map[i]; 6258 6224 t = btf__type_by_id(btf, id); 6259 - type_size = btf_type_size(t); 6225 + type_size = btf_type_size(btf, t); 6260 6226 memcpy(nt, t, type_size); 6261 6227 6262 6228 /* fix up referenced IDs for BTF */ ··· 6282 6248 6283 6249 for (nt = new_types, i = 0; i < id_map_cnt - start_offs; i++) { 6284 6250 btf->type_offs[i] = nt - new_types; 6285 - nt += btf_type_size(nt); 6251 + nt += btf_type_size(btf, nt); 6286 6252 } 6287 6253 6288 6254 free(order_map);