linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes
@ 2016-08-25 16:24 Masami Hiramatsu
  2016-08-25 16:24 ` [PATCH v2 1/3] perf-probe: Show trace event definition Masami Hiramatsu
                   ` (4 more replies)
  0 siblings, 5 replies; 17+ messages in thread
From: Masami Hiramatsu @ 2016-08-25 16:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Hi,

Here is the 2nd version of remote cross-arch probe support on perf-probe.
V1 is here:
  https://lkml.org/lkml/2016/8/24/29

Currently perf-probe doesn't supoort cross/remote target. This means
we have to cross-build the perf-tools including libraries (elfutils,
libelf etc.), and to prepare vmlinux with debuginfo which can be 
accessed from the target machine.
This requires too much resource for a small embededd device.

If we can analyze the debuginfo by perf-probe on host machine,
we do not need to cross-build perf-tools, nor copy vmlinux on the
device. :)

For that purpose, this series adds --definition(-D) command for
perf-probe, which shows trace event definition instead of adding
it in running kernel, according to Arnaldo's comment.
Using -D with --vmlinux(or -k)=OFFLINE-VMLINUX, perf-probe reads
the vmlinux architecture and show definition with correct
dwarf-registers.

  perf probe -k <cross-vmlinux> -D <probe-point> <arguments>

Here is an example:
  -----
  $ perf probe --vmlinux=./vmlinux-arm --definition 'do_sys_open $params'
  p:probe/do_sys_open do_sys_open+0 dfd=%r5:s32 filename=%r1:u32 flags=%r6:s32 mode=%r3:u16
  -----
Here, we can get probe/do_sys_open event by "copy & paste" the
definition to target-machine's debugfs/tracing/kprobe_events.

Note that it shows definition with direct symbol name instead of
_text+offset. It is treated as an offline module.

Thanks,
---

Masami Hiramatsu (3):
      perf-probe: Show trace event definition
      perf-probe: Ignore vmlinux buildid if offline kernel is given
      perf-probe: Support probing on offline cross-arch binary


 tools/perf/Documentation/perf-probe.txt            |    9 +++
 tools/perf/arch/arm/include/dwarf-regs-table.h     |    9 +++
 tools/perf/arch/arm64/include/dwarf-regs-table.h   |   13 +++++
 tools/perf/arch/powerpc/include/dwarf-regs-table.h |   27 ++++++++++
 tools/perf/arch/s390/include/dwarf-regs-table.h    |    8 +++
 tools/perf/arch/sh/include/dwarf-regs-table.h      |   25 +++++++++
 tools/perf/arch/sparc/include/dwarf-regs-table.h   |   18 +++++++
 tools/perf/arch/x86/include/dwarf-regs-table.h     |   14 +++++
 tools/perf/arch/xtensa/include/dwarf-regs-table.h  |    8 +++
 tools/perf/builtin-probe.c                         |   34 ++++++++++--
 tools/perf/util/Build                              |    1 
 tools/perf/util/dwarf-regs.c                       |   55 ++++++++++++++++++++
 tools/perf/util/include/dwarf-regs.h               |    6 ++
 tools/perf/util/probe-event.c                      |   50 ++++++++++++++++++
 tools/perf/util/probe-event.h                      |    1 
 tools/perf/util/probe-finder.c                     |   27 ++++++----
 tools/perf/util/probe-finder.h                     |    1 
 tools/perf/util/symbol-elf.c                       |    2 -
 18 files changed, 289 insertions(+), 19 deletions(-)
 create mode 100644 tools/perf/arch/arm/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/arm64/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/powerpc/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/s390/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/sh/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/sparc/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/x86/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/xtensa/include/dwarf-regs-table.h
 create mode 100644 tools/perf/util/dwarf-regs.c

--
Masami Hiramatsu (Linaro Ltd.) <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 1/3] perf-probe: Show trace event definition
  2016-08-25 16:24 [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu
@ 2016-08-25 16:24 ` Masami Hiramatsu
  2016-09-05 13:22   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
  2016-08-25 16:24 ` [PATCH v2 2/3] perf-probe: Ignore vmlinux buildid if offline kernel is given Masami Hiramatsu
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 17+ messages in thread
From: Masami Hiramatsu @ 2016-08-25 16:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Add --definition/-D option for showing the trace-event
definition in stdout. This can be useful in debugging
or combined with a shell script.

e.g.
  ----
  # perf probe --definition 'do_sys_open $params'
  p:probe/do_sys_open _text+2261728 dfd=%di:s32 filename=%si:u64 flags=%dx:s32 mode=%cx:u16
  ----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-probe.txt |    7 +++++
 tools/perf/builtin-probe.c              |   26 +++++++++++++-----
 tools/perf/util/probe-event.c           |   46 +++++++++++++++++++++++++++++++
 tools/perf/util/probe-event.h           |    1 +
 4 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index f37d123..56db4d4 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -21,6 +21,8 @@ or
 'perf probe' [options] --vars='PROBEPOINT'
 or
 'perf probe' [options] --funcs
+or
+'perf probe' [options] --definition='PROBE' [...]
 
 DESCRIPTION
 -----------
@@ -96,6 +98,11 @@ OPTIONS
 	can also list functions in a user space executable / shared library.
 	This also can accept a FILTER rule argument.
 
+-D::
+--definition=::
+	Show trace-event definition converted from given probe-event instead
+	of write it into tracing/[k,u]probe_events.
+
 --filter=FILTER::
 	(Only for --vars and --funcs) Set filter. FILTER is a combination of glob
 	pattern, see FILTER PATTERN for detail.
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index ee5b421..7a3d8c4 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -326,6 +326,11 @@ static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs)
 	if (ret < 0)
 		goto out_cleanup;
 
+	if (params.command == 'D') {	/* it shows definition */
+		ret = show_probe_trace_events(pevs, npevs);
+		goto out_cleanup;
+	}
+
 	ret = apply_perf_probe_events(pevs, npevs);
 	if (ret < 0)
 		goto out_cleanup;
@@ -454,6 +459,14 @@ out:
 	return ret;
 }
 
+#ifdef HAVE_DWARF_SUPPORT
+#define PROBEDEF_STR	\
+	"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT [[NAME=]ARG ...]"
+#else
+#define PROBEDEF_STR	"[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]"
+#endif
+
+
 static int
 __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 {
@@ -479,13 +492,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 			     opt_set_filter_with_command, DEFAULT_LIST_FILTER),
 	OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
 		     opt_set_filter_with_command),
-	OPT_CALLBACK('a', "add", NULL,
-#ifdef HAVE_DWARF_SUPPORT
-		"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
-		" [[NAME=]ARG ...]",
-#else
-		"[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]",
-#endif
+	OPT_CALLBACK('a', "add", NULL, PROBEDEF_STR,
 		"probe point definition, where\n"
 		"\t\tGROUP:\tGroup name (optional)\n"
 		"\t\tEVENT:\tEvent name\n"
@@ -503,6 +510,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 		"\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
 #endif
 		opt_add_probe_event),
+	OPT_CALLBACK('D', "definition", NULL, PROBEDEF_STR,
+		"Show trace event definition of given traceevent for k/uprobe_events.",
+		opt_add_probe_event),
 	OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events"
 		    " with existing name"),
 	OPT_CALLBACK('L', "line", NULL,
@@ -548,6 +558,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	set_option_flag(options, 'a', "add", PARSE_OPT_EXCLUSIVE);
 	set_option_flag(options, 'd', "del", PARSE_OPT_EXCLUSIVE);
+	set_option_flag(options, 'D', "definition", PARSE_OPT_EXCLUSIVE);
 	set_option_flag(options, 'l', "list", PARSE_OPT_EXCLUSIVE);
 #ifdef HAVE_DWARF_SUPPORT
 	set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE);
@@ -644,6 +655,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 		}
 		break;
 	case 'a':
+	case 'D':
 		/* Ensure the last given target is used */
 		if (params.target && !params.target_used) {
 			pr_err("  Error: -x/-m must follow the probe definitions.\n");
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 2873396..ad7094d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -3207,6 +3207,52 @@ int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)
 	return 0;
 }
 
