From: Wang Nan <wangnan0@huawei.com>
To: <ast@plumgrid.com>, <davem@davemloft.net>, <acme@kernel.org>,
<mingo@redhat.com>, <a.p.zijlstra@chello.nl>,
<masami.hiramatsu.pt@hitachi.com>, <jolsa@kernel.org>
Cc: <lizefan@kernel.org>, <linux-kernel@vger.kernel.org>,
<pi3orama@163.com>, <hekuang@huawei.com>
Subject: [RFC PATCH 05/22] perf bpf: open eBPF object file and do basic validation.
Date: Thu, 30 Apr 2015 10:52:28 +0000 [thread overview]
Message-ID: <1430391165-30267-6-git-send-email-wangnan0@huawei.com> (raw)
In-Reply-To: <1430391165-30267-1-git-send-email-wangnan0@huawei.com>
This patch adds basic 'struct bpf_obj' which will be used for eBPF
object files loading. eBPF object files are compiled by LLVM as ELF
format. In this patch, libelf is used to open those files, read EHDR
and do basic validation according to e_type and e_machine.
All elf related staffs are grouped together and reside in
'struct bpf_obj'. bpf_obj_clear_elf() is introduced to clear it.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
---
tools/perf/util/bpf-loader.c | 133 +++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/bpf-loader.h | 16 ++++++
2 files changed, 149 insertions(+)
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 84d3cc3..3eb7504 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -20,10 +20,143 @@
#include <linux/types.h>
#include <linux/bpf.h>
+static LIST_HEAD(bpf_obj_list);
+
+static struct bpf_obj *__bpf_obj_alloc(const char *path)
+{
+ struct bpf_obj *obj;
+
+ obj = calloc(1, sizeof(struct bpf_obj));
+ if (!obj) {
+ pr_err("bpf: alloc memory failed for %s\n", path);
+ return NULL;
+ }
+
+ obj->path = strdup(path);
+ if (!obj->path) {
+ pr_err("bpf: failed to strdup '%s'\n", path);
+ free(obj);
+ return NULL;
+ }
+ return obj;
+}
+
+static void bpf_obj_clear_elf(struct bpf_obj *obj)
+{
+ if (!obj_elf_valid(obj))
+ return;
+
+ if (obj->elf.elf) {
+ elf_end(obj->elf.elf);
+ obj->elf.elf = NULL;
+ }
+ if (obj->elf.fd >= 0) {
+ close(obj->elf.fd);
+ obj->elf.fd = -1;
+ }
+}
+
+static void bpf_obj_close(struct bpf_obj *obj)
+{
+ if (!obj)
+ return;
+
+ bpf_obj_clear_elf(obj);
+
+ if (obj->path)
+ free(obj->path);
+ free(obj);
+}
+
+static struct bpf_obj *bpf_obj_alloc(const char *path)
+{
+ struct bpf_obj *obj;
+
+ obj = __bpf_obj_alloc(path);
+ if (!obj)
+ goto out;
+
+ obj->elf.fd = -1;
+ return obj;
+out:
+ bpf_obj_close(obj);
+ return NULL;
+}
+
+static int bpf_obj_elf_init(struct bpf_obj *obj)
+{
+ int err = 0;
+ GElf_Ehdr *ep;
+
+ if (obj_elf_valid(obj)) {
+ pr_err("bpf: elf init: internal error\n");
+ return -EEXIST;
+ }
+
+ obj->elf.fd = open(obj->path, O_RDONLY);
+ if (obj->elf.fd < 0) {
+ pr_err("bpf: failed to open %s: %s\n", obj->path,
+ strerror(errno));
+ return -errno;
+ }
+
+ obj->elf.elf = elf_begin(obj->elf.fd,
+ PERF_ELF_C_READ_MMAP,
+ NULL);
+ if (!obj->elf.elf) {
+ pr_err("bpf: failed to open %s as ELF file\n",
+ obj->path);
+ err = -EINVAL;
+ goto errout;
+ }
+
+ if (!gelf_getehdr(obj->elf.elf, &obj->elf.ehdr)) {
+ pr_err("bpf: failed to get EHDR from %s\n",
+ obj->path);
+ err = -EINVAL;
+ goto errout;
+ }
+ ep = &obj->elf.ehdr;
+
+ if ((ep->e_type != ET_REL) || (ep->e_machine != 0)) {
+ pr_err("bpf: %s is not an eBPF object file\n",
+ obj->path);
+ err = -EINVAL;
+ goto errout;
+ }
+
+ return 0;
+errout:
+ bpf_obj_clear_elf(obj);
+ return err;
+}
+
int bpf__load(const char *path)
{
+ struct bpf_obj *obj;
+ int err;
+
pr_debug("bpf: loading %s\n", path);
+
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ pr_err("bpf: failed to init libelf for %s\n", path);
+ return -ENOTSUP;
+ }
+
+ obj = bpf_obj_alloc(path);
+ if (!obj) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if ((err = bpf_obj_elf_init(obj)))
+ goto out;
+
+ list_add(&obj->list, &bpf_obj_list);
return 0;
+out:
+ bpf_obj_close(obj);
+ return -1;
}
int bpf__run(void)
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 122b178..6a6651b 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -18,4 +18,20 @@
int bpf__load(const char *path);
int bpf__run(void);
+struct bpf_obj {
+ /* All bpf objs should be linked together. */
+ struct list_head list;
+ char *path;
+
+ /*
+ * Information when doing elf related work. Only valid if fd
+ * is valid.
+ */
+ struct {
+ int fd;
+ Elf *elf;
+ GElf_Ehdr ehdr;
+ } elf;
+};
+#define obj_elf_valid(o) ((o)->elf.fd >= 0)
#endif
--
1.8.3.4
next prev parent reply other threads:[~2015-04-30 11:02 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-30 10:52 [RFC PATCH 00/22] perf tools: introduce 'perf bpf' command to load eBPF programs Wang Nan
2015-04-30 10:52 ` [RFC PATCH 01/22] perf: probe: avoid segfault if passed with '' Wang Nan
2015-05-05 14:09 ` Masami Hiramatsu
2015-05-05 15:26 ` Arnaldo Carvalho de Melo
2015-05-05 16:33 ` Masami Hiramatsu
2015-04-30 10:52 ` [RFC PATCH 02/22] perf: bpf: prepare: add __aligned_u64 to types.h Wang Nan
2015-04-30 10:52 ` [RFC PATCH 03/22] perf: add bpf common operations Wang Nan
2015-04-30 10:52 ` [RFC PATCH 04/22] perf tools: Add new 'perf bpf' command Wang Nan
2015-05-11 6:28 ` Namhyung Kim
2015-04-30 10:52 ` Wang Nan [this message]
2015-04-30 10:52 ` [RFC PATCH 06/22] perf bpf: check swap according to EHDR Wang Nan
2015-04-30 10:52 ` [RFC PATCH 07/22] perf bpf: iterater over elf sections to collect information Wang Nan
2015-04-30 10:52 ` [RFC PATCH 08/22] perf bpf: collect version and license from ELF Wang Nan
2015-04-30 10:52 ` [RFC PATCH 09/22] perf bpf: collect map definitions Wang Nan
2015-05-11 6:32 ` Namhyung Kim
2015-04-30 10:52 ` [RFC PATCH 10/22] perf bpf: collect config section in object Wang Nan
2015-04-30 10:52 ` [RFC PATCH 11/22] perf bpf: collect symbol table in object files Wang Nan
2015-04-30 10:52 ` [RFC PATCH 12/22] perf bpf: collect bpf programs from " Wang Nan
2015-04-30 10:52 ` [RFC PATCH 13/22] perf bpf: collects relocation sections from object file Wang Nan
2015-04-30 10:52 ` [RFC PATCH 14/22] perf bpf: config eBPF programs based on their names Wang Nan
2015-04-30 10:52 ` [RFC PATCH 15/22] perf bpf: config eBPF programs using config section Wang Nan
2015-04-30 10:52 ` [RFC PATCH 16/22] perf bpf: create maps needed by object file Wang Nan
2015-04-30 10:52 ` [RFC PATCH 17/22] perf bpf: relocation programs Wang Nan
2015-04-30 10:52 ` [RFC PATCH 18/22] perf bpf: load eBPF programs into kernel Wang Nan
2015-04-30 10:52 ` [RFC PATCH 19/22] perf bpf: dump eBPF program before loading Wang Nan
2015-04-30 10:52 ` [RFC PATCH 20/22] perf bpf: clean elf memory after loading Wang Nan
2015-04-30 10:52 ` [RFC PATCH 21/22] perf bpf: probe at kprobe points Wang Nan
2015-05-05 16:34 ` Masami Hiramatsu
2015-05-06 2:36 ` Wang Nan
2015-04-30 10:52 ` [RFC PATCH 22/22] perf bpf: attaches eBPF program to perf fd Wang Nan
2015-05-01 4:37 ` [RFC PATCH 00/22] perf tools: introduce 'perf bpf' command to load eBPF programs Alexei Starovoitov
2015-05-01 11:06 ` Peter Zijlstra
2015-05-01 11:49 ` Ingo Molnar
2015-05-01 16:56 ` Alexei Starovoitov
2015-05-01 17:06 ` Ingo Molnar
2015-05-05 15:39 ` Arnaldo Carvalho de Melo
2015-05-02 7:19 ` Wang Nan
2015-05-05 3:02 ` Alexei Starovoitov
2015-05-05 4:41 ` Wang Nan
2015-05-05 5:49 ` Alexei Starovoitov
2015-05-05 6:14 ` Wang Nan
2015-05-06 4:46 ` Wang Nan
2015-05-06 4:56 ` Alexei Starovoitov
2015-05-06 5:00 ` Wang Nan
2015-05-01 7:16 ` Ingo Molnar
2015-05-05 21:52 ` Brendan Gregg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1430391165-30267-6-git-send-email-wangnan0@huawei.com \
--to=wangnan0@huawei.com \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@kernel.org \
--cc=ast@plumgrid.com \
--cc=davem@davemloft.net \
--cc=hekuang@huawei.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lizefan@kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@redhat.com \
--cc=pi3orama@163.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®