Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751357AbbEXIaB (ORCPT ); Sun, 24 May 2015 04:30:01 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:28115 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750927AbbEXI2h (ORCPT ); Sun, 24 May 2015 04:28:37 -0400 From: He Kuang To: , , , , , , , , , , , CC: , Subject: [RFC PATCH v2 10/15] perf bpf: Process debuginfo for generating bpf prologue Date: Sun, 24 May 2015 08:28:06 +0000 Message-ID: <1432456091-73384-11-git-send-email-hekuang@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1432456091-73384-1-git-send-email-hekuang@huawei.com> References: <1432456091-73384-1-git-send-email-hekuang@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.197.210] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020206.55618BB1.00E7,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 4e0d49fddab75cb6958f19f9affd7361 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5911 Lines: 204 Process debuginfo for bpf prologue, the process function is copied and modified from debuginfo__find_trace_events(), with a different callback function for generating bpf prologue bytecode. Signed-off-by: He Kuang --- tools/perf/util/probe-event.c | 27 ++++++++++++ tools/perf/util/probe-event.h | 2 + tools/perf/util/probe-finder.c | 93 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/probe-finder.h | 4 ++ 4 files changed, 126 insertions(+) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 7f9f431..ccbf4d9 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -914,6 +914,33 @@ out: return ret; } +int get_bpf_prologue(struct perf_probe_event *pev, char **result, int *count) +{ + int ret; + struct debuginfo *dinfo; + bool need_dwarf; + + ret = init_symbol_maps(false); + if (ret < 0) + return ret; + + need_dwarf = perf_probe_event_need_dwarf(pev); + + dinfo = open_debuginfo(NULL, !need_dwarf); + + if (!dinfo) { + if (need_dwarf) + return -ENOENT; + pr_debug("Could not open debuginfo. Try to use symbols.\n"); + return 0; + } + + pr_debug("Try to generate bpf prologue from debuginfo.\n"); + + ret = debuginfo__find_bpf_prologue(dinfo, pev, result, count); + + return ret; +} #else /* !HAVE_DWARF_SUPPORT */ static int diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 6c19395..3eb0183 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -106,6 +106,8 @@ extern char *synthesize_perf_probe_command(struct perf_probe_event *pev); extern char *synthesize_probe_trace_command(struct probe_trace_event *tev); extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len); +extern int get_bpf_prologue(struct perf_probe_event *pev, + char **result, int *count); /* Check the perf_probe_event needs debuginfo */ extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 4de7649..6785eab 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -39,6 +39,7 @@ #include "util.h" #include "symbol.h" #include "probe-finder.h" +#include /* Kprobe tracer basic type is up to u64 */ #define MAX_BASIC_TYPE_BITS 64 @@ -1177,6 +1178,70 @@ static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf, return n; } +static int generate_bpf_prologue(Dwarf_Die *sc_die, struct probe_finder *pf) +{ + struct trace_event_finder *tf = + container_of(pf, struct trace_event_finder, pf); + struct probe_trace_event *tev; + struct perf_probe_arg *args; + int ret, i; + Dwarf_Die vr_die; + + /* Check number of tevs */ + if (tf->ntevs == tf->max_tevs) { + pr_warning("Too many( > %d) probe point found.\n", + tf->max_tevs); + return -ERANGE; + } + tev = &tf->tevs[tf->ntevs++]; + + /* Expand special probe argument if exist */ + args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS); + if (args == NULL) + return -ENOMEM; + + ret = expand_probe_args(sc_die, pf, args); + if (ret <= 0) + goto end; + + /* restrict nargs <= BPF_PROLOGUE_NRARGS_MAX */ + if (ret > BPF_PROLOGUE_NRARGS_MAX) + ret = BPF_PROLOGUE_NRARGS_MAX; + + tev->nargs = ret; + tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); + if (tev->args == NULL) { + ret = -ENOMEM; + goto end; + } + + /* Find each argument */ + for (i = 0; i < tev->nargs; i++) { + pf->pvar = &args[i]; + pf->tvar = &tev->args[i]; + + /* Search child die for local variables and parameters. */ + if (!die_find_variable_at(sc_die, pf->pvar->var, + pf->addr, &vr_die)) { + /* Search again in global variables */ + if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, + 0, &vr_die)) { + pr_warning("Failed to find '%s' in this function.\n", + pf->pvar->var); + ret = -ENOENT; + } + } + + if (ret >= 0) + ret = convert_variable(&vr_die, pf); + if (ret != 0) + break; + } +end: + free(args); + return ret; +} + /* Add a found probe point into trace event list */ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) { @@ -1261,6 +1326,34 @@ int debuginfo__find_trace_events(struct debuginfo *dbg, return (ret < 0) ? ret : tf.ntevs; } +#define BPF_MAX_TEVS (1) +int debuginfo__find_bpf_prologue(struct debuginfo *dbg, + struct perf_probe_event *pev, + char **result, int *count) +{ + struct trace_event_finder tf = { + .pf = {.pev = pev, .callback = generate_bpf_prologue}, + .mod = dbg->mod, .max_tevs = BPF_MAX_TEVS}; + struct probe_trace_event *tevs; + int ret; + + /* Allocate result tevs array */ + tevs = zalloc(sizeof(struct probe_trace_event) * BPF_MAX_TEVS); + if (tevs == NULL) + return -ENOMEM; + + tf.tevs = tevs; + tf.ntevs = 0; + + ret = debuginfo__find_probes(dbg, &tf.pf); + + *result = NULL; + *count = 0; + + free(tevs); + return ret; +} + #define MAX_VAR_LEN 64 /* Collect available variables in this scope */ diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index f53553d..f046c63 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h @@ -43,6 +43,10 @@ extern int debuginfo__find_trace_events(struct debuginfo *dbg, struct probe_trace_event **tevs, int max_tevs); +extern int debuginfo__find_bpf_prologue(struct debuginfo *dbg, + struct perf_probe_event *pev, + char **result, int *count); + /* Find a perf_probe_point from debuginfo */ extern int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr, -- 1.8.5.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/