aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-finder.c
diff options
context:
space:
mode:
authorChase Douglas <chase.douglas@canonical.com>2010-06-14 15:26:30 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-06-17 09:27:57 -0400
commit9ed7e1b85cd55dc46cb9410a23086bdaa2ff3eb9 (patch)
tree40690ef063892ff970f3961c33aef500d13c58db /tools/perf/util/probe-finder.c
parentcfc21cc641dae17a4ebda29ed093134358449577 (diff)
perf probe: Add kernel source path option
The probe plugin requires access to the source code for some operations. The source code must be in the exact same location as specified by the DWARF tags, but sometimes the location is an absolute path that cannot be replicated by a normal user. This change adds the -s|--source option to allow the user to specify the root of the kernel source tree. Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Masami Hiramatsu <mhiramat@redhat.com> LKML-Reference: <1276543590-10486-1-git-send-email-chase.douglas@canonical.com> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r--tools/perf/util/probe-finder.c58
1 files changed, 55 insertions, 3 deletions
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 */
67static 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:
1096static int line_range_add_line(const char *src, unsigned int lineno, 1146static 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}