aboutsummaryrefslogtreecommitdiffstats
path: root/tools/bpf/bpftool/prog.c
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2018-11-19 18:29:21 -0500
committerAlexei Starovoitov <ast@kernel.org>2018-11-20 13:54:39 -0500
commit254471e57a86b8dc1a2cc19848e99f5d7c0558f4 (patch)
tree1892de2dc8c361322df68d459f0e63e59d901450 /tools/bpf/bpftool/prog.c
parent999d82cbc04416cc7f2b5cb6daab947c16f0fd3a (diff)
tools/bpf: bpftool: add support for func types
This patch added support to print function signature if btf func_info is available. Note that ksym now uses function name instead of prog_name as prog_name has a limit of 16 bytes including ending '\0'. The following is a sample output for selftests test_btf with file test_btf_haskv.o for translated insns and jited insns respectively. $ bpftool prog dump xlated id 1 int _dummy_tracepoint(struct dummy_tracepoint_args * arg): 0: (85) call pc+2#bpf_prog_2dcecc18072623fc_test_long_fname_1 1: (b7) r0 = 0 2: (95) exit int test_long_fname_1(struct dummy_tracepoint_args * arg): 3: (85) call pc+1#bpf_prog_89d64e4abf0f0126_test_long_fname_2 4: (95) exit int test_long_fname_2(struct dummy_tracepoint_args * arg): 5: (b7) r2 = 0 6: (63) *(u32 *)(r10 -4) = r2 7: (79) r1 = *(u64 *)(r1 +8) ... 22: (07) r1 += 1 23: (63) *(u32 *)(r0 +4) = r1 24: (95) exit $ bpftool prog dump jited id 1 int _dummy_tracepoint(struct dummy_tracepoint_args * arg): bpf_prog_b07ccb89267cf242__dummy_tracepoint: 0: push %rbp 1: mov %rsp,%rbp ...... 3c: add $0x28,%rbp 40: leaveq 41: retq int test_long_fname_1(struct dummy_tracepoint_args * arg): bpf_prog_2dcecc18072623fc_test_long_fname_1: 0: push %rbp 1: mov %rsp,%rbp ...... 3a: add $0x28,%rbp 3e: leaveq 3f: retq int test_long_fname_2(struct dummy_tracepoint_args * arg): bpf_prog_89d64e4abf0f0126_test_long_fname_2: 0: push %rbp 1: mov %rsp,%rbp ...... 80: add $0x28,%rbp 84: leaveq 85: retq Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'tools/bpf/bpftool/prog.c')
-rw-r--r--tools/bpf/bpftool/prog.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index c176e1aa66fe..37b1daf19da6 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -47,6 +47,7 @@
47#include <linux/err.h> 47#include <linux/err.h>
48 48
49#include <bpf.h> 49#include <bpf.h>
50#include <btf.h>
50#include <libbpf.h> 51#include <libbpf.h>
51 52
52#include "cfg.h" 53#include "cfg.h"
@@ -451,14 +452,19 @@ static int do_dump(int argc, char **argv)
451 struct bpf_prog_info info = {}; 452 struct bpf_prog_info info = {};
452 unsigned int *func_lens = NULL; 453 unsigned int *func_lens = NULL;
453 const char *disasm_opt = NULL; 454 const char *disasm_opt = NULL;
455 unsigned int finfo_rec_size;
454 unsigned int nr_func_ksyms; 456 unsigned int nr_func_ksyms;
455 unsigned int nr_func_lens; 457 unsigned int nr_func_lens;
456 struct dump_data dd = {}; 458 struct dump_data dd = {};
457 __u32 len = sizeof(info); 459 __u32 len = sizeof(info);
460 struct btf *btf = NULL;
461 void *func_info = NULL;
462 unsigned int finfo_cnt;
458 unsigned int buf_size; 463 unsigned int buf_size;
459 char *filepath = NULL; 464 char *filepath = NULL;
460 bool opcodes = false; 465 bool opcodes = false;
461 bool visual = false; 466 bool visual = false;
467 char func_sig[1024];
462 unsigned char *buf; 468 unsigned char *buf;
463 __u32 *member_len; 469 __u32 *member_len;
464 __u64 *member_ptr; 470 __u64 *member_ptr;
@@ -551,6 +557,17 @@ static int do_dump(int argc, char **argv)
551 } 557 }
552 } 558 }
553 559
560 finfo_cnt = info.func_info_cnt;
561 finfo_rec_size = info.func_info_rec_size;
562 if (finfo_cnt && finfo_rec_size) {
563 func_info = malloc(finfo_cnt * finfo_rec_size);
564 if (!func_info) {
565 p_err("mem alloc failed");
566 close(fd);
567 goto err_free;
568 }
569 }
570
554 memset(&info, 0, sizeof(info)); 571 memset(&info, 0, sizeof(info));
555 572
556 *member_ptr = ptr_to_u64(buf); 573 *member_ptr = ptr_to_u64(buf);
@@ -559,6 +576,9 @@ static int do_dump(int argc, char **argv)
559 info.nr_jited_ksyms = nr_func_ksyms; 576 info.nr_jited_ksyms = nr_func_ksyms;
560 info.jited_func_lens = ptr_to_u64(func_lens); 577 info.jited_func_lens = ptr_to_u64(func_lens);
561 info.nr_jited_func_lens = nr_func_lens; 578 info.nr_jited_func_lens = nr_func_lens;
579 info.func_info_cnt = finfo_cnt;
580 info.func_info_rec_size = finfo_rec_size;
581 info.func_info = ptr_to_u64(func_info);
562 582
563 err = bpf_obj_get_info_by_fd(fd, &info, &len); 583 err = bpf_obj_get_info_by_fd(fd, &info, &len);
564 close(fd); 584 close(fd);
@@ -582,6 +602,18 @@ static int do_dump(int argc, char **argv)
582 goto err_free; 602 goto err_free;
583 } 603 }
584 604
605 if (info.func_info_cnt != finfo_cnt) {
606 p_err("incorrect func_info_cnt %d vs. expected %d",
607 info.func_info_cnt, finfo_cnt);
608 goto err_free;
609 }
610
611 if (info.func_info_rec_size != finfo_rec_size) {
612 p_err("incorrect func_info_rec_size %d vs. expected %d",
613 info.func_info_rec_size, finfo_rec_size);
614 goto err_free;
615 }
616
585 if ((member_len == &info.jited_prog_len && 617 if ((member_len == &info.jited_prog_len &&
586 info.jited_prog_insns == 0) || 618 info.jited_prog_insns == 0) ||
587 (member_len == &info.xlated_prog_len && 619 (member_len == &info.xlated_prog_len &&
@@ -590,6 +622,11 @@ static int do_dump(int argc, char **argv)
590 goto err_free; 622 goto err_free;
591 } 623 }
592 624
625 if (info.btf_id && btf_get_from_id(info.btf_id, &btf)) {
626 p_err("failed to get btf");
627 goto err_free;
628 }
629
593 if (filepath) { 630 if (filepath) {
594 fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0600); 631 fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
595 if (fd < 0) { 632 if (fd < 0) {
@@ -622,6 +659,7 @@ static int do_dump(int argc, char **argv)
622 659
623 if (info.nr_jited_func_lens && info.jited_func_lens) { 660 if (info.nr_jited_func_lens && info.jited_func_lens) {
624 struct kernel_sym *sym = NULL; 661 struct kernel_sym *sym = NULL;
662 struct bpf_func_info *record;
625 char sym_name[SYM_MAX_NAME]; 663 char sym_name[SYM_MAX_NAME];
626 unsigned char *img = buf; 664 unsigned char *img = buf;
627 __u64 *ksyms = NULL; 665 __u64 *ksyms = NULL;
@@ -648,12 +686,25 @@ static int do_dump(int argc, char **argv)
648 strcpy(sym_name, "unknown"); 686 strcpy(sym_name, "unknown");
649 } 687 }
650 688
689 if (func_info) {
690 record = func_info + i * finfo_rec_size;
691 btf_dumper_type_only(btf, record->type_id,
692 func_sig,
693 sizeof(func_sig));
694 }
695
651 if (json_output) { 696 if (json_output) {
652 jsonw_start_object(json_wtr); 697 jsonw_start_object(json_wtr);
698 if (func_info && func_sig[0] != '\0') {
699 jsonw_name(json_wtr, "proto");
700 jsonw_string(json_wtr, func_sig);
701 }
653 jsonw_name(json_wtr, "name"); 702 jsonw_name(json_wtr, "name");
654 jsonw_string(json_wtr, sym_name); 703 jsonw_string(json_wtr, sym_name);
655 jsonw_name(json_wtr, "insns"); 704 jsonw_name(json_wtr, "insns");
656 } else { 705 } else {
706 if (func_info && func_sig[0] != '\0')
707 printf("%s:\n", func_sig);
657 printf("%s:\n", sym_name); 708 printf("%s:\n", sym_name);
658 } 709 }
659 710
@@ -682,6 +733,9 @@ static int do_dump(int argc, char **argv)
682 kernel_syms_load(&dd); 733 kernel_syms_load(&dd);
683 dd.nr_jited_ksyms = info.nr_jited_ksyms; 734 dd.nr_jited_ksyms = info.nr_jited_ksyms;
684 dd.jited_ksyms = (__u64 *) info.jited_ksyms; 735 dd.jited_ksyms = (__u64 *) info.jited_ksyms;
736 dd.btf = btf;
737 dd.func_info = func_info;
738 dd.finfo_rec_size = finfo_rec_size;
685 739
686 if (json_output) 740 if (json_output)
687 dump_xlated_json(&dd, buf, *member_len, opcodes); 741 dump_xlated_json(&dd, buf, *member_len, opcodes);
@@ -693,12 +747,14 @@ static int do_dump(int argc, char **argv)
693 free(buf); 747 free(buf);
694 free(func_ksyms); 748 free(func_ksyms);
695 free(func_lens); 749 free(func_lens);
750 free(func_info);
696 return 0; 751 return 0;
697 752
698err_free: 753err_free:
699 free(buf); 754 free(buf);
700 free(func_ksyms); 755 free(func_ksyms);
701 free(func_lens); 756 free(func_lens);
757 free(func_info);
702 return -1; 758 return -1;
703} 759}
704 760