diff options
author | Martin KaFai Lau <kafai@fb.com> | 2018-12-07 19:42:32 -0500 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2018-12-09 16:54:38 -0500 |
commit | b053b439b72ad152257ecc3f71cfb4c619b0137e (patch) | |
tree | 9cb7c5a026580ee81dff5af7fd84eee3eb2571a4 /tools/bpf/bpftool/prog.c | |
parent | 3d65014146c69bbc4d2947f60dbd722d352cdc46 (diff) |
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@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.c | 100 |
1 files changed, 90 insertions, 10 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index a9a51123454c..65b921ffd10a 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -423,24 +423,26 @@ static int do_show(int argc, char **argv) | |||
423 | 423 | ||
424 | static int do_dump(int argc, char **argv) | 424 | static int do_dump(int argc, char **argv) |
425 | { | 425 | { |
426 | unsigned int finfo_rec_size, linfo_rec_size, jited_linfo_rec_size; | ||
427 | void *func_info = NULL, *linfo = NULL, *jited_linfo = NULL; | ||
428 | unsigned int finfo_cnt, linfo_cnt = 0, jited_linfo_cnt = 0; | ||
429 | struct bpf_prog_linfo *prog_linfo = NULL; | ||
426 | unsigned long *func_ksyms = NULL; | 430 | unsigned long *func_ksyms = NULL; |
427 | struct bpf_prog_info info = {}; | 431 | struct bpf_prog_info info = {}; |
428 | unsigned int *func_lens = NULL; | 432 | unsigned int *func_lens = NULL; |
429 | const char *disasm_opt = NULL; | 433 | const char *disasm_opt = NULL; |
430 | unsigned int finfo_rec_size; | ||
431 | unsigned int nr_func_ksyms; | 434 | unsigned int nr_func_ksyms; |
432 | unsigned int nr_func_lens; | 435 | unsigned int nr_func_lens; |
433 | struct dump_data dd = {}; | 436 | struct dump_data dd = {}; |
434 | __u32 len = sizeof(info); | 437 | __u32 len = sizeof(info); |
435 | struct btf *btf = NULL; | 438 | struct btf *btf = NULL; |
436 | void *func_info = NULL; | ||
437 | unsigned int finfo_cnt; | ||
438 | unsigned int buf_size; | 439 | unsigned int buf_size; |
439 | char *filepath = NULL; | 440 | char *filepath = NULL; |
440 | bool opcodes = false; | 441 | bool opcodes = false; |
441 | bool visual = false; | 442 | bool visual = false; |
442 | char func_sig[1024]; | 443 | char func_sig[1024]; |
443 | unsigned char *buf; | 444 | unsigned char *buf; |
445 | bool linum = false; | ||
444 | __u32 *member_len; | 446 | __u32 *member_len; |
445 | __u64 *member_ptr; | 447 | __u64 *member_ptr; |
446 | ssize_t n; | 448 | ssize_t n; |
@@ -484,6 +486,9 @@ static int do_dump(int argc, char **argv) | |||
484 | } else if (is_prefix(*argv, "visual")) { | 486 | } else if (is_prefix(*argv, "visual")) { |
485 | visual = true; | 487 | visual = true; |
486 | NEXT_ARG(); | 488 | NEXT_ARG(); |
489 | } else if (is_prefix(*argv, "linum")) { | ||
490 | linum = true; | ||
491 | NEXT_ARG(); | ||
487 | } | 492 | } |
488 | 493 | ||
489 | if (argc) { | 494 | if (argc) { |
@@ -543,6 +548,32 @@ static int do_dump(int argc, char **argv) | |||
543 | } | 548 | } |
544 | } | 549 | } |
545 | 550 | ||
551 | linfo_rec_size = info.line_info_rec_size; | ||
552 | if (info.line_info_cnt && linfo_rec_size && info.btf_id) { | ||
553 | linfo_cnt = info.line_info_cnt; | ||
554 | linfo = malloc(linfo_cnt * linfo_rec_size); | ||
555 | if (!linfo) { | ||
556 | p_err("mem alloc failed"); | ||
557 | close(fd); | ||
558 | goto err_free; | ||
559 | } | ||
560 | } | ||
561 | |||
562 | jited_linfo_rec_size = info.jited_line_info_rec_size; | ||
563 | if (info.jited_line_info_cnt && | ||
564 | jited_linfo_rec_size && | ||
565 | info.nr_jited_ksyms && | ||
566 | info.nr_jited_func_lens && | ||
567 | info.btf_id) { | ||
568 | jited_linfo_cnt = info.jited_line_info_cnt; | ||
569 | jited_linfo = malloc(jited_linfo_cnt * jited_linfo_rec_size); | ||
570 | if (!jited_linfo) { | ||
571 | p_err("mem alloc failed"); | ||
572 | close(fd); | ||
573 | goto err_free; | ||
574 | } | ||
575 | } | ||
576 | |||
546 | memset(&info, 0, sizeof(info)); | 577 | memset(&info, 0, sizeof(info)); |
547 | 578 | ||
548 | *member_ptr = ptr_to_u64(buf); | 579 | *member_ptr = ptr_to_u64(buf); |
@@ -554,6 +585,13 @@ static int do_dump(int argc, char **argv) | |||
554 | info.func_info_cnt = finfo_cnt; | 585 | info.func_info_cnt = finfo_cnt; |
555 | info.func_info_rec_size = finfo_rec_size; | 586 | info.func_info_rec_size = finfo_rec_size; |
556 | info.func_info = ptr_to_u64(func_info); | 587 | info.func_info = ptr_to_u64(func_info); |
588 | info.line_info_cnt = linfo_cnt; | ||
589 | info.line_info_rec_size = linfo_rec_size; | ||
590 | info.line_info = ptr_to_u64(linfo); | ||
591 | info.jited_line_info_cnt = jited_linfo_cnt; | ||
592 | info.jited_line_info_rec_size = jited_linfo_rec_size; | ||
593 | info.jited_line_info = ptr_to_u64(jited_linfo); | ||
594 | |||
557 | 595 | ||
558 | err = bpf_obj_get_info_by_fd(fd, &info, &len); | 596 | err = bpf_obj_get_info_by_fd(fd, &info, &len); |
559 | close(fd); | 597 | close(fd); |
@@ -596,6 +634,30 @@ static int do_dump(int argc, char **argv) | |||
596 | finfo_cnt = 0; | 634 | finfo_cnt = 0; |
597 | } | 635 | } |
598 | 636 | ||
637 | if (linfo && info.line_info_cnt != linfo_cnt) { | ||
638 | p_err("incorrect line_info_cnt %u vs. expected %u", | ||
639 | info.line_info_cnt, linfo_cnt); | ||
640 | goto err_free; | ||
641 | } | ||
642 | |||
643 | if (info.line_info_rec_size != linfo_rec_size) { | ||
644 | p_err("incorrect line_info_rec_size %u vs. expected %u", | ||
645 | info.line_info_rec_size, linfo_rec_size); | ||
646 | goto err_free; | ||
647 | } | ||
648 | |||
649 | if (jited_linfo && info.jited_line_info_cnt != jited_linfo_cnt) { | ||
650 | p_err("incorrect jited_line_info_cnt %u vs. expected %u", | ||
651 | info.jited_line_info_cnt, jited_linfo_cnt); | ||
652 | goto err_free; | ||
653 | } | ||
654 | |||
655 | if (info.jited_line_info_rec_size != jited_linfo_rec_size) { | ||
656 | p_err("incorrect jited_line_info_rec_size %u vs. expected %u", | ||
657 | info.jited_line_info_rec_size, jited_linfo_rec_size); | ||
658 | goto err_free; | ||
659 | } | ||
660 | |||
599 | if ((member_len == &info.jited_prog_len && | 661 | if ((member_len == &info.jited_prog_len && |
600 | info.jited_prog_insns == 0) || | 662 | info.jited_prog_insns == 0) || |
601 | (member_len == &info.xlated_prog_len && | 663 | (member_len == &info.xlated_prog_len && |
@@ -609,6 +671,12 @@ static int do_dump(int argc, char **argv) | |||
609 | goto err_free; | 671 | goto err_free; |
610 | } | 672 | } |
611 | 673 | ||
674 | if (linfo_cnt) { | ||
675 | prog_linfo = bpf_prog_linfo__new(&info); | ||
676 | if (!prog_linfo) | ||
677 | p_err("error in processing bpf_line_info. continue without it."); | ||
678 | } | ||
679 | |||
612 | if (filepath) { | 680 | if (filepath) { |
613 | fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0600); | 681 | fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0600); |
614 | if (fd < 0) { | 682 | if (fd < 0) { |
@@ -690,8 +758,11 @@ static int do_dump(int argc, char **argv) | |||
690 | printf("%s:\n", sym_name); | 758 | printf("%s:\n", sym_name); |
691 | } | 759 | } |
692 | 760 | ||
693 | disasm_print_insn(img, lens[i], opcodes, name, | 761 | disasm_print_insn(img, lens[i], opcodes, |
694 | disasm_opt); | 762 | name, disasm_opt, btf, |
763 | prog_linfo, ksyms[i], i, | ||
764 | linum); | ||
765 | |||
695 | img += lens[i]; | 766 | img += lens[i]; |
696 | 767 | ||
697 | if (json_output) | 768 | if (json_output) |
@@ -704,7 +775,7 @@ static int do_dump(int argc, char **argv) | |||
704 | jsonw_end_array(json_wtr); | 775 | jsonw_end_array(json_wtr); |
705 | } else { | 776 | } else { |
706 | disasm_print_insn(buf, *member_len, opcodes, name, | 777 | disasm_print_insn(buf, *member_len, opcodes, name, |
707 | disasm_opt); | 778 | disasm_opt, btf, NULL, 0, 0, false); |
708 | } | 779 | } |
709 | } else if (visual) { | 780 | } else if (visual) { |
710 | if (json_output) | 781 | if (json_output) |
@@ -718,11 +789,14 @@ static int do_dump(int argc, char **argv) | |||
718 | dd.btf = btf; | 789 | dd.btf = btf; |
719 | dd.func_info = func_info; | 790 | dd.func_info = func_info; |
720 | dd.finfo_rec_size = finfo_rec_size; | 791 | dd.finfo_rec_size = finfo_rec_size; |
792 | dd.prog_linfo = prog_linfo; | ||
721 | 793 | ||
722 | if (json_output) | 794 | if (json_output) |
723 | dump_xlated_json(&dd, buf, *member_len, opcodes); | 795 | dump_xlated_json(&dd, buf, *member_len, opcodes, |
796 | linum); | ||
724 | else | 797 | else |
725 | dump_xlated_plain(&dd, buf, *member_len, opcodes); | 798 | dump_xlated_plain(&dd, buf, *member_len, opcodes, |
799 | linum); | ||
726 | kernel_syms_destroy(&dd); | 800 | kernel_syms_destroy(&dd); |
727 | } | 801 | } |
728 | 802 | ||
@@ -730,6 +804,9 @@ static int do_dump(int argc, char **argv) | |||
730 | free(func_ksyms); | 804 | free(func_ksyms); |
731 | free(func_lens); | 805 | free(func_lens); |
732 | free(func_info); | 806 | free(func_info); |
807 | free(linfo); | ||
808 | free(jited_linfo); | ||
809 | bpf_prog_linfo__free(prog_linfo); | ||
733 | return 0; | 810 | return 0; |
734 | 811 | ||
735 | err_free: | 812 | err_free: |
@@ -737,6 +814,9 @@ err_free: | |||
737 | free(func_ksyms); | 814 | free(func_ksyms); |
738 | free(func_lens); | 815 | free(func_lens); |
739 | free(func_info); | 816 | free(func_info); |
817 | free(linfo); | ||
818 | free(jited_linfo); | ||
819 | bpf_prog_linfo__free(prog_linfo); | ||
740 | return -1; | 820 | return -1; |
741 | } | 821 | } |
742 | 822 | ||
@@ -1138,8 +1218,8 @@ static int do_help(int argc, char **argv) | |||
1138 | 1218 | ||
1139 | fprintf(stderr, | 1219 | fprintf(stderr, |
1140 | "Usage: %s %s { show | list } [PROG]\n" | 1220 | "Usage: %s %s { show | list } [PROG]\n" |
1141 | " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n" | 1221 | " %s %s dump xlated PROG [{ file FILE | opcodes | visual | linum }]\n" |
1142 | " %s %s dump jited PROG [{ file FILE | opcodes }]\n" | 1222 | " %s %s dump jited PROG [{ file FILE | opcodes | linum }]\n" |
1143 | " %s %s pin PROG FILE\n" | 1223 | " %s %s pin PROG FILE\n" |
1144 | " %s %s { load | loadall } OBJ PATH \\\n" | 1224 | " %s %s { load | loadall } OBJ PATH \\\n" |
1145 | " [type TYPE] [dev NAME] \\\n" | 1225 | " [type TYPE] [dev NAME] \\\n" |