diff options
Diffstat (limited to 'tools/bpf/bpftool/prog.c')
-rw-r--r-- | tools/bpf/bpftool/prog.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index e05ab58d39e2..39b88e760367 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -422,7 +422,9 @@ static int do_dump(int argc, char **argv) | |||
422 | { | 422 | { |
423 | unsigned long *func_ksyms = NULL; | 423 | unsigned long *func_ksyms = NULL; |
424 | struct bpf_prog_info info = {}; | 424 | struct bpf_prog_info info = {}; |
425 | unsigned int *func_lens = NULL; | ||
425 | unsigned int nr_func_ksyms; | 426 | unsigned int nr_func_ksyms; |
427 | unsigned int nr_func_lens; | ||
426 | struct dump_data dd = {}; | 428 | struct dump_data dd = {}; |
427 | __u32 len = sizeof(info); | 429 | __u32 len = sizeof(info); |
428 | unsigned int buf_size; | 430 | unsigned int buf_size; |
@@ -508,12 +510,24 @@ static int do_dump(int argc, char **argv) | |||
508 | } | 510 | } |
509 | } | 511 | } |
510 | 512 | ||
513 | nr_func_lens = info.nr_jited_func_lens; | ||
514 | if (nr_func_lens) { | ||
515 | func_lens = malloc(nr_func_lens * sizeof(__u32)); | ||
516 | if (!func_lens) { | ||
517 | p_err("mem alloc failed"); | ||
518 | close(fd); | ||
519 | goto err_free; | ||
520 | } | ||
521 | } | ||
522 | |||
511 | memset(&info, 0, sizeof(info)); | 523 | memset(&info, 0, sizeof(info)); |
512 | 524 | ||
513 | *member_ptr = ptr_to_u64(buf); | 525 | *member_ptr = ptr_to_u64(buf); |
514 | *member_len = buf_size; | 526 | *member_len = buf_size; |
515 | info.jited_ksyms = ptr_to_u64(func_ksyms); | 527 | info.jited_ksyms = ptr_to_u64(func_ksyms); |
516 | info.nr_jited_ksyms = nr_func_ksyms; | 528 | info.nr_jited_ksyms = nr_func_ksyms; |
529 | info.jited_func_lens = ptr_to_u64(func_lens); | ||
530 | info.nr_jited_func_lens = nr_func_lens; | ||
517 | 531 | ||
518 | err = bpf_obj_get_info_by_fd(fd, &info, &len); | 532 | err = bpf_obj_get_info_by_fd(fd, &info, &len); |
519 | close(fd); | 533 | close(fd); |
@@ -532,6 +546,11 @@ static int do_dump(int argc, char **argv) | |||
532 | goto err_free; | 546 | goto err_free; |
533 | } | 547 | } |
534 | 548 | ||
549 | if (info.nr_jited_func_lens > nr_func_lens) { | ||
550 | p_err("too many values returned"); | ||
551 | goto err_free; | ||
552 | } | ||
553 | |||
535 | if ((member_len == &info.jited_prog_len && | 554 | if ((member_len == &info.jited_prog_len && |
536 | info.jited_prog_insns == 0) || | 555 | info.jited_prog_insns == 0) || |
537 | (member_len == &info.xlated_prog_len && | 556 | (member_len == &info.xlated_prog_len && |
@@ -569,7 +588,57 @@ static int do_dump(int argc, char **argv) | |||
569 | goto err_free; | 588 | goto err_free; |
570 | } | 589 | } |
571 | 590 | ||
572 | disasm_print_insn(buf, *member_len, opcodes, name); | 591 | if (info.nr_jited_func_lens && info.jited_func_lens) { |
592 | struct kernel_sym *sym = NULL; | ||
593 | char sym_name[SYM_MAX_NAME]; | ||
594 | unsigned char *img = buf; | ||
595 | __u64 *ksyms = NULL; | ||
596 | __u32 *lens; | ||
597 | __u32 i; | ||
598 | |||
599 | if (info.nr_jited_ksyms) { | ||
600 | kernel_syms_load(&dd); | ||
601 | ksyms = (__u64 *) info.jited_ksyms; | ||
602 | } | ||
603 | |||
604 | if (json_output) | ||
605 | jsonw_start_array(json_wtr); | ||
606 | |||
607 | lens = (__u32 *) info.jited_func_lens; | ||
608 | for (i = 0; i < info.nr_jited_func_lens; i++) { | ||
609 | if (ksyms) { | ||
610 | sym = kernel_syms_search(&dd, ksyms[i]); | ||
611 | if (sym) | ||
612 | sprintf(sym_name, "%s", sym->name); | ||
613 | else | ||
614 | sprintf(sym_name, "0x%016llx", ksyms[i]); | ||
615 | } else { | ||
616 | strcpy(sym_name, "unknown"); | ||
617 | } | ||
618 | |||
619 | if (json_output) { | ||
620 | jsonw_start_object(json_wtr); | ||
621 | jsonw_name(json_wtr, "name"); | ||
622 | jsonw_string(json_wtr, sym_name); | ||
623 | jsonw_name(json_wtr, "insns"); | ||
624 | } else { | ||
625 | printf("%s:\n", sym_name); | ||
626 | } | ||
627 | |||
628 | disasm_print_insn(img, lens[i], opcodes, name); | ||
629 | img += lens[i]; | ||
630 | |||
631 | if (json_output) | ||
632 | jsonw_end_object(json_wtr); | ||
633 | else | ||
634 | printf("\n"); | ||
635 | } | ||
636 | |||
637 | if (json_output) | ||
638 | jsonw_end_array(json_wtr); | ||
639 | } else { | ||
640 | disasm_print_insn(buf, *member_len, opcodes, name); | ||
641 | } | ||
573 | } else if (visual) { | 642 | } else if (visual) { |
574 | if (json_output) | 643 | if (json_output) |
575 | jsonw_null(json_wtr); | 644 | jsonw_null(json_wtr); |
@@ -589,11 +658,13 @@ static int do_dump(int argc, char **argv) | |||
589 | 658 | ||
590 | free(buf); | 659 | free(buf); |
591 | free(func_ksyms); | 660 | free(func_ksyms); |
661 | free(func_lens); | ||
592 | return 0; | 662 | return 0; |
593 | 663 | ||
594 | err_free: | 664 | err_free: |
595 | free(buf); | 665 | free(buf); |
596 | free(func_ksyms); | 666 | free(func_ksyms); |
667 | free(func_lens); | ||
597 | return -1; | 668 | return -1; |
598 | } | 669 | } |
599 | 670 | ||