diff options
-rw-r--r-- | tools/perf/Documentation/perf-probe.txt | 4 | ||||
-rw-r--r-- | tools/perf/builtin-probe.c | 2 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 58 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 1 |
4 files changed, 62 insertions, 3 deletions
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index 94a258c96a44..ea531d9d975c 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt | |||
@@ -31,6 +31,10 @@ OPTIONS | |||
31 | --vmlinux=PATH:: | 31 | --vmlinux=PATH:: |
32 | Specify vmlinux path which has debuginfo (Dwarf binary). | 32 | Specify vmlinux path which has debuginfo (Dwarf binary). |
33 | 33 | ||
34 | -s:: | ||
35 | --source=PATH:: | ||
36 | Specify path to kernel source. | ||
37 | |||
34 | -v:: | 38 | -v:: |
35 | --verbose:: | 39 | --verbose:: |
36 | Be more verbose (show parsed arguments, etc). | 40 | Be more verbose (show parsed arguments, etc). |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index e4a4da32a568..54551867e7e0 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -182,6 +182,8 @@ static const struct option options[] = { | |||
182 | "Show source code lines.", opt_show_lines), | 182 | "Show source code lines.", opt_show_lines), |
183 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, | 183 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, |
184 | "file", "vmlinux pathname"), | 184 | "file", "vmlinux pathname"), |
185 | OPT_STRING('s', "source", &symbol_conf.source_prefix, | ||
186 | "directory", "path to kernel source"), | ||
185 | #endif | 187 | #endif |
186 | OPT__DRY_RUN(&probe_event_dry_run), | 188 | OPT__DRY_RUN(&probe_event_dry_run), |
187 | OPT_INTEGER('\0', "max-probes", ¶ms.max_probe_points, | 189 | OPT_INTEGER('\0', "max-probes", ¶ms.max_probe_points, |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index d964cb199c67..baf665383498 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "event.h" | 37 | #include "event.h" |
38 | #include "debug.h" | 38 | #include "debug.h" |
39 | #include "util.h" | 39 | #include "util.h" |
40 | #include "symbol.h" | ||
40 | #include "probe-finder.h" | 41 | #include "probe-finder.h" |
41 | 42 | ||
42 | /* Kprobe tracer basic type is up to u64 */ | 43 | /* Kprobe tracer basic type is up to u64 */ |
@@ -57,6 +58,55 @@ static int strtailcmp(const char *s1, const char *s2) | |||
57 | return 0; | 58 | return 0; |
58 | } | 59 | } |
59 | 60 | ||
61 | /* | ||
62 | * Find a src file from a DWARF tag path. Prepend optional source path prefix | ||
63 | * and chop off leading directories that do not exist. Result is passed back as | ||
64 | * a newly allocated path on success. | ||
65 | * Return 0 if file was found and readable, -errno otherwise. | ||
66 | */ | ||
67 | static int get_real_path(const char *raw_path, char **new_path) | ||
68 | { | ||
69 | if (!symbol_conf.source_prefix) { | ||
70 | if (access(raw_path, R_OK) == 0) { | ||
71 | *new_path = strdup(raw_path); | ||
72 | return 0; | ||
73 | } else | ||
74 | return -errno; | ||
75 | } | ||
76 | |||
77 | *new_path = malloc((strlen(symbol_conf.source_prefix) + | ||
78 | strlen(raw_path) + 2)); | ||
79 | if (!*new_path) | ||
80 | return -ENOMEM; | ||
81 | |||
82 | for (;;) { | ||
83 | sprintf(*new_path, "%s/%s", symbol_conf.source_prefix, | ||
84 | raw_path); | ||
85 | |||
86 | if (access(*new_path, R_OK) == 0) | ||
87 | return 0; | ||
88 | |||
89 | switch (errno) { | ||
90 | case ENAMETOOLONG: | ||
91 | case ENOENT: | ||
92 | case EROFS: | ||
93 | case EFAULT: | ||
94 | raw_path = strchr(++raw_path, '/'); | ||
95 | if (!raw_path) { | ||
96 | free(*new_path); | ||
97 | *new_path = NULL; | ||
98 | return -ENOENT; | ||
99 | } | ||
100 | continue; | ||
101 | |||
102 | default: | ||
103 | free(*new_path); | ||
104 | *new_path = NULL; | ||
105 | return -errno; | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
60 | /* Line number list operations */ | 110 | /* Line number list operations */ |
61 | 111 | ||
62 | /* Add a line to line number list */ | 112 | /* Add a line to line number list */ |
@@ -1096,11 +1146,13 @@ end: | |||
1096 | static int line_range_add_line(const char *src, unsigned int lineno, | 1146 | static int line_range_add_line(const char *src, unsigned int lineno, |
1097 | struct line_range *lr) | 1147 | struct line_range *lr) |
1098 | { | 1148 | { |
1149 | int ret; | ||
1150 | |||
1099 | /* Copy real path */ | 1151 | /* Copy real path */ |
1100 | if (!lr->path) { | 1152 | if (!lr->path) { |
1101 | lr->path = strdup(src); | 1153 | ret = get_real_path(src, &lr->path); |
1102 | if (lr->path == NULL) | 1154 | if (ret != 0) |
1103 | return -ENOMEM; | 1155 | return ret; |
1104 | } | 1156 | } |
1105 | return line_list__add_line(&lr->line_list, lineno); | 1157 | return line_list__add_line(&lr->line_list, lineno); |
1106 | } | 1158 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 10b7ff859ce0..80e569bbdecc 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -71,6 +71,7 @@ struct symbol_conf { | |||
71 | full_paths, | 71 | full_paths, |
72 | show_cpu_utilization; | 72 | show_cpu_utilization; |
73 | const char *vmlinux_name, | 73 | const char *vmlinux_name, |
74 | *source_prefix, | ||
74 | *field_sep; | 75 | *field_sep; |
75 | const char *default_guest_vmlinux_name, | 76 | const char *default_guest_vmlinux_name, |
76 | *default_guest_kallsyms, | 77 | *default_guest_kallsyms, |