perf probe: Introduce remote cross-arch probes
Subsystems (2)
v2 cover perf probe: Introduce remote cross-arch probes
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.) <[email protected]>
PATCH v2 1/3 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 ----
--- 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(-)
tools/perf/Documentation/perf-probe.txt +7 -0
@@ -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.
tools/perf/builtin-probe.c +19 -7
@@ -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" );
tools/perf/util/probe-event.c +46 -0
52 lines not on this page · raw message
tools/perf/util/probe-event.h +1 -0
@@ -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);
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Show trace event definition
perf probe: Show trace event definition
Commit-ID: 1c20b1d15473a91e2fccecbcd2809d80ff4b4924 Gitweb: http://git.kernel.org/tip/1c20b1d15473a91e2fccecbcd2809d80ff4b4924 Author: Masami Hiramatsu <[email protected]> AuthorDate: Fri, 26 Aug 2016 01:24:27 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> 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 ----
--- 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(-)
tools/perf/Documentation/perf-probe.txt +7 -0
@@ -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.
tools/perf/builtin-probe.c +19 -7
@@ -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" );
tools/perf/util/probe-event.c +46 -0
52 lines not on this page · raw message
tools/perf/util/probe-event.h +1 -0
@@ -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);
PATCH v2 2/3 perf-probe: Ignore vmlinux buildid if offline kernel is given
In reply to Masami HiramatsuIgnore 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
-------
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(-)
tools/perf/Documentation/perf-probe.txt +2 -0
@@ -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::
tools/perf/builtin-probe.c +9 -1
@@ -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" );
tools/perf/util/probe-event.c +4 -0
@@ -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" );
tools/perf/util/symbol-elf.c +1 -1
@@ -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 ) {
Re: [PATCH v2 2/3] perf-probe: Ignore vmlinux buildid if offline kernel is given
Quoted 5 lines · On Fri, 26 Aug 2016 01:24:42 +0900 Masami Hiramatsu <[email protected]> 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,
Quoted 91 lines
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 <[email protected]>---
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(-)tools/perf/Documentation/perf-probe.txt +2
-0@@ -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::tools/perf/builtin-probe.c +9
-1@@ -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" );tools/perf/util/probe-event.c +4
-0@@ -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" );tools/perf/util/symbol-elf.c +1
-1@@ -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 ) {
Signature · 1 line
Masami Hiramatsu <[email protected]>
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Ignore vmlinux buildid if offline kernel is given
In reply to Masami Hiramatsuperf probe: Ignore vmlinux buildid if offline kernel is given
Commit-ID: 428aff82e92a29da0e4276623180f9a98f2d5b16 Gitweb: http://git.kernel.org/tip/428aff82e92a29da0e4276623180f9a98f2d5b16 Author: Masami Hiramatsu <[email protected]> AuthorDate: Fri, 26 Aug 2016 01:24:42 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> 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
------- 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(-)
tools/perf/Documentation/perf-probe.txt +2 -0
@@ -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::
tools/perf/builtin-probe.c +9 -1
@@ -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" );
tools/perf/util/probe-event.c +4 -0
@@ -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" );
tools/perf/util/symbol-elf.c +1 -1
@@ -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 ) {
PATCH v2 3/3 perf-probe: Support probing on offline cross-arch binary
In reply to Masami HiramatsuSupport 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
---
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
tools/perf/arch/arm/include/dwarf-regs-table.h new file +9 -0
@@ -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
tools/perf/arch/arm64/include/dwarf-regs-table.h new file +13 -0
@@ -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
tools/perf/arch/powerpc/include/dwarf-regs-table.h new file +27 -0
@@ -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
tools/perf/arch/s390/include/dwarf-regs-table.h new file +8 -0
@@ -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
tools/perf/arch/sh/include/dwarf-regs-table.h new file +25 -0
@@ -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
tools/perf/arch/sparc/include/dwarf-regs-table.h new file +18 -0
@@ -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
tools/perf/arch/x86/include/dwarf-regs-table.h new file +14 -0
@@ -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
tools/perf/arch/xtensa/include/dwarf-regs-table.h new file +8 -0
@@ -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
tools/perf/util/Build +1 -0
@@ -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
tools/perf/util/dwarf-regs.c new file +55 -0
55 lines not on this page · raw message
tools/perf/util/include/dwarf-regs.h +6 -0
@@ -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
tools/perf/util/probe-finder.c +16 -11
@@ -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;
tools/perf/util/probe-finder.h +1 -0
@@ -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 */ };
Arnaldo Carvalho de Melo
maintainerRe: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
Em Fri, Aug 26, 2016 at 01:24:57AM +0900, Masami Hiramatsu escreveu:
Quoted 11 lines
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
Quoted 384 lines
Signed-off-by Masami Hiramatsu <[email protected]>---
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.ctools/perf/arch/arm/include/dwarf-regs-table.h new file +9
-0@@ -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 tools/perf/arch/arm64/include/dwarf-regs-table.h new file +13
-0@@ -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 tools/perf/arch/powerpc/include/dwarf-regs-table.h new file +27
-0@@ -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 tools/perf/arch/s390/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/arch/sh/include/dwarf-regs-table.h new file +25
-0@@ -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 tools/perf/arch/sparc/include/dwarf-regs-table.h new file +18
-0@@ -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 tools/perf/arch/x86/include/dwarf-regs-table.h new file +14
-0@@ -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 tools/perf/arch/xtensa/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/util/Build +1
-0@@ -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.otools/perf/util/dwarf-regs.c new file +55
-0@@ -0,0 +1,55 @@ +/* +* dwarf-regs.c : Mapping of DWARF debug register numbers into register names. +* +* Written by: Masami Hiramatsu <[email protected]> +*/ + +#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 ; +}tools/perf/util/include/dwarf-regs.h +6
-0@@ -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 tools/perf/util/probe-finder.c +16
-11@@ -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;tools/perf/util/probe-finder.h +1
-0@@ -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 */ };
Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
Quoted 13 lines · On Wed, 31 Aug 2016 17:54:11 -0300 Arnaldo Carvalho de Melo <[email protected]>…
Em Fri, Aug 26, 2016 at 01:24:57AM +0900, Masami Hiramatsu escreveu:
Quoted 11 lines
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
Quoted 3 lines
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,
Quoted 387 lines
- Arnaldo
Quoted 384 lines
Signed-off-by Masami Hiramatsu <[email protected]>---
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.ctools/perf/arch/arm/include/dwarf-regs-table.h new file +9
-0@@ -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 tools/perf/arch/arm64/include/dwarf-regs-table.h new file +13
-0@@ -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 tools/perf/arch/powerpc/include/dwarf-regs-table.h new file +27
-0@@ -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 tools/perf/arch/s390/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/arch/sh/include/dwarf-regs-table.h new file +25
-0@@ -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 tools/perf/arch/sparc/include/dwarf-regs-table.h new file +18
-0@@ -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 tools/perf/arch/x86/include/dwarf-regs-table.h new file +14
-0@@ -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 tools/perf/arch/xtensa/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/util/Build +1
-0@@ -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.otools/perf/util/dwarf-regs.c new file +55
-0@@ -0,0 +1,55 @@ +/* +* dwarf-regs.c : Mapping of DWARF debug register numbers into register names. +* +* Written by: Masami Hiramatsu <[email protected]> +*/ + +#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 ; +}tools/perf/util/include/dwarf-regs.h +6
-0@@ -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 tools/perf/util/probe-finder.c +16
-11@@ -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;tools/perf/util/probe-finder.h +1
-0@@ -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 */ };
Signature · 1 line
Masami Hiramatsu <[email protected]>
Arnaldo Carvalho de Melo
maintainer[BUG] Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
Em Thu, Sep 01, 2016 at 08:25:25AM +0900, Masami Hiramatsu escreveu:
Quoted 16 lines
Quoted 13 lines · On Wed, 31 Aug 2016 17:54:11 -0300 Arnaldo Carvalho de Melo <[email protected]>…
Em Fri, Aug 26, 2016 at 01:24:57AM +0900, Masami Hiramatsu escreveu:
Quoted 11 lines
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
Quoted 5 lines
Quoted 3 lines
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 argumentbpf_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
Quoted 393 lines
Thank you,
Quoted 387 lines
- Arnaldo
Quoted 384 lines
Signed-off-by Masami Hiramatsu <[email protected]>---
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.ctools/perf/arch/arm/include/dwarf-regs-table.h new file +9
-0@@ -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 tools/perf/arch/arm64/include/dwarf-regs-table.h new file +13
-0@@ -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 tools/perf/arch/powerpc/include/dwarf-regs-table.h new file +27
-0@@ -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 tools/perf/arch/s390/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/arch/sh/include/dwarf-regs-table.h new file +25
-0@@ -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 tools/perf/arch/sparc/include/dwarf-regs-table.h new file +18
-0@@ -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 tools/perf/arch/x86/include/dwarf-regs-table.h new file +14
-0@@ -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 tools/perf/arch/xtensa/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/util/Build +1
-0@@ -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.otools/perf/util/dwarf-regs.c new file +55
-0@@ -0,0 +1,55 @@ +/* +* dwarf-regs.c : Mapping of DWARF debug register numbers into register names. +* +* Written by: Masami Hiramatsu <[email protected]> +*/ + +#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 ; +}tools/perf/util/include/dwarf-regs.h +6
-0@@ -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 tools/perf/util/probe-finder.c +16
-11@@ -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;tools/perf/util/probe-finder.h +1
-0@@ -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 */ };Signature · 1 line
Masami Hiramatsu <[email protected]>
Arnaldo Carvalho de Melo
maintainerRe: [BUGFIX] Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
Em Fri, Sep 09, 2016 at 11:37:41AM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 9 lines
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]#
Quoted 8 lines
[root@jouet linux]# perf test -v bpf
<SNIP>
Found 1probe_trace_events.
Opening/sys/kernel/debug/tracing//kprobe_eventswrite=1
Parsingprobe_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:
tools/perf/arch/x86/include/dwarf-regs-table.h +1 -1
@@ -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" , };
Quoted 414 lines
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_eventswrite=1 Opening/sys/kernel/debug/tracing//uprobe_eventswrite=1 Parsingprobe_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
Quoted 393 lines
Thank you,
Quoted 387 lines
- Arnaldo
Quoted 384 lines
Signed-off-by Masami Hiramatsu <[email protected]>---
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.ctools/perf/arch/arm/include/dwarf-regs-table.h new file +9
-0@@ -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 tools/perf/arch/arm64/include/dwarf-regs-table.h new file +13
-0@@ -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 tools/perf/arch/powerpc/include/dwarf-regs-table.h new file +27
-0@@ -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 tools/perf/arch/s390/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/arch/sh/include/dwarf-regs-table.h new file +25
-0@@ -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 tools/perf/arch/sparc/include/dwarf-regs-table.h new file +18
-0@@ -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 tools/perf/arch/x86/include/dwarf-regs-table.h new file +14
-0@@ -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 tools/perf/arch/xtensa/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/util/Build +1
-0@@ -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.otools/perf/util/dwarf-regs.c new file +55
-0@@ -0,0 +1,55 @@ +/* +* dwarf-regs.c : Mapping of DWARF debug register numbers into register names. +* +* Written by: Masami Hiramatsu <[email protected]> +*/ + +#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 ; +}tools/perf/util/include/dwarf-regs.h +6
-0@@ -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 tools/perf/util/probe-finder.c +16
-11@@ -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;tools/perf/util/probe-finder.h +1
-0@@ -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 */ };Signature · 1 line
Masami Hiramatsu <[email protected]>
Masami Hiramatsu
Acked-byRe: [BUGFIX] Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
Quoted 35 lines · On Fri, 9 Sep 2016 11:59:55 -0300 Arnaldo Carvalho de Melo <[email protected]>…
Em Fri, Sep 09, 2016 at 11:37:41AM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 9 lines
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]#
Quoted 8 lines
[root@jouet linux]# perf test -v bpf
<SNIP>
Found 1probe_trace_events.
Opening/sys/kernel/debug/tracing//kprobe_eventswrite=1
Parsingprobe_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>(quoted diff) +1
-3-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:s32Fixed by this patch:
tools/perf/arch/x86/include/dwarf-regs-table.h +0
-0
tools/perf/arch/x86/include/dwarf-regs-table.h static const char * const x86_32_regstr_tbl[] = { · line 13
Quoted 8 lines
tools/perf/arch/x86/include/dwarf-regs-table.h +1
-1@@ -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!
BTW,
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+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,
Quoted 416 lines
Quoted 416 lines
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_eventswrite=1 Opening/sys/kernel/debug/tracing//uprobe_eventswrite=1 Parsingprobe_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
Quoted 393 lines
Thank you,
Quoted 387 lines
- Arnaldo
Quoted 384 lines
Signed-off-by Masami Hiramatsu <[email protected]>---
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.ctools/perf/arch/arm/include/dwarf-regs-table.h new file +9
-0@@ -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 tools/perf/arch/arm64/include/dwarf-regs-table.h new file +13
-0@@ -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 tools/perf/arch/powerpc/include/dwarf-regs-table.h new file +27
-0@@ -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 tools/perf/arch/s390/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/arch/sh/include/dwarf-regs-table.h new file +25
-0@@ -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 tools/perf/arch/sparc/include/dwarf-regs-table.h new file +18
-0@@ -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 tools/perf/arch/x86/include/dwarf-regs-table.h new file +14
-0@@ -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 tools/perf/arch/xtensa/include/dwarf-regs-table.h new file +8
-0@@ -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 tools/perf/util/Build +1
-0@@ -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.otools/perf/util/dwarf-regs.c new file +55
-0@@ -0,0 +1,55 @@ +/* +* dwarf-regs.c : Mapping of DWARF debug register numbers into register names. +* +* Written by: Masami Hiramatsu <[email protected]> +*/ + +#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 ; +}tools/perf/util/include/dwarf-regs.h +6
-0@@ -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 tools/perf/util/probe-finder.c +16
-11@@ -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;tools/perf/util/probe-finder.h +1
-0@@ -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 */ };Signature · 1 line
Masami Hiramatsu <[email protected]>
Signature · 1 line
Masami Hiramatsu <[email protected]>
Arnaldo Carvalho de Melo
maintainerRe: [BUGFIX] Re: [PATCH v2 3/3] perf-probe: Support probing on offline cross-arch binary
Em Sat, Sep 10, 2016 at 12:28:07AM +0900, Masami Hiramatsu escreveu:
Quoted 16 lines
Quoted 13 lines · On Fri, 9 Sep 2016 11:59:55 -0300 Arnaldo Carvalho de Melo <[email protected]>…
# diff /tmp/fail /tmp/ok <SNIP>(quoted diff) +1
-3-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:s32Fixed by this patch:
+++
b/tools/perf/arch/x86/include/dwarf-regs-table.h(quoted diff) +0
-0@@ -7,7 +7,7 @@ static const char * const x86_32_regstr_tbl[] = { };
Quoted 8 lines
tools/perf/arch/x86/include/dwarf-regs-table.h static const char * const x86_32_regstr_tbl[] = { · line 13
Quoted 6 lines
tools/perf/arch/x86/include/dwarf-regs-table.h +1
-1static 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.
Quoted 1 line
Acked-by Masami Hiramatsu <[email protected]>
Thanks, added it to the patch.
- Arnaldo
- Arnaldo
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Support probing on offline cross-arch binary
In reply to Masami Hiramatsuperf probe: Support probing on offline cross-arch binary
Commit-ID: 293d5b43948309434568f4dcbb36cce4c3c51bd5 Gitweb: http://git.kernel.org/tip/293d5b43948309434568f4dcbb36cce4c3c51bd5 Author: Masami Hiramatsu <[email protected]> AuthorDate: Fri, 26 Aug 2016 01:24:57 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> 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).
--- 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(-)
tools/perf/arch/arm/include/dwarf-regs-table.h new file +9 -0
@@ -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
tools/perf/arch/arm64/include/dwarf-regs-table.h new file +13 -0
@@ -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
tools/perf/arch/powerpc/include/dwarf-regs-table.h new file +27 -0
@@ -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
tools/perf/arch/s390/include/dwarf-regs-table.h new file +8 -0
@@ -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
tools/perf/arch/sh/include/dwarf-regs-table.h new file +25 -0
@@ -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
tools/perf/arch/sparc/include/dwarf-regs-table.h new file +18 -0
@@ -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
tools/perf/arch/x86/include/dwarf-regs-table.h new file +14 -0
@@ -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
tools/perf/arch/xtensa/include/dwarf-regs-table.h new file +8 -0
@@ -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
tools/perf/util/Build +1 -0
@@ -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
tools/perf/util/dwarf-regs.c new file +59 -0
59 lines not on this page · raw message
tools/perf/util/include/dwarf-regs.h +6 -0
@@ -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
tools/perf/util/probe-finder.c +16 -11
@@ -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;
tools/perf/util/probe-finder.h +1 -0
@@ -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 */ };
PATCH v2 4/4 perf-probe: Ignore vmlinux Build-id when offline vmlinux given
In reply to Masami HiramatsuIgnore 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
-------- tools/perf/builtin-probe.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
tools/perf/builtin-probe.c +8 -7
@@ -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 */
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Ignore vmlinux Build-id when offline vmlinux given
perf probe: Ignore vmlinux Build-id when offline vmlinux given
Commit-ID: e50243bbeb528e92e31e03e560b557737c9def3c Gitweb: http://git.kernel.org/tip/e50243bbeb528e92e31e03e560b557737c9def3c Author: Masami Hiramatsu <[email protected]> AuthorDate: Fri, 26 Aug 2016 23:57:58 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> 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
-------- tools/perf/builtin-probe.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
tools/perf/builtin-probe.c +8 -7
@@ -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 */
ping?
Quoted 76 lines · On Fri, 26 Aug 2016 01:24:10 +0900 Masami Hiramatsu <[email protected]> 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/29Currently 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 binarytools/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.) <[email protected]>
Signature · 1 line
Masami Hiramatsu <[email protected]>