aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/libbpf.c
diff options
context:
space:
mode:
authorAndrii Nakryiko <andriin@fb.com>2019-06-17 15:26:54 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2019-06-17 18:10:40 -0400
commitdb48814bd2833ee231f48bd2030082369b88f9ef (patch)
treecca3be34591c388b5859afe0d29063591142809c /tools/lib/bpf/libbpf.c
parentbf82927125dd25003d76ed5541da704df21de57a (diff)
libbpf: identify maps by section index in addition to offset
To support maps to be defined in multiple sections, it's important to identify map not just by offset within its section, but section index as well. This patch adds tracking of section index. For global data, we record section index of corresponding .data/.bss/.rodata ELF section for uniformity, and thus don't need a special value of offset for those maps. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r--tools/lib/bpf/libbpf.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 88609dca4f7d..b1f3ab4b39b3 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -207,7 +207,8 @@ static const char * const libbpf_type_to_btf_name[] = {
207struct bpf_map { 207struct bpf_map {
208 int fd; 208 int fd;
209 char *name; 209 char *name;
210 size_t offset; 210 int sec_idx;
211 size_t sec_offset;
211 int map_ifindex; 212 int map_ifindex;
212 int inner_map_fd; 213 int inner_map_fd;
213 struct bpf_map_def def; 214 struct bpf_map_def def;
@@ -647,7 +648,9 @@ static int compare_bpf_map(const void *_a, const void *_b)
647 const struct bpf_map *a = _a; 648 const struct bpf_map *a = _a;
648 const struct bpf_map *b = _b; 649 const struct bpf_map *b = _b;
649 650
650 return a->offset - b->offset; 651 if (a->sec_idx != b->sec_idx)
652 return a->sec_idx - b->sec_idx;
653 return a->sec_offset - b->sec_offset;
651} 654}
652 655
653static bool bpf_map_type__is_map_in_map(enum bpf_map_type type) 656static bool bpf_map_type__is_map_in_map(enum bpf_map_type type)
@@ -800,7 +803,7 @@ static struct bpf_map *bpf_object__add_map(struct bpf_object *obj)
800 803
801static int 804static int
802bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type, 805bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type,
803 Elf_Data *data, void **data_buff) 806 int sec_idx, Elf_Data *data, void **data_buff)
804{ 807{
805 char map_name[BPF_OBJ_NAME_LEN]; 808 char map_name[BPF_OBJ_NAME_LEN];
806 struct bpf_map_def *def; 809 struct bpf_map_def *def;
@@ -811,7 +814,8 @@ bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type,
811 return PTR_ERR(map); 814 return PTR_ERR(map);
812 815
813 map->libbpf_type = type; 816 map->libbpf_type = type;
814 map->offset = ~(typeof(map->offset))0; 817 map->sec_idx = sec_idx;
818 map->sec_offset = 0;
815 snprintf(map_name, sizeof(map_name), "%.8s%.7s", obj->name, 819 snprintf(map_name, sizeof(map_name), "%.8s%.7s", obj->name,
816 libbpf_type_to_btf_name[type]); 820 libbpf_type_to_btf_name[type]);
817 map->name = strdup(map_name); 821 map->name = strdup(map_name);
@@ -819,6 +823,8 @@ bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type,
819 pr_warning("failed to alloc map name\n"); 823 pr_warning("failed to alloc map name\n");
820 return -ENOMEM; 824 return -ENOMEM;
821 } 825 }
826 pr_debug("map '%s' (global data): at sec_idx %d, offset %zu.\n",
827 map_name, map->sec_idx, map->sec_offset);
822 828
823 def = &map->def; 829 def = &map->def;
824 def->type = BPF_MAP_TYPE_ARRAY; 830 def->type = BPF_MAP_TYPE_ARRAY;
@@ -851,6 +857,7 @@ static int bpf_object__init_global_data_maps(struct bpf_object *obj)
851 */ 857 */
852 if (obj->efile.data_shndx >= 0) { 858 if (obj->efile.data_shndx >= 0) {
853 err = bpf_object__init_internal_map(obj, LIBBPF_MAP_DATA, 859 err = bpf_object__init_internal_map(obj, LIBBPF_MAP_DATA,
860 obj->efile.data_shndx,
854 obj->efile.data, 861 obj->efile.data,
855 &obj->sections.data); 862 &obj->sections.data);
856 if (err) 863 if (err)
@@ -858,6 +865,7 @@ static int bpf_object__init_global_data_maps(struct bpf_object *obj)
858 } 865 }
859 if (obj->efile.rodata_shndx >= 0) { 866 if (obj->efile.rodata_shndx >= 0) {
860 err = bpf_object__init_internal_map(obj, LIBBPF_MAP_RODATA, 867 err = bpf_object__init_internal_map(obj, LIBBPF_MAP_RODATA,
868 obj->efile.rodata_shndx,
861 obj->efile.rodata, 869 obj->efile.rodata,
862 &obj->sections.rodata); 870 &obj->sections.rodata);
863 if (err) 871 if (err)
@@ -865,6 +873,7 @@ static int bpf_object__init_global_data_maps(struct bpf_object *obj)
865 } 873 }
866 if (obj->efile.bss_shndx >= 0) { 874 if (obj->efile.bss_shndx >= 0) {
867 err = bpf_object__init_internal_map(obj, LIBBPF_MAP_BSS, 875 err = bpf_object__init_internal_map(obj, LIBBPF_MAP_BSS,
876 obj->efile.bss_shndx,
868 obj->efile.bss, NULL); 877 obj->efile.bss, NULL);
869 if (err) 878 if (err)
870 return err; 879 return err;
@@ -948,7 +957,10 @@ static int bpf_object__init_user_maps(struct bpf_object *obj, bool strict)
948 } 957 }
949 958
950 map->libbpf_type = LIBBPF_MAP_UNSPEC; 959 map->libbpf_type = LIBBPF_MAP_UNSPEC;
951 map->offset = sym.st_value; 960 map->sec_idx = sym.st_shndx;
961 map->sec_offset = sym.st_value;
962 pr_debug("map '%s' (legacy): at sec_idx %d, offset %zu.\n",
963 map_name, map->sec_idx, map->sec_offset);
952 if (sym.st_value + map_def_sz > data->d_size) { 964 if (sym.st_value + map_def_sz > data->d_size) {
953 pr_warning("corrupted maps section in %s: last map \"%s\" too small\n", 965 pr_warning("corrupted maps section in %s: last map \"%s\" too small\n",
954 obj->path, map_name); 966 obj->path, map_name);
@@ -1448,9 +1460,13 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
1448 if (maps[map_idx].libbpf_type != type) 1460 if (maps[map_idx].libbpf_type != type)
1449 continue; 1461 continue;
1450 if (type != LIBBPF_MAP_UNSPEC || 1462 if (type != LIBBPF_MAP_UNSPEC ||
1451 maps[map_idx].offset == sym.st_value) { 1463 (maps[map_idx].sec_idx == sym.st_shndx &&
1452 pr_debug("relocation: find map %zd (%s) for insn %u\n", 1464 maps[map_idx].sec_offset == sym.st_value)) {
1453 map_idx, maps[map_idx].name, insn_idx); 1465 pr_debug("relocation: found map %zd (%s, sec_idx %d, offset %zu) for insn %u\n",
1466 map_idx, maps[map_idx].name,
1467 maps[map_idx].sec_idx,
1468 maps[map_idx].sec_offset,
1469 insn_idx);
1454 break; 1470 break;
1455 } 1471 }
1456 } 1472 }
@@ -3468,13 +3484,7 @@ bpf_object__find_map_fd_by_name(struct bpf_object *obj, const char *name)
3468struct bpf_map * 3484struct bpf_map *
3469bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset) 3485bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset)
3470{ 3486{
3471 int i; 3487 return ERR_PTR(-ENOTSUP);
3472
3473 for (i = 0; i < obj->nr_maps; i++) {
3474 if (obj->maps[i].offset == offset)
3475 return &obj->maps[i];
3476 }
3477 return ERR_PTR(-ENOENT);
3478} 3488}
3479 3489
3480long libbpf_get_error(const void *ptr) 3490long libbpf_get_error(const void *ptr)