Skip to content

Commit

Permalink
tools lib bpf: Extract and collect map names from BPF object file
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Wang Nan authored and Arnaldo Carvalho de Melo committed Nov 28, 2015
1 parent 9d759a9 commit 561bbcc
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
65 changes: 62 additions & 3 deletions tools/lib/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ struct bpf_program {

struct bpf_map {
int fd;
char *name;
struct bpf_map_def def;
void *priv;
bpf_map_clear_priv_t clear_priv;
Expand Down Expand Up @@ -526,12 +527,46 @@ bpf_object__init_maps(struct bpf_object *obj, void *data,
return 0;
}

static void
bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)
{
int i;
Elf_Data *symbols = obj->efile.symbols;

if (!symbols || maps_shndx < 0)
return;

for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) {
GElf_Sym sym;
size_t map_idx;
const char *map_name;

if (!gelf_getsym(symbols, i, &sym))
continue;
if (sym.st_shndx != maps_shndx)
continue;

map_name = elf_strptr(obj->efile.elf,
obj->efile.ehdr.e_shstrndx,
sym.st_name);
map_idx = sym.st_value / sizeof(struct bpf_map_def);
if (map_idx >= obj->nr_maps) {
pr_warning("index of map \"%s\" is buggy: %zu > %zu\n",
map_name, map_idx, obj->nr_maps);
continue;
}
obj->maps[map_idx].name = strdup(map_name);
pr_debug("map %zu is \"%s\"\n", map_idx,
obj->maps[map_idx].name);
}
}

static int bpf_object__elf_collect(struct bpf_object *obj)
{
Elf *elf = obj->efile.elf;
GElf_Ehdr *ep = &obj->efile.ehdr;
Elf_Scn *scn = NULL;
int idx = 0, err = 0;
int idx = 0, err = 0, maps_shndx = -1;

/* Elf is corrupted/truncated, avoid calling elf_strptr. */
if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
Expand Down Expand Up @@ -581,10 +616,11 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
err = bpf_object__init_kversion(obj,
data->d_buf,
data->d_size);
else if (strcmp(name, "maps") == 0)
else if (strcmp(name, "maps") == 0) {
err = bpf_object__init_maps(obj, data->d_buf,
data->d_size);
else if (sh.sh_type == SHT_SYMTAB) {
maps_shndx = idx;
} else if (sh.sh_type == SHT_SYMTAB) {
if (obj->efile.symbols) {
pr_warning("bpf: multiple SYMTAB in %s\n",
obj->path);
Expand Down Expand Up @@ -625,6 +661,9 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
if (err)
goto out;
}

if (maps_shndx >= 0)
bpf_object__init_maps_name(obj, maps_shndx);
out:
return err;
}
Expand Down Expand Up @@ -1086,6 +1125,7 @@ void bpf_object__close(struct bpf_object *obj)
bpf_object__unload(obj);

for (i = 0; i < obj->nr_maps; i++) {
zfree(&obj->maps[i].name);
if (obj->maps[i].clear_priv)
obj->maps[i].clear_priv(&obj->maps[i],
obj->maps[i].priv);
Expand Down Expand Up @@ -1266,6 +1306,13 @@ int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef)
return 0;
}

const char *bpf_map__get_name(struct bpf_map *map)
{
if (!map)
return NULL;
return map->name;
}

int bpf_map__set_private(struct bpf_map *map, void *priv,
bpf_map_clear_priv_t clear_priv)
{
Expand Down Expand Up @@ -1318,3 +1365,15 @@ bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
return NULL;
return &obj->maps[idx];
}

struct bpf_map *
bpf_object__get_map_by_name(struct bpf_object *obj, const char *name)
{
struct bpf_map *pos;

bpf_map__for_each(pos, obj) {
if (strcmp(pos->name, name) == 0)
return pos;
}
return NULL;
}
3 changes: 3 additions & 0 deletions tools/lib/bpf/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ struct bpf_map_def {
* it is not a uapi header so no need to consider name clash.
*/
struct bpf_map;
struct bpf_map *
bpf_object__get_map_by_name(struct bpf_object *obj, const char *name);

struct bpf_map *
bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
Expand All @@ -180,6 +182,7 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj);

int bpf_map__get_fd(struct bpf_map *map);
int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef);
const char *bpf_map__get_name(struct bpf_map *map);

typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
int bpf_map__set_private(struct bpf_map *map, void *priv,
Expand Down

0 comments on commit 561bbcc

Please sign in to comment.