Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools lib bpf: Extract and collect map names from BPF object file

This patch collects name of maps in BPF object files and saves them into
'maps' field in 'struct bpf_object'. 'bpf_object__get_map_by_name' is
introduced to retrive fd and definitions of a map through its name.

Signed-off-by: He Kuang <hekuang@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: He Kuang <hekuang@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1448614067-197576-3-git-send-email-wangnan0@huawei.com
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Wang Nan and committed by
Arnaldo Carvalho de Melo
561bbcca 9d759a9b

+65 -3
+62 -3
tools/lib/bpf/libbpf.c
··· 165 165 166 166 struct bpf_map { 167 167 int fd; 168 + char *name; 168 169 struct bpf_map_def def; 169 170 void *priv; 170 171 bpf_map_clear_priv_t clear_priv; ··· 527 526 return 0; 528 527 } 529 528 529 + static void 530 + bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx) 531 + { 532 + int i; 533 + Elf_Data *symbols = obj->efile.symbols; 534 + 535 + if (!symbols || maps_shndx < 0) 536 + return; 537 + 538 + for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) { 539 + GElf_Sym sym; 540 + size_t map_idx; 541 + const char *map_name; 542 + 543 + if (!gelf_getsym(symbols, i, &sym)) 544 + continue; 545 + if (sym.st_shndx != maps_shndx) 546 + continue; 547 + 548 + map_name = elf_strptr(obj->efile.elf, 549 + obj->efile.ehdr.e_shstrndx, 550 + sym.st_name); 551 + map_idx = sym.st_value / sizeof(struct bpf_map_def); 552 + if (map_idx >= obj->nr_maps) { 553 + pr_warning("index of map \"%s\" is buggy: %zu > %zu\n", 554 + map_name, map_idx, obj->nr_maps); 555 + continue; 556 + } 557 + obj->maps[map_idx].name = strdup(map_name); 558 + pr_debug("map %zu is \"%s\"\n", map_idx, 559 + obj->maps[map_idx].name); 560 + } 561 + } 562 + 530 563 static int bpf_object__elf_collect(struct bpf_object *obj) 531 564 { 532 565 Elf *elf = obj->efile.elf; 533 566 GElf_Ehdr *ep = &obj->efile.ehdr; 534 567 Elf_Scn *scn = NULL; 535 - int idx = 0, err = 0; 568 + int idx = 0, err = 0, maps_shndx = -1; 536 569 537 570 /* Elf is corrupted/truncated, avoid calling elf_strptr. */ 538 571 if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) { ··· 616 581 err = bpf_object__init_kversion(obj, 617 582 data->d_buf, 618 583 data->d_size); 619 - else if (strcmp(name, "maps") == 0) 584 + else if (strcmp(name, "maps") == 0) { 620 585 err = bpf_object__init_maps(obj, data->d_buf, 621 586 data->d_size); 622 - else if (sh.sh_type == SHT_SYMTAB) { 587 + maps_shndx = idx; 588 + } else if (sh.sh_type == SHT_SYMTAB) { 623 589 if (obj->efile.symbols) { 624 590 pr_warning("bpf: multiple SYMTAB in %s\n", 625 591 obj->path); ··· 661 625 if (err) 662 626 goto out; 663 627 } 628 + 629 + if (maps_shndx >= 0) 630 + bpf_object__init_maps_name(obj, maps_shndx); 664 631 out: 665 632 return err; 666 633 } ··· 1125 1086 bpf_object__unload(obj); 1126 1087 1127 1088 for (i = 0; i < obj->nr_maps; i++) { 1089 + zfree(&obj->maps[i].name); 1128 1090 if (obj->maps[i].clear_priv) 1129 1091 obj->maps[i].clear_priv(&obj->maps[i], 1130 1092 obj->maps[i].priv); ··· 1306 1266 return 0; 1307 1267 } 1308 1268 1269 + const char *bpf_map__get_name(struct bpf_map *map) 1270 + { 1271 + if (!map) 1272 + return NULL; 1273 + return map->name; 1274 + } 1275 + 1309 1276 int bpf_map__set_private(struct bpf_map *map, void *priv, 1310 1277 bpf_map_clear_priv_t clear_priv) 1311 1278 { ··· 1364 1317 if (idx >= obj->nr_maps) 1365 1318 return NULL; 1366 1319 return &obj->maps[idx]; 1320 + } 1321 + 1322 + struct bpf_map * 1323 + bpf_object__get_map_by_name(struct bpf_object *obj, const char *name) 1324 + { 1325 + struct bpf_map *pos; 1326 + 1327 + bpf_map__for_each(pos, obj) { 1328 + if (strcmp(pos->name, name) == 0) 1329 + return pos; 1330 + } 1331 + return NULL; 1367 1332 }
+3
tools/lib/bpf/libbpf.h
··· 170 170 * it is not a uapi header so no need to consider name clash. 171 171 */ 172 172 struct bpf_map; 173 + struct bpf_map * 174 + bpf_object__get_map_by_name(struct bpf_object *obj, const char *name); 173 175 174 176 struct bpf_map * 175 177 bpf_map__next(struct bpf_map *map, struct bpf_object *obj); ··· 182 180 183 181 int bpf_map__get_fd(struct bpf_map *map); 184 182 int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef); 183 + const char *bpf_map__get_name(struct bpf_map *map); 185 184 186 185 typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); 187 186 int bpf_map__set_private(struct bpf_map *map, void *priv,