bpf tools: Iterate over ELF sections to collect information
bpf_obj_elf_collect() is introduced to iterate over each elf sections to collection information in eBPF object files. This function will futher enhanced to collect license, kernel version, programs, configs and map information. Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: David Ahern <dsahern@gmail.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kaixu Xia <xiakaixu@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1435716878-189507-9-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
committed by
Arnaldo Carvalho de Melo
parent
cc4228d57c
commit
296036653a
@@ -220,6 +220,57 @@ mismatch:
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Elf is corrupted/truncated, avoid calling elf_strptr. */
|
||||||
|
if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
|
||||||
|
pr_warning("failed to get e_shstrndx from %s\n",
|
||||||
|
obj->path);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((scn = elf_nextscn(elf, scn)) != NULL) {
|
||||||
|
char *name;
|
||||||
|
GElf_Shdr sh;
|
||||||
|
Elf_Data *data;
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
if (gelf_getshdr(scn, &sh) != &sh) {
|
||||||
|
pr_warning("failed to get section header from %s\n",
|
||||||
|
obj->path);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = elf_strptr(elf, ep->e_shstrndx, sh.sh_name);
|
||||||
|
if (!name) {
|
||||||
|
pr_warning("failed to get section name from %s\n",
|
||||||
|
obj->path);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = elf_getdata(scn, 0);
|
||||||
|
if (!data) {
|
||||||
|
pr_warning("failed to get section data from %s(%s)\n",
|
||||||
|
name, obj->path);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
pr_debug("section %s, size %ld, link %d, flags %lx, type=%d\n",
|
||||||
|
name, (unsigned long)data->d_size,
|
||||||
|
(int)sh.sh_link, (unsigned long)sh.sh_flags,
|
||||||
|
(int)sh.sh_type);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static struct bpf_object *
|
static struct bpf_object *
|
||||||
__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
|
__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
|
||||||
{
|
{
|
||||||
@@ -238,6 +289,8 @@ __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
|
|||||||
goto out;
|
goto out;
|
||||||
if (bpf_object__check_endianness(obj))
|
if (bpf_object__check_endianness(obj))
|
||||||
goto out;
|
goto out;
|
||||||
|
if (bpf_object__elf_collect(obj))
|
||||||
|
goto out;
|
||||||
|
|
||||||
bpf_object__elf_finish(obj);
|
bpf_object__elf_finish(obj);
|
||||||
return obj;
|
return obj;
|
||||||
|
|||||||
Reference in New Issue
Block a user