After gethered all vars represented in trace_probe_arg, we can now use
functions in libbpf to generate the args prologue.

Signed-off-by: He Kuang <heku...@huawei.com>
---
 tools/perf/util/probe-finder.c | 83 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 6785eab..455ff0f 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1242,6 +1242,67 @@ end:
        return ret;
 }
 
+/*
+ * Convert args to bpf prologue
+ * 1) First pass for calculating the new program length:
+ *   synthesize_probe_bpf(arg, nargs, NULL, &new_len);
+ *
+ * 2) 2nd pass do the actually convert
+ *   new_prog = malloc(sizeof(struct bpf_insn) * new_len);
+ *   synthesize_probe_bpf(arg, nargs, new_prog, &new_len);
+ */
+static int synthesize_probe_bpf(struct probe_trace_arg *arg,
+                               int nargs,
+                               char *new_prog,
+                               int *new_len)
+{
+       int i;
+       char *new_insn = new_prog;
+
+       if (nargs == 0) {
+               *new_len = 0;
+               return 0;
+       }
+
+       new_insn += bpf_prologue_begin(new_prog);
+       /* Find each argument */
+       for (i = 0; i < nargs; i++) {
+               struct probe_trace_arg_ref *ref = arg[i].ref;
+               unsigned int regn = arg[i].regn;
+
+               /* Print argument value */
+               if (arg[i].value[0] == '@' && ref) {
+                       /* TODO parse other arguments */
+                       pr_debug("%d%+ld", regn, ref->offset);
+               } else {
+                       int depth = 0;
+
+                       new_insn += bpf_prologue_arg_deref(
+                               get_arch_reg_offset(regn),
+                               i + 1,
+                               depth++,
+                               new_prog ? new_insn : NULL,
+                               !ref);
+
+                       while (ref) {
+                               new_insn += bpf_prologue_arg_deref(
+                                       ref->offset,
+                                       i + 1,
+                                       depth++,
+                                       new_prog ? new_insn : NULL,
+                                       !ref->next);
+                               ref = ref->next;
+                       }
+               }
+       }
+
+       new_insn += bpf_prologue_end(new_prog ? new_insn : NULL,
+                                       nargs);
+       *new_len = new_insn - new_prog;
+
+       return 0;
+}
+
 /* Add a found probe point into trace event list */
 static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
 {
@@ -1335,6 +1396,8 @@ int debuginfo__find_bpf_prologue(struct debuginfo *dbg,
                        .pf = {.pev = pev, .callback = generate_bpf_prologue},
                        .mod = dbg->mod, .max_tevs = BPF_MAX_TEVS};
        struct probe_trace_event *tevs;
+       struct probe_trace_event *tev;
+       char *new_prog;
        int ret;
 
        /* Allocate result tevs array */
@@ -1347,9 +1410,25 @@ int debuginfo__find_bpf_prologue(struct debuginfo *dbg,
 
        ret = debuginfo__find_probes(dbg, &tf.pf);
 
-       *result = NULL;
-       *count = 0;
+       tev = &tevs[0];
+
+       synthesize_probe_bpf(tev->args, tev->nargs, NULL, count);
+       if (*count == 0)
+               goto end;
+
+       new_prog = malloc(*count);
+       if (!new_prog) {
+               ret = -ENOMEM;
+               goto end;
+       }
 
+       synthesize_probe_bpf(tev->args, tev->nargs, new_prog, count);
+
+       /* assign result to tvar */
+       *result = (char *)new_prog;
+
+end:
+       /* release tevs */
        free(tevs);
        return ret;
 }
-- 
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