+static int show_probe_trace_event(struct probe_trace_event *tev)
+{
+	char *buf = synthesize_probe_trace_command(tev);
+
+	if (!buf) {
+		pr_debug("Failed to synthesize probe trace event.\n");
+		return -EINVAL;
+	}
+
+	/* Showing definition always go stdout */
+	printf("%s\n", buf);
+	free(buf);
+
+	return 0;
+}
+
+int show_probe_trace_events(struct perf_probe_event *pevs, int npevs)
+{
+	struct strlist *namelist = strlist__new(NULL, NULL);
+	struct probe_trace_event *tev;
+	struct perf_probe_event *pev;
+	int i, j, ret = 0;
+
+	if (!namelist)
+		return -ENOMEM;
+
+	for (j = 0; j < npevs && !ret; j++) {
+		pev = &pevs[j];
+		for (i = 0; i < pev->ntevs && !ret; i++) {
+			tev = &pev->tevs[i];
+			/* Skip if the symbol is out of .text or blacklisted */
+			if (!tev->point.symbol && !pev->uprobes)
+				continue;
+
+			/* Set new name for tev (and update namelist) */
+			ret = probe_trace_event__set_name(tev, pev,
+							  namelist, true);
+			if (!ret)
+				ret = show_probe_trace_event(tev);
+		}
+	}
+	strlist__delete(namelist);
+
+	return ret;
+}
+
 int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
 {
 	int i, ret = 0;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index f4f45db..6209408 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -147,6 +147,7 @@ int line_range__init(struct line_range *lr);
 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
 int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
 int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
+int show_probe_trace_events(struct perf_probe_event *pevs, int npevs);
 void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
 int del_perf_probe_events(struct strfilter *filter);
 

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/3] perf-probe: Ignore vmlinux buildid if offline kernel is given
  2016-08-25 16:24 [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu
  2016-08-25 16:24 ` [PATCH v2 1/3] perf-probe: Show trace event definition Masami Hiramatsu
@ 2016-08-25 16:24 ` Masami Hiramatsu
  2016-08-26 14:02   ` Masami Hiramatsu
  2016-09-05 13:22   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
  2016-08-25 16:24 ` [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary Masami Hiramatsu
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 17+ messages in thread
From: Masami Hiramatsu @ 2016-08-25 16:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Ignore the buildid of running kernel when both of --definition and
--vmlinux is given because that kernel should be off-line.
This also skips post-processing of kprobe event for relocating
symbol and checking blacklist, because it can not be done on
off-line kernel.

E.g. without this fix perf shows an error as below
  ----
  $ perf probe --vmlinux=./vmlinux-arm --definition do_sys_open
  ./vmlinux-arm with build id 7a1f76dd56e9c4da707cd3d6333f50748141434b not found, continuing without symbols
  Failed to find symbol do_sys_open in kernel
    Error: Failed to add events.
  ----
with this fix, we can get the definition
  ----
  $ perf probe --vmlinux=./vmlinux-arm --definition do_sys_open
  p:probe/do_sys_open do_sys_open+0
  ----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes from v1:
  - Update the condition since --definition is introduced.
  - Skip post processing because this is not running kernel.
  - Update documentation too.
---
 tools/perf/Documentation/perf-probe.txt |    2 ++
 tools/perf/builtin-probe.c              |   10 +++++++++-
 tools/perf/util/probe-event.c           |    4 ++++
 tools/perf/util/symbol-elf.c            |    2 +-
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 56db4d4..e6c9902 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -36,6 +36,8 @@ OPTIONS
 -k::
 --vmlinux=PATH::
 	Specify vmlinux path which has debuginfo (Dwarf binary).
+	Only when using this with --definition, you can give an offline
+	vmlinux file.
 
 -m::
 --module=MODNAME|PATH::
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 7a3d8c4..b4220cd 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -654,8 +654,16 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 			return ret;
 		}
 		break;
-	case 'a':
 	case 'D':
+		/*
+		 * If user gives offline vmlinux, ignore buildid, since
+		 * --definition doesn't change running kernel.
+		 */
+		if (symbol_conf.vmlinux_name)
+			symbol_conf.ignore_vmlinux_buildid = true;
+		/* fall through */
+	case 'a':
+
 		/* Ensure the last given target is used */
 		if (params.target && !params.target_used) {
 			pr_err("  Error: -x/-m must follow the probe definitions.\n");
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index ad7094d..8dcec0c 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -674,6 +674,10 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
 	char *tmp;
 	int i, skipped = 0;
 
+	/* Skip post process if the target is an offline kernel */
+	if (symbol_conf.ignore_vmlinux_buildid)
+		return 0;
+
 	reloc_sym = kernel_get_ref_reloc_sym();
 	if (!reloc_sym) {
 		pr_warning("Relocated base symbol is not found!\n");
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index a811c13..013cebf 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -685,7 +685,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
 	}
 
 	/* Always reject images with a mismatched build-id: */
-	if (dso->has_build_id) {
+	if (dso->has_build_id && !symbol_conf.ignore_vmlinux_buildid) {
 		u8 build_id[BUILD_ID_SIZE];
 
 		if (elf_read_build_id(elf, build_id, BUILD_ID_SIZE) < 0) {

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
  2016-08-25 16:24 [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu
  2016-08-25 16:24 ` [PATCH v2 1/3] perf-probe: Show trace event definition Masami Hiramatsu
  2016-08-25 16:24 ` [PATCH v2 2/3] perf-probe: Ignore vmlinux buildid if offline kernel is given Masami Hiramatsu
@ 2016-08-25 16:24 ` Masami Hiramatsu
  2016-08-31 20:54   ` Arnaldo Carvalho de Melo
  2016-09-05 13:23   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
  2016-08-26 14:57 ` [PATCH v2 4/4] perf-probe: Ignore vmlinux Build-id when offline vmlinux given Masami Hiramatsu
  2016-08-31  1:01 ` [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu
  4 siblings, 2 replies; 17+ messages in thread
From: Masami Hiramatsu @ 2016-08-25 16:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Support probing on offline cross-architecture binary by
adding getting the target machine arch from ELF and
choose correct register string for the machine.

Here is an example:
  -----
  $ perf probe --vmlinux=./vmlinux-arm --definition 'do_sys_open $params'
  p:probe/do_sys_open do_sys_open+0 dfd=%r5:s32 filename=%r1:u32 flags=%r6:s32 mode=%r3:u16
  -----
Here, we can get probe/do_sys_open event by "copy & paste" from
./tracing/kprobe_events to target-machine's debugfs/tracing/kprobe_events

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
  Changes from v1:
   - Change the example.
---
 tools/perf/arch/arm/include/dwarf-regs-table.h     |    9 +++
 tools/perf/arch/arm64/include/dwarf-regs-table.h   |   13 +++++
 tools/perf/arch/powerpc/include/dwarf-regs-table.h |   27 ++++++++++
 tools/perf/arch/s390/include/dwarf-regs-table.h    |    8 +++
 tools/perf/arch/sh/include/dwarf-regs-table.h      |   25 +++++++++
 tools/perf/arch/sparc/include/dwarf-regs-table.h   |   18 +++++++
 tools/perf/arch/x86/include/dwarf-regs-table.h     |   14 +++++
 tools/perf/arch/xtensa/include/dwarf-regs-table.h  |    8 +++
 tools/perf/util/Build                              |    1 
 tools/perf/util/dwarf-regs.c                       |   55 ++++++++++++++++++++
 tools/perf/util/include/dwarf-regs.h               |    6 ++
 tools/perf/util/probe-finder.c                     |   27 ++++++----
 tools/perf/util/probe-finder.h                     |    1 
 13 files changed, 201 insertions(+), 11 deletions(-)
 create mode 100644 tools/perf/arch/arm/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/arm64/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/powerpc/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/s390/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/sh/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/sparc/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/x86/include/dwarf-regs-table.h
 create mode 100644 tools/perf/arch/xtensa/include/dwarf-regs-table.h
 create mode 100644 tools/perf/util/dwarf-regs.c

diff --git a/tools/perf/arch/arm/include/dwarf-regs-table.h b/tools/perf/arch/arm/include/dwarf-regs-table.h
new file mode 100644
index 0000000..f298d03
--- /dev/null
+++ b/tools/perf/arch/arm/include/dwarf-regs-table.h
@@ -0,0 +1,9 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const arm_regstr_tbl[] = {
+	"%r0", "%r1", "%r2", "%r3", "%r4",
+	"%r5", "%r6", "%r7", "%r8", "%r9", "%r10",
+	"%fp", "%ip", "%sp", "%lr", "%pc",
+};
+#endif
diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h
new file mode 100644
index 0000000..2675936
--- /dev/null
+++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h
@@ -0,0 +1,13 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const aarch64_regstr_tbl[] = {
+	"%r0", "%r1", "%r2", "%r3", "%r4",
+	"%r5", "%r6", "%r7", "%r8", "%r9",
+	"%r10", "%r11", "%r12", "%r13", "%r14",
+	"%r15", "%r16", "%r17", "%r18", "%r19",
+	"%r20", "%r21", "%r22", "%r23", "%r24",
+	"%r25", "%r26", "%r27", "%r28", "%r29",
+	"%lr", "%sp",
+};
+#endif
diff --git a/tools/perf/arch/powerpc/include/dwarf-regs-table.h b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
new file mode 100644
index 0000000..db4730f
--- /dev/null
+++ b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
@@ -0,0 +1,27 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+/*
+ * Reference:
+ * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
+ * http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
+ */
+#define REG_DWARFNUM_NAME(reg, idx)	[idx] = "%" #reg
+
+static const char * const powerpc_regstr_tbl[] = {
+	"%gpr0", "%gpr1", "%gpr2", "%gpr3", "%gpr4",
+	"%gpr5", "%gpr6", "%gpr7", "%gpr8", "%gpr9",
+	"%gpr10", "%gpr11", "%gpr12", "%gpr13", "%gpr14",
+	"%gpr15", "%gpr16", "%gpr17", "%gpr18", "%gpr19",
+	"%gpr20", "%gpr21", "%gpr22", "%gpr23", "%gpr24",
+	"%gpr25", "%gpr26", "%gpr27", "%gpr28", "%gpr29",
+	"%gpr30", "%gpr31",
+	REG_DWARFNUM_NAME(msr,   66),
+	REG_DWARFNUM_NAME(ctr,   109),
+	REG_DWARFNUM_NAME(link,  108),
+	REG_DWARFNUM_NAME(xer,   101),
+	REG_DWARFNUM_NAME(dar,   119),
+	REG_DWARFNUM_NAME(dsisr, 118),
+};
+
+#endif
diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
new file mode 100644
index 0000000..9da74a9
--- /dev/null
+++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
@@ -0,0 +1,8 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const s390_regstr_tbl[] = {
+	"%r0", "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
+	"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
+};
+#endif
diff --git a/tools/perf/arch/sh/include/dwarf-regs-table.h b/tools/perf/arch/sh/include/dwarf-regs-table.h
new file mode 100644
index 0000000..3a2deaf
--- /dev/null
+++ b/tools/perf/arch/sh/include/dwarf-regs-table.h
@@ -0,0 +1,25 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+const char * const sh_regstr_tbl[] = {
+	"r0",
+	"r1",
+	"r2",
+	"r3",
+	"r4",
+	"r5",
+	"r6",
+	"r7",
+	"r8",
+	"r9",
+	"r10",
+	"r11",
+	"r12",
+	"r13",
+	"r14",
+	"r15",
+	"pc",
+	"pr",
+};
+
+#endif
diff --git a/tools/perf/arch/sparc/include/dwarf-regs-table.h b/tools/perf/arch/sparc/include/dwarf-regs-table.h
new file mode 100644
index 0000000..12c0761
--- /dev/null
+++ b/tools/perf/arch/sparc/include/dwarf-regs-table.h
@@ -0,0 +1,18 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const sparc_regstr_tbl[] = {
+	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
+	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
+	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
+	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",
+	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
+	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
+	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
+	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
+	"%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",
+	"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",
+	"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",
+	"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",
+};
+#endif
diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
new file mode 100644
index 0000000..39ac7cb
--- /dev/null
+++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
@@ -0,0 +1,14 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const x86_32_regstr_tbl[] = {
+	"%ax", "%cx", "%dx", "%bx", "$stack",/* Stack address instead of %sp */
+	"%bp", "%si", "%di",
+};
+
+static const char * const x86_64_regstr_tbl[] = {
+	"%ax", "dx", "%cx", "%bx", "%si", "%di",
+	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
+	"%r12", "%r13", "%r14", "%r15",
+};
+#endif
diff --git a/tools/perf/arch/xtensa/include/dwarf-regs-table.h b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
new file mode 100644
index 0000000..aa0444a
--- /dev/null
+++ b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
@@ -0,0 +1,8 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const xtensa_regstr_tbl[] = {
+	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
+	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
+};
+#endif
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 91c5f6e..f1a6d17 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -98,6 +98,7 @@ endif
 
 libperf-$(CONFIG_DWARF) += probe-finder.o
 libperf-$(CONFIG_DWARF) += dwarf-aux.o
+libperf-$(CONFIG_DWARF) += dwarf-regs.o
 
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
new file mode 100644
index 0000000..ce15816
--- /dev/null
+++ b/tools/perf/util/dwarf-regs.c
@@ -0,0 +1,55 @@
+/*
+ * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
+ *
+ * Written by: Masami Hiramatsu <mhiramat@kernel.org>
+ */
+
+#include <util.h>
+#include <debug.h>
+#include <dwarf-regs.h>
+#include <elf.h>
+
+/* Define const char * {arch}_register_tbl[] */
+#define DEFINE_DWARF_REGSTR_TABLE
+#include "../arch/x86/include/dwarf-regs-table.h"
+#include "../arch/arm/include/dwarf-regs-table.h"
+#include "../arch/arm64/include/dwarf-regs-table.h"
+#include "../arch/sh/include/dwarf-regs-table.h"
+#include "../arch/powerpc/include/dwarf-regs-table.h"
+#include "../arch/s390/include/dwarf-regs-table.h"
+#include "../arch/sparc/include/dwarf-regs-table.h"
+#include "../arch/xtensa/include/dwarf-regs-table.h"
+
+#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
+
+/* Return architecture dependent register string (for kprobe-tracer) */
+const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
+{
+	switch (machine) {
+	case EM_NONE:	/* Generic arch - use host arch */
+		return get_arch_regstr(n);
+	case EM_386:
+		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
+	case EM_X86_64:
+		return __get_dwarf_regstr(x86_64_regstr_tbl, n);
+	case EM_ARM:
+		return __get_dwarf_regstr(arm_regstr_tbl, n);
+	case EM_AARCH64:
+		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
+	case EM_SH:
+		return __get_dwarf_regstr(sh_regstr_tbl, n);
+	case EM_S390:
+		return __get_dwarf_regstr(s390_regstr_tbl, n);
+	case EM_PPC:
+	case EM_PPC64:
+		return __get_dwarf_regstr(powerpc_regstr_tbl, n);
+	case EM_SPARC:
+	case EM_SPARCV9:
+		return __get_dwarf_regstr(sparc_regstr_tbl, n);
+	case EM_XTENSA:
+		return __get_dwarf_regstr(xtensa_regstr_tbl, n);
+	default:
+		pr_err("ELF MACHINE %x is not supported.\n", machine);
+	}
+	return NULL;
+}
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 07c644e..43bfd8d 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -3,6 +3,12 @@
 
 #ifdef HAVE_DWARF_SUPPORT
 const char *get_arch_regstr(unsigned int n);
+/*
+ * get_dwarf_regstr - Returns ftrace register string from DWARF regnum
+ * n: DWARF register number
+ * machine: ELF machine signature (EM_*)
+ */
+const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
 #endif
 
 #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index ac4740f..508b61c 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -171,6 +171,7 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
  */
 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
 				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
+				     unsigned int machine,
 				     struct probe_trace_arg *tvar)
 {
 	Dwarf_Attribute attr;
@@ -266,7 +267,7 @@ static_var:
 	if (!tvar)
 		return ret2;
 
-	regs = get_arch_regstr(regn);
+	regs = get_dwarf_regstr(regn, machine);
 	if (!regs) {
 		/* This should be a bug in DWARF or this tool */
 		pr_warning("Mapping for the register number %u "
@@ -543,7 +544,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
 		 dwarf_diename(vr_die));
 
 	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
-					&pf->sp_die, pf->tvar);
+					&pf->sp_die, pf->machine, pf->tvar);
 	if (ret == -ENOENT || ret == -EINVAL) {
 		pr_err("Failed to find the location of the '%s' variable at this address.\n"
 		       " Perhaps it has been optimized out.\n"
@@ -1106,11 +1107,8 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
 				  struct probe_finder *pf)
 {
 	int ret = 0;
-
-#if _ELFUTILS_PREREQ(0, 142)
 	Elf *elf;
 	GElf_Ehdr ehdr;
-	GElf_Shdr shdr;
 
 	if (pf->cfi_eh || pf->cfi_dbg)
 		return debuginfo__find_probe_location(dbg, pf);
@@ -1123,11 +1121,18 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
 	if (gelf_getehdr(elf, &ehdr) == NULL)
 		return -EINVAL;
 
-	if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
-	    shdr.sh_type == SHT_PROGBITS)
-		pf->cfi_eh = dwarf_getcfi_elf(elf);
+	pf->machine = ehdr.e_machine;
+
+#if _ELFUTILS_PREREQ(0, 142)
+	do {
+		GElf_Shdr shdr;
+
+		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
+		    shdr.sh_type == SHT_PROGBITS)
+			pf->cfi_eh = dwarf_getcfi_elf(elf);
 
-	pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
+		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
+	} while (0);
 #endif
 
 	ret = debuginfo__find_probe_location(dbg, pf);
@@ -1155,7 +1160,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
 	    (tag == DW_TAG_variable && vf->vars)) {
 		if (convert_variable_location(die_mem, vf->pf->addr,
 					      vf->pf->fb_ops, &pf->sp_die,
-					      NULL) == 0) {
+					      pf->machine, NULL) == 0) {
 			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
 			if (vf->args[vf->nargs].var == NULL) {
 				vf->ret = -ENOMEM;
@@ -1318,7 +1323,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
 	    tag == DW_TAG_variable) {
 		ret = convert_variable_location(die_mem, af->pf.addr,
 						af->pf.fb_ops, &af->pf.sp_die,
-						NULL);
+						af->pf.machine, NULL);
 		if (ret == 0 || ret == -ERANGE) {
 			int ret2;
 			bool externs = !af->child;
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 51137fc..f1d8558 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -80,6 +80,7 @@ struct probe_finder {
 	Dwarf_CFI		*cfi_dbg;
 #endif
 	Dwarf_Op		*fb_ops;	/* Frame base attribute */
+	unsigned int		machine;	/* Target machine arch */
 	struct perf_probe_arg	*pvar;		/* Current target variable */
 	struct probe_trace_arg	*tvar;		/* Current result variable */
 };

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 2/3] perf-probe: Ignore vmlinux buildid if offline kernel is given
  2016-08-25 16:24 ` [PATCH v2 2/3] perf-probe: Ignore vmlinux buildid if offline kernel is given Masami Hiramatsu
@ 2016-08-26 14:02   ` Masami Hiramatsu
  2016-09-05 13:22   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
  1 sibling, 0 replies; 17+ messages in thread
From: Masami Hiramatsu @ 2016-08-26 14:02 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Arnaldo Carvalho de Melo, linux-kernel, Peter Zijlstra,
	Ingo Molnar, Jiri Olsa

On Fri, 26 Aug 2016 01:24:42 +0900
Masami Hiramatsu <mhiramat@kernel.org> wrote:

> Ignore the buildid of running kernel when both of --definition and
> --vmlinux is given because that kernel should be off-line.
> This also skips post-processing of kprobe event for relocating
> symbol and checking blacklist, because it can not be done on
> off-line kernel.

Ahh, I missed other commands which doesn't change running kernel,
like --funcs, --vars, --lines. Those also should ignore buildid if
vmlinux is given. (--add, --del, and --list depend on/change running
kernel)

I'll add a patch to handle that.

Thank you,

> 
> E.g. without this fix perf shows an error as below
>   ----
>   $ perf probe --vmlinux=./vmlinux-arm --definition do_sys_open
>   ./vmlinux-arm with build id 7a1f76dd56e9c4da707cd3d6333f50748141434b not found, continuing without symbols
>   Failed to find symbol do_sys_open in kernel
>     Error: Failed to add events.
>   ----
> with this fix, we can get the definition
>   ----
>   $ perf probe --vmlinux=./vmlinux-arm --definition do_sys_open
>   p:probe/do_sys_open do_sys_open+0
>   ----
> 
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> ---
>  Changes from v1:
>   - Update the condition since --definition is introduced.
>   - Skip post processing because this is not running kernel.
>   - Update documentation too.
> ---
>  tools/perf/Documentation/perf-probe.txt |    2 ++
>  tools/perf/builtin-probe.c              |   10 +++++++++-
>  tools/perf/util/probe-event.c           |    4 ++++
>  tools/perf/util/symbol-elf.c            |    2 +-
>  4 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
> index 56db4d4..e6c9902 100644
> --- a/tools/perf/Documentation/perf-probe.txt
> +++ b/tools/perf/Documentation/perf-probe.txt
> @@ -36,6 +36,8 @@ OPTIONS
>  -k::
>  --vmlinux=PATH::
>  	Specify vmlinux path which has debuginfo (Dwarf binary).
> +	Only when using this with --definition, you can give an offline
> +	vmlinux file.
>  
>  -m::
>  --module=MODNAME|PATH::
> diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
> index 7a3d8c4..b4220cd 100644
> --- a/tools/perf/builtin-probe.c
> +++ b/tools/perf/builtin-probe.c
> @@ -654,8 +654,16 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
>  			return ret;
>  		}
>  		break;
> -	case 'a':
>  	case 'D':
> +		/*
> +		 * If user gives offline vmlinux, ignore buildid, since
> +		 * --definition doesn't change running kernel.
> +		 */
> +		if (symbol_conf.vmlinux_name)
> +			symbol_conf.ignore_vmlinux_buildid = true;
> +		/* fall through */
> +	case 'a':
> +
>  		/* Ensure the last given target is used */
>  		if (params.target && !params.target_used) {
>  			pr_err("  Error: -x/-m must follow the probe definitions.\n");
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index ad7094d..8dcec0c 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -674,6 +674,10 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
>  	char *tmp;
>  	int i, skipped = 0;
>  
> +	/* Skip post process if the target is an offline kernel */
> +	if (symbol_conf.ignore_vmlinux_buildid)
> +		return 0;
> +
>  	reloc_sym = kernel_get_ref_reloc_sym();
>  	if (!reloc_sym) {
>  		pr_warning("Relocated base symbol is not found!\n");
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index a811c13..013cebf 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -685,7 +685,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
>  	}
>  
>  	/* Always reject images with a mismatched build-id: */
> -	if (dso->has_build_id) {
> +	if (dso->has_build_id && !symbol_conf.ignore_vmlinux_buildid) {
>  		u8 build_id[BUILD_ID_SIZE];
>  
>  		if (elf_read_build_id(elf, build_id, BUILD_ID_SIZE) < 0) {
> 


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 4/4] perf-probe: Ignore vmlinux Build-id when offline vmlinux given
  2016-08-25 16:24 [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu
                   ` (2 preceding siblings ...)
  2016-08-25 16:24 ` [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary Masami Hiramatsu
@ 2016-08-26 14:57 ` Masami Hiramatsu
  2016-09-05 13:23   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
  2016-08-31  1:01 ` [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu
  4 siblings, 1 reply; 17+ messages in thread
From: Masami Hiramatsu @ 2016-08-26 14:57 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Ignore vmlinux build-id when user gives offline vmlinux if
the command does not affect running kernel.
perf-probe has several actions some of them does not change
the running kernel, like --lines, --vars, and --funcs.

e.g.
  -----
  $ ./perf probe -k ./vmlinux-arm -V do_sys_open:14
  Available variables at do_sys_open:14
          @<do_sys_open+202>
                  char*   filename
                  int     dfd
                  int     fd
                  int     flags
                  struct filename*        tmp
                  struct open_flags       op
                  umode_t mode
  -----


Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 tools/perf/builtin-probe.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index b4220cd..f87996b 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -611,6 +611,14 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 	 */
 	symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
 
+	/*
+	 * Except for --list, --del and --add, other command doesn't depend
+	 * nor change running kernel. So if user gives offline vmlinux,
+	 * ignore its buildid.
+	 */
+	if (!strchr("lda", params.command) && symbol_conf.vmlinux_name)
+		symbol_conf.ignore_vmlinux_buildid = true;
+
 	switch (params.command) {
 	case 'l':
 		if (params.uprobes) {
@@ -655,13 +663,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 		}
 		break;
 	case 'D':
-		/*
-		 * If user gives offline vmlinux, ignore buildid, since
-		 * --definition doesn't change running kernel.
-		 */
-		if (symbol_conf.vmlinux_name)
-			symbol_conf.ignore_vmlinux_buildid = true;
-		/* fall through */
 	case 'a':
 
 		/* Ensure the last given target is used */

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes
  2016-08-25 16:24 [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu
                   ` (3 preceding siblings ...)
  2016-08-26 14:57 ` [PATCH v2 4/4] perf-probe: Ignore vmlinux Build-id when offline vmlinux given Masami Hiramatsu
@ 2016-08-31  1:01 ` Masami Hiramatsu
  4 siblings, 0 replies; 17+ messages in thread
From: Masami Hiramatsu @ 2016-08-31  1:01 UTC (permalink / raw)
  To: Masami Hiramatsu, Arnaldo Carvalho de Melo
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

ping?

On Fri, 26 Aug 2016 01:24:10 +0900
Masami Hiramatsu <mhiramat@kernel.org> wrote:

> Hi,
> 
> Here is the 2nd version of remote cross-arch probe support on perf-probe.
> V1 is here:
>   https://lkml.org/lkml/2016/8/24/29
> 
> Currently perf-probe doesn't supoort cross/remote target. This means
> we have to cross-build the perf-tools including libraries (elfutils,
> libelf etc.), and to prepare vmlinux with debuginfo which can be 
> accessed from the target machine.
> This requires too much resource for a small embededd device.
> 
> If we can analyze the debuginfo by perf-probe on host machine,
> we do not need to cross-build perf-tools, nor copy vmlinux on the
> device. :)
> 
> For that purpose, this series adds --definition(-D) command for
> perf-probe, which shows trace event definition instead of adding
> it in running kernel, according to Arnaldo's comment.
> Using -D with --vmlinux(or -k)=OFFLINE-VMLINUX, perf-probe reads
> the vmlinux architecture and show definition with correct
> dwarf-registers.
> 
>   perf probe -k <cross-vmlinux> -D <probe-point> <arguments>
> 
> Here is an example:
>   -----
>   $ perf probe --vmlinux=./vmlinux-arm --definition 'do_sys_open $params'
>   p:probe/do_sys_open do_sys_open+0 dfd=%r5:s32 filename=%r1:u32 flags=%r6:s32 mode=%r3:u16
>   -----
> Here, we can get probe/do_sys_open event by "copy & paste" the
> definition to target-machine's debugfs/tracing/kprobe_events.
> 
> Note that it shows definition with direct symbol name instead of
> _text+offset. It is treated as an offline module.
> 
> Thanks,
> ---
> 
> Masami Hiramatsu (3):
>       perf-probe: Show trace event definition
>       perf-probe: Ignore vmlinux buildid if offline kernel is given
>       perf-probe: Support probing on offline cross-arch binary
> 
> 
>  tools/perf/Documentation/perf-probe.txt            |    9 +++
>  tools/perf/arch/arm/include/dwarf-regs-table.h     |    9 +++
>  tools/perf/arch/arm64/include/dwarf-regs-table.h   |   13 +++++
>  tools/perf/arch/powerpc/include/dwarf-regs-table.h |   27 ++++++++++
>  tools/perf/arch/s390/include/dwarf-regs-table.h    |    8 +++
>  tools/perf/arch/sh/include/dwarf-regs-table.h      |   25 +++++++++
>  tools/perf/arch/sparc/include/dwarf-regs-table.h   |   18 +++++++
>  tools/perf/arch/x86/include/dwarf-regs-table.h     |   14 +++++
>  tools/perf/arch/xtensa/include/dwarf-regs-table.h  |    8 +++
>  tools/perf/builtin-probe.c                         |   34 ++++++++++--
>  tools/perf/util/Build                              |    1 
>  tools/perf/util/dwarf-regs.c                       |   55 ++++++++++++++++++++
>  tools/perf/util/include/dwarf-regs.h               |    6 ++
>  tools/perf/util/probe-event.c                      |   50 ++++++++++++++++++
>  tools/perf/util/probe-event.h                      |    1 
>  tools/perf/util/probe-finder.c                     |   27 ++++++----
>  tools/perf/util/probe-finder.h                     |    1 
>  tools/perf/util/symbol-elf.c                       |    2 -
>  18 files changed, 289 insertions(+), 19 deletions(-)
>  create mode 100644 tools/perf/arch/arm/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/arm64/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/powerpc/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/s390/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/sh/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/sparc/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/x86/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/xtensa/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/util/dwarf-regs.c
> 
> --
> Masami Hiramatsu (Linaro Ltd.) <mhiramat@kernel.org>


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
  2016-08-25 16:24 ` [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary Masami Hiramatsu
@ 2016-08-31 20:54   ` Arnaldo Carvalho de Melo
  2016-08-31 23:25     ` Masami Hiramatsu
  2016-09-05 13:23   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
  1 sibling, 1 reply; 17+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-08-31 20:54 UTC (permalink / raw)
  To: Masami Hiramatsu; +Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Em Fri, Aug 26, 2016 at 01:24:57AM +0900, Masami Hiramatsu escreveu:
> Support probing on offline cross-architecture binary by
> adding getting the target machine arch from ELF and
> choose correct register string for the machine.
> 
> Here is an example:
>   -----
>   $ perf probe --vmlinux=./vmlinux-arm --definition 'do_sys_open $params'
>   p:probe/do_sys_open do_sys_open+0 dfd=%r5:s32 filename=%r1:u32 flags=%r6:s32 mode=%r3:u16
>   -----
> Here, we can get probe/do_sys_open event by "copy & paste" from
> ./tracing/kprobe_events to target-machine's debugfs/tracing/kprobe_events

Fixing the example not to refer to "tracing/kprobe_events", as it is not
there anymore, instead append what '--definition' produced to the target
machine <tracefs mountpoint>/tracing/kprobe_events file.

- Arnaldo
 
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> ---
>   Changes from v1:
>    - Change the example.
> ---
>  tools/perf/arch/arm/include/dwarf-regs-table.h     |    9 +++
>  tools/perf/arch/arm64/include/dwarf-regs-table.h   |   13 +++++
>  tools/perf/arch/powerpc/include/dwarf-regs-table.h |   27 ++++++++++
>  tools/perf/arch/s390/include/dwarf-regs-table.h    |    8 +++
>  tools/perf/arch/sh/include/dwarf-regs-table.h      |   25 +++++++++
>  tools/perf/arch/sparc/include/dwarf-regs-table.h   |   18 +++++++
>  tools/perf/arch/x86/include/dwarf-regs-table.h     |   14 +++++
>  tools/perf/arch/xtensa/include/dwarf-regs-table.h  |    8 +++
>  tools/perf/util/Build                              |    1 
>  tools/perf/util/dwarf-regs.c                       |   55 ++++++++++++++++++++
>  tools/perf/util/include/dwarf-regs.h               |    6 ++
>  tools/perf/util/probe-finder.c                     |   27 ++++++----
>  tools/perf/util/probe-finder.h                     |    1 
>  13 files changed, 201 insertions(+), 11 deletions(-)
>  create mode 100644 tools/perf/arch/arm/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/arm64/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/powerpc/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/s390/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/sh/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/sparc/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/x86/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/arch/xtensa/include/dwarf-regs-table.h
>  create mode 100644 tools/perf/util/dwarf-regs.c
> 
> diff --git a/tools/perf/arch/arm/include/dwarf-regs-table.h b/tools/perf/arch/arm/include/dwarf-regs-table.h
> new file mode 100644
> index 0000000..f298d03
> --- /dev/null
> +++ b/tools/perf/arch/arm/include/dwarf-regs-table.h
> @@ -0,0 +1,9 @@
> +#ifdef DEFINE_DWARF_REGSTR_TABLE
> +/* This is included in perf/util/dwarf-regs.c */
> +
> +static const char * const arm_regstr_tbl[] = {
> +	"%r0", "%r1", "%r2", "%r3", "%r4",
> +	"%r5", "%r6", "%r7", "%r8", "%r9", "%r10",
> +	"%fp", "%ip", "%sp", "%lr", "%pc",
> +};
> +#endif
> diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> new file mode 100644
> index 0000000..2675936
> --- /dev/null
> +++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> @@ -0,0 +1,13 @@
> +#ifdef DEFINE_DWARF_REGSTR_TABLE
> +/* This is included in perf/util/dwarf-regs.c */
> +
> +static const char * const aarch64_regstr_tbl[] = {
> +	"%r0", "%r1", "%r2", "%r3", "%r4",
> +	"%r5", "%r6", "%r7", "%r8", "%r9",
> +	"%r10", "%r11", "%r12", "%r13", "%r14",
> +	"%r15", "%r16", "%r17", "%r18", "%r19",
> +	"%r20", "%r21", "%r22", "%r23", "%r24",
> +	"%r25", "%r26", "%r27", "%r28", "%r29",
> +	"%lr", "%sp",
> +};
> +#endif
> diff --git a/tools/perf/arch/powerpc/include/dwarf-regs-table.h b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> new file mode 100644
> index 0000000..db4730f
> --- /dev/null
> +++ b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> @@ -0,0 +1,27 @@
> +#ifdef DEFINE_DWARF_REGSTR_TABLE
> +/* This is included in perf/util/dwarf-regs.c */
> +
> +/*
> + * Reference:
> + * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
> + * http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
> + */
> +#define REG_DWARFNUM_NAME(reg, idx)	[idx] = "%" #reg
> +
> +static const char * const powerpc_regstr_tbl[] = {
> +	"%gpr0", "%gpr1", "%gpr2", "%gpr3", "%gpr4",
> +	"%gpr5", "%gpr6", "%gpr7", "%gpr8", "%gpr9",
> +	"%gpr10", "%gpr11", "%gpr12", "%gpr13", "%gpr14",
> +	"%gpr15", "%gpr16", "%gpr17", "%gpr18", "%gpr19",
> +	"%gpr20", "%gpr21", "%gpr22", "%gpr23", "%gpr24",
> +	"%gpr25", "%gpr26", "%gpr27", "%gpr28", "%gpr29",
> +	"%gpr30", "%gpr31",
> +	REG_DWARFNUM_NAME(msr,   66),
> +	REG_DWARFNUM_NAME(ctr,   109),
> +	REG_DWARFNUM_NAME(link,  108),
> +	REG_DWARFNUM_NAME(xer,   101),
> +	REG_DWARFNUM_NAME(dar,   119),
> +	REG_DWARFNUM_NAME(dsisr, 118),
> +};
> +
> +#endif
> diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
> new file mode 100644
> index 0000000..9da74a9
> --- /dev/null
> +++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
> @@ -0,0 +1,8 @@
> +#ifdef DEFINE_DWARF_REGSTR_TABLE
> +/* This is included in perf/util/dwarf-regs.c */
> +
> +static const char * const s390_regstr_tbl[] = {
> +	"%r0", "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
> +	"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
> +};
> +#endif
> diff --git a/tools/perf/arch/sh/include/dwarf-regs-table.h b/tools/perf/arch/sh/include/dwarf-regs-table.h
> new file mode 100644
> index 0000000..3a2deaf
> --- /dev/null
> +++ b/tools/perf/arch/sh/include/dwarf-regs-table.h
> @@ -0,0 +1,25 @@
> +#ifdef DEFINE_DWARF_REGSTR_TABLE
> +/* This is included in perf/util/dwarf-regs.c */
> +
> +const char * const sh_regstr_tbl[] = {
> +	"r0",
> +	"r1",
> +	"r2",
> +	"r3",
> +	"r4",
> +	"r5",
> +	"r6",
> +	"r7",
> +	"r8",
> +	"r9",
> +	"r10",
> +	"r11",
> +	"r12",
> +	"r13",
> +	"r14",
> +	"r15",
> +	"pc",
> +	"pr",
> +};
> +
> +#endif
> diff --git a/tools/perf/arch/sparc/include/dwarf-regs-table.h b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> new file mode 100644
> index 0000000..12c0761
> --- /dev/null
> +++ b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> @@ -0,0 +1,18 @@
> +#ifdef DEFINE_DWARF_REGSTR_TABLE
> +/* This is included in perf/util/dwarf-regs.c */
> +
> +static const char * const sparc_regstr_tbl[] = {
> +	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
> +	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
> +	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
> +	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",
> +	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
> +	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
> +	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
> +	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
> +	"%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",
> +	"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",
> +	"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",
> +	"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",
> +};
> +#endif
> diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
> new file mode 100644
> index 0000000..39ac7cb
> --- /dev/null
> +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
> @@ -0,0 +1,14 @@
> +#ifdef DEFINE_DWARF_REGSTR_TABLE
> +/* This is included in perf/util/dwarf-regs.c */
> +
> +static const char * const x86_32_regstr_tbl[] = {
> +	"%ax", "%cx", "%dx", "%bx", "$stack",/* Stack address instead of %sp */
> +	"%bp", "%si", "%di",
> +};
> +
> +static const char * const x86_64_regstr_tbl[] = {
> +	"%ax", "dx", "%cx", "%bx", "%si", "%di",
> +	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
> +	"%r12", "%r13", "%r14", "%r15",
> +};
> +#endif
> diff --git a/tools/perf/arch/xtensa/include/dwarf-regs-table.h b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> new file mode 100644
> index 0000000..aa0444a
> --- /dev/null
> +++ b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> @@ -0,0 +1,8 @@
> +#ifdef DEFINE_DWARF_REGSTR_TABLE
> +/* This is included in perf/util/dwarf-regs.c */
> +
> +static const char * const xtensa_regstr_tbl[] = {
> +	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
> +	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
> +};
> +#endif
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index 91c5f6e..f1a6d17 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -98,6 +98,7 @@ endif
>  
>  libperf-$(CONFIG_DWARF) += probe-finder.o
>  libperf-$(CONFIG_DWARF) += dwarf-aux.o
> +libperf-$(CONFIG_DWARF) += dwarf-regs.o
>  
>  libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
>  libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
> diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> new file mode 100644
> index 0000000..ce15816
> --- /dev/null
> +++ b/tools/perf/util/dwarf-regs.c
> @@ -0,0 +1,55 @@
> +/*
> + * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
> + *
> + * Written by: Masami Hiramatsu <mhiramat@kernel.org>
> + */
> +
> +#include <util.h>
> +#include <debug.h>
> +#include <dwarf-regs.h>
> +#include <elf.h>
> +
> +/* Define const char * {arch}_register_tbl[] */
> +#define DEFINE_DWARF_REGSTR_TABLE
> +#include "../arch/x86/include/dwarf-regs-table.h"
> +#include "../arch/arm/include/dwarf-regs-table.h"
> +#include "../arch/arm64/include/dwarf-regs-table.h"
> +#include "../arch/sh/include/dwarf-regs-table.h"
> +#include "../arch/powerpc/include/dwarf-regs-table.h"
> +#include "../arch/s390/include/dwarf-regs-table.h"
> +#include "../arch/sparc/include/dwarf-regs-table.h"
> +#include "../arch/xtensa/include/dwarf-regs-table.h"
> +
> +#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
> +
> +/* Return architecture dependent register string (for kprobe-tracer) */
> +const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
> +{
> +	switch (machine) {
> +	case EM_NONE:	/* Generic arch - use host arch */
> +		return get_arch_regstr(n);
> +	case EM_386:
> +		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
> +	case EM_X86_64:
> +		return __get_dwarf_regstr(x86_64_regstr_tbl, n);
> +	case EM_ARM:
> +		return __get_dwarf_regstr(arm_regstr_tbl, n);
> +	case EM_AARCH64:
> +		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
> +	case EM_SH:
> +		return __get_dwarf_regstr(sh_regstr_tbl, n);
> +	case EM_S390:
> +		return __get_dwarf_regstr(s390_regstr_tbl, n);
> +	case EM_PPC:
> +	case EM_PPC64:
> +		return __get_dwarf_regstr(powerpc_regstr_tbl, n);
> +	case EM_SPARC:
> +	case EM_SPARCV9:
> +		return __get_dwarf_regstr(sparc_regstr_tbl, n);
> +	case EM_XTENSA:
> +		return __get_dwarf_regstr(xtensa_regstr_tbl, n);
> +	default:
> +		pr_err("ELF MACHINE %x is not supported.\n", machine);
> +	}
> +	return NULL;
> +}
> diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> index 07c644e..43bfd8d 100644
> --- a/tools/perf/util/include/dwarf-regs.h
> +++ b/tools/perf/util/include/dwarf-regs.h
> @@ -3,6 +3,12 @@
>  
>  #ifdef HAVE_DWARF_SUPPORT
>  const char *get_arch_regstr(unsigned int n);
> +/*
> + * get_dwarf_regstr - Returns ftrace register string from DWARF regnum
> + * n: DWARF register number
> + * machine: ELF machine signature (EM_*)
> + */
> +const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
>  #endif
>  
>  #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
> diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> index ac4740f..508b61c 100644
> --- a/tools/perf/util/probe-finder.c
> +++ b/tools/perf/util/probe-finder.c
> @@ -171,6 +171,7 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
>   */
>  static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
>  				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
> +				     unsigned int machine,
>  				     struct probe_trace_arg *tvar)
>  {
>  	Dwarf_Attribute attr;
> @@ -266,7 +267,7 @@ static_var:
>  	if (!tvar)
>  		return ret2;
>  
> -	regs = get_arch_regstr(regn);
> +	regs = get_dwarf_regstr(regn, machine);
>  	if (!regs) {
>  		/* This should be a bug in DWARF or this tool */
>  		pr_warning("Mapping for the register number %u "
> @@ -543,7 +544,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
>  		 dwarf_diename(vr_die));
>  
>  	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
> -					&pf->sp_die, pf->tvar);
> +					&pf->sp_die, pf->machine, pf->tvar);
>  	if (ret == -ENOENT || ret == -EINVAL) {
>  		pr_err("Failed to find the location of the '%s' variable at this address.\n"
>  		       " Perhaps it has been optimized out.\n"
> @@ -1106,11 +1107,8 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
>  				  struct probe_finder *pf)
>  {
>  	int ret = 0;
> -
> -#if _ELFUTILS_PREREQ(0, 142)
>  	Elf *elf;
>  	GElf_Ehdr ehdr;
> -	GElf_Shdr shdr;
>  
>  	if (pf->cfi_eh || pf->cfi_dbg)
>  		return debuginfo__find_probe_location(dbg, pf);
> @@ -1123,11 +1121,18 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
>  	if (gelf_getehdr(elf, &ehdr) == NULL)
>  		return -EINVAL;
>  
> -	if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> -	    shdr.sh_type == SHT_PROGBITS)
> -		pf->cfi_eh = dwarf_getcfi_elf(elf);
> +	pf->machine = ehdr.e_machine;
> +
> +#if _ELFUTILS_PREREQ(0, 142)
> +	do {
> +		GElf_Shdr shdr;
> +
> +		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> +		    shdr.sh_type == SHT_PROGBITS)
> +			pf->cfi_eh = dwarf_getcfi_elf(elf);
>  
> -	pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> +		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> +	} while (0);
>  #endif
>  
>  	ret = debuginfo__find_probe_location(dbg, pf);
> @@ -1155,7 +1160,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
>  	    (tag == DW_TAG_variable && vf->vars)) {
>  		if (convert_variable_location(die_mem, vf->pf->addr,
>  					      vf->pf->fb_ops, &pf->sp_die,
> -					      NULL) == 0) {
> +					      pf->machine, NULL) == 0) {
>  			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
>  			if (vf->args[vf->nargs].var == NULL) {
>  				vf->ret = -ENOMEM;
> @@ -1318,7 +1323,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
>  	    tag == DW_TAG_variable) {
>  		ret = convert_variable_location(die_mem, af->pf.addr,
>  						af->pf.fb_ops, &af->pf.sp_die,
> -						NULL);
> +						af->pf.machine, NULL);
>  		if (ret == 0 || ret == -ERANGE) {
>  			int ret2;
>  			bool externs = !af->child;
> diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
> index 51137fc..f1d8558 100644
> --- a/tools/perf/util/probe-finder.h
> +++ b/tools/perf/util/probe-finder.h
> @@ -80,6 +80,7 @@ struct probe_finder {
>  	Dwarf_CFI		*cfi_dbg;
>  #endif
>  	Dwarf_Op		*fb_ops;	/* Frame base attribute */
> +	unsigned int		machine;	/* Target machine arch */
>  	struct perf_probe_arg	*pvar;		/* Current target variable */
>  	struct probe_trace_arg	*tvar;		/* Current result variable */
>  };

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
  2016-08-31 20:54   ` Arnaldo Carvalho de Melo
@ 2016-08-31 23:25     ` Masami Hiramatsu
  2016-09-09 14:37       ` [BUG] " Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 17+ messages in thread
From: Masami Hiramatsu @ 2016-08-31 23:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

On Wed, 31 Aug 2016 17:54:11 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> Em Fri, Aug 26, 2016 at 01:24:57AM +0900, Masami Hiramatsu escreveu:
> > Support probing on offline cross-architecture binary by
> > adding getting the target machine arch from ELF and
> > choose correct register string for the machine.
> > 
> > Here is an example:
> >   -----
> >   $ perf probe --vmlinux=./vmlinux-arm --definition 'do_sys_open $params'
> >   p:probe/do_sys_open do_sys_open+0 dfd=%r5:s32 filename=%r1:u32 flags=%r6:s32 mode=%r3:u16
> >   -----
> > Here, we can get probe/do_sys_open event by "copy & paste" from
> > ./tracing/kprobe_events to target-machine's debugfs/tracing/kprobe_events
> 
> Fixing the example not to refer to "tracing/kprobe_events", as it is not
> there anymore, instead append what '--definition' produced to the target
> machine <tracefs mountpoint>/tracing/kprobe_events file.

Oops, right, it's my mistake...

Thank you,

> 
> - Arnaldo
>  
> > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > ---
> >   Changes from v1:
> >    - Change the example.
> > ---
> >  tools/perf/arch/arm/include/dwarf-regs-table.h     |    9 +++
> >  tools/perf/arch/arm64/include/dwarf-regs-table.h   |   13 +++++
> >  tools/perf/arch/powerpc/include/dwarf-regs-table.h |   27 ++++++++++
> >  tools/perf/arch/s390/include/dwarf-regs-table.h    |    8 +++
> >  tools/perf/arch/sh/include/dwarf-regs-table.h      |   25 +++++++++
> >  tools/perf/arch/sparc/include/dwarf-regs-table.h   |   18 +++++++
> >  tools/perf/arch/x86/include/dwarf-regs-table.h     |   14 +++++
> >  tools/perf/arch/xtensa/include/dwarf-regs-table.h  |    8 +++
> >  tools/perf/util/Build                              |    1 
> >  tools/perf/util/dwarf-regs.c                       |   55 ++++++++++++++++++++
> >  tools/perf/util/include/dwarf-regs.h               |    6 ++
> >  tools/perf/util/probe-finder.c                     |   27 ++++++----
> >  tools/perf/util/probe-finder.h                     |    1 
> >  13 files changed, 201 insertions(+), 11 deletions(-)
> >  create mode 100644 tools/perf/arch/arm/include/dwarf-regs-table.h
> >  create mode 100644 tools/perf/arch/arm64/include/dwarf-regs-table.h
> >  create mode 100644 tools/perf/arch/powerpc/include/dwarf-regs-table.h
> >  create mode 100644 tools/perf/arch/s390/include/dwarf-regs-table.h
> >  create mode 100644 tools/perf/arch/sh/include/dwarf-regs-table.h
> >  create mode 100644 tools/perf/arch/sparc/include/dwarf-regs-table.h
> >  create mode 100644 tools/perf/arch/x86/include/dwarf-regs-table.h
> >  create mode 100644 tools/perf/arch/xtensa/include/dwarf-regs-table.h
> >  create mode 100644 tools/perf/util/dwarf-regs.c
> > 
> > diff --git a/tools/perf/arch/arm/include/dwarf-regs-table.h b/tools/perf/arch/arm/include/dwarf-regs-table.h
> > new file mode 100644
> > index 0000000..f298d03
> > --- /dev/null
> > +++ b/tools/perf/arch/arm/include/dwarf-regs-table.h
> > @@ -0,0 +1,9 @@
> > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > +/* This is included in perf/util/dwarf-regs.c */
> > +
> > +static const char * const arm_regstr_tbl[] = {
> > +	"%r0", "%r1", "%r2", "%r3", "%r4",
> > +	"%r5", "%r6", "%r7", "%r8", "%r9", "%r10",
> > +	"%fp", "%ip", "%sp", "%lr", "%pc",
> > +};
> > +#endif
> > diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> > new file mode 100644
> > index 0000000..2675936
> > --- /dev/null
> > +++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> > @@ -0,0 +1,13 @@
> > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > +/* This is included in perf/util/dwarf-regs.c */
> > +
> > +static const char * const aarch64_regstr_tbl[] = {
> > +	"%r0", "%r1", "%r2", "%r3", "%r4",
> > +	"%r5", "%r6", "%r7", "%r8", "%r9",
> > +	"%r10", "%r11", "%r12", "%r13", "%r14",
> > +	"%r15", "%r16", "%r17", "%r18", "%r19",
> > +	"%r20", "%r21", "%r22", "%r23", "%r24",
> > +	"%r25", "%r26", "%r27", "%r28", "%r29",
> > +	"%lr", "%sp",
> > +};
> > +#endif
> > diff --git a/tools/perf/arch/powerpc/include/dwarf-regs-table.h b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > new file mode 100644
> > index 0000000..db4730f
> > --- /dev/null
> > +++ b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > @@ -0,0 +1,27 @@
> > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > +/* This is included in perf/util/dwarf-regs.c */
> > +
> > +/*
> > + * Reference:
> > + * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
> > + * http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
> > + */
> > +#define REG_DWARFNUM_NAME(reg, idx)	[idx] = "%" #reg
> > +
> > +static const char * const powerpc_regstr_tbl[] = {
> > +	"%gpr0", "%gpr1", "%gpr2", "%gpr3", "%gpr4",
> > +	"%gpr5", "%gpr6", "%gpr7", "%gpr8", "%gpr9",
> > +	"%gpr10", "%gpr11", "%gpr12", "%gpr13", "%gpr14",
> > +	"%gpr15", "%gpr16", "%gpr17", "%gpr18", "%gpr19",
> > +	"%gpr20", "%gpr21", "%gpr22", "%gpr23", "%gpr24",
> > +	"%gpr25", "%gpr26", "%gpr27", "%gpr28", "%gpr29",
> > +	"%gpr30", "%gpr31",
> > +	REG_DWARFNUM_NAME(msr,   66),
> > +	REG_DWARFNUM_NAME(ctr,   109),
> > +	REG_DWARFNUM_NAME(link,  108),
> > +	REG_DWARFNUM_NAME(xer,   101),
> > +	REG_DWARFNUM_NAME(dar,   119),
> > +	REG_DWARFNUM_NAME(dsisr, 118),
> > +};
> > +
> > +#endif
> > diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
> > new file mode 100644
> > index 0000000..9da74a9
> > --- /dev/null
> > +++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
> > @@ -0,0 +1,8 @@
> > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > +/* This is included in perf/util/dwarf-regs.c */
> > +
> > +static const char * const s390_regstr_tbl[] = {
> > +	"%r0", "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
> > +	"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
> > +};
> > +#endif
> > diff --git a/tools/perf/arch/sh/include/dwarf-regs-table.h b/tools/perf/arch/sh/include/dwarf-regs-table.h
> > new file mode 100644
> > index 0000000..3a2deaf
> > --- /dev/null
> > +++ b/tools/perf/arch/sh/include/dwarf-regs-table.h
> > @@ -0,0 +1,25 @@
> > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > +/* This is included in perf/util/dwarf-regs.c */
> > +
> > +const char * const sh_regstr_tbl[] = {
> > +	"r0",
> > +	"r1",
> > +	"r2",
> > +	"r3",
> > +	"r4",
> > +	"r5",
> > +	"r6",
> > +	"r7",
> > +	"r8",
> > +	"r9",
> > +	"r10",
> > +	"r11",
> > +	"r12",
> > +	"r13",
> > +	"r14",
> > +	"r15",
> > +	"pc",
> > +	"pr",
> > +};
> > +
> > +#endif
> > diff --git a/tools/perf/arch/sparc/include/dwarf-regs-table.h b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> > new file mode 100644
> > index 0000000..12c0761
> > --- /dev/null
> > +++ b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> > @@ -0,0 +1,18 @@
> > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > +/* This is included in perf/util/dwarf-regs.c */
> > +
> > +static const char * const sparc_regstr_tbl[] = {
> > +	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
> > +	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
> > +	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
> > +	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",
> > +	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
> > +	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
> > +	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
> > +	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
> > +	"%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",
> > +	"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",
> > +	"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",
> > +	"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",
> > +};
> > +#endif
> > diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > new file mode 100644
> > index 0000000..39ac7cb
> > --- /dev/null
> > +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > @@ -0,0 +1,14 @@
> > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > +/* This is included in perf/util/dwarf-regs.c */
> > +
> > +static const char * const x86_32_regstr_tbl[] = {
> > +	"%ax", "%cx", "%dx", "%bx", "$stack",/* Stack address instead of %sp */
> > +	"%bp", "%si", "%di",
> > +};
> > +
> > +static const char * const x86_64_regstr_tbl[] = {
> > +	"%ax", "dx", "%cx", "%bx", "%si", "%di",
> > +	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
> > +	"%r12", "%r13", "%r14", "%r15",
> > +};
> > +#endif
> > diff --git a/tools/perf/arch/xtensa/include/dwarf-regs-table.h b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > new file mode 100644
> > index 0000000..aa0444a
> > --- /dev/null
> > +++ b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > @@ -0,0 +1,8 @@
> > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > +/* This is included in perf/util/dwarf-regs.c */
> > +
> > +static const char * const xtensa_regstr_tbl[] = {
> > +	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
> > +	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
> > +};
> > +#endif
> > diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> > index 91c5f6e..f1a6d17 100644
> > --- a/tools/perf/util/Build
> > +++ b/tools/perf/util/Build
> > @@ -98,6 +98,7 @@ endif
> >  
> >  libperf-$(CONFIG_DWARF) += probe-finder.o
> >  libperf-$(CONFIG_DWARF) += dwarf-aux.o
> > +libperf-$(CONFIG_DWARF) += dwarf-regs.o
> >  
> >  libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> >  libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
> > diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> > new file mode 100644
> > index 0000000..ce15816
> > --- /dev/null
> > +++ b/tools/perf/util/dwarf-regs.c
> > @@ -0,0 +1,55 @@
> > +/*
> > + * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
> > + *
> > + * Written by: Masami Hiramatsu <mhiramat@kernel.org>
> > + */
> > +
> > +#include <util.h>
> > +#include <debug.h>
> > +#include <dwarf-regs.h>
> > +#include <elf.h>
> > +
> > +/* Define const char * {arch}_register_tbl[] */
> > +#define DEFINE_DWARF_REGSTR_TABLE
> > +#include "../arch/x86/include/dwarf-regs-table.h"
> > +#include "../arch/arm/include/dwarf-regs-table.h"
> > +#include "../arch/arm64/include/dwarf-regs-table.h"
> > +#include "../arch/sh/include/dwarf-regs-table.h"
> > +#include "../arch/powerpc/include/dwarf-regs-table.h"
> > +#include "../arch/s390/include/dwarf-regs-table.h"
> > +#include "../arch/sparc/include/dwarf-regs-table.h"
> > +#include "../arch/xtensa/include/dwarf-regs-table.h"
> > +
> > +#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
> > +
> > +/* Return architecture dependent register string (for kprobe-tracer) */
> > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
> > +{
> > +	switch (machine) {
> > +	case EM_NONE:	/* Generic arch - use host arch */
> > +		return get_arch_regstr(n);
> > +	case EM_386:
> > +		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
> > +	case EM_X86_64:
> > +		return __get_dwarf_regstr(x86_64_regstr_tbl, n);
> > +	case EM_ARM:
> > +		return __get_dwarf_regstr(arm_regstr_tbl, n);
> > +	case EM_AARCH64:
> > +		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
> > +	case EM_SH:
> > +		return __get_dwarf_regstr(sh_regstr_tbl, n);
> > +	case EM_S390:
> > +		return __get_dwarf_regstr(s390_regstr_tbl, n);
> > +	case EM_PPC:
> > +	case EM_PPC64:
> > +		return __get_dwarf_regstr(powerpc_regstr_tbl, n);
> > +	case EM_SPARC:
> > +	case EM_SPARCV9:
> > +		return __get_dwarf_regstr(sparc_regstr_tbl, n);
> > +	case EM_XTENSA:
> > +		return __get_dwarf_regstr(xtensa_regstr_tbl, n);
> > +	default:
> > +		pr_err("ELF MACHINE %x is not supported.\n", machine);
> > +	}
> > +	return NULL;
> > +}
> > diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> > index 07c644e..43bfd8d 100644
> > --- a/tools/perf/util/include/dwarf-regs.h
> > +++ b/tools/perf/util/include/dwarf-regs.h
> > @@ -3,6 +3,12 @@
> >  
> >  #ifdef HAVE_DWARF_SUPPORT
> >  const char *get_arch_regstr(unsigned int n);
> > +/*
> > + * get_dwarf_regstr - Returns ftrace register string from DWARF regnum
> > + * n: DWARF register number
> > + * machine: ELF machine signature (EM_*)
> > + */
> > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
> >  #endif
> >  
> >  #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
> > diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> > index ac4740f..508b61c 100644
> > --- a/tools/perf/util/probe-finder.c
> > +++ b/tools/perf/util/probe-finder.c
> > @@ -171,6 +171,7 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
> >   */
> >  static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
> >  				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
> > +				     unsigned int machine,
> >  				     struct probe_trace_arg *tvar)
> >  {
> >  	Dwarf_Attribute attr;
> > @@ -266,7 +267,7 @@ static_var:
> >  	if (!tvar)
> >  		return ret2;
> >  
> > -	regs = get_arch_regstr(regn);
> > +	regs = get_dwarf_regstr(regn, machine);
> >  	if (!regs) {
> >  		/* This should be a bug in DWARF or this tool */
> >  		pr_warning("Mapping for the register number %u "
> > @@ -543,7 +544,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
> >  		 dwarf_diename(vr_die));
> >  
> >  	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
> > -					&pf->sp_die, pf->tvar);
> > +					&pf->sp_die, pf->machine, pf->tvar);
> >  	if (ret == -ENOENT || ret == -EINVAL) {
> >  		pr_err("Failed to find the location of the '%s' variable at this address.\n"
> >  		       " Perhaps it has been optimized out.\n"
> > @@ -1106,11 +1107,8 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
> >  				  struct probe_finder *pf)
> >  {
> >  	int ret = 0;
> > -
> > -#if _ELFUTILS_PREREQ(0, 142)
> >  	Elf *elf;
> >  	GElf_Ehdr ehdr;
> > -	GElf_Shdr shdr;
> >  
> >  	if (pf->cfi_eh || pf->cfi_dbg)
> >  		return debuginfo__find_probe_location(dbg, pf);
> > @@ -1123,11 +1121,18 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
> >  	if (gelf_getehdr(elf, &ehdr) == NULL)
> >  		return -EINVAL;
> >  
> > -	if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> > -	    shdr.sh_type == SHT_PROGBITS)
> > -		pf->cfi_eh = dwarf_getcfi_elf(elf);
> > +	pf->machine = ehdr.e_machine;
> > +
> > +#if _ELFUTILS_PREREQ(0, 142)
> > +	do {
> > +		GElf_Shdr shdr;
> > +
> > +		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> > +		    shdr.sh_type == SHT_PROGBITS)
> > +			pf->cfi_eh = dwarf_getcfi_elf(elf);
> >  
> > -	pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> > +		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> > +	} while (0);
> >  #endif
> >  
> >  	ret = debuginfo__find_probe_location(dbg, pf);
> > @@ -1155,7 +1160,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
> >  	    (tag == DW_TAG_variable && vf->vars)) {
> >  		if (convert_variable_location(die_mem, vf->pf->addr,
> >  					      vf->pf->fb_ops, &pf->sp_die,
> > -					      NULL) == 0) {
> > +					      pf->machine, NULL) == 0) {
> >  			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
> >  			if (vf->args[vf->nargs].var == NULL) {
> >  				vf->ret = -ENOMEM;
> > @@ -1318,7 +1323,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
> >  	    tag == DW_TAG_variable) {
> >  		ret = convert_variable_location(die_mem, af->pf.addr,
> >  						af->pf.fb_ops, &af->pf.sp_die,
> > -						NULL);
> > +						af->pf.machine, NULL);
> >  		if (ret == 0 || ret == -ERANGE) {
> >  			int ret2;
> >  			bool externs = !af->child;
> > diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
> > index 51137fc..f1d8558 100644
> > --- a/tools/perf/util/probe-finder.h
> > +++ b/tools/perf/util/probe-finder.h
> > @@ -80,6 +80,7 @@ struct probe_finder {
> >  	Dwarf_CFI		*cfi_dbg;
> >  #endif
> >  	Dwarf_Op		*fb_ops;	/* Frame base attribute */
> > +	unsigned int		machine;	/* Target machine arch */
> >  	struct perf_probe_arg	*pvar;		/* Current target variable */
> >  	struct probe_trace_arg	*tvar;		/* Current result variable */
> >  };


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [tip:perf/core] perf probe: Show trace event definition
  2016-08-25 16:24 ` [PATCH v2 1/3] perf-probe: Show trace event definition Masami Hiramatsu
@ 2016-09-05 13:22   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-09-05 13:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, acme, peterz, mingo, tglx, hpa, mingo, mhiramat, jolsa

Commit-ID:  1c20b1d15473a91e2fccecbcd2809d80ff4b4924
Gitweb:     http://git.kernel.org/tip/1c20b1d15473a91e2fccecbcd2809d80ff4b4924
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Fri, 26 Aug 2016 01:24:27 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 1 Sep 2016 09:44:13 -0300

perf probe: Show trace event definition

Add --definition/-D option for showing the trace-event definition in
stdout. This can be useful in debugging or combined with a shell script.

e.g.
  ----
  # perf probe --definition 'do_sys_open $params'
  p:probe/do_sys_open _text+2261728 dfd=%di:s32 filename=%si:u64 flags=%dx:s32 mode=%cx:u16
  ----

Suggested-and-Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/147214226712.23638.2240534040014013658.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-probe.txt |  7 +++++
 tools/perf/builtin-probe.c              | 26 ++++++++++++++-----
 tools/perf/util/probe-event.c           | 46 +++++++++++++++++++++++++++++++++
 tools/perf/util/probe-event.h           |  1 +
 4 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index f37d123..56db4d4 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -21,6 +21,8 @@ or
 'perf probe' [options] --vars='PROBEPOINT'
 or
 'perf probe' [options] --funcs
+or
+'perf probe' [options] --definition='PROBE' [...]
 
 DESCRIPTION
 -----------
@@ -96,6 +98,11 @@ OPTIONS
 	can also list functions in a user space executable / shared library.
 	This also can accept a FILTER rule argument.
 
+-D::
+--definition=::
+	Show trace-event definition converted from given probe-event instead
+	of write it into tracing/[k,u]probe_events.
+
 --filter=FILTER::
 	(Only for --vars and --funcs) Set filter. FILTER is a combination of glob
 	pattern, see FILTER PATTERN for detail.
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index ee5b421..7a3d8c4 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -326,6 +326,11 @@ static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs)
 	if (ret < 0)
 		goto out_cleanup;
 
+	if (params.command == 'D') {	/* it shows definition */
+		ret = show_probe_trace_events(pevs, npevs);
+		goto out_cleanup;
+	}
+
 	ret = apply_perf_probe_events(pevs, npevs);
 	if (ret < 0)
 		goto out_cleanup;
@@ -454,6 +459,14 @@ out:
 	return ret;
 }
 
+#ifdef HAVE_DWARF_SUPPORT
+#define PROBEDEF_STR	\
+	"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT [[NAME=]ARG ...]"
+#else
+#define PROBEDEF_STR	"[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]"
+#endif
+
+
 static int
 __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 {
@@ -479,13 +492,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 			     opt_set_filter_with_command, DEFAULT_LIST_FILTER),
 	OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
 		     opt_set_filter_with_command),
-	OPT_CALLBACK('a', "add", NULL,
-#ifdef HAVE_DWARF_SUPPORT
-		"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
-		" [[NAME=]ARG ...]",
-#else
-		"[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]",
-#endif
+	OPT_CALLBACK('a', "add", NULL, PROBEDEF_STR,
 		"probe point definition, where\n"
 		"\t\tGROUP:\tGroup name (optional)\n"
 		"\t\tEVENT:\tEvent name\n"
@@ -503,6 +510,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 		"\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
 #endif
 		opt_add_probe_event),
+	OPT_CALLBACK('D', "definition", NULL, PROBEDEF_STR,
+		"Show trace event definition of given traceevent for k/uprobe_events.",
+		opt_add_probe_event),
 	OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events"
 		    " with existing name"),
 	OPT_CALLBACK('L', "line", NULL,
@@ -548,6 +558,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	set_option_flag(options, 'a', "add", PARSE_OPT_EXCLUSIVE);
 	set_option_flag(options, 'd', "del", PARSE_OPT_EXCLUSIVE);
+	set_option_flag(options, 'D', "definition", PARSE_OPT_EXCLUSIVE);
 	set_option_flag(options, 'l', "list", PARSE_OPT_EXCLUSIVE);
 #ifdef HAVE_DWARF_SUPPORT
 	set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE);
@@ -644,6 +655,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 		}
 		break;
 	case 'a':
+	case 'D':
 		/* Ensure the last given target is used */
 		if (params.target && !params.target_used) {
 			pr_err("  Error: -x/-m must follow the probe definitions.\n");
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 0bed2ee..4a49cb8 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -3207,6 +3207,52 @@ int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)
 	return 0;
 }
 
+static int show_probe_trace_event(struct probe_trace_event *tev)
+{
+	char *buf = synthesize_probe_trace_command(tev);
+
+	if (!buf) {
+		pr_debug("Failed to synthesize probe trace event.\n");
+		return -EINVAL;
+	}
+
+	/* Showing definition always go stdout */
+	printf("%s\n", buf);
+	free(buf);
+
+	return 0;
+}
+
+int show_probe_trace_events(struct perf_probe_event *pevs, int npevs)
+{
+	struct strlist *namelist = strlist__new(NULL, NULL);
+	struct probe_trace_event *tev;
+	struct perf_probe_event *pev;
+	int i, j, ret = 0;
+
+	if (!namelist)
+		return -ENOMEM;
+
+	for (j = 0; j < npevs && !ret; j++) {
+		pev = &pevs[j];
+		for (i = 0; i < pev->ntevs && !ret; i++) {
+			tev = &pev->tevs[i];
+			/* Skip if the symbol is out of .text or blacklisted */
+			if (!tev->point.symbol && !pev->uprobes)
+				continue;
+
+			/* Set new name for tev (and update namelist) */
+			ret = probe_trace_event__set_name(tev, pev,
+							  namelist, true);
+			if (!ret)
+				ret = show_probe_trace_event(tev);
+		}
+	}
+	strlist__delete(namelist);
+
+	return ret;
+}
+
 int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
 {
 	int i, ret = 0;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index f4f45db..6209408 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -147,6 +147,7 @@ int line_range__init(struct line_range *lr);
 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
 int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
 int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
+int show_probe_trace_events(struct perf_probe_event *pevs, int npevs);
 void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
 int del_perf_probe_events(struct strfilter *filter);
 

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [tip:perf/core] perf probe: Ignore vmlinux buildid if offline kernel is given
  2016-08-25 16:24 ` [PATCH v2 2/3] perf-probe: Ignore vmlinux buildid if offline kernel is given Masami Hiramatsu
  2016-08-26 14:02   ` Masami Hiramatsu
@ 2016-09-05 13:22   ` tip-bot for Masami Hiramatsu
  1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-09-05 13:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, linux-kernel, mingo, acme, jolsa, hpa, peterz, mhiramat

Commit-ID:  428aff82e92a29da0e4276623180f9a98f2d5b16
Gitweb:     http://git.kernel.org/tip/428aff82e92a29da0e4276623180f9a98f2d5b16
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Fri, 26 Aug 2016 01:24:42 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 1 Sep 2016 09:44:14 -0300

perf probe: Ignore vmlinux buildid if offline kernel is given

Ignore the buildid of running kernel when both of --definition and
--vmlinux is given because that kernel should be off-line.

This also skips post-processing of kprobe event for relocating symbol
and checking blacklist, because it can not be done on off-line kernel.

E.g. without this fix perf shows an error as below
  ----
  $ perf probe --vmlinux=./vmlinux-arm --definition do_sys_open
  ./vmlinux-arm with build id 7a1f76dd56e9c4da707cd3d6333f50748141434b not found, continuing without symbols
  Failed to find symbol do_sys_open in kernel
    Error: Failed to add events.
  ----
with this fix, we can get the definition
  ----
  $ perf probe --vmlinux=./vmlinux-arm --definition do_sys_open
  p:probe/do_sys_open do_sys_open+0
  ----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/147214228193.23638.12581984840822162131.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-probe.txt |  2 ++
 tools/perf/builtin-probe.c              | 10 +++++++++-
 tools/perf/util/probe-event.c           |  4 ++++
 tools/perf/util/symbol-elf.c            |  2 +-
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 56db4d4..e6c9902 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -36,6 +36,8 @@ OPTIONS
 -k::
 --vmlinux=PATH::
 	Specify vmlinux path which has debuginfo (Dwarf binary).
+	Only when using this with --definition, you can give an offline
+	vmlinux file.
 
 -m::
 --module=MODNAME|PATH::
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 7a3d8c4..b4220cd 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -654,8 +654,16 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 			return ret;
 		}
 		break;
-	case 'a':
 	case 'D':
+		/*
+		 * If user gives offline vmlinux, ignore buildid, since
+		 * --definition doesn't change running kernel.
+		 */
+		if (symbol_conf.vmlinux_name)
+			symbol_conf.ignore_vmlinux_buildid = true;
+		/* fall through */
+	case 'a':
+
 		/* Ensure the last given target is used */
 		if (params.target && !params.target_used) {
 			pr_err("  Error: -x/-m must follow the probe definitions.\n");
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 4a49cb8..8a1e9e6 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -674,6 +674,10 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
 	char *tmp;
 	int i, skipped = 0;
 
+	/* Skip post process if the target is an offline kernel */
+	if (symbol_conf.ignore_vmlinux_buildid)
+		return 0;
+
 	reloc_sym = kernel_get_ref_reloc_sym();
 	if (!reloc_sym) {
 		pr_warning("Relocated base symbol is not found!\n");
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index fbe31ef..e680371 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -732,7 +732,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
 	}
 
 	/* Always reject images with a mismatched build-id: */
-	if (dso->has_build_id) {
+	if (dso->has_build_id && !symbol_conf.ignore_vmlinux_buildid) {
 		u8 build_id[BUILD_ID_SIZE];
 
 		if (elf_read_build_id(elf, build_id, BUILD_ID_SIZE) < 0) {

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [tip:perf/core] perf probe: Support probing on offline cross-arch binary
  2016-08-25 16:24 ` [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary Masami Hiramatsu
  2016-08-31 20:54   ` Arnaldo Carvalho de Melo
@ 2016-09-05 13:23   ` tip-bot for Masami Hiramatsu
  1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-09-05 13:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, tglx, jolsa, hpa, peterz, mhiramat, mingo

Commit-ID:  293d5b43948309434568f4dcbb36cce4c3c51bd5
Gitweb:     http://git.kernel.org/tip/293d5b43948309434568f4dcbb36cce4c3c51bd5
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Fri, 26 Aug 2016 01:24:57 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 1 Sep 2016 12:41:09 -0300

perf probe: Support probing on offline cross-arch binary

Support probing on offline cross-architecture binary by adding getting
the target machine arch from ELF and choose correct register string for
the machine.

Here is an example:
  -----
  $ perf probe --vmlinux=./vmlinux-arm --definition 'do_sys_open $params'
  p:probe/do_sys_open do_sys_open+0 dfd=%r5:s32 filename=%r1:u32 flags=%r6:s32 mode=%r3:u16
  -----

Here, we can get probe/do_sys_open from above and append it to to the target
machine's tracing/kprobe_events file in the tracefs mountput, usually
/sys/kernel/debug/tracing/kprobe_events (or /sys/kernel/tracing/kprobe_events).

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/147214229717.23638.6440579792548044658.stgit@devbox
[ Add definition for EM_AARCH64 to fix the build on at least centos 6, debian 7 & ubuntu 12.04.5 ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/arm/include/dwarf-regs-table.h     |  9 ++++
 tools/perf/arch/arm64/include/dwarf-regs-table.h   | 13 +++++
 tools/perf/arch/powerpc/include/dwarf-regs-table.h | 27 ++++++++++
 tools/perf/arch/s390/include/dwarf-regs-table.h    |  8 +++
 tools/perf/arch/sh/include/dwarf-regs-table.h      | 25 +++++++++
 tools/perf/arch/sparc/include/dwarf-regs-table.h   | 18 +++++++
 tools/perf/arch/x86/include/dwarf-regs-table.h     | 14 +++++
 tools/perf/arch/xtensa/include/dwarf-regs-table.h  |  8 +++
 tools/perf/util/Build                              |  1 +
 tools/perf/util/dwarf-regs.c                       | 59 ++++++++++++++++++++++
 tools/perf/util/include/dwarf-regs.h               |  6 +++
 tools/perf/util/probe-finder.c                     | 27 ++++++----
 tools/perf/util/probe-finder.h                     |  1 +
 13 files changed, 205 insertions(+), 11 deletions(-)

diff --git a/tools/perf/arch/arm/include/dwarf-regs-table.h b/tools/perf/arch/arm/include/dwarf-regs-table.h
new file mode 100644
index 0000000..f298d03
--- /dev/null
+++ b/tools/perf/arch/arm/include/dwarf-regs-table.h
@@ -0,0 +1,9 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const arm_regstr_tbl[] = {
+	"%r0", "%r1", "%r2", "%r3", "%r4",
+	"%r5", "%r6", "%r7", "%r8", "%r9", "%r10",
+	"%fp", "%ip", "%sp", "%lr", "%pc",
+};
+#endif
diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h
new file mode 100644
index 0000000..2675936
--- /dev/null
+++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h
@@ -0,0 +1,13 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const aarch64_regstr_tbl[] = {
+	"%r0", "%r1", "%r2", "%r3", "%r4",
+	"%r5", "%r6", "%r7", "%r8", "%r9",
+	"%r10", "%r11", "%r12", "%r13", "%r14",
+	"%r15", "%r16", "%r17", "%r18", "%r19",
+	"%r20", "%r21", "%r22", "%r23", "%r24",
+	"%r25", "%r26", "%r27", "%r28", "%r29",
+	"%lr", "%sp",
+};
+#endif
diff --git a/tools/perf/arch/powerpc/include/dwarf-regs-table.h b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
new file mode 100644
index 0000000..db4730f
--- /dev/null
+++ b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
@@ -0,0 +1,27 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+/*
+ * Reference:
+ * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
+ * http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
+ */
+#define REG_DWARFNUM_NAME(reg, idx)	[idx] = "%" #reg
+
+static const char * const powerpc_regstr_tbl[] = {
+	"%gpr0", "%gpr1", "%gpr2", "%gpr3", "%gpr4",
+	"%gpr5", "%gpr6", "%gpr7", "%gpr8", "%gpr9",
+	"%gpr10", "%gpr11", "%gpr12", "%gpr13", "%gpr14",
+	"%gpr15", "%gpr16", "%gpr17", "%gpr18", "%gpr19",
+	"%gpr20", "%gpr21", "%gpr22", "%gpr23", "%gpr24",
+	"%gpr25", "%gpr26", "%gpr27", "%gpr28", "%gpr29",
+	"%gpr30", "%gpr31",
+	REG_DWARFNUM_NAME(msr,   66),
+	REG_DWARFNUM_NAME(ctr,   109),
+	REG_DWARFNUM_NAME(link,  108),
+	REG_DWARFNUM_NAME(xer,   101),
+	REG_DWARFNUM_NAME(dar,   119),
+	REG_DWARFNUM_NAME(dsisr, 118),
+};
+
+#endif
diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
new file mode 100644
index 0000000..9da74a9
--- /dev/null
+++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
@@ -0,0 +1,8 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const s390_regstr_tbl[] = {
+	"%r0", "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
+	"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
+};
+#endif
diff --git a/tools/perf/arch/sh/include/dwarf-regs-table.h b/tools/perf/arch/sh/include/dwarf-regs-table.h
new file mode 100644
index 0000000..3a2deaf
--- /dev/null
+++ b/tools/perf/arch/sh/include/dwarf-regs-table.h
@@ -0,0 +1,25 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+const char * const sh_regstr_tbl[] = {
+	"r0",
+	"r1",
+	"r2",
+	"r3",
+	"r4",
+	"r5",
+	"r6",
+	"r7",
+	"r8",
+	"r9",
+	"r10",
+	"r11",
+	"r12",
+	"r13",
+	"r14",
+	"r15",
+	"pc",
+	"pr",
+};
+
+#endif
diff --git a/tools/perf/arch/sparc/include/dwarf-regs-table.h b/tools/perf/arch/sparc/include/dwarf-regs-table.h
new file mode 100644
index 0000000..12c0761
--- /dev/null
+++ b/tools/perf/arch/sparc/include/dwarf-regs-table.h
@@ -0,0 +1,18 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const sparc_regstr_tbl[] = {
+	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
+	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
+	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
+	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",
+	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
+	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
+	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
+	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
+	"%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",
+	"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",
+	"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",
+	"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",
+};
+#endif
diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
new file mode 100644
index 0000000..39ac7cb
--- /dev/null
+++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
@@ -0,0 +1,14 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const x86_32_regstr_tbl[] = {
+	"%ax", "%cx", "%dx", "%bx", "$stack",/* Stack address instead of %sp */
+	"%bp", "%si", "%di",
+};
+
+static const char * const x86_64_regstr_tbl[] = {
+	"%ax", "dx", "%cx", "%bx", "%si", "%di",
+	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
+	"%r12", "%r13", "%r14", "%r15",
+};
+#endif
diff --git a/tools/perf/arch/xtensa/include/dwarf-regs-table.h b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
new file mode 100644
index 0000000..aa0444a
--- /dev/null
+++ b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
@@ -0,0 +1,8 @@
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
+
+static const char * const xtensa_regstr_tbl[] = {
+	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
+	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
+};
+#endif
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 91c5f6e..f1a6d17 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -98,6 +98,7 @@ endif
 
 libperf-$(CONFIG_DWARF) += probe-finder.o
 libperf-$(CONFIG_DWARF) += dwarf-aux.o
+libperf-$(CONFIG_DWARF) += dwarf-regs.o
 
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
new file mode 100644
index 0000000..62bc4a8
--- /dev/null
+++ b/tools/perf/util/dwarf-regs.c
@@ -0,0 +1,59 @@
+/*
+ * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
+ *
+ * Written by: Masami Hiramatsu <mhiramat@kernel.org>
+ */
+
+#include <util.h>
+#include <debug.h>
+#include <dwarf-regs.h>
+#include <elf.h>
+
+#ifndef EM_AARCH64
+#define EM_AARCH64	183  /* ARM 64 bit */
+#endif
+
+/* Define const char * {arch}_register_tbl[] */
+#define DEFINE_DWARF_REGSTR_TABLE
+#include "../arch/x86/include/dwarf-regs-table.h"
+#include "../arch/arm/include/dwarf-regs-table.h"
+#include "../arch/arm64/include/dwarf-regs-table.h"
+#include "../arch/sh/include/dwarf-regs-table.h"
+#include "../arch/powerpc/include/dwarf-regs-table.h"
+#include "../arch/s390/include/dwarf-regs-table.h"
+#include "../arch/sparc/include/dwarf-regs-table.h"
+#include "../arch/xtensa/include/dwarf-regs-table.h"
+
+#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
+
+/* Return architecture dependent register string (for kprobe-tracer) */
+const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
+{
+	switch (machine) {
+	case EM_NONE:	/* Generic arch - use host arch */
+		return get_arch_regstr(n);
+	case EM_386:
+		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
+	case EM_X86_64:
+		return __get_dwarf_regstr(x86_64_regstr_tbl, n);
+	case EM_ARM:
+		return __get_dwarf_regstr(arm_regstr_tbl, n);
+	case EM_AARCH64:
+		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
+	case EM_SH:
+		return __get_dwarf_regstr(sh_regstr_tbl, n);
+	case EM_S390:
+		return __get_dwarf_regstr(s390_regstr_tbl, n);
+	case EM_PPC:
+	case EM_PPC64:
+		return __get_dwarf_regstr(powerpc_regstr_tbl, n);
+	case EM_SPARC:
+	case EM_SPARCV9:
+		return __get_dwarf_regstr(sparc_regstr_tbl, n);
+	case EM_XTENSA:
+		return __get_dwarf_regstr(xtensa_regstr_tbl, n);
+	default:
+		pr_err("ELF MACHINE %x is not supported.\n", machine);
+	}
+	return NULL;
+}
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 07c644e..43bfd8d 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -3,6 +3,12 @@
 
 #ifdef HAVE_DWARF_SUPPORT
 const char *get_arch_regstr(unsigned int n);
+/*
+ * get_dwarf_regstr - Returns ftrace register string from DWARF regnum
+ * n: DWARF register number
+ * machine: ELF machine signature (EM_*)
+ */
+const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
 #endif
 
 #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index ac4740f..508b61c 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -171,6 +171,7 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
  */
 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
 				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
+				     unsigned int machine,
 				     struct probe_trace_arg *tvar)
 {
 	Dwarf_Attribute attr;
@@ -266,7 +267,7 @@ static_var:
 	if (!tvar)
 		return ret2;
 
-	regs = get_arch_regstr(regn);
+	regs = get_dwarf_regstr(regn, machine);
 	if (!regs) {
 		/* This should be a bug in DWARF or this tool */
 		pr_warning("Mapping for the register number %u "
@@ -543,7 +544,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
 		 dwarf_diename(vr_die));
 
 	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
-					&pf->sp_die, pf->tvar);
+					&pf->sp_die, pf->machine, pf->tvar);
 	if (ret == -ENOENT || ret == -EINVAL) {
 		pr_err("Failed to find the location of the '%s' variable at this address.\n"
 		       " Perhaps it has been optimized out.\n"
@@ -1106,11 +1107,8 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
 				  struct probe_finder *pf)
 {
 	int ret = 0;
-
-#if _ELFUTILS_PREREQ(0, 142)
 	Elf *elf;
 	GElf_Ehdr ehdr;
-	GElf_Shdr shdr;
 
 	if (pf->cfi_eh || pf->cfi_dbg)
 		return debuginfo__find_probe_location(dbg, pf);
@@ -1123,11 +1121,18 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
 	if (gelf_getehdr(elf, &ehdr) == NULL)
 		return -EINVAL;
 
-	if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
-	    shdr.sh_type == SHT_PROGBITS)
-		pf->cfi_eh = dwarf_getcfi_elf(elf);
+	pf->machine = ehdr.e_machine;
+
+#if _ELFUTILS_PREREQ(0, 142)
+	do {
+		GElf_Shdr shdr;
+
+		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
+		    shdr.sh_type == SHT_PROGBITS)
+			pf->cfi_eh = dwarf_getcfi_elf(elf);
 
-	pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
+		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
+	} while (0);
 #endif
 
 	ret = debuginfo__find_probe_location(dbg, pf);
@@ -1155,7 +1160,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
 	    (tag == DW_TAG_variable && vf->vars)) {
 		if (convert_variable_location(die_mem, vf->pf->addr,
 					      vf->pf->fb_ops, &pf->sp_die,
-					      NULL) == 0) {
+					      pf->machine, NULL) == 0) {
 			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
 			if (vf->args[vf->nargs].var == NULL) {
 				vf->ret = -ENOMEM;
@@ -1318,7 +1323,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
 	    tag == DW_TAG_variable) {
 		ret = convert_variable_location(die_mem, af->pf.addr,
 						af->pf.fb_ops, &af->pf.sp_die,
-						NULL);
+						af->pf.machine, NULL);
 		if (ret == 0 || ret == -ERANGE) {
 			int ret2;
 			bool externs = !af->child;
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 51137fc..f1d8558 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -80,6 +80,7 @@ struct probe_finder {
 	Dwarf_CFI		*cfi_dbg;
 #endif
 	Dwarf_Op		*fb_ops;	/* Frame base attribute */
+	unsigned int		machine;	/* Target machine arch */
 	struct perf_probe_arg	*pvar;		/* Current target variable */
 	struct probe_trace_arg	*tvar;		/* Current result variable */
 };

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [tip:perf/core] perf probe: Ignore vmlinux Build-id when offline vmlinux given
  2016-08-26 14:57 ` [PATCH v2 4/4] perf-probe: Ignore vmlinux Build-id when offline vmlinux given Masami Hiramatsu
@ 2016-09-05 13:23   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-09-05 13:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mhiramat, hpa, tglx, acme, mingo, jolsa, peterz, linux-kernel

Commit-ID:  e50243bbeb528e92e31e03e560b557737c9def3c
Gitweb:     http://git.kernel.org/tip/e50243bbeb528e92e31e03e560b557737c9def3c
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Fri, 26 Aug 2016 23:57:58 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 1 Sep 2016 12:42:22 -0300

perf probe: Ignore vmlinux Build-id when offline vmlinux given

Ignore vmlinux build-id when user gives offline vmlinux if the command
does not affect running kernel.

perf-probe has several actions some of them does not change the running
kernel, like --lines, --vars, and --funcs.

e.g.
  -----
  $ ./perf probe -k ./vmlinux-arm -V do_sys_open:14
  Available variables at do_sys_open:14
          @<do_sys_open+202>
                  char*   filename
                  int     dfd
                  int     fd
                  int     flags
                  struct filename*        tmp
                  struct open_flags       op
                  umode_t mode
  -----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/147222347320.5088.2582658035296667520.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-probe.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index b4220cd..f87996b 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -611,6 +611,14 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 	 */
 	symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
 
+	/*
+	 * Except for --list, --del and --add, other command doesn't depend
+	 * nor change running kernel. So if user gives offline vmlinux,
+	 * ignore its buildid.
+	 */
+	if (!strchr("lda", params.command) && symbol_conf.vmlinux_name)
+		symbol_conf.ignore_vmlinux_buildid = true;
+
 	switch (params.command) {
 	case 'l':
 		if (params.uprobes) {
@@ -655,13 +663,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 		}
 		break;
 	case 'D':
-		/*
-		 * If user gives offline vmlinux, ignore buildid, since
-		 * --definition doesn't change running kernel.
-		 */
-		if (symbol_conf.vmlinux_name)
-			symbol_conf.ignore_vmlinux_buildid = true;
-		/* fall through */
 	case 'a':
 
 		/* Ensure the last given target is used */

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [BUG] Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
  2016-08-31 23:25     ` Masami Hiramatsu
@ 2016-09-09 14:37       ` Arnaldo Carvalho de Melo
  2016-09-09 14:59         ` [BUGFIX] " Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 17+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-09 14:37 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Wang Nan, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Em Thu, Sep 01, 2016 at 08:25:25AM +0900, Masami Hiramatsu escreveu:
> On Wed, 31 Aug 2016 17:54:11 -0300
> Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> 
> > Em Fri, Aug 26, 2016 at 01:24:57AM +0900, Masami Hiramatsu escreveu:
> > > Support probing on offline cross-architecture binary by
> > > adding getting the target machine arch from ELF and
> > > choose correct register string for the machine.
> > > 
> > > Here is an example:
> > >   -----
> > >   $ perf probe --vmlinux=./vmlinux-arm --definition 'do_sys_open $params'
> > >   p:probe/do_sys_open do_sys_open+0 dfd=%r5:s32 filename=%r1:u32 flags=%r6:s32 mode=%r3:u16
> > >   -----
> > > Here, we can get probe/do_sys_open event by "copy & paste" from
> > > ./tracing/kprobe_events to target-machine's debugfs/tracing/kprobe_events
> > 
> > Fixing the example not to refer to "tracing/kprobe_events", as it is not
> > there anymore, instead append what '--definition' produced to the target
> > machine <tracefs mountpoint>/tracing/kprobe_events file.
> 
> Oops, right, it's my mistake...

I just bisect down to this cset as the reason for:

[root@jouet linux]# perf test bpf
37: Test BPF filter                                          :
37.1: Test basic BPF filtering                               : Ok
37.2: Test BPF prologue generation                           : FAILED!
37.3: Test BPF relocation checker                            : Skip
[root@jouet linux]# 

[root@jouet linux]# perf test -v bpf
<SNIP>
Found 1 probe_trace_events.
Opening /sys/kernel/debug/tracing//kprobe_events write=1
Parsing probe_events: p:probe/vfs_getname _text+2483816
pathname=+0(%di):string
Group:probe Event:vfs_getname probe:p
Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32
offset=%si:s64 orig=dx:s32
Failed to write event: Invalid argument
bpf_probe: failed to apply perf probe eventsFailed to add events
selected by BPF
Opening /sys/kernel/debug/tracing//kprobe_events write=1
Opening /sys/kernel/debug/tracing//uprobe_events write=1
Parsing probe_events: p:probe/vfs_getname _text+2483816
pathname=+0(%di):string
Group:probe Event:vfs_getname probe:p
test child finished with -1
---- end ----
Test BPF filter subtest 1: FAILED!
37.3: Test BPF relocation checker                            :
--- force skipped ---
Test BPF filter subtest 2: Skip
[root@jouet linux]# 

Trying to fix this...

- Arnaldo

 
> Thank you,
> 
> > 
> > - Arnaldo
> >  
> > > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > > ---
> > >   Changes from v1:
> > >    - Change the example.
> > > ---
> > >  tools/perf/arch/arm/include/dwarf-regs-table.h     |    9 +++
> > >  tools/perf/arch/arm64/include/dwarf-regs-table.h   |   13 +++++
> > >  tools/perf/arch/powerpc/include/dwarf-regs-table.h |   27 ++++++++++
> > >  tools/perf/arch/s390/include/dwarf-regs-table.h    |    8 +++
> > >  tools/perf/arch/sh/include/dwarf-regs-table.h      |   25 +++++++++
> > >  tools/perf/arch/sparc/include/dwarf-regs-table.h   |   18 +++++++
> > >  tools/perf/arch/x86/include/dwarf-regs-table.h     |   14 +++++
> > >  tools/perf/arch/xtensa/include/dwarf-regs-table.h  |    8 +++
> > >  tools/perf/util/Build                              |    1 
> > >  tools/perf/util/dwarf-regs.c                       |   55 ++++++++++++++++++++
> > >  tools/perf/util/include/dwarf-regs.h               |    6 ++
> > >  tools/perf/util/probe-finder.c                     |   27 ++++++----
> > >  tools/perf/util/probe-finder.h                     |    1 
> > >  13 files changed, 201 insertions(+), 11 deletions(-)
> > >  create mode 100644 tools/perf/arch/arm/include/dwarf-regs-table.h
> > >  create mode 100644 tools/perf/arch/arm64/include/dwarf-regs-table.h
> > >  create mode 100644 tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > >  create mode 100644 tools/perf/arch/s390/include/dwarf-regs-table.h
> > >  create mode 100644 tools/perf/arch/sh/include/dwarf-regs-table.h
> > >  create mode 100644 tools/perf/arch/sparc/include/dwarf-regs-table.h
> > >  create mode 100644 tools/perf/arch/x86/include/dwarf-regs-table.h
> > >  create mode 100644 tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > >  create mode 100644 tools/perf/util/dwarf-regs.c
> > > 
> > > diff --git a/tools/perf/arch/arm/include/dwarf-regs-table.h b/tools/perf/arch/arm/include/dwarf-regs-table.h
> > > new file mode 100644
> > > index 0000000..f298d03
> > > --- /dev/null
> > > +++ b/tools/perf/arch/arm/include/dwarf-regs-table.h
> > > @@ -0,0 +1,9 @@
> > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > +/* This is included in perf/util/dwarf-regs.c */
> > > +
> > > +static const char * const arm_regstr_tbl[] = {
> > > +	"%r0", "%r1", "%r2", "%r3", "%r4",
> > > +	"%r5", "%r6", "%r7", "%r8", "%r9", "%r10",
> > > +	"%fp", "%ip", "%sp", "%lr", "%pc",
> > > +};
> > > +#endif
> > > diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> > > new file mode 100644
> > > index 0000000..2675936
> > > --- /dev/null
> > > +++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> > > @@ -0,0 +1,13 @@
> > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > +/* This is included in perf/util/dwarf-regs.c */
> > > +
> > > +static const char * const aarch64_regstr_tbl[] = {
> > > +	"%r0", "%r1", "%r2", "%r3", "%r4",
> > > +	"%r5", "%r6", "%r7", "%r8", "%r9",
> > > +	"%r10", "%r11", "%r12", "%r13", "%r14",
> > > +	"%r15", "%r16", "%r17", "%r18", "%r19",
> > > +	"%r20", "%r21", "%r22", "%r23", "%r24",
> > > +	"%r25", "%r26", "%r27", "%r28", "%r29",
> > > +	"%lr", "%sp",
> > > +};
> > > +#endif
> > > diff --git a/tools/perf/arch/powerpc/include/dwarf-regs-table.h b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > > new file mode 100644
> > > index 0000000..db4730f
> > > --- /dev/null
> > > +++ b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > > @@ -0,0 +1,27 @@
> > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > +/* This is included in perf/util/dwarf-regs.c */
> > > +
> > > +/*
> > > + * Reference:
> > > + * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
> > > + * http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
> > > + */
> > > +#define REG_DWARFNUM_NAME(reg, idx)	[idx] = "%" #reg
> > > +
> > > +static const char * const powerpc_regstr_tbl[] = {
> > > +	"%gpr0", "%gpr1", "%gpr2", "%gpr3", "%gpr4",
> > > +	"%gpr5", "%gpr6", "%gpr7", "%gpr8", "%gpr9",
> > > +	"%gpr10", "%gpr11", "%gpr12", "%gpr13", "%gpr14",
> > > +	"%gpr15", "%gpr16", "%gpr17", "%gpr18", "%gpr19",
> > > +	"%gpr20", "%gpr21", "%gpr22", "%gpr23", "%gpr24",
> > > +	"%gpr25", "%gpr26", "%gpr27", "%gpr28", "%gpr29",
> > > +	"%gpr30", "%gpr31",
> > > +	REG_DWARFNUM_NAME(msr,   66),
> > > +	REG_DWARFNUM_NAME(ctr,   109),
> > > +	REG_DWARFNUM_NAME(link,  108),
> > > +	REG_DWARFNUM_NAME(xer,   101),
> > > +	REG_DWARFNUM_NAME(dar,   119),
> > > +	REG_DWARFNUM_NAME(dsisr, 118),
> > > +};
> > > +
> > > +#endif
> > > diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
> > > new file mode 100644
> > > index 0000000..9da74a9
> > > --- /dev/null
> > > +++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
> > > @@ -0,0 +1,8 @@
> > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > +/* This is included in perf/util/dwarf-regs.c */
> > > +
> > > +static const char * const s390_regstr_tbl[] = {
> > > +	"%r0", "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
> > > +	"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
> > > +};
> > > +#endif
> > > diff --git a/tools/perf/arch/sh/include/dwarf-regs-table.h b/tools/perf/arch/sh/include/dwarf-regs-table.h
> > > new file mode 100644
> > > index 0000000..3a2deaf
> > > --- /dev/null
> > > +++ b/tools/perf/arch/sh/include/dwarf-regs-table.h
> > > @@ -0,0 +1,25 @@
> > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > +/* This is included in perf/util/dwarf-regs.c */
> > > +
> > > +const char * const sh_regstr_tbl[] = {
> > > +	"r0",
> > > +	"r1",
> > > +	"r2",
> > > +	"r3",
> > > +	"r4",
> > > +	"r5",
> > > +	"r6",
> > > +	"r7",
> > > +	"r8",
> > > +	"r9",
> > > +	"r10",
> > > +	"r11",
> > > +	"r12",
> > > +	"r13",
> > > +	"r14",
> > > +	"r15",
> > > +	"pc",
> > > +	"pr",
> > > +};
> > > +
> > > +#endif
> > > diff --git a/tools/perf/arch/sparc/include/dwarf-regs-table.h b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> > > new file mode 100644
> > > index 0000000..12c0761
> > > --- /dev/null
> > > +++ b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> > > @@ -0,0 +1,18 @@
> > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > +/* This is included in perf/util/dwarf-regs.c */
> > > +
> > > +static const char * const sparc_regstr_tbl[] = {
> > > +	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
> > > +	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
> > > +	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
> > > +	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",
> > > +	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
> > > +	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
> > > +	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
> > > +	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
> > > +	"%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",
> > > +	"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",
> > > +	"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",
> > > +	"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",
> > > +};
> > > +#endif
> > > diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > > new file mode 100644
> > > index 0000000..39ac7cb
> > > --- /dev/null
> > > +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > > @@ -0,0 +1,14 @@
> > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > +/* This is included in perf/util/dwarf-regs.c */
> > > +
> > > +static const char * const x86_32_regstr_tbl[] = {
> > > +	"%ax", "%cx", "%dx", "%bx", "$stack",/* Stack address instead of %sp */
> > > +	"%bp", "%si", "%di",
> > > +};
> > > +
> > > +static const char * const x86_64_regstr_tbl[] = {
> > > +	"%ax", "dx", "%cx", "%bx", "%si", "%di",
> > > +	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
> > > +	"%r12", "%r13", "%r14", "%r15",
> > > +};
> > > +#endif
> > > diff --git a/tools/perf/arch/xtensa/include/dwarf-regs-table.h b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > > new file mode 100644
> > > index 0000000..aa0444a
> > > --- /dev/null
> > > +++ b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > > @@ -0,0 +1,8 @@
> > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > +/* This is included in perf/util/dwarf-regs.c */
> > > +
> > > +static const char * const xtensa_regstr_tbl[] = {
> > > +	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
> > > +	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
> > > +};
> > > +#endif
> > > diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> > > index 91c5f6e..f1a6d17 100644
> > > --- a/tools/perf/util/Build
> > > +++ b/tools/perf/util/Build
> > > @@ -98,6 +98,7 @@ endif
> > >  
> > >  libperf-$(CONFIG_DWARF) += probe-finder.o
> > >  libperf-$(CONFIG_DWARF) += dwarf-aux.o
> > > +libperf-$(CONFIG_DWARF) += dwarf-regs.o
> > >  
> > >  libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> > >  libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
> > > diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> > > new file mode 100644
> > > index 0000000..ce15816
> > > --- /dev/null
> > > +++ b/tools/perf/util/dwarf-regs.c
> > > @@ -0,0 +1,55 @@
> > > +/*
> > > + * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
> > > + *
> > > + * Written by: Masami Hiramatsu <mhiramat@kernel.org>
> > > + */
> > > +
> > > +#include <util.h>
> > > +#include <debug.h>
> > > +#include <dwarf-regs.h>
> > > +#include <elf.h>
> > > +
> > > +/* Define const char * {arch}_register_tbl[] */
> > > +#define DEFINE_DWARF_REGSTR_TABLE
> > > +#include "../arch/x86/include/dwarf-regs-table.h"
> > > +#include "../arch/arm/include/dwarf-regs-table.h"
> > > +#include "../arch/arm64/include/dwarf-regs-table.h"
> > > +#include "../arch/sh/include/dwarf-regs-table.h"
> > > +#include "../arch/powerpc/include/dwarf-regs-table.h"
> > > +#include "../arch/s390/include/dwarf-regs-table.h"
> > > +#include "../arch/sparc/include/dwarf-regs-table.h"
> > > +#include "../arch/xtensa/include/dwarf-regs-table.h"
> > > +
> > > +#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
> > > +
> > > +/* Return architecture dependent register string (for kprobe-tracer) */
> > > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
> > > +{
> > > +	switch (machine) {
> > > +	case EM_NONE:	/* Generic arch - use host arch */
> > > +		return get_arch_regstr(n);
> > > +	case EM_386:
> > > +		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
> > > +	case EM_X86_64:
> > > +		return __get_dwarf_regstr(x86_64_regstr_tbl, n);
> > > +	case EM_ARM:
> > > +		return __get_dwarf_regstr(arm_regstr_tbl, n);
> > > +	case EM_AARCH64:
> > > +		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
> > > +	case EM_SH:
> > > +		return __get_dwarf_regstr(sh_regstr_tbl, n);
> > > +	case EM_S390:
> > > +		return __get_dwarf_regstr(s390_regstr_tbl, n);
> > > +	case EM_PPC:
> > > +	case EM_PPC64:
> > > +		return __get_dwarf_regstr(powerpc_regstr_tbl, n);
> > > +	case EM_SPARC:
> > > +	case EM_SPARCV9:
> > > +		return __get_dwarf_regstr(sparc_regstr_tbl, n);
> > > +	case EM_XTENSA:
> > > +		return __get_dwarf_regstr(xtensa_regstr_tbl, n);
> > > +	default:
> > > +		pr_err("ELF MACHINE %x is not supported.\n", machine);
> > > +	}
> > > +	return NULL;
> > > +}
> > > diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> > > index 07c644e..43bfd8d 100644
> > > --- a/tools/perf/util/include/dwarf-regs.h
> > > +++ b/tools/perf/util/include/dwarf-regs.h
> > > @@ -3,6 +3,12 @@
> > >  
> > >  #ifdef HAVE_DWARF_SUPPORT
> > >  const char *get_arch_regstr(unsigned int n);
> > > +/*
> > > + * get_dwarf_regstr - Returns ftrace register string from DWARF regnum
> > > + * n: DWARF register number
> > > + * machine: ELF machine signature (EM_*)
> > > + */
> > > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
> > >  #endif
> > >  
> > >  #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
> > > diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> > > index ac4740f..508b61c 100644
> > > --- a/tools/perf/util/probe-finder.c
> > > +++ b/tools/perf/util/probe-finder.c
> > > @@ -171,6 +171,7 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
> > >   */
> > >  static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
> > >  				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
> > > +				     unsigned int machine,
> > >  				     struct probe_trace_arg *tvar)
> > >  {
> > >  	Dwarf_Attribute attr;
> > > @@ -266,7 +267,7 @@ static_var:
> > >  	if (!tvar)
> > >  		return ret2;
> > >  
> > > -	regs = get_arch_regstr(regn);
> > > +	regs = get_dwarf_regstr(regn, machine);
> > >  	if (!regs) {
> > >  		/* This should be a bug in DWARF or this tool */
> > >  		pr_warning("Mapping for the register number %u "
> > > @@ -543,7 +544,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
> > >  		 dwarf_diename(vr_die));
> > >  
> > >  	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
> > > -					&pf->sp_die, pf->tvar);
> > > +					&pf->sp_die, pf->machine, pf->tvar);
> > >  	if (ret == -ENOENT || ret == -EINVAL) {
> > >  		pr_err("Failed to find the location of the '%s' variable at this address.\n"
> > >  		       " Perhaps it has been optimized out.\n"
> > > @@ -1106,11 +1107,8 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
> > >  				  struct probe_finder *pf)
> > >  {
> > >  	int ret = 0;
> > > -
> > > -#if _ELFUTILS_PREREQ(0, 142)
> > >  	Elf *elf;
> > >  	GElf_Ehdr ehdr;
> > > -	GElf_Shdr shdr;
> > >  
> > >  	if (pf->cfi_eh || pf->cfi_dbg)
> > >  		return debuginfo__find_probe_location(dbg, pf);
> > > @@ -1123,11 +1121,18 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
> > >  	if (gelf_getehdr(elf, &ehdr) == NULL)
> > >  		return -EINVAL;
> > >  
> > > -	if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> > > -	    shdr.sh_type == SHT_PROGBITS)
> > > -		pf->cfi_eh = dwarf_getcfi_elf(elf);
> > > +	pf->machine = ehdr.e_machine;
> > > +
> > > +#if _ELFUTILS_PREREQ(0, 142)
> > > +	do {
> > > +		GElf_Shdr shdr;
> > > +
> > > +		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> > > +		    shdr.sh_type == SHT_PROGBITS)
> > > +			pf->cfi_eh = dwarf_getcfi_elf(elf);
> > >  
> > > -	pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> > > +		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> > > +	} while (0);
> > >  #endif
> > >  
> > >  	ret = debuginfo__find_probe_location(dbg, pf);
> > > @@ -1155,7 +1160,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
> > >  	    (tag == DW_TAG_variable && vf->vars)) {
> > >  		if (convert_variable_location(die_mem, vf->pf->addr,
> > >  					      vf->pf->fb_ops, &pf->sp_die,
> > > -					      NULL) == 0) {
> > > +					      pf->machine, NULL) == 0) {
> > >  			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
> > >  			if (vf->args[vf->nargs].var == NULL) {
> > >  				vf->ret = -ENOMEM;
> > > @@ -1318,7 +1323,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
> > >  	    tag == DW_TAG_variable) {
> > >  		ret = convert_variable_location(die_mem, af->pf.addr,
> > >  						af->pf.fb_ops, &af->pf.sp_die,
> > > -						NULL);
> > > +						af->pf.machine, NULL);
> > >  		if (ret == 0 || ret == -ERANGE) {
> > >  			int ret2;
> > >  			bool externs = !af->child;
> > > diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
> > > index 51137fc..f1d8558 100644
> > > --- a/tools/perf/util/probe-finder.h
> > > +++ b/tools/perf/util/probe-finder.h
> > > @@ -80,6 +80,7 @@ struct probe_finder {
> > >  	Dwarf_CFI		*cfi_dbg;
> > >  #endif
> > >  	Dwarf_Op		*fb_ops;	/* Frame base attribute */
> > > +	unsigned int		machine;	/* Target machine arch */
> > >  	struct perf_probe_arg	*pvar;		/* Current target variable */
> > >  	struct probe_trace_arg	*tvar;		/* Current result variable */
> > >  };
> 
> 
> -- 
> Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUGFIX] Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
  2016-09-09 14:37       ` [BUG] " Arnaldo Carvalho de Melo
@ 2016-09-09 14:59         ` Arnaldo Carvalho de Melo
  2016-09-09 15:28           ` Masami Hiramatsu
  0 siblings, 1 reply; 17+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-09 14:59 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Wang Nan, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Em Fri, Sep 09, 2016 at 11:37:41AM -0300, Arnaldo Carvalho de Melo escreveu:
> I just bisect down to this cset as the reason for:
> 
> [root@jouet linux]# perf test bpf
> 37: Test BPF filter                                          :
> 37.1: Test basic BPF filtering                               : Ok
> 37.2: Test BPF prologue generation                           : FAILED!
> 37.3: Test BPF relocation checker                            : Skip
> [root@jouet linux]# 
> 
> [root@jouet linux]# perf test -v bpf
> <SNIP>
> Found 1 probe_trace_events.
> Opening /sys/kernel/debug/tracing//kprobe_events write=1
> Parsing probe_events: p:probe/vfs_getname _text+2483816
> pathname=+0(%di):string
> Group:probe Event:vfs_getname probe:p
> Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=dx:s32


# diff /tmp/fail /tmp/ok
<SNIP>
-Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=dx:s32
-Failed to write event: Invalid argument
-bpf_probe: failed to apply perf probe eventsFailed to add events selected by BPF
+Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=%dx:s32
<SNIP>

Fixed by this patch:

diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
index 39ac7cbb525b..9b5e5cbb4209 100644
--- a/tools/perf/arch/x86/include/dwarf-regs-table.h
+++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
@@ -7,7 +7,7 @@ static const char * const x86_32_regstr_tbl[] = {
 };
 
 static const char * const x86_64_regstr_tbl[] = {
-	"%ax", "dx", "%cx", "%bx", "%si", "%di",
+	"%ax", "%dx", "%cx", "%bx", "%si", "%di",
 	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
 	"%r12", "%r13", "%r14", "%r15",
 };


> Failed to write event: Invalid argument
> bpf_probe: failed to apply perf probe eventsFailed to add events
> selected by BPF
> Opening /sys/kernel/debug/tracing//kprobe_events write=1
> Opening /sys/kernel/debug/tracing//uprobe_events write=1
> Parsing probe_events: p:probe/vfs_getname _text+2483816
> pathname=+0(%di):string
> Group:probe Event:vfs_getname probe:p
> test child finished with -1
> ---- end ----
> Test BPF filter subtest 1: FAILED!
> 37.3: Test BPF relocation checker                            :
> --- force skipped ---
> Test BPF filter subtest 2: Skip
> [root@jouet linux]# 
> 
> Trying to fix this...
> 
> - Arnaldo
> 
>  
> > Thank you,
> > 
> > > 
> > > - Arnaldo
> > >  
> > > > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > > > ---
> > > >   Changes from v1:
> > > >    - Change the example.
> > > > ---
> > > >  tools/perf/arch/arm/include/dwarf-regs-table.h     |    9 +++
> > > >  tools/perf/arch/arm64/include/dwarf-regs-table.h   |   13 +++++
> > > >  tools/perf/arch/powerpc/include/dwarf-regs-table.h |   27 ++++++++++
> > > >  tools/perf/arch/s390/include/dwarf-regs-table.h    |    8 +++
> > > >  tools/perf/arch/sh/include/dwarf-regs-table.h      |   25 +++++++++
> > > >  tools/perf/arch/sparc/include/dwarf-regs-table.h   |   18 +++++++
> > > >  tools/perf/arch/x86/include/dwarf-regs-table.h     |   14 +++++
> > > >  tools/perf/arch/xtensa/include/dwarf-regs-table.h  |    8 +++
> > > >  tools/perf/util/Build                              |    1 
> > > >  tools/perf/util/dwarf-regs.c                       |   55 ++++++++++++++++++++
> > > >  tools/perf/util/include/dwarf-regs.h               |    6 ++
> > > >  tools/perf/util/probe-finder.c                     |   27 ++++++----
> > > >  tools/perf/util/probe-finder.h                     |    1 
> > > >  13 files changed, 201 insertions(+), 11 deletions(-)
> > > >  create mode 100644 tools/perf/arch/arm/include/dwarf-regs-table.h
> > > >  create mode 100644 tools/perf/arch/arm64/include/dwarf-regs-table.h
> > > >  create mode 100644 tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > > >  create mode 100644 tools/perf/arch/s390/include/dwarf-regs-table.h
> > > >  create mode 100644 tools/perf/arch/sh/include/dwarf-regs-table.h
> > > >  create mode 100644 tools/perf/arch/sparc/include/dwarf-regs-table.h
> > > >  create mode 100644 tools/perf/arch/x86/include/dwarf-regs-table.h
> > > >  create mode 100644 tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > > >  create mode 100644 tools/perf/util/dwarf-regs.c
> > > > 
> > > > diff --git a/tools/perf/arch/arm/include/dwarf-regs-table.h b/tools/perf/arch/arm/include/dwarf-regs-table.h
> > > > new file mode 100644
> > > > index 0000000..f298d03
> > > > --- /dev/null
> > > > +++ b/tools/perf/arch/arm/include/dwarf-regs-table.h
> > > > @@ -0,0 +1,9 @@
> > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > +
> > > > +static const char * const arm_regstr_tbl[] = {
> > > > +	"%r0", "%r1", "%r2", "%r3", "%r4",
> > > > +	"%r5", "%r6", "%r7", "%r8", "%r9", "%r10",
> > > > +	"%fp", "%ip", "%sp", "%lr", "%pc",
> > > > +};
> > > > +#endif
> > > > diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> > > > new file mode 100644
> > > > index 0000000..2675936
> > > > --- /dev/null
> > > > +++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> > > > @@ -0,0 +1,13 @@
> > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > +
> > > > +static const char * const aarch64_regstr_tbl[] = {
> > > > +	"%r0", "%r1", "%r2", "%r3", "%r4",
> > > > +	"%r5", "%r6", "%r7", "%r8", "%r9",
> > > > +	"%r10", "%r11", "%r12", "%r13", "%r14",
> > > > +	"%r15", "%r16", "%r17", "%r18", "%r19",
> > > > +	"%r20", "%r21", "%r22", "%r23", "%r24",
> > > > +	"%r25", "%r26", "%r27", "%r28", "%r29",
> > > > +	"%lr", "%sp",
> > > > +};
> > > > +#endif
> > > > diff --git a/tools/perf/arch/powerpc/include/dwarf-regs-table.h b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > > > new file mode 100644
> > > > index 0000000..db4730f
> > > > --- /dev/null
> > > > +++ b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > > > @@ -0,0 +1,27 @@
> > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > +
> > > > +/*
> > > > + * Reference:
> > > > + * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
> > > > + * http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
> > > > + */
> > > > +#define REG_DWARFNUM_NAME(reg, idx)	[idx] = "%" #reg
> > > > +
> > > > +static const char * const powerpc_regstr_tbl[] = {
> > > > +	"%gpr0", "%gpr1", "%gpr2", "%gpr3", "%gpr4",
> > > > +	"%gpr5", "%gpr6", "%gpr7", "%gpr8", "%gpr9",
> > > > +	"%gpr10", "%gpr11", "%gpr12", "%gpr13", "%gpr14",
> > > > +	"%gpr15", "%gpr16", "%gpr17", "%gpr18", "%gpr19",
> > > > +	"%gpr20", "%gpr21", "%gpr22", "%gpr23", "%gpr24",
> > > > +	"%gpr25", "%gpr26", "%gpr27", "%gpr28", "%gpr29",
> > > > +	"%gpr30", "%gpr31",
> > > > +	REG_DWARFNUM_NAME(msr,   66),
> > > > +	REG_DWARFNUM_NAME(ctr,   109),
> > > > +	REG_DWARFNUM_NAME(link,  108),
> > > > +	REG_DWARFNUM_NAME(xer,   101),
> > > > +	REG_DWARFNUM_NAME(dar,   119),
> > > > +	REG_DWARFNUM_NAME(dsisr, 118),
> > > > +};
> > > > +
> > > > +#endif
> > > > diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
> > > > new file mode 100644
> > > > index 0000000..9da74a9
> > > > --- /dev/null
> > > > +++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
> > > > @@ -0,0 +1,8 @@
> > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > +
> > > > +static const char * const s390_regstr_tbl[] = {
> > > > +	"%r0", "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
> > > > +	"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
> > > > +};
> > > > +#endif
> > > > diff --git a/tools/perf/arch/sh/include/dwarf-regs-table.h b/tools/perf/arch/sh/include/dwarf-regs-table.h
> > > > new file mode 100644
> > > > index 0000000..3a2deaf
> > > > --- /dev/null
> > > > +++ b/tools/perf/arch/sh/include/dwarf-regs-table.h
> > > > @@ -0,0 +1,25 @@
> > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > +
> > > > +const char * const sh_regstr_tbl[] = {
> > > > +	"r0",
> > > > +	"r1",
> > > > +	"r2",
> > > > +	"r3",
> > > > +	"r4",
> > > > +	"r5",
> > > > +	"r6",
> > > > +	"r7",
> > > > +	"r8",
> > > > +	"r9",
> > > > +	"r10",
> > > > +	"r11",
> > > > +	"r12",
> > > > +	"r13",
> > > > +	"r14",
> > > > +	"r15",
> > > > +	"pc",
> > > > +	"pr",
> > > > +};
> > > > +
> > > > +#endif
> > > > diff --git a/tools/perf/arch/sparc/include/dwarf-regs-table.h b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> > > > new file mode 100644
> > > > index 0000000..12c0761
> > > > --- /dev/null
> > > > +++ b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> > > > @@ -0,0 +1,18 @@
> > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > +
> > > > +static const char * const sparc_regstr_tbl[] = {
> > > > +	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
> > > > +	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
> > > > +	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
> > > > +	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",
> > > > +	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
> > > > +	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
> > > > +	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
> > > > +	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
> > > > +	"%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",
> > > > +	"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",
> > > > +	"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",
> > > > +	"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",
> > > > +};
> > > > +#endif
> > > > diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > > > new file mode 100644
> > > > index 0000000..39ac7cb
> > > > --- /dev/null
> > > > +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > > > @@ -0,0 +1,14 @@
> > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > +
> > > > +static const char * const x86_32_regstr_tbl[] = {
> > > > +	"%ax", "%cx", "%dx", "%bx", "$stack",/* Stack address instead of %sp */
> > > > +	"%bp", "%si", "%di",
> > > > +};
> > > > +
> > > > +static const char * const x86_64_regstr_tbl[] = {
> > > > +	"%ax", "dx", "%cx", "%bx", "%si", "%di",
> > > > +	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
> > > > +	"%r12", "%r13", "%r14", "%r15",
> > > > +};
> > > > +#endif
> > > > diff --git a/tools/perf/arch/xtensa/include/dwarf-regs-table.h b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > > > new file mode 100644
> > > > index 0000000..aa0444a
> > > > --- /dev/null
> > > > +++ b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > > > @@ -0,0 +1,8 @@
> > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > +
> > > > +static const char * const xtensa_regstr_tbl[] = {
> > > > +	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
> > > > +	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
> > > > +};
> > > > +#endif
> > > > diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> > > > index 91c5f6e..f1a6d17 100644
> > > > --- a/tools/perf/util/Build
> > > > +++ b/tools/perf/util/Build
> > > > @@ -98,6 +98,7 @@ endif
> > > >  
> > > >  libperf-$(CONFIG_DWARF) += probe-finder.o
> > > >  libperf-$(CONFIG_DWARF) += dwarf-aux.o
> > > > +libperf-$(CONFIG_DWARF) += dwarf-regs.o
> > > >  
> > > >  libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> > > >  libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
> > > > diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> > > > new file mode 100644
> > > > index 0000000..ce15816
> > > > --- /dev/null
> > > > +++ b/tools/perf/util/dwarf-regs.c
> > > > @@ -0,0 +1,55 @@
> > > > +/*
> > > > + * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
> > > > + *
> > > > + * Written by: Masami Hiramatsu <mhiramat@kernel.org>
> > > > + */
> > > > +
> > > > +#include <util.h>
> > > > +#include <debug.h>
> > > > +#include <dwarf-regs.h>
> > > > +#include <elf.h>
> > > > +
> > > > +/* Define const char * {arch}_register_tbl[] */
> > > > +#define DEFINE_DWARF_REGSTR_TABLE
> > > > +#include "../arch/x86/include/dwarf-regs-table.h"
> > > > +#include "../arch/arm/include/dwarf-regs-table.h"
> > > > +#include "../arch/arm64/include/dwarf-regs-table.h"
> > > > +#include "../arch/sh/include/dwarf-regs-table.h"
> > > > +#include "../arch/powerpc/include/dwarf-regs-table.h"
> > > > +#include "../arch/s390/include/dwarf-regs-table.h"
> > > > +#include "../arch/sparc/include/dwarf-regs-table.h"
> > > > +#include "../arch/xtensa/include/dwarf-regs-table.h"
> > > > +
> > > > +#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
> > > > +
> > > > +/* Return architecture dependent register string (for kprobe-tracer) */
> > > > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
> > > > +{
> > > > +	switch (machine) {
> > > > +	case EM_NONE:	/* Generic arch - use host arch */
> > > > +		return get_arch_regstr(n);
> > > > +	case EM_386:
> > > > +		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
> > > > +	case EM_X86_64:
> > > > +		return __get_dwarf_regstr(x86_64_regstr_tbl, n);
> > > > +	case EM_ARM:
> > > > +		return __get_dwarf_regstr(arm_regstr_tbl, n);
> > > > +	case EM_AARCH64:
> > > > +		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
> > > > +	case EM_SH:
> > > > +		return __get_dwarf_regstr(sh_regstr_tbl, n);
> > > > +	case EM_S390:
> > > > +		return __get_dwarf_regstr(s390_regstr_tbl, n);
> > > > +	case EM_PPC:
> > > > +	case EM_PPC64:
> > > > +		return __get_dwarf_regstr(powerpc_regstr_tbl, n);
> > > > +	case EM_SPARC:
> > > > +	case EM_SPARCV9:
> > > > +		return __get_dwarf_regstr(sparc_regstr_tbl, n);
> > > > +	case EM_XTENSA:
> > > > +		return __get_dwarf_regstr(xtensa_regstr_tbl, n);
> > > > +	default:
> > > > +		pr_err("ELF MACHINE %x is not supported.\n", machine);
> > > > +	}
> > > > +	return NULL;
> > > > +}
> > > > diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> > > > index 07c644e..43bfd8d 100644
> > > > --- a/tools/perf/util/include/dwarf-regs.h
> > > > +++ b/tools/perf/util/include/dwarf-regs.h
> > > > @@ -3,6 +3,12 @@
> > > >  
> > > >  #ifdef HAVE_DWARF_SUPPORT
> > > >  const char *get_arch_regstr(unsigned int n);
> > > > +/*
> > > > + * get_dwarf_regstr - Returns ftrace register string from DWARF regnum
> > > > + * n: DWARF register number
> > > > + * machine: ELF machine signature (EM_*)
> > > > + */
> > > > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
> > > >  #endif
> > > >  
> > > >  #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
> > > > diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> > > > index ac4740f..508b61c 100644
> > > > --- a/tools/perf/util/probe-finder.c
> > > > +++ b/tools/perf/util/probe-finder.c
> > > > @@ -171,6 +171,7 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
> > > >   */
> > > >  static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
> > > >  				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
> > > > +				     unsigned int machine,
> > > >  				     struct probe_trace_arg *tvar)
> > > >  {
> > > >  	Dwarf_Attribute attr;
> > > > @@ -266,7 +267,7 @@ static_var:
> > > >  	if (!tvar)
> > > >  		return ret2;
> > > >  
> > > > -	regs = get_arch_regstr(regn);
> > > > +	regs = get_dwarf_regstr(regn, machine);
> > > >  	if (!regs) {
> > > >  		/* This should be a bug in DWARF or this tool */
> > > >  		pr_warning("Mapping for the register number %u "
> > > > @@ -543,7 +544,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
> > > >  		 dwarf_diename(vr_die));
> > > >  
> > > >  	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
> > > > -					&pf->sp_die, pf->tvar);
> > > > +					&pf->sp_die, pf->machine, pf->tvar);
> > > >  	if (ret == -ENOENT || ret == -EINVAL) {
> > > >  		pr_err("Failed to find the location of the '%s' variable at this address.\n"
> > > >  		       " Perhaps it has been optimized out.\n"
> > > > @@ -1106,11 +1107,8 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
> > > >  				  struct probe_finder *pf)
> > > >  {
> > > >  	int ret = 0;
> > > > -
> > > > -#if _ELFUTILS_PREREQ(0, 142)
> > > >  	Elf *elf;
> > > >  	GElf_Ehdr ehdr;
> > > > -	GElf_Shdr shdr;
> > > >  
> > > >  	if (pf->cfi_eh || pf->cfi_dbg)
> > > >  		return debuginfo__find_probe_location(dbg, pf);
> > > > @@ -1123,11 +1121,18 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
> > > >  	if (gelf_getehdr(elf, &ehdr) == NULL)
> > > >  		return -EINVAL;
> > > >  
> > > > -	if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> > > > -	    shdr.sh_type == SHT_PROGBITS)
> > > > -		pf->cfi_eh = dwarf_getcfi_elf(elf);
> > > > +	pf->machine = ehdr.e_machine;
> > > > +
> > > > +#if _ELFUTILS_PREREQ(0, 142)
> > > > +	do {
> > > > +		GElf_Shdr shdr;
> > > > +
> > > > +		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> > > > +		    shdr.sh_type == SHT_PROGBITS)
> > > > +			pf->cfi_eh = dwarf_getcfi_elf(elf);
> > > >  
> > > > -	pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> > > > +		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> > > > +	} while (0);
> > > >  #endif
> > > >  
> > > >  	ret = debuginfo__find_probe_location(dbg, pf);
> > > > @@ -1155,7 +1160,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
> > > >  	    (tag == DW_TAG_variable && vf->vars)) {
> > > >  		if (convert_variable_location(die_mem, vf->pf->addr,
> > > >  					      vf->pf->fb_ops, &pf->sp_die,
> > > > -					      NULL) == 0) {
> > > > +					      pf->machine, NULL) == 0) {
> > > >  			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
> > > >  			if (vf->args[vf->nargs].var == NULL) {
> > > >  				vf->ret = -ENOMEM;
> > > > @@ -1318,7 +1323,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
> > > >  	    tag == DW_TAG_variable) {
> > > >  		ret = convert_variable_location(die_mem, af->pf.addr,
> > > >  						af->pf.fb_ops, &af->pf.sp_die,
> > > > -						NULL);
> > > > +						af->pf.machine, NULL);
> > > >  		if (ret == 0 || ret == -ERANGE) {
> > > >  			int ret2;
> > > >  			bool externs = !af->child;
> > > > diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
> > > > index 51137fc..f1d8558 100644
> > > > --- a/tools/perf/util/probe-finder.h
> > > > +++ b/tools/perf/util/probe-finder.h
> > > > @@ -80,6 +80,7 @@ struct probe_finder {
> > > >  	Dwarf_CFI		*cfi_dbg;
> > > >  #endif
> > > >  	Dwarf_Op		*fb_ops;	/* Frame base attribute */
> > > > +	unsigned int		machine;	/* Target machine arch */
> > > >  	struct perf_probe_arg	*pvar;		/* Current target variable */
> > > >  	struct probe_trace_arg	*tvar;		/* Current result variable */
> > > >  };
> > 
> > 
> > -- 
> > Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [BUGFIX] Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
  2016-09-09 14:59         ` [BUGFIX] " Arnaldo Carvalho de Melo
@ 2016-09-09 15:28           ` Masami Hiramatsu
  2016-09-09 15:43             ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 17+ messages in thread
From: Masami Hiramatsu @ 2016-09-09 15:28 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Wang Nan, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

On Fri, 9 Sep 2016 11:59:55 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> Em Fri, Sep 09, 2016 at 11:37:41AM -0300, Arnaldo Carvalho de Melo escreveu:
> > I just bisect down to this cset as the reason for:
> > 
> > [root@jouet linux]# perf test bpf
> > 37: Test BPF filter                                          :
> > 37.1: Test basic BPF filtering                               : Ok
> > 37.2: Test BPF prologue generation                           : FAILED!
> > 37.3: Test BPF relocation checker                            : Skip
> > [root@jouet linux]# 
> > 
> > [root@jouet linux]# perf test -v bpf
> > <SNIP>
> > Found 1 probe_trace_events.
> > Opening /sys/kernel/debug/tracing//kprobe_events write=1
> > Parsing probe_events: p:probe/vfs_getname _text+2483816
> > pathname=+0(%di):string
> > Group:probe Event:vfs_getname probe:p
> > Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=dx:s32
> 
> 
> # diff /tmp/fail /tmp/ok
> <SNIP>
> -Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=dx:s32
> -Failed to write event: Invalid argument
> -bpf_probe: failed to apply perf probe eventsFailed to add events selected by BPF
> +Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=%dx:s32
> <SNIP>
> 
> Fixed by this patch:
> 
> diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
> index 39ac7cbb525b..9b5e5cbb4209 100644
> --- a/tools/perf/arch/x86/include/dwarf-regs-table.h
> +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
> @@ -7,7 +7,7 @@ static const char * const x86_32_regstr_tbl[] = {
>  };
>  
>  static const char * const x86_64_regstr_tbl[] = {
> -	"%ax", "dx", "%cx", "%bx", "%si", "%di",
> +	"%ax", "%dx", "%cx", "%bx", "%si", "%di",
>  	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
>  	"%r12", "%r13", "%r14", "%r15",
>  };

Oops, it's my typo... thank you for reporting and fixing!

Acked-by: Masami Hiramatsu <mhiramat@kernel.org>

BTW,

> > > > > +static const char * const xtensa_regstr_tbl[] = {
> > > > > +	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
> > > > > +	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
> > > > > +};
> > > > > +#endif

Actually, this may also needs % for each register name, however,
currently xtensa have no probe support ... I'm not sure why this
is ported.

Thanks,


> 
> 
> > Failed to write event: Invalid argument
> > bpf_probe: failed to apply perf probe eventsFailed to add events
> > selected by BPF
> > Opening /sys/kernel/debug/tracing//kprobe_events write=1
> > Opening /sys/kernel/debug/tracing//uprobe_events write=1
> > Parsing probe_events: p:probe/vfs_getname _text+2483816
> > pathname=+0(%di):string
> > Group:probe Event:vfs_getname probe:p
> > test child finished with -1
> > ---- end ----
> > Test BPF filter subtest 1: FAILED!
> > 37.3: Test BPF relocation checker                            :
> > --- force skipped ---
> > Test BPF filter subtest 2: Skip
> > [root@jouet linux]# 
> > 
> > Trying to fix this...
> > 
> > - Arnaldo
> > 
> >  
> > > Thank you,
> > > 
> > > > 
> > > > - Arnaldo
> > > >  
> > > > > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > > > > ---
> > > > >   Changes from v1:
> > > > >    - Change the example.
> > > > > ---
> > > > >  tools/perf/arch/arm/include/dwarf-regs-table.h     |    9 +++
> > > > >  tools/perf/arch/arm64/include/dwarf-regs-table.h   |   13 +++++
> > > > >  tools/perf/arch/powerpc/include/dwarf-regs-table.h |   27 ++++++++++
> > > > >  tools/perf/arch/s390/include/dwarf-regs-table.h    |    8 +++
> > > > >  tools/perf/arch/sh/include/dwarf-regs-table.h      |   25 +++++++++
> > > > >  tools/perf/arch/sparc/include/dwarf-regs-table.h   |   18 +++++++
> > > > >  tools/perf/arch/x86/include/dwarf-regs-table.h     |   14 +++++
> > > > >  tools/perf/arch/xtensa/include/dwarf-regs-table.h  |    8 +++
> > > > >  tools/perf/util/Build                              |    1 
> > > > >  tools/perf/util/dwarf-regs.c                       |   55 ++++++++++++++++++++
> > > > >  tools/perf/util/include/dwarf-regs.h               |    6 ++
> > > > >  tools/perf/util/probe-finder.c                     |   27 ++++++----
> > > > >  tools/perf/util/probe-finder.h                     |    1 
> > > > >  13 files changed, 201 insertions(+), 11 deletions(-)
> > > > >  create mode 100644 tools/perf/arch/arm/include/dwarf-regs-table.h
> > > > >  create mode 100644 tools/perf/arch/arm64/include/dwarf-regs-table.h
> > > > >  create mode 100644 tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > > > >  create mode 100644 tools/perf/arch/s390/include/dwarf-regs-table.h
> > > > >  create mode 100644 tools/perf/arch/sh/include/dwarf-regs-table.h
> > > > >  create mode 100644 tools/perf/arch/sparc/include/dwarf-regs-table.h
> > > > >  create mode 100644 tools/perf/arch/x86/include/dwarf-regs-table.h
> > > > >  create mode 100644 tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > > > >  create mode 100644 tools/perf/util/dwarf-regs.c
> > > > > 
> > > > > diff --git a/tools/perf/arch/arm/include/dwarf-regs-table.h b/tools/perf/arch/arm/include/dwarf-regs-table.h
> > > > > new file mode 100644
> > > > > index 0000000..f298d03
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/arch/arm/include/dwarf-regs-table.h
> > > > > @@ -0,0 +1,9 @@
> > > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > > +
> > > > > +static const char * const arm_regstr_tbl[] = {
> > > > > +	"%r0", "%r1", "%r2", "%r3", "%r4",
> > > > > +	"%r5", "%r6", "%r7", "%r8", "%r9", "%r10",
> > > > > +	"%fp", "%ip", "%sp", "%lr", "%pc",
> > > > > +};
> > > > > +#endif
> > > > > diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> > > > > new file mode 100644
> > > > > index 0000000..2675936
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h
> > > > > @@ -0,0 +1,13 @@
> > > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > > +
> > > > > +static const char * const aarch64_regstr_tbl[] = {
> > > > > +	"%r0", "%r1", "%r2", "%r3", "%r4",
> > > > > +	"%r5", "%r6", "%r7", "%r8", "%r9",
> > > > > +	"%r10", "%r11", "%r12", "%r13", "%r14",
> > > > > +	"%r15", "%r16", "%r17", "%r18", "%r19",
> > > > > +	"%r20", "%r21", "%r22", "%r23", "%r24",
> > > > > +	"%r25", "%r26", "%r27", "%r28", "%r29",
> > > > > +	"%lr", "%sp",
> > > > > +};
> > > > > +#endif
> > > > > diff --git a/tools/perf/arch/powerpc/include/dwarf-regs-table.h b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > > > > new file mode 100644
> > > > > index 0000000..db4730f
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/arch/powerpc/include/dwarf-regs-table.h
> > > > > @@ -0,0 +1,27 @@
> > > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > > +
> > > > > +/*
> > > > > + * Reference:
> > > > > + * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
> > > > > + * http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
> > > > > + */
> > > > > +#define REG_DWARFNUM_NAME(reg, idx)	[idx] = "%" #reg
> > > > > +
> > > > > +static const char * const powerpc_regstr_tbl[] = {
> > > > > +	"%gpr0", "%gpr1", "%gpr2", "%gpr3", "%gpr4",
> > > > > +	"%gpr5", "%gpr6", "%gpr7", "%gpr8", "%gpr9",
> > > > > +	"%gpr10", "%gpr11", "%gpr12", "%gpr13", "%gpr14",
> > > > > +	"%gpr15", "%gpr16", "%gpr17", "%gpr18", "%gpr19",
> > > > > +	"%gpr20", "%gpr21", "%gpr22", "%gpr23", "%gpr24",
> > > > > +	"%gpr25", "%gpr26", "%gpr27", "%gpr28", "%gpr29",
> > > > > +	"%gpr30", "%gpr31",
> > > > > +	REG_DWARFNUM_NAME(msr,   66),
> > > > > +	REG_DWARFNUM_NAME(ctr,   109),
> > > > > +	REG_DWARFNUM_NAME(link,  108),
> > > > > +	REG_DWARFNUM_NAME(xer,   101),
> > > > > +	REG_DWARFNUM_NAME(dar,   119),
> > > > > +	REG_DWARFNUM_NAME(dsisr, 118),
> > > > > +};
> > > > > +
> > > > > +#endif
> > > > > diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
> > > > > new file mode 100644
> > > > > index 0000000..9da74a9
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
> > > > > @@ -0,0 +1,8 @@
> > > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > > +
> > > > > +static const char * const s390_regstr_tbl[] = {
> > > > > +	"%r0", "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
> > > > > +	"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
> > > > > +};
> > > > > +#endif
> > > > > diff --git a/tools/perf/arch/sh/include/dwarf-regs-table.h b/tools/perf/arch/sh/include/dwarf-regs-table.h
> > > > > new file mode 100644
> > > > > index 0000000..3a2deaf
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/arch/sh/include/dwarf-regs-table.h
> > > > > @@ -0,0 +1,25 @@
> > > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > > +
> > > > > +const char * const sh_regstr_tbl[] = {
> > > > > +	"r0",
> > > > > +	"r1",
> > > > > +	"r2",
> > > > > +	"r3",
> > > > > +	"r4",
> > > > > +	"r5",
> > > > > +	"r6",
> > > > > +	"r7",
> > > > > +	"r8",
> > > > > +	"r9",
> > > > > +	"r10",
> > > > > +	"r11",
> > > > > +	"r12",
> > > > > +	"r13",
> > > > > +	"r14",
> > > > > +	"r15",
> > > > > +	"pc",
> > > > > +	"pr",
> > > > > +};
> > > > > +
> > > > > +#endif
> > > > > diff --git a/tools/perf/arch/sparc/include/dwarf-regs-table.h b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> > > > > new file mode 100644
> > > > > index 0000000..12c0761
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/arch/sparc/include/dwarf-regs-table.h
> > > > > @@ -0,0 +1,18 @@
> > > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > > +
> > > > > +static const char * const sparc_regstr_tbl[] = {
> > > > > +	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
> > > > > +	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
> > > > > +	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
> > > > > +	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",
> > > > > +	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
> > > > > +	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
> > > > > +	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
> > > > > +	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
> > > > > +	"%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",
> > > > > +	"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",
> > > > > +	"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",
> > > > > +	"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",
> > > > > +};
> > > > > +#endif
> > > > > diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > > > > new file mode 100644
> > > > > index 0000000..39ac7cb
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > > > > @@ -0,0 +1,14 @@
> > > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > > +
> > > > > +static const char * const x86_32_regstr_tbl[] = {
> > > > > +	"%ax", "%cx", "%dx", "%bx", "$stack",/* Stack address instead of %sp */
> > > > > +	"%bp", "%si", "%di",
> > > > > +};
> > > > > +
> > > > > +static const char * const x86_64_regstr_tbl[] = {
> > > > > +	"%ax", "dx", "%cx", "%bx", "%si", "%di",
> > > > > +	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
> > > > > +	"%r12", "%r13", "%r14", "%r15",
> > > > > +};
> > > > > +#endif
> > > > > diff --git a/tools/perf/arch/xtensa/include/dwarf-regs-table.h b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > > > > new file mode 100644
> > > > > index 0000000..aa0444a
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/arch/xtensa/include/dwarf-regs-table.h
> > > > > @@ -0,0 +1,8 @@
> > > > > +#ifdef DEFINE_DWARF_REGSTR_TABLE
> > > > > +/* This is included in perf/util/dwarf-regs.c */
> > > > > +
> > > > > +static const char * const xtensa_regstr_tbl[] = {
> > > > > +	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
> > > > > +	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
> > > > > +};
> > > > > +#endif
> > > > > diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> > > > > index 91c5f6e..f1a6d17 100644
> > > > > --- a/tools/perf/util/Build
> > > > > +++ b/tools/perf/util/Build
> > > > > @@ -98,6 +98,7 @@ endif
> > > > >  
> > > > >  libperf-$(CONFIG_DWARF) += probe-finder.o
> > > > >  libperf-$(CONFIG_DWARF) += dwarf-aux.o
> > > > > +libperf-$(CONFIG_DWARF) += dwarf-regs.o
> > > > >  
> > > > >  libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> > > > >  libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
> > > > > diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> > > > > new file mode 100644
> > > > > index 0000000..ce15816
> > > > > --- /dev/null
> > > > > +++ b/tools/perf/util/dwarf-regs.c
> > > > > @@ -0,0 +1,55 @@
> > > > > +/*
> > > > > + * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
> > > > > + *
> > > > > + * Written by: Masami Hiramatsu <mhiramat@kernel.org>
> > > > > + */
> > > > > +
> > > > > +#include <util.h>
> > > > > +#include <debug.h>
> > > > > +#include <dwarf-regs.h>
> > > > > +#include <elf.h>
> > > > > +
> > > > > +/* Define const char * {arch}_register_tbl[] */
> > > > > +#define DEFINE_DWARF_REGSTR_TABLE
> > > > > +#include "../arch/x86/include/dwarf-regs-table.h"
> > > > > +#include "../arch/arm/include/dwarf-regs-table.h"
> > > > > +#include "../arch/arm64/include/dwarf-regs-table.h"
> > > > > +#include "../arch/sh/include/dwarf-regs-table.h"
> > > > > +#include "../arch/powerpc/include/dwarf-regs-table.h"
> > > > > +#include "../arch/s390/include/dwarf-regs-table.h"
> > > > > +#include "../arch/sparc/include/dwarf-regs-table.h"
> > > > > +#include "../arch/xtensa/include/dwarf-regs-table.h"
> > > > > +
> > > > > +#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
> > > > > +
> > > > > +/* Return architecture dependent register string (for kprobe-tracer) */
> > > > > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
> > > > > +{
> > > > > +	switch (machine) {
> > > > > +	case EM_NONE:	/* Generic arch - use host arch */
> > > > > +		return get_arch_regstr(n);
> > > > > +	case EM_386:
> > > > > +		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
> > > > > +	case EM_X86_64:
> > > > > +		return __get_dwarf_regstr(x86_64_regstr_tbl, n);
> > > > > +	case EM_ARM:
> > > > > +		return __get_dwarf_regstr(arm_regstr_tbl, n);
> > > > > +	case EM_AARCH64:
> > > > > +		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
> > > > > +	case EM_SH:
> > > > > +		return __get_dwarf_regstr(sh_regstr_tbl, n);
> > > > > +	case EM_S390:
> > > > > +		return __get_dwarf_regstr(s390_regstr_tbl, n);
> > > > > +	case EM_PPC:
> > > > > +	case EM_PPC64:
> > > > > +		return __get_dwarf_regstr(powerpc_regstr_tbl, n);
> > > > > +	case EM_SPARC:
> > > > > +	case EM_SPARCV9:
> > > > > +		return __get_dwarf_regstr(sparc_regstr_tbl, n);
> > > > > +	case EM_XTENSA:
> > > > > +		return __get_dwarf_regstr(xtensa_regstr_tbl, n);
> > > > > +	default:
> > > > > +		pr_err("ELF MACHINE %x is not supported.\n", machine);
> > > > > +	}
> > > > > +	return NULL;
> > > > > +}
> > > > > diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> > > > > index 07c644e..43bfd8d 100644
> > > > > --- a/tools/perf/util/include/dwarf-regs.h
> > > > > +++ b/tools/perf/util/include/dwarf-regs.h
> > > > > @@ -3,6 +3,12 @@
> > > > >  
> > > > >  #ifdef HAVE_DWARF_SUPPORT
> > > > >  const char *get_arch_regstr(unsigned int n);
> > > > > +/*
> > > > > + * get_dwarf_regstr - Returns ftrace register string from DWARF regnum
> > > > > + * n: DWARF register number
> > > > > + * machine: ELF machine signature (EM_*)
> > > > > + */
> > > > > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
> > > > >  #endif
> > > > >  
> > > > >  #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
> > > > > diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> > > > > index ac4740f..508b61c 100644
> > > > > --- a/tools/perf/util/probe-finder.c
> > > > > +++ b/tools/perf/util/probe-finder.c
> > > > > @@ -171,6 +171,7 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
> > > > >   */
> > > > >  static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
> > > > >  				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
> > > > > +				     unsigned int machine,
> > > > >  				     struct probe_trace_arg *tvar)
> > > > >  {
> > > > >  	Dwarf_Attribute attr;
> > > > > @@ -266,7 +267,7 @@ static_var:
> > > > >  	if (!tvar)
> > > > >  		return ret2;
> > > > >  
> > > > > -	regs = get_arch_regstr(regn);
> > > > > +	regs = get_dwarf_regstr(regn, machine);
> > > > >  	if (!regs) {
> > > > >  		/* This should be a bug in DWARF or this tool */
> > > > >  		pr_warning("Mapping for the register number %u "
> > > > > @@ -543,7 +544,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
> > > > >  		 dwarf_diename(vr_die));
> > > > >  
> > > > >  	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
> > > > > -					&pf->sp_die, pf->tvar);
> > > > > +					&pf->sp_die, pf->machine, pf->tvar);
> > > > >  	if (ret == -ENOENT || ret == -EINVAL) {
> > > > >  		pr_err("Failed to find the location of the '%s' variable at this address.\n"
> > > > >  		       " Perhaps it has been optimized out.\n"
> > > > > @@ -1106,11 +1107,8 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
> > > > >  				  struct probe_finder *pf)
> > > > >  {
> > > > >  	int ret = 0;
> > > > > -
> > > > > -#if _ELFUTILS_PREREQ(0, 142)
> > > > >  	Elf *elf;
> > > > >  	GElf_Ehdr ehdr;
> > > > > -	GElf_Shdr shdr;
> > > > >  
> > > > >  	if (pf->cfi_eh || pf->cfi_dbg)
> > > > >  		return debuginfo__find_probe_location(dbg, pf);
> > > > > @@ -1123,11 +1121,18 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
> > > > >  	if (gelf_getehdr(elf, &ehdr) == NULL)
> > > > >  		return -EINVAL;
> > > > >  
> > > > > -	if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> > > > > -	    shdr.sh_type == SHT_PROGBITS)
> > > > > -		pf->cfi_eh = dwarf_getcfi_elf(elf);
> > > > > +	pf->machine = ehdr.e_machine;
> > > > > +
> > > > > +#if _ELFUTILS_PREREQ(0, 142)
> > > > > +	do {
> > > > > +		GElf_Shdr shdr;
> > > > > +
> > > > > +		if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
> > > > > +		    shdr.sh_type == SHT_PROGBITS)
> > > > > +			pf->cfi_eh = dwarf_getcfi_elf(elf);
> > > > >  
> > > > > -	pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> > > > > +		pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
> > > > > +	} while (0);
> > > > >  #endif
> > > > >  
> > > > >  	ret = debuginfo__find_probe_location(dbg, pf);
> > > > > @@ -1155,7 +1160,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
> > > > >  	    (tag == DW_TAG_variable && vf->vars)) {
> > > > >  		if (convert_variable_location(die_mem, vf->pf->addr,
> > > > >  					      vf->pf->fb_ops, &pf->sp_die,
> > > > > -					      NULL) == 0) {
> > > > > +					      pf->machine, NULL) == 0) {
> > > > >  			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
> > > > >  			if (vf->args[vf->nargs].var == NULL) {
> > > > >  				vf->ret = -ENOMEM;
> > > > > @@ -1318,7 +1323,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
> > > > >  	    tag == DW_TAG_variable) {
> > > > >  		ret = convert_variable_location(die_mem, af->pf.addr,
> > > > >  						af->pf.fb_ops, &af->pf.sp_die,
> > > > > -						NULL);
> > > > > +						af->pf.machine, NULL);
> > > > >  		if (ret == 0 || ret == -ERANGE) {
> > > > >  			int ret2;
> > > > >  			bool externs = !af->child;
> > > > > diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
> > > > > index 51137fc..f1d8558 100644
> > > > > --- a/tools/perf/util/probe-finder.h
> > > > > +++ b/tools/perf/util/probe-finder.h
> > > > > @@ -80,6 +80,7 @@ struct probe_finder {
> > > > >  	Dwarf_CFI		*cfi_dbg;
> > > > >  #endif
> > > > >  	Dwarf_Op		*fb_ops;	/* Frame base attribute */
> > > > > +	unsigned int		machine;	/* Target machine arch */
> > > > >  	struct perf_probe_arg	*pvar;		/* Current target variable */
> > > > >  	struct probe_trace_arg	*tvar;		/* Current result variable */
> > > > >  };
> > > 
> > > 
> > > -- 
> > > Masami Hiramatsu <mhiramat@kernel.org>


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUGFIX] Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
  2016-09-09 15:28           ` Masami Hiramatsu
@ 2016-09-09 15:43             ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 17+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-09 15:43 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Wang Nan, linux-kernel, Peter Zijlstra, Ingo Molnar, Jiri Olsa

Em Sat, Sep 10, 2016 at 12:28:07AM +0900, Masami Hiramatsu escreveu:
> On Fri, 9 Sep 2016 11:59:55 -0300
> Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> > # diff /tmp/fail /tmp/ok
> > <SNIP>
> > -Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=dx:s32
> > -Failed to write event: Invalid argument
> > -bpf_probe: failed to apply perf probe eventsFailed to add events selected by BPF
> > +Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=%dx:s32
> > <SNIP>

> > Fixed by this patch:

> > +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h
> > @@ -7,7 +7,7 @@ static const char * const x86_32_regstr_tbl[] = {
> >  };

> >  static const char * const x86_64_regstr_tbl[] = {
> > -	"%ax", "dx", "%cx", "%bx", "%si", "%di",
> > +	"%ax", "%dx", "%cx", "%bx", "%si", "%di",
> >  	"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
> >  	"%r12", "%r13", "%r14", "%r15",
> >  };
 
> Oops, it's my typo... thank you for reporting and fixing!

Right, but it was my fault as well, I should've payed attention to the
output of 'perf test' and replied to you so that you could figure this
out and resend.

Anyway, its good that this gets exercised by that test, its just a
matter of us making sure that no regressions appear on 'perf test'
before pushing things upstream.
 
> Acked-by: Masami Hiramatsu <mhiramat@kernel.org>

Thanks, added it to the patch.

- Arnaldo

- Arnaldo

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2016-09-09 15:43 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-25 16:24 [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu
2016-08-25 16:24 ` [PATCH v2 1/3] perf-probe: Show trace event definition Masami Hiramatsu
2016-09-05 13:22   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2016-08-25 16:24 ` [PATCH v2 2/3] perf-probe: Ignore vmlinux buildid if offline kernel is given Masami Hiramatsu
2016-08-26 14:02   ` Masami Hiramatsu
2016-09-05 13:22   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2016-08-25 16:24 ` [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary Masami Hiramatsu
2016-08-31 20:54   ` Arnaldo Carvalho de Melo
2016-08-31 23:25     ` Masami Hiramatsu
2016-09-09 14:37       ` [BUG] " Arnaldo Carvalho de Melo
2016-09-09 14:59         ` [BUGFIX] " Arnaldo Carvalho de Melo
2016-09-09 15:28           ` Masami Hiramatsu
2016-09-09 15:43             ` Arnaldo Carvalho de Melo
2016-09-05 13:23   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2016-08-26 14:57 ` [PATCH v2 4/4] perf-probe: Ignore vmlinux Build-id when offline vmlinux given Masami Hiramatsu
2016-09-05 13:23   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2016-08-31  1:01 ` [PATCH v2 0/3] perf probe: Introduce remote cross-arch probes Masami Hiramatsu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).