aboutsummaryrefslogtreecommitdiffstats
path: root/tools/bpf/bpftool/prog.c
diff options
context:
space:
mode:
authorSong Liu <songliubraving@fb.com>2019-03-12 01:30:39 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-03-19 15:52:06 -0400
commitcae73f2339231d61022769f09c94e4500e8ad47a (patch)
tree6783057d08de13b3b5a46985b1cbb865eff7a19c /tools/bpf/bpftool/prog.c
parent34be16466d4dc06f3d604dafbcdb3327b72e78da (diff)
bpftool: use bpf_program__get_prog_info_linear() in prog.c:do_dump()
This patches uses bpf_program__get_prog_info_linear() to simplify the logic in prog.c do_dump(). Committer testing: Before: # bpftool prog dump xlated id 208 > /tmp/dump.xlated.before # bpftool prog dump jited id 208 > /tmp/dump.jited.before # bpftool map dump id 107 > /tmp/map.dump.before After: # ~acme/git/perf/tools/bpf/bpftool/bpftool map dump id 107 > /tmp/map.dump.after # ~acme/git/perf/tools/bpf/bpftool/bpftool prog dump xlated id 208 > /tmp/dump.xlated.after # ~acme/git/perf/tools/bpf/bpftool/bpftool prog dump jited id 208 > /tmp/dump.jited.after # diff -u /tmp/dump.xlated.before /tmp/dump.xlated.after # diff -u /tmp/dump.jited.before /tmp/dump.jited.after # diff -u /tmp/map.dump.before /tmp/map.dump.after # ~acme/git/perf/tools/bpf/bpftool/bpftool prog dump xlated id 208 0: (bf) r6 = r1 1: (85) call bpf_get_current_pid_tgid#80800 2: (63) *(u32 *)(r10 -328) = r0 3: (bf) r2 = r10 4: (07) r2 += -328 5: (18) r1 = map[id:107] 7: (85) call __htab_map_lookup_elem#85680 8: (15) if r0 == 0x0 goto pc+1 9: (07) r0 += 56 10: (b7) r7 = 0 11: (55) if r0 != 0x0 goto pc+52 12: (bf) r1 = r10 13: (07) r1 += -328 14: (b7) r2 = 64 15: (bf) r3 = r6 16: (85) call bpf_probe_read#-46848 17: (bf) r2 = r10 18: (07) r2 += -320 19: (18) r1 = map[id:106] 21: (07) r1 += 208 22: (61) r0 = *(u32 *)(r2 +0) 23: (35) if r0 >= 0x200 goto pc+3 24: (67) r0 <<= 3 25: (0f) r0 += r1 26: (05) goto pc+1 27: (b7) r0 = 0 28: (15) if r0 == 0x0 goto pc+35 29: (71) r1 = *(u8 *)(r0 +0) 30: (15) if r1 == 0x0 goto pc+33 31: (b7) r5 = 64 32: (79) r1 = *(u64 *)(r10 -320) 33: (15) if r1 == 0x2 goto pc+2 34: (15) if r1 == 0x101 goto pc+3 35: (55) if r1 != 0x15 goto pc+19 36: (79) r3 = *(u64 *)(r6 +16) 37: (05) goto pc+1 38: (79) r3 = *(u64 *)(r6 +24) 39: (15) if r3 == 0x0 goto pc+15 40: (b7) r1 = 0 41: (63) *(u32 *)(r10 -260) = r1 42: (bf) r1 = r10 43: (07) r1 += -256 44: (b7) r2 = 256 45: (85) call bpf_probe_read_str#-46704 46: (b7) r5 = 328 47: (63) *(u32 *)(r10 -264) = r0 48: (bf) r1 = r0 49: (67) r1 <<= 32 50: (77) r1 >>= 32 51: (25) if r1 > 0xff goto pc+3 52: (07) r0 += 72 53: (57) r0 &= 255 54: (bf) r5 = r0 55: (bf) r4 = r10 56: (07) r4 += -328 57: (bf) r1 = r6 58: (18) r2 = map[id:105] 60: (18) r3 = 0xffffffff 62: (85) call bpf_perf_event_output_tp#-45104 63: (bf) r7 = r0 64: (bf) r0 = r7 65: (95) exit # Signed-off-by: Song Liu <songliubraving@fb.com> Reviewed-by: Jiri Olsa <jolsa@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: kernel-team@fb.com Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stanislav Fomichev <sdf@google.com> Link: http://lkml.kernel.org/r/20190312053051.2690567-4-songliubraving@fb.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/bpf/bpftool/prog.c')
-rw-r--r--tools/bpf/bpftool/prog.c266
1 files changed, 59 insertions, 207 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 8ef80d65a474..d2be5a06c339 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -401,41 +401,31 @@ static int do_show(int argc, char **argv)
401 401
402static int do_dump(int argc, char **argv) 402static int do_dump(int argc, char **argv)
403{ 403{
404 unsigned int finfo_rec_size, linfo_rec_size, jited_linfo_rec_size; 404 struct bpf_prog_info_linear *info_linear;
405 void *func_info = NULL, *linfo = NULL, *jited_linfo = NULL;
406 unsigned int nr_finfo, nr_linfo = 0, nr_jited_linfo = 0;
407 struct bpf_prog_linfo *prog_linfo = NULL; 405 struct bpf_prog_linfo *prog_linfo = NULL;
408 unsigned long *func_ksyms = NULL; 406 enum {DUMP_JITED, DUMP_XLATED} mode;
409 struct bpf_prog_info info = {};
410 unsigned int *func_lens = NULL;
411 const char *disasm_opt = NULL; 407 const char *disasm_opt = NULL;
412 unsigned int nr_func_ksyms; 408 struct bpf_prog_info *info;
413 unsigned int nr_func_lens;
414 struct dump_data dd = {}; 409 struct dump_data dd = {};
415 __u32 len = sizeof(info); 410 void *func_info = NULL;
416 struct btf *btf = NULL; 411 struct btf *btf = NULL;
417 unsigned int buf_size;
418 char *filepath = NULL; 412 char *filepath = NULL;
419 bool opcodes = false; 413 bool opcodes = false;
420 bool visual = false; 414 bool visual = false;
421 char func_sig[1024]; 415 char func_sig[1024];
422 unsigned char *buf; 416 unsigned char *buf;
423 bool linum = false; 417 bool linum = false;
424 __u32 *member_len; 418 __u32 member_len;
425 __u64 *member_ptr; 419 __u64 arrays;
426 ssize_t n; 420 ssize_t n;
427 int err;
428 int fd; 421 int fd;
429 422
430 if (is_prefix(*argv, "jited")) { 423 if (is_prefix(*argv, "jited")) {
431 if (disasm_init()) 424 if (disasm_init())
432 return -1; 425 return -1;
433 426 mode = DUMP_JITED;
434 member_len = &info.jited_prog_len;
435 member_ptr = &info.jited_prog_insns;
436 } else if (is_prefix(*argv, "xlated")) { 427 } else if (is_prefix(*argv, "xlated")) {
437 member_len = &info.xlated_prog_len; 428 mode = DUMP_XLATED;
438 member_ptr = &info.xlated_prog_insns;
439 } else { 429 } else {
440 p_err("expected 'xlated' or 'jited', got: %s", *argv); 430 p_err("expected 'xlated' or 'jited', got: %s", *argv);
441 return -1; 431 return -1;
@@ -474,175 +464,50 @@ static int do_dump(int argc, char **argv)
474 return -1; 464 return -1;
475 } 465 }
476 466
477 err = bpf_obj_get_info_by_fd(fd, &info, &len); 467 if (mode == DUMP_JITED)
478 if (err) { 468 arrays = 1UL << BPF_PROG_INFO_JITED_INSNS;
479 p_err("can't get prog info: %s", strerror(errno)); 469 else
480 return -1; 470 arrays = 1UL << BPF_PROG_INFO_XLATED_INSNS;
481 }
482
483 if (!*member_len) {
484 p_info("no instructions returned");
485 close(fd);
486 return 0;
487 }
488 471
489 buf_size = *member_len; 472 arrays |= 1UL << BPF_PROG_INFO_JITED_KSYMS;
473 arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS;
474 arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO;
475 arrays |= 1UL << BPF_PROG_INFO_LINE_INFO;
476 arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO;
490 477
491 buf = malloc(buf_size); 478 info_linear = bpf_program__get_prog_info_linear(fd, arrays);
492 if (!buf) { 479 close(fd);
493 p_err("mem alloc failed"); 480 if (IS_ERR_OR_NULL(info_linear)) {
494 close(fd); 481 p_err("can't get prog info: %s", strerror(errno));
495 return -1; 482 return -1;
496 } 483 }
497 484
498 nr_func_ksyms = info.nr_jited_ksyms; 485 info = &info_linear->info;
499 if (nr_func_ksyms) { 486 if (mode == DUMP_JITED) {
500 func_ksyms = malloc(nr_func_ksyms * sizeof(__u64)); 487 if (info->jited_prog_len == 0) {
501 if (!func_ksyms) { 488 p_info("no instructions returned");
502 p_err("mem alloc failed");
503 close(fd);
504 goto err_free;
505 }
506 }
507
508 nr_func_lens = info.nr_jited_func_lens;
509 if (nr_func_lens) {
510 func_lens = malloc(nr_func_lens * sizeof(__u32));
511 if (!func_lens) {
512 p_err("mem alloc failed");
513 close(fd);
514 goto err_free; 489 goto err_free;
515 } 490 }
516 } 491 buf = (unsigned char *)(info->jited_prog_insns);
517 492 member_len = info->jited_prog_len;
518 nr_finfo = info.nr_func_info; 493 } else { /* DUMP_XLATED */
519 finfo_rec_size = info.func_info_rec_size; 494 if (info->xlated_prog_len == 0) {
520 if (nr_finfo && finfo_rec_size) { 495 p_err("error retrieving insn dump: kernel.kptr_restrict set?");
521 func_info = malloc(nr_finfo * finfo_rec_size);
522 if (!func_info) {
523 p_err("mem alloc failed");
524 close(fd);
525 goto err_free; 496 goto err_free;
526 } 497 }
498 buf = (unsigned char *)info->xlated_prog_insns;
499 member_len = info->xlated_prog_len;
527 } 500 }
528 501
529 linfo_rec_size = info.line_info_rec_size; 502 if (info->btf_id && btf__get_from_id(info->btf_id, &btf)) {
530 if (info.nr_line_info && linfo_rec_size && info.btf_id) {
531 nr_linfo = info.nr_line_info;
532 linfo = malloc(nr_linfo * linfo_rec_size);
533 if (!linfo) {
534 p_err("mem alloc failed");
535 close(fd);
536 goto err_free;
537 }
538 }
539
540 jited_linfo_rec_size = info.jited_line_info_rec_size;
541 if (info.nr_jited_line_info &&
542 jited_linfo_rec_size &&
543 info.nr_jited_ksyms &&
544 info.nr_jited_func_lens &&
545 info.btf_id) {
546 nr_jited_linfo = info.nr_jited_line_info;
547 jited_linfo = malloc(nr_jited_linfo * jited_linfo_rec_size);
548 if (!jited_linfo) {
549 p_err("mem alloc failed");
550 close(fd);
551 goto err_free;
552 }
553 }
554
555 memset(&info, 0, sizeof(info));
556
557 *member_ptr = ptr_to_u64(buf);
558 *member_len = buf_size;
559 info.jited_ksyms = ptr_to_u64(func_ksyms);
560 info.nr_jited_ksyms = nr_func_ksyms;
561 info.jited_func_lens = ptr_to_u64(func_lens);
562 info.nr_jited_func_lens = nr_func_lens;
563 info.nr_func_info = nr_finfo;
564 info.func_info_rec_size = finfo_rec_size;
565 info.func_info = ptr_to_u64(func_info);
566 info.nr_line_info = nr_linfo;
567 info.line_info_rec_size = linfo_rec_size;
568 info.line_info = ptr_to_u64(linfo);
569 info.nr_jited_line_info = nr_jited_linfo;
570 info.jited_line_info_rec_size = jited_linfo_rec_size;
571 info.jited_line_info = ptr_to_u64(jited_linfo);
572
573 err = bpf_obj_get_info_by_fd(fd, &info, &len);
574 close(fd);
575 if (err) {
576 p_err("can't get prog info: %s", strerror(errno));
577 goto err_free;
578 }
579
580 if (*member_len > buf_size) {
581 p_err("too many instructions returned");
582 goto err_free;
583 }
584
585 if (info.nr_jited_ksyms > nr_func_ksyms) {
586 p_err("too many addresses returned");
587 goto err_free;
588 }
589
590 if (info.nr_jited_func_lens > nr_func_lens) {
591 p_err("too many values returned");
592 goto err_free;
593 }
594
595 if (info.nr_func_info != nr_finfo) {
596 p_err("incorrect nr_func_info %d vs. expected %d",
597 info.nr_func_info, nr_finfo);
598 goto err_free;
599 }
600
601 if (info.func_info_rec_size != finfo_rec_size) {
602 p_err("incorrect func_info_rec_size %d vs. expected %d",
603 info.func_info_rec_size, finfo_rec_size);
604 goto err_free;
605 }
606
607 if (linfo && info.nr_line_info != nr_linfo) {
608 p_err("incorrect nr_line_info %u vs. expected %u",
609 info.nr_line_info, nr_linfo);
610 goto err_free;
611 }
612
613 if (info.line_info_rec_size != linfo_rec_size) {
614 p_err("incorrect line_info_rec_size %u vs. expected %u",
615 info.line_info_rec_size, linfo_rec_size);
616 goto err_free;
617 }
618
619 if (jited_linfo && info.nr_jited_line_info != nr_jited_linfo) {
620 p_err("incorrect nr_jited_line_info %u vs. expected %u",
621 info.nr_jited_line_info, nr_jited_linfo);
622 goto err_free;
623 }
624
625 if (info.jited_line_info_rec_size != jited_linfo_rec_size) {
626 p_err("incorrect jited_line_info_rec_size %u vs. expected %u",
627 info.jited_line_info_rec_size, jited_linfo_rec_size);
628 goto err_free;
629 }
630
631 if ((member_len == &info.jited_prog_len &&
632 info.jited_prog_insns == 0) ||
633 (member_len == &info.xlated_prog_len &&
634 info.xlated_prog_insns == 0)) {
635 p_err("error retrieving insn dump: kernel.kptr_restrict set?");
636 goto err_free;
637 }
638
639 if (info.btf_id && btf__get_from_id(info.btf_id, &btf)) {
640 p_err("failed to get btf"); 503 p_err("failed to get btf");
641 goto err_free; 504 goto err_free;
642 } 505 }
643 506
644 if (nr_linfo) { 507 func_info = (void *)info->func_info;
645 prog_linfo = bpf_prog_linfo__new(&info); 508
509 if (info->nr_line_info) {
510 prog_linfo = bpf_prog_linfo__new(info);
646 if (!prog_linfo) 511 if (!prog_linfo)
647 p_info("error in processing bpf_line_info. continue without it."); 512 p_info("error in processing bpf_line_info. continue without it.");
648 } 513 }
@@ -655,9 +520,9 @@ static int do_dump(int argc, char **argv)
655 goto err_free; 520 goto err_free;
656 } 521 }
657 522
658 n = write(fd, buf, *member_len); 523 n = write(fd, buf, member_len);
659 close(fd); 524 close(fd);
660 if (n != *member_len) { 525 if (n != member_len) {
661 p_err("error writing output file: %s", 526 p_err("error writing output file: %s",
662 n < 0 ? strerror(errno) : "short write"); 527 n < 0 ? strerror(errno) : "short write");
663 goto err_free; 528 goto err_free;
@@ -665,19 +530,19 @@ static int do_dump(int argc, char **argv)
665 530
666 if (json_output) 531 if (json_output)
667 jsonw_null(json_wtr); 532 jsonw_null(json_wtr);
668 } else if (member_len == &info.jited_prog_len) { 533 } else if (mode == DUMP_JITED) {
669 const char *name = NULL; 534 const char *name = NULL;
670 535
671 if (info.ifindex) { 536 if (info->ifindex) {
672 name = ifindex_to_bfd_params(info.ifindex, 537 name = ifindex_to_bfd_params(info->ifindex,
673 info.netns_dev, 538 info->netns_dev,
674 info.netns_ino, 539 info->netns_ino,
675 &disasm_opt); 540 &disasm_opt);
676 if (!name) 541 if (!name)
677 goto err_free; 542 goto err_free;
678 } 543 }
679 544
680 if (info.nr_jited_func_lens && info.jited_func_lens) { 545 if (info->nr_jited_func_lens && info->jited_func_lens) {
681 struct kernel_sym *sym = NULL; 546 struct kernel_sym *sym = NULL;
682 struct bpf_func_info *record; 547 struct bpf_func_info *record;
683 char sym_name[SYM_MAX_NAME]; 548 char sym_name[SYM_MAX_NAME];
@@ -685,17 +550,16 @@ static int do_dump(int argc, char **argv)
685 __u64 *ksyms = NULL; 550 __u64 *ksyms = NULL;
686 __u32 *lens; 551 __u32 *lens;
687 __u32 i; 552 __u32 i;
688 553 if (info->nr_jited_ksyms) {
689 if (info.nr_jited_ksyms) {
690 kernel_syms_load(&dd); 554 kernel_syms_load(&dd);
691 ksyms = (__u64 *) info.jited_ksyms; 555 ksyms = (__u64 *) info->jited_ksyms;
692 } 556 }
693 557
694 if (json_output) 558 if (json_output)
695 jsonw_start_array(json_wtr); 559 jsonw_start_array(json_wtr);
696 560
697 lens = (__u32 *) info.jited_func_lens; 561 lens = (__u32 *) info->jited_func_lens;
698 for (i = 0; i < info.nr_jited_func_lens; i++) { 562 for (i = 0; i < info->nr_jited_func_lens; i++) {
699 if (ksyms) { 563 if (ksyms) {
700 sym = kernel_syms_search(&dd, ksyms[i]); 564 sym = kernel_syms_search(&dd, ksyms[i]);
701 if (sym) 565 if (sym)
@@ -707,7 +571,7 @@ static int do_dump(int argc, char **argv)
707 } 571 }
708 572
709 if (func_info) { 573 if (func_info) {
710 record = func_info + i * finfo_rec_size; 574 record = func_info + i * info->func_info_rec_size;
711 btf_dumper_type_only(btf, record->type_id, 575 btf_dumper_type_only(btf, record->type_id,
712 func_sig, 576 func_sig,
713 sizeof(func_sig)); 577 sizeof(func_sig));
@@ -744,49 +608,37 @@ static int do_dump(int argc, char **argv)
744 if (json_output) 608 if (json_output)
745 jsonw_end_array(json_wtr); 609 jsonw_end_array(json_wtr);
746 } else { 610 } else {
747 disasm_print_insn(buf, *member_len, opcodes, name, 611 disasm_print_insn(buf, member_len, opcodes, name,
748 disasm_opt, btf, NULL, 0, 0, false); 612 disasm_opt, btf, NULL, 0, 0, false);
749 } 613 }
750 } else if (visual) { 614 } else if (visual) {
751 if (json_output) 615 if (json_output)
752 jsonw_null(json_wtr); 616 jsonw_null(json_wtr);
753 else 617 else
754 dump_xlated_cfg(buf, *member_len); 618 dump_xlated_cfg(buf, member_len);
755 } else { 619 } else {
756 kernel_syms_load(&dd); 620 kernel_syms_load(&dd);
757 dd.nr_jited_ksyms = info.nr_jited_ksyms; 621 dd.nr_jited_ksyms = info->nr_jited_ksyms;
758 dd.jited_ksyms = (__u64 *) info.jited_ksyms; 622 dd.jited_ksyms = (__u64 *) info->jited_ksyms;
759 dd.btf = btf; 623 dd.btf = btf;
760 dd.func_info = func_info; 624 dd.func_info = func_info;
761 dd.finfo_rec_size = finfo_rec_size; 625 dd.finfo_rec_size = info->func_info_rec_size;
762 dd.prog_linfo = prog_linfo; 626 dd.prog_linfo = prog_linfo;
763 627
764 if (json_output) 628 if (json_output)
765 dump_xlated_json(&dd, buf, *member_len, opcodes, 629 dump_xlated_json(&dd, buf, member_len, opcodes,
766 linum); 630 linum);
767 else 631 else
768 dump_xlated_plain(&dd, buf, *member_len, opcodes, 632 dump_xlated_plain(&dd, buf, member_len, opcodes,
769 linum); 633 linum);
770 kernel_syms_destroy(&dd); 634 kernel_syms_destroy(&dd);
771 } 635 }
772 636
773 free(buf); 637 free(info_linear);
774 free(func_ksyms);
775 free(func_lens);
776 free(func_info);
777 free(linfo);
778 free(jited_linfo);
779 bpf_prog_linfo__free(prog_linfo);
780 return 0; 638 return 0;
781 639
782err_free: 640err_free:
783 free(buf); 641 free(info_linear);
784 free(func_ksyms);
785 free(func_lens);
786 free(func_info);
787 free(linfo);
788 free(jited_linfo);
789 bpf_prog_linfo__free(prog_linfo);
790 return -1; 642 return -1;
791} 643}
792 644