aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-probe.c72
-rw-r--r--tools/perf/util/event.h2
-rw-r--r--tools/perf/util/map.c14
3 files changed, 41 insertions, 47 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 8b4fdaeefa29..0584b7a0ed36 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -38,33 +38,27 @@
38#include "util/strlist.h" 38#include "util/strlist.h"
39#include "util/event.h" 39#include "util/event.h"
40#include "util/debug.h" 40#include "util/debug.h"
41#include "util/symbol.h"
42#include "util/thread.h"
43#include "util/session.h"
41#include "util/parse-options.h" 44#include "util/parse-options.h"
42#include "util/parse-events.h" /* For debugfs_path */ 45#include "util/parse-events.h" /* For debugfs_path */
43#include "util/probe-finder.h" 46#include "util/probe-finder.h"
44#include "util/probe-event.h" 47#include "util/probe-event.h"
45 48
46/* Default vmlinux search paths */
47#define NR_SEARCH_PATH 4
48const char *default_search_path[NR_SEARCH_PATH] = {
49"/lib/modules/%s/build/vmlinux", /* Custom build kernel */
50"/usr/lib/debug/lib/modules/%s/vmlinux", /* Red Hat debuginfo */
51"/boot/vmlinux-debug-%s", /* Ubuntu */
52"./vmlinux", /* CWD */
53};
54
55#define MAX_PATH_LEN 256 49#define MAX_PATH_LEN 256
56#define MAX_PROBES 128 50#define MAX_PROBES 128
57 51
58/* Session management structure */ 52/* Session management structure */
59static struct { 53static struct {
60 char *vmlinux;
61 char *release;
62 bool need_dwarf; 54 bool need_dwarf;
63 bool list_events; 55 bool list_events;
64 bool force_add; 56 bool force_add;
65 int nr_probe; 57 int nr_probe;
66 struct probe_point probes[MAX_PROBES]; 58 struct probe_point probes[MAX_PROBES];
67 struct strlist *dellist; 59 struct strlist *dellist;
60 struct symbol_conf conf;
61 struct perf_session *psession;
68} session; 62} session;
69 63
70 64
@@ -122,33 +116,21 @@ static int opt_del_probe_event(const struct option *opt __used,
122} 116}
123 117
124#ifndef NO_LIBDWARF 118#ifndef NO_LIBDWARF
125static int open_default_vmlinux(void) 119static int open_vmlinux(void)
126{ 120{
127 struct utsname uts; 121 struct map *kmap;
128 char fname[MAX_PATH_LEN]; 122 kmap = map_groups__find_by_name(&session.psession->kmaps,
129 int fd, ret, i; 123 MAP__FUNCTION, "[kernel.kallsyms]");
130 124 if (!kmap) {
131 ret = uname(&uts); 125 pr_debug("Could not find kernel map.\n");
132 if (ret) { 126 return -ENOENT;
133 pr_debug("uname() failed.\n");
134 return -errno;
135 } 127 }
136 session.release = uts.release; 128 if (map__load(kmap, session.psession, NULL) < 0) {
137 for (i = 0; i < NR_SEARCH_PATH; i++) { 129 pr_debug("Failed to load kernel map.\n");
138 ret = snprintf(fname, MAX_PATH_LEN, 130 return -EINVAL;
139 default_search_path[i], session.release);
140 if (ret >= MAX_PATH_LEN || ret < 0) {
141 pr_debug("Filename(%d,%s) is too long.\n", i,
142 uts.release);
143 errno = E2BIG;
144 return -E2BIG;
145 }
146 pr_debug("try to open %s\n", fname);
147 fd = open(fname, O_RDONLY);
148 if (fd >= 0)
149 break;
150 } 131 }
151 return fd; 132 pr_debug("Try to open %s\n", kmap->dso->long_name);
133 return open(kmap->dso->long_name, O_RDONLY);
152} 134}
153#endif 135#endif
154 136
@@ -164,8 +146,8 @@ static const struct option options[] = {
164 OPT_BOOLEAN('v', "verbose", &verbose, 146 OPT_BOOLEAN('v', "verbose", &verbose,
165 "be more verbose (show parsed arguments, etc)"), 147 "be more verbose (show parsed arguments, etc)"),
166#ifndef NO_LIBDWARF 148#ifndef NO_LIBDWARF
167 OPT_STRING('k', "vmlinux", &session.vmlinux, "file", 149 OPT_STRING('k', "vmlinux", &session.conf.vmlinux_name,
168 "vmlinux/module pathname"), 150 "file", "vmlinux pathname"),
169#endif 151#endif
170 OPT_BOOLEAN('l', "list", &session.list_events, 152 OPT_BOOLEAN('l', "list", &session.list_events,
171 "list up current probe events"), 153 "list up current probe events"),
@@ -236,17 +218,23 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
236 return 0; 218 return 0;
237 } 219 }
238 220
221 /* Initialize symbol maps for vmlinux */
222 if (session.conf.vmlinux_name == NULL)
223 session.conf.try_vmlinux_path = true;
224 if (symbol__init(&session.conf) < 0)
225 die("Failed to init symbol map.");
226 session.psession = perf_session__new(NULL, O_WRONLY, false,
227 &session.conf);
228 if (session.psession == NULL)
229 die("Failed to init perf_session.");
230
239 if (session.need_dwarf) 231 if (session.need_dwarf)
240#ifdef NO_LIBDWARF 232#ifdef NO_LIBDWARF
241 die("Debuginfo-analysis is not supported"); 233 die("Debuginfo-analysis is not supported");
242#else /* !NO_LIBDWARF */ 234#else /* !NO_LIBDWARF */
243 pr_debug("Some probes require debuginfo.\n"); 235 pr_debug("Some probes require debuginfo.\n");
244 236
245 if (session.vmlinux) { 237 fd = open_vmlinux();
246 pr_debug("Try to open %s.", session.vmlinux);
247 fd = open(session.vmlinux, O_RDONLY);
248 } else
249 fd = open_default_vmlinux();
250 if (fd < 0) { 238 if (fd < 0) {
251 if (session.need_dwarf) 239 if (session.need_dwarf)
252 die("Could not open debuginfo file."); 240 die("Could not open debuginfo file.");
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index a92e0b039a6a..8027309b0422 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -152,6 +152,8 @@ size_t map__fprintf(struct map *self, FILE *fp);
152 152
153struct perf_session; 153struct perf_session;
154 154
155int map__load(struct map *self, struct perf_session *session,
156 symbol_filter_t filter);
155struct symbol *map__find_symbol(struct map *self, struct perf_session *session, 157struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
156 u64 addr, symbol_filter_t filter); 158 u64 addr, symbol_filter_t filter);
157struct symbol *map__find_symbol_by_name(struct map *self, const char *name, 159struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 8b3dd467adb5..c4d55a0da2ea 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -104,12 +104,16 @@ void map__fixup_end(struct map *self)
104 104
105#define DSO__DELETED "(deleted)" 105#define DSO__DELETED "(deleted)"
106 106
107static int map__load(struct map *self, struct perf_session *session, 107int map__load(struct map *self, struct perf_session *session,
108 symbol_filter_t filter) 108 symbol_filter_t filter)
109{ 109{
110 const char *name = self->dso->long_name; 110 const char *name = self->dso->long_name;
111 int nr = dso__load(self->dso, self, session, filter); 111 int nr;
112 112
113 if (dso__loaded(self->dso, self->type))
114 return 0;
115
116 nr = dso__load(self->dso, self, session, filter);
113 if (nr < 0) { 117 if (nr < 0) {
114 if (self->dso->has_build_id) { 118 if (self->dso->has_build_id) {
115 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 119 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
@@ -147,7 +151,7 @@ static int map__load(struct map *self, struct perf_session *session,
147struct symbol *map__find_symbol(struct map *self, struct perf_session *session, 151struct symbol *map__find_symbol(struct map *self, struct perf_session *session,
148 u64 addr, symbol_filter_t filter) 152 u64 addr, symbol_filter_t filter)
149{ 153{
150 if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0) 154 if (map__load(self, session, filter) < 0)
151 return NULL; 155 return NULL;
152 156
153 return dso__find_symbol(self->dso, self->type, addr); 157 return dso__find_symbol(self->dso, self->type, addr);
@@ -157,7 +161,7 @@ struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
157 struct perf_session *session, 161 struct perf_session *session,
158 symbol_filter_t filter) 162 symbol_filter_t filter)
159{ 163{
160 if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0) 164 if (map__load(self, session, filter) < 0)
161 return NULL; 165 return NULL;
162 166
163 if (!dso__sorted_by_name(self->dso, self->type)) 167 if (!dso__sorted_by_name(self->dso, self->type))