aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/bpf')
-rw-r--r--tools/lib/bpf/btf.c102
-rw-r--r--tools/lib/bpf/btf.h2
-rw-r--r--tools/lib/bpf/libbpf.map1
3 files changed, 57 insertions, 48 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 4fba0aa989df..f6b724ed1bdd 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -42,9 +42,8 @@ struct btf {
42 42
43struct btf_ext_info { 43struct btf_ext_info {
44 /* 44 /*
45 * info points to a deep copy of the individual info section 45 * info points to the individual info section (e.g. func_info and
46 * (e.g. func_info and line_info) from the .BTF.ext. 46 * line_info) from the .BTF.ext. It does not include the __u32 rec_size.
47 * It does not include the __u32 rec_size.
48 */ 47 */
49 void *info; 48 void *info;
50 __u32 rec_size; 49 __u32 rec_size;
@@ -52,8 +51,13 @@ struct btf_ext_info {
52}; 51};
53 52
54struct btf_ext { 53struct btf_ext {
54 union {
55 struct btf_ext_header *hdr;
56 void *data;
57 };
55 struct btf_ext_info func_info; 58 struct btf_ext_info func_info;
56 struct btf_ext_info line_info; 59 struct btf_ext_info line_info;
60 __u32 data_size;
57}; 61};
58 62
59struct btf_ext_info_sec { 63struct btf_ext_info_sec {
@@ -596,7 +600,7 @@ int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
596 return 0; 600 return 0;
597} 601}
598 602
599struct btf_ext_sec_copy_param { 603struct btf_ext_sec_setup_param {
600 __u32 off; 604 __u32 off;
601 __u32 len; 605 __u32 len;
602 __u32 min_rec_size; 606 __u32 min_rec_size;
@@ -604,20 +608,14 @@ struct btf_ext_sec_copy_param {
604 const char *desc; 608 const char *desc;
605}; 609};
606 610
607static int btf_ext_copy_info(struct btf_ext *btf_ext, 611static int btf_ext_setup_info(struct btf_ext *btf_ext,
608 __u8 *data, __u32 data_size, 612 struct btf_ext_sec_setup_param *ext_sec)
609 struct btf_ext_sec_copy_param *ext_sec)
610{ 613{
611 const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
612 const struct btf_ext_info_sec *sinfo; 614 const struct btf_ext_info_sec *sinfo;
613 struct btf_ext_info *ext_info; 615 struct btf_ext_info *ext_info;
614 __u32 info_left, record_size; 616 __u32 info_left, record_size;
615 /* The start of the info sec (including the __u32 record_size). */ 617 /* The start of the info sec (including the __u32 record_size). */
616 const void *info; 618 void *info;
617
618 /* data and data_size do not include btf_ext_header from now on */
619 data = data + hdr->hdr_len;
620 data_size -= hdr->hdr_len;
621 619
622 if (ext_sec->off & 0x03) { 620 if (ext_sec->off & 0x03) {
623 pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n", 621 pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n",
@@ -625,16 +623,15 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
625 return -EINVAL; 623 return -EINVAL;
626 } 624 }
627 625
628 if (data_size < ext_sec->off || 626 info = btf_ext->data + btf_ext->hdr->hdr_len + ext_sec->off;
629 ext_sec->len > data_size - ext_sec->off) { 627 info_left = ext_sec->len;
628
629 if (btf_ext->data + btf_ext->data_size < info + ext_sec->len) {
630 pr_debug("%s section (off:%u len:%u) is beyond the end of the ELF section .BTF.ext\n", 630 pr_debug("%s section (off:%u len:%u) is beyond the end of the ELF section .BTF.ext\n",
631 ext_sec->desc, ext_sec->off, ext_sec->len); 631 ext_sec->desc, ext_sec->off, ext_sec->len);
632 return -EINVAL; 632 return -EINVAL;
633 } 633 }
634 634
635 info = data + ext_sec->off;
636 info_left = ext_sec->len;
637
638 /* At least a record size */ 635 /* At least a record size */
639 if (info_left < sizeof(__u32)) { 636 if (info_left < sizeof(__u32)) {
640 pr_debug(".BTF.ext %s record size not found\n", ext_sec->desc); 637 pr_debug(".BTF.ext %s record size not found\n", ext_sec->desc);
@@ -646,7 +643,7 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
646 if (record_size < ext_sec->min_rec_size || 643 if (record_size < ext_sec->min_rec_size ||
647 record_size & 0x03) { 644 record_size & 0x03) {
648 pr_debug("%s section in .BTF.ext has invalid record size %u\n", 645 pr_debug("%s section in .BTF.ext has invalid record size %u\n",
649 ext_sec->desc, record_size); 646 ext_sec->desc, record_size);
650 return -EINVAL; 647 return -EINVAL;
651 } 648 }
652 649
@@ -692,42 +689,35 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
692 ext_info = ext_sec->ext_info; 689 ext_info = ext_sec->ext_info;
693 ext_info->len = ext_sec->len - sizeof(__u32); 690 ext_info->len = ext_sec->len - sizeof(__u32);
694 ext_info->rec_size = record_size; 691 ext_info->rec_size = record_size;
695 ext_info->info = malloc(ext_info->len); 692 ext_info->info = info + sizeof(__u32);
696 if (!ext_info->info)
697 return -ENOMEM;
698 memcpy(ext_info->info, info + sizeof(__u32), ext_info->len);
699 693
700 return 0; 694 return 0;
701} 695}
702 696
703static int btf_ext_copy_func_info(struct btf_ext *btf_ext, 697static int btf_ext_setup_func_info(struct btf_ext *btf_ext)
704 __u8 *data, __u32 data_size)
705{ 698{
706 const struct btf_ext_header *hdr = (struct btf_ext_header *)data; 699 struct btf_ext_sec_setup_param param = {
707 struct btf_ext_sec_copy_param param = { 700 .off = btf_ext->hdr->func_info_off,
708 .off = hdr->func_info_off, 701 .len = btf_ext->hdr->func_info_len,
709 .len = hdr->func_info_len,
710 .min_rec_size = sizeof(struct bpf_func_info_min), 702 .min_rec_size = sizeof(struct bpf_func_info_min),
711 .ext_info = &btf_ext->func_info, 703 .ext_info = &btf_ext->func_info,
712 .desc = "func_info" 704 .desc = "func_info"
713 }; 705 };
714 706
715 return btf_ext_copy_info(btf_ext, data, data_size, &param); 707 return btf_ext_setup_info(btf_ext, &param);
716} 708}
717 709
718static int btf_ext_copy_line_info(struct btf_ext *btf_ext, 710static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
719 __u8 *data, __u32 data_size)
720{ 711{
721 const struct btf_ext_header *hdr = (struct btf_ext_header *)data; 712 struct btf_ext_sec_setup_param param = {
722 struct btf_ext_sec_copy_param param = { 713 .off = btf_ext->hdr->line_info_off,
723 .off = hdr->line_info_off, 714 .len = btf_ext->hdr->line_info_len,
724 .len = hdr->line_info_len,
725 .min_rec_size = sizeof(struct bpf_line_info_min), 715 .min_rec_size = sizeof(struct bpf_line_info_min),
726 .ext_info = &btf_ext->line_info, 716 .ext_info = &btf_ext->line_info,
727 .desc = "line_info", 717 .desc = "line_info",
728 }; 718 };
729 719
730 return btf_ext_copy_info(btf_ext, data, data_size, &param); 720 return btf_ext_setup_info(btf_ext, &param);
731} 721}
732 722
733static int btf_ext_parse_hdr(__u8 *data, __u32 data_size) 723static int btf_ext_parse_hdr(__u8 *data, __u32 data_size)
@@ -767,9 +757,7 @@ void btf_ext__free(struct btf_ext *btf_ext)
767{ 757{
768 if (!btf_ext) 758 if (!btf_ext)
769 return; 759 return;
770 760 free(btf_ext->data);
771 free(btf_ext->func_info.info);
772 free(btf_ext->line_info.info);
773 free(btf_ext); 761 free(btf_ext);
774} 762}
775 763
@@ -786,13 +774,23 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
786 if (!btf_ext) 774 if (!btf_ext)
787 return ERR_PTR(-ENOMEM); 775 return ERR_PTR(-ENOMEM);
788 776
789 err = btf_ext_copy_func_info(btf_ext, data, size); 777 btf_ext->data_size = size;
790 if (err) { 778 btf_ext->data = malloc(size);
791 btf_ext__free(btf_ext); 779 if (!btf_ext->data) {
792 return ERR_PTR(err); 780 err = -ENOMEM;
781 goto done;
793 } 782 }
783 memcpy(btf_ext->data, data, size);
784
785 err = btf_ext_setup_func_info(btf_ext);
786 if (err)
787 goto done;
794 788
795 err = btf_ext_copy_line_info(btf_ext, data, size); 789 err = btf_ext_setup_line_info(btf_ext);
790 if (err)
791 goto done;
792
793done:
796 if (err) { 794 if (err) {
797 btf_ext__free(btf_ext); 795 btf_ext__free(btf_ext);
798 return ERR_PTR(err); 796 return ERR_PTR(err);
@@ -801,6 +799,12 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
801 return btf_ext; 799 return btf_ext;
802} 800}
803 801
802const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size)
803{
804 *size = btf_ext->data_size;
805 return btf_ext->data;
806}
807
804static int btf_ext_reloc_info(const struct btf *btf, 808static int btf_ext_reloc_info(const struct btf *btf,
805 const struct btf_ext_info *ext_info, 809 const struct btf_ext_info *ext_info,
806 const char *sec_name, __u32 insns_cnt, 810 const char *sec_name, __u32 insns_cnt,
@@ -849,7 +853,8 @@ static int btf_ext_reloc_info(const struct btf *btf,
849 return -ENOENT; 853 return -ENOENT;
850} 854}
851 855
852int btf_ext__reloc_func_info(const struct btf *btf, const struct btf_ext *btf_ext, 856int btf_ext__reloc_func_info(const struct btf *btf,
857 const struct btf_ext *btf_ext,
853 const char *sec_name, __u32 insns_cnt, 858 const char *sec_name, __u32 insns_cnt,
854 void **func_info, __u32 *cnt) 859 void **func_info, __u32 *cnt)
855{ 860{
@@ -857,7 +862,8 @@ int btf_ext__reloc_func_info(const struct btf *btf, const struct btf_ext *btf_ex
857 insns_cnt, func_info, cnt); 862 insns_cnt, func_info, cnt);
858} 863}
859 864
860int btf_ext__reloc_line_info(const struct btf *btf, const struct btf_ext *btf_ext, 865int btf_ext__reloc_line_info(const struct btf *btf,
866 const struct btf_ext *btf_ext,
861 const char *sec_name, __u32 insns_cnt, 867 const char *sec_name, __u32 insns_cnt,
862 void **line_info, __u32 *cnt) 868 void **line_info, __u32 *cnt)
863{ 869{
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 10fe412461fe..0306b54d54eb 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -78,6 +78,8 @@ LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
78 78
79LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size); 79LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size);
80LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext); 80LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext);
81LIBBPF_API const void *btf_ext__get_raw_data(const struct btf_ext* btf_ext,
82 __u32 *size);
81LIBBPF_API int btf_ext__reloc_func_info(const struct btf *btf, 83LIBBPF_API int btf_ext__reloc_func_info(const struct btf *btf,
82 const struct btf_ext *btf_ext, 84 const struct btf_ext *btf_ext,
83 const char *sec_name, __u32 insns_cnt, 85 const char *sec_name, __u32 insns_cnt,
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 9e10467f8cbb..eb78c7c261d9 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -141,6 +141,7 @@ LIBBPF_0.0.2 {
141 btf__load; 141 btf__load;
142 btf_ext__free; 142 btf_ext__free;
143 btf_ext__func_info_rec_size; 143 btf_ext__func_info_rec_size;
144 btf_ext__get_raw_data;
144 btf_ext__line_info_rec_size; 145 btf_ext__line_info_rec_size;
145 btf_ext__new; 146 btf_ext__new;
146 btf_ext__reloc_func_info; 147 btf_ext__reloc_func_info;