Generate 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/perf/util/bpf-loader.c | 66 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index c646ca4..8c746ef 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -900,6 +900,69 @@ bpf_perf_prog_load(struct bpf_obj *obj, struct 
bpf_perf_prog *prog)
        return 0;
 }
 
+#ifdef HAVE_DWARF_SUPPORT
+#if 0
+static void show_bpf_insn(char *buf, int len)
+{
+       int i, j;
+       char *ptr = buf;
+
+       for (i = 0; i < len; i++) {
+               pr_debug("[%03d] ", i);
+               for (j = 0; j < 8; j++)
+                       pr_debug("0x%02x, ", (*ptr++) & 0xff);
+               pr_debug("\\\n");
+       }
+}
+#endif
+
+static int bpf_obj_prologue(struct bpf_obj *obj)
+{
+       struct bpf_perf_prog *prog;
+       int ret = -1;
+
+       list_for_each_entry(prog, &obj->progs_list, list) {
+               int count;
+               char *result;
+               int new_count;
+
+               if (!prog->pev)
+                       continue;
+
+               ret = get_bpf_prologue(prog->pev, &result, &count);
+               if (ret)
+                       return ret;
+
+               if (count > 0) {
+                       bpf_dump_prog((struct bpf_insn *)result, count);
+
+                       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;
+               } else {
+                       pr_debug("bpf: no prologue generated\n");
+               }
+       }
+
+       return ret;
+}
+#else
+static int bpf_progs_prologue(struct bpf_obj *obj __maybe_unused)
+{
+       return 0;
+}
+#endif
+
 static int
 bpf_obj_load_progs(struct bpf_obj *obj)
 {
@@ -946,6 +1009,9 @@ int bpf__load(const char *path)
                goto out;
        if ((err = bpf_obj_relocate(obj)))
                goto out;
+       err = bpf_obj_prologue(obj);
+       if (err)
+               goto out;
        if ((err = bpf_obj_load_progs(obj)))
                goto out;
 
-- 
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