diff options
author | Song Liu <songliubraving@fb.com> | 2019-03-12 01:30:39 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-03-19 15:52:06 -0400 |
commit | cae73f2339231d61022769f09c94e4500e8ad47a (patch) | |
tree | 6783057d08de13b3b5a46985b1cbb865eff7a19c /tools/bpf/bpftool/prog.c | |
parent | 34be16466d4dc06f3d604dafbcdb3327b72e78da (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.c | 266 |
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 | ||
402 | static int do_dump(int argc, char **argv) | 402 | static 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 | ||
782 | err_free: | 640 | err_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 | ||