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

tools/bpftool: Add bpftool support for split BTF

Add ability to work with split BTF by providing extra -B flag, which allows to
specify the path to the base BTF file.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/bpf/20201105043402.2530976-12-andrii@kernel.org

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
75fa1777 232338fa

+21 -4
+6 -3
tools/bpf/bpftool/btf.c
··· 358 358 } 359 359 } else { 360 360 int cnt = btf__get_nr_types(btf); 361 + int start_id = 1; 361 362 362 - for (i = 1; i <= cnt; i++) { 363 + if (base_btf) 364 + start_id = btf__get_nr_types(base_btf) + 1; 365 + 366 + for (i = start_id; i <= cnt; i++) { 363 367 t = btf__type_by_id(btf, i); 364 368 dump_btf_type(btf, i, t); 365 369 } ··· 442 438 return -1; 443 439 } 444 440 src = GET_ARG(); 445 - 446 441 if (is_prefix(src, "map")) { 447 442 struct bpf_map_info info = {}; 448 443 __u32 len = sizeof(info); ··· 502 499 } 503 500 NEXT_ARG(); 504 501 } else if (is_prefix(src, "file")) { 505 - btf = btf__parse(*argv, NULL); 502 + btf = btf__parse_split(*argv, base_btf); 506 503 if (IS_ERR(btf)) { 507 504 err = -PTR_ERR(btf); 508 505 btf = NULL;
+14 -1
tools/bpf/bpftool/main.c
··· 11 11 12 12 #include <bpf/bpf.h> 13 13 #include <bpf/libbpf.h> 14 + #include <bpf/btf.h> 14 15 15 16 #include "main.h" 16 17 ··· 29 28 bool block_mount; 30 29 bool verifier_logs; 31 30 bool relaxed_maps; 31 + struct btf *base_btf; 32 32 struct pinned_obj_table prog_table; 33 33 struct pinned_obj_table map_table; 34 34 struct pinned_obj_table link_table; ··· 393 391 { "mapcompat", no_argument, NULL, 'm' }, 394 392 { "nomount", no_argument, NULL, 'n' }, 395 393 { "debug", no_argument, NULL, 'd' }, 394 + { "base-btf", required_argument, NULL, 'B' }, 396 395 { 0 } 397 396 }; 398 397 int opt, ret; ··· 410 407 hash_init(link_table.table); 411 408 412 409 opterr = 0; 413 - while ((opt = getopt_long(argc, argv, "Vhpjfmnd", 410 + while ((opt = getopt_long(argc, argv, "VhpjfmndB:", 414 411 options, NULL)) >= 0) { 415 412 switch (opt) { 416 413 case 'V': ··· 444 441 libbpf_set_print(print_all_levels); 445 442 verifier_logs = true; 446 443 break; 444 + case 'B': 445 + base_btf = btf__parse(optarg, NULL); 446 + if (libbpf_get_error(base_btf)) { 447 + p_err("failed to parse base BTF at '%s': %ld\n", 448 + optarg, libbpf_get_error(base_btf)); 449 + base_btf = NULL; 450 + return -1; 451 + } 452 + break; 447 453 default: 448 454 p_err("unrecognized option '%s'", argv[optind - 1]); 449 455 if (json_output) ··· 477 465 delete_pinned_obj_table(&map_table); 478 466 delete_pinned_obj_table(&link_table); 479 467 } 468 + btf__free(base_btf); 480 469 481 470 return ret; 482 471 }
+1
tools/bpf/bpftool/main.h
··· 90 90 extern bool block_mount; 91 91 extern bool verifier_logs; 92 92 extern bool relaxed_maps; 93 + extern struct btf *base_btf; 93 94 extern struct pinned_obj_table prog_table; 94 95 extern struct pinned_obj_table map_table; 95 96 extern struct pinned_obj_table link_table;