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

tools/resolve_btfids: Add support for 8-byte BTF sets

A flag is a 4-byte symbol that may follow a BTF ID in a set8. This is
used in the kernel to tag kfuncs in BTF sets with certain flags. Add
support to adjust the sorting code so that it passes size as 8 bytes
for 8-byte BTF sets.

Cc: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20220721134245.2450-3-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Kumar Kartikeya Dwivedi and committed by
Alexei Starovoitov
ef2c6f37 ab21d606

+34 -6
+34 -6
tools/bpf/resolve_btfids/main.c
··· 45 45 * .zero 4 46 46 * __BTF_ID__func__vfs_fallocate__4: 47 47 * .zero 4 48 + * 49 + * set8 - store symbol size into first 4 bytes and sort following 50 + * ID list 51 + * 52 + * __BTF_ID__set8__list: 53 + * .zero 8 54 + * list: 55 + * __BTF_ID__func__vfs_getattr__3: 56 + * .zero 4 57 + * .word (1 << 0) | (1 << 2) 58 + * __BTF_ID__func__vfs_fallocate__5: 59 + * .zero 4 60 + * .word (1 << 3) | (1 << 1) | (1 << 2) 48 61 */ 49 62 50 63 #define _GNU_SOURCE ··· 85 72 #define BTF_TYPEDEF "typedef" 86 73 #define BTF_FUNC "func" 87 74 #define BTF_SET "set" 75 + #define BTF_SET8 "set8" 88 76 89 77 #define ADDR_CNT 100 90 78 ··· 98 84 }; 99 85 int addr_cnt; 100 86 bool is_set; 87 + bool is_set8; 101 88 Elf64_Addr addr[ADDR_CNT]; 102 89 }; 103 90 ··· 246 231 return id; 247 232 } 248 233 249 - static struct btf_id *add_set(struct object *obj, char *name) 234 + static struct btf_id *add_set(struct object *obj, char *name, bool is_set8) 250 235 { 251 236 /* 252 237 * __BTF_ID__set__name 253 238 * name = ^ 254 239 * id = ^ 255 240 */ 256 - char *id = name + sizeof(BTF_SET "__") - 1; 241 + char *id = name + (is_set8 ? sizeof(BTF_SET8 "__") : sizeof(BTF_SET "__")) - 1; 257 242 int len = strlen(name); 258 243 259 244 if (id >= name + len) { ··· 459 444 } else if (!strncmp(prefix, BTF_FUNC, sizeof(BTF_FUNC) - 1)) { 460 445 obj->nr_funcs++; 461 446 id = add_symbol(&obj->funcs, prefix, sizeof(BTF_FUNC) - 1); 447 + /* set8 */ 448 + } else if (!strncmp(prefix, BTF_SET8, sizeof(BTF_SET8) - 1)) { 449 + id = add_set(obj, prefix, true); 450 + /* 451 + * SET8 objects store list's count, which is encoded 452 + * in symbol's size, together with 'cnt' field hence 453 + * that - 1. 454 + */ 455 + if (id) { 456 + id->cnt = sym.st_size / sizeof(uint64_t) - 1; 457 + id->is_set8 = true; 458 + } 462 459 /* set */ 463 460 } else if (!strncmp(prefix, BTF_SET, sizeof(BTF_SET) - 1)) { 464 - id = add_set(obj, prefix); 461 + id = add_set(obj, prefix, false); 465 462 /* 466 463 * SET objects store list's count, which is encoded 467 464 * in symbol's size, together with 'cnt' field hence ··· 598 571 int *ptr = data->d_buf; 599 572 int i; 600 573 601 - if (!id->id && !id->is_set) 574 + /* For set, set8, id->id may be 0 */ 575 + if (!id->id && !id->is_set && !id->is_set8) 602 576 pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name); 603 577 604 578 for (i = 0; i < id->addr_cnt; i++) { ··· 671 643 } 672 644 673 645 idx = idx / sizeof(int); 674 - base = &ptr[idx] + 1; 646 + base = &ptr[idx] + (id->is_set8 ? 2 : 1); 675 647 cnt = ptr[idx]; 676 648 677 649 pr_debug("sorting addr %5lu: cnt %6d [%s]\n", 678 650 (idx + 1) * sizeof(int), cnt, id->name); 679 651 680 - qsort(base, cnt, sizeof(int), cmp_id); 652 + qsort(base, cnt, id->is_set8 ? sizeof(uint64_t) : sizeof(int), cmp_id); 681 653 682 654 next = rb_next(next); 683 655 }