diff options
Diffstat (limited to 'tools')
| -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, |
