Combine bpf prologue before attaching bpf progs to perf probe event. If
prologue is generated, it will be pasted in front of the original bpf
prog.

Signed-off-by: He Kuang <heku...@huawei.com>
---
 tools/lib/bpf/libbpf.c       | 27 +++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h       |  2 ++
 tools/perf/util/bpf-loader.c | 27 +++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 89c725a..c0b792f 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1087,3 +1087,30 @@ int bpf_prog_get_fd(struct bpf_prog_handler *handler, 
int *pfd)
        *pfd = prog->fd;
        return 0;
 }
+
+int bpf_obj_prologue(struct bpf_prog_handler *handler, char *result, int size)
+{
+       struct bpf_program *prog;
+       int new_count;
+       int count = size / sizeof(struct bpf_insn);
+
+       prog = handler_to_prog(handler);
+       if (!prog)
+               return -EINVAL;
+
+       new_count = prog->insns_cnt + count;
+       result = realloc(result,
+                       new_count * sizeof(struct bpf_insn));
+       if (!result)
+               return -ENOMEM;
+
+       memcpy(result + count * sizeof(struct bpf_insn),
+               prog->insns,
+               prog->insns_cnt * sizeof(struct bpf_insn));
+
+       free(prog->insns);
+       prog->insns = (struct bpf_insn *)result;
+       prog->insns_cnt = new_count;
+
+       return 0;
+}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 9d6d4f7..7df58fd 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -53,6 +53,8 @@ int bpf_prog_get_title(struct bpf_prog_handler *handler,
 
 int bpf_prog_get_fd(struct bpf_prog_handler *handler, int *pfd);
 
+int bpf_obj_prologue(struct bpf_prog_handler *handler, char *result, int 
count);
+
 /*
  * packed attribute is unnecessary for 'bpf_map_def'.
  */
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index b793c69..3f93d04 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -168,6 +168,31 @@ void bpf_clear(void)
                bpf_close_object(params.objects[i]);
 }
 
+static int bpf_prologue(void)
+{
+       int i, ret;
+
+       for (i = 0; i < (int)params.nr_progs; i++) {
+               struct bpf_prog_handler *prog =
+                       params.progs[i].prog;
+               struct perf_probe_event *pevent =
+                       params.progs[i].pevent;
+               int count;
+               char *result;
+
+               ret = get_bpf_prologue(pevent, &result, &count);
+               if (ret)
+                       return ret;
+
+               if (count > 0)
+                       ret = bpf_obj_prologue(prog, result, count);
+               else
+                       pr_debug("bpf: no prologue generated\n");
+       }
+
+       return ret;
+}
+
 static bool is_probing = false;
 
 int bpf_unprobe(void)
@@ -220,6 +245,8 @@ int bpf_load(void)
        size_t i;
        int err;
 
+       bpf_prologue();
+
        for (i = 0; i < params.nr_objects; i++) {
                err = bpf_load_object(params.objects[i]);
                if (err) {
-- 
1.8.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to