aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN7
-rw-r--r--tools/perf/util/event.c45
-rw-r--r--tools/perf/util/event.h10
-rw-r--r--tools/perf/util/evlist.c196
-rw-r--r--tools/perf/util/evlist.h8
-rw-r--r--tools/perf/util/evsel.c85
-rw-r--r--tools/perf/util/evsel.h13
-rw-r--r--tools/perf/util/header.c39
-rw-r--r--tools/perf/util/header.h2
-rw-r--r--tools/perf/util/include/asm/alternative-asm.h8
-rw-r--r--tools/perf/util/include/linux/const.h1
-rw-r--r--tools/perf/util/include/linux/list.h4
-rw-r--r--tools/perf/util/parse-events.c123
-rw-r--r--tools/perf/util/probe-finder.c73
-rw-r--r--tools/perf/util/probe-finder.h2
-rw-r--r--tools/perf/util/python.c25
-rw-r--r--tools/perf/util/session.c72
-rw-r--r--tools/perf/util/session.h5
-rw-r--r--tools/perf/util/symbol.c677
-rw-r--r--tools/perf/util/symbol.h81
-rw-r--r--tools/perf/util/ui/browsers/annotate.c7
-rw-r--r--tools/perf/util/ui/browsers/hists.c2
22 files changed, 931 insertions, 554 deletions
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index 26d4d3fd6deb..ad73300f7bac 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -23,12 +23,7 @@ if test -d ../../.git -o -f ../../.git &&
23then 23then
24 VN=$(echo "$VN" | sed -e 's/-/./g'); 24 VN=$(echo "$VN" | sed -e 's/-/./g');
25else 25else
26 eval $(grep '^VERSION[[:space:]]*=' ../../Makefile|tr -d ' ') 26 VN=$(MAKEFLAGS= make -sC ../.. kernelversion)
27 eval $(grep '^PATCHLEVEL[[:space:]]*=' ../../Makefile|tr -d ' ')
28 eval $(grep '^SUBLEVEL[[:space:]]*=' ../../Makefile|tr -d ' ')
29 eval $(grep '^EXTRAVERSION[[:space:]]*=' ../../Makefile|tr -d ' ')
30
31 VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}"
32fi 27fi
33 28
34VN=$(expr "$VN" : v*'\(.*\)') 29VN=$(expr "$VN" : v*'\(.*\)')
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 1023f67633a4..3c1b8a632101 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -9,21 +9,21 @@
9#include "thread_map.h" 9#include "thread_map.h"
10 10
11static const char *perf_event__names[] = { 11static const char *perf_event__names[] = {
12 [0] = "TOTAL", 12 [0] = "TOTAL",
13 [PERF_RECORD_MMAP] = "MMAP", 13 [PERF_RECORD_MMAP] = "MMAP",
14 [PERF_RECORD_LOST] = "LOST", 14 [PERF_RECORD_LOST] = "LOST",
15 [PERF_RECORD_COMM] = "COMM", 15 [PERF_RECORD_COMM] = "COMM",
16 [PERF_RECORD_EXIT] = "EXIT", 16 [PERF_RECORD_EXIT] = "EXIT",
17 [PERF_RECORD_THROTTLE] = "THROTTLE", 17 [PERF_RECORD_THROTTLE] = "THROTTLE",
18 [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE", 18 [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE",
19 [PERF_RECORD_FORK] = "FORK", 19 [PERF_RECORD_FORK] = "FORK",
20 [PERF_RECORD_READ] = "READ", 20 [PERF_RECORD_READ] = "READ",
21 [PERF_RECORD_SAMPLE] = "SAMPLE", 21 [PERF_RECORD_SAMPLE] = "SAMPLE",
22 [PERF_RECORD_HEADER_ATTR] = "ATTR", 22 [PERF_RECORD_HEADER_ATTR] = "ATTR",
23 [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", 23 [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE",
24 [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", 24 [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA",
25 [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", 25 [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID",
26 [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", 26 [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND",
27}; 27};
28 28
29const char *perf_event__name(unsigned int id) 29const char *perf_event__name(unsigned int id)
@@ -537,9 +537,18 @@ static int perf_event__process_kernel_mmap(union perf_event *event,
537 goto out_problem; 537 goto out_problem;
538 538
539 perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); 539 perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps);
540 perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, 540
541 symbol_name, 541 /*
542 event->mmap.pgoff); 542 * Avoid using a zero address (kptr_restrict) for the ref reloc
543 * symbol. Effectively having zero here means that at record
544 * time /proc/sys/kernel/kptr_restrict was non zero.
545 */
546 if (event->mmap.pgoff != 0) {
547 perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
548 symbol_name,
549 event->mmap.pgoff);
550 }
551
543 if (machine__is_default_guest(machine)) { 552 if (machine__is_default_guest(machine)) {
544 /* 553 /*
545 * preload dso of guest kernel and modules 554 * preload dso of guest kernel and modules
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 9c35170fb379..1d7f66488a88 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -56,6 +56,13 @@ struct read_event {
56 u64 id; 56 u64 id;
57}; 57};
58 58
59
60#define PERF_SAMPLE_MASK \
61 (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \
62 PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR | \
63 PERF_SAMPLE_ID | PERF_SAMPLE_STREAM_ID | \
64 PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD)
65
59struct sample_event { 66struct sample_event {
60 struct perf_event_header header; 67 struct perf_event_header header;
61 u64 array[]; 68 u64 array[];
@@ -178,6 +185,7 @@ int perf_event__preprocess_sample(const union perf_event *self,
178const char *perf_event__name(unsigned int id); 185const char *perf_event__name(unsigned int id);
179 186
180int perf_event__parse_sample(const union perf_event *event, u64 type, 187int perf_event__parse_sample(const union perf_event *event, u64 type,
181 bool sample_id_all, struct perf_sample *sample); 188 int sample_size, bool sample_id_all,
189 struct perf_sample *sample);
182 190
183#endif /* __PERF_RECORD_H */ 191#endif /* __PERF_RECORD_H */
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index d852cefa20de..b021ea9265c3 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -165,11 +165,11 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
165 return NULL; 165 return NULL;
166} 166}
167 167
168union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) 168union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
169{ 169{
170 /* XXX Move this to perf.c, making it generally available */ 170 /* XXX Move this to perf.c, making it generally available */
171 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 171 unsigned int page_size = sysconf(_SC_PAGE_SIZE);
172 struct perf_mmap *md = &evlist->mmap[cpu]; 172 struct perf_mmap *md = &evlist->mmap[idx];
173 unsigned int head = perf_mmap__read_head(md); 173 unsigned int head = perf_mmap__read_head(md);
174 unsigned int old = md->prev; 174 unsigned int old = md->prev;
175 unsigned char *data = md->base + page_size; 175 unsigned char *data = md->base + page_size;
@@ -234,36 +234,122 @@ union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu)
234 234
235void perf_evlist__munmap(struct perf_evlist *evlist) 235void perf_evlist__munmap(struct perf_evlist *evlist)
236{ 236{
237 int cpu; 237 int i;
238 238
239 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 239 for (i = 0; i < evlist->nr_mmaps; i++) {
240 if (evlist->mmap[cpu].base != NULL) { 240 if (evlist->mmap[i].base != NULL) {
241 munmap(evlist->mmap[cpu].base, evlist->mmap_len); 241 munmap(evlist->mmap[i].base, evlist->mmap_len);
242 evlist->mmap[cpu].base = NULL; 242 evlist->mmap[i].base = NULL;
243 } 243 }
244 } 244 }
245
246 free(evlist->mmap);
247 evlist->mmap = NULL;
245} 248}
246 249
247int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 250int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
248{ 251{
249 evlist->mmap = zalloc(evlist->cpus->nr * sizeof(struct perf_mmap)); 252 evlist->nr_mmaps = evlist->cpus->nr;
253 if (evlist->cpus->map[0] == -1)
254 evlist->nr_mmaps = evlist->threads->nr;
255 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
250 return evlist->mmap != NULL ? 0 : -ENOMEM; 256 return evlist->mmap != NULL ? 0 : -ENOMEM;
251} 257}
252 258
253static int __perf_evlist__mmap(struct perf_evlist *evlist, int cpu, int prot, 259static int __perf_evlist__mmap(struct perf_evlist *evlist,
254 int mask, int fd) 260 int idx, int prot, int mask, int fd)
255{ 261{
256 evlist->mmap[cpu].prev = 0; 262 evlist->mmap[idx].prev = 0;
257 evlist->mmap[cpu].mask = mask; 263 evlist->mmap[idx].mask = mask;
258 evlist->mmap[cpu].base = mmap(NULL, evlist->mmap_len, prot, 264 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
259 MAP_SHARED, fd, 0); 265 MAP_SHARED, fd, 0);
260 if (evlist->mmap[cpu].base == MAP_FAILED) 266 if (evlist->mmap[idx].base == MAP_FAILED)
261 return -1; 267 return -1;
262 268
263 perf_evlist__add_pollfd(evlist, fd); 269 perf_evlist__add_pollfd(evlist, fd);
264 return 0; 270 return 0;
265} 271}
266 272
273static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)
274{
275 struct perf_evsel *evsel;
276 int cpu, thread;
277
278 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
279 int output = -1;
280
281 for (thread = 0; thread < evlist->threads->nr; thread++) {
282 list_for_each_entry(evsel, &evlist->entries, node) {
283 int fd = FD(evsel, cpu, thread);
284
285 if (output == -1) {
286 output = fd;
287 if (__perf_evlist__mmap(evlist, cpu,
288 prot, mask, output) < 0)
289 goto out_unmap;
290 } else {
291 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
292 goto out_unmap;
293 }
294
295 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
296 perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
297 goto out_unmap;
298 }
299 }
300 }
301
302 return 0;
303
304out_unmap:
305 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
306 if (evlist->mmap[cpu].base != NULL) {
307 munmap(evlist->mmap[cpu].base, evlist->mmap_len);
308 evlist->mmap[cpu].base = NULL;
309 }
310 }
311 return -1;
312}
313
314static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)
315{
316 struct perf_evsel *evsel;
317 int thread;
318
319 for (thread = 0; thread < evlist->threads->nr; thread++) {
320 int output = -1;
321
322 list_for_each_entry(evsel, &evlist->entries, node) {
323 int fd = FD(evsel, 0, thread);
324
325 if (output == -1) {
326 output = fd;
327 if (__perf_evlist__mmap(evlist, thread,
328 prot, mask, output) < 0)
329 goto out_unmap;
330 } else {
331 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
332 goto out_unmap;
333 }
334
335 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
336 perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)
337 goto out_unmap;
338 }
339 }
340
341 return 0;
342
343out_unmap:
344 for (thread = 0; thread < evlist->threads->nr; thread++) {
345 if (evlist->mmap[thread].base != NULL) {
346 munmap(evlist->mmap[thread].base, evlist->mmap_len);
347 evlist->mmap[thread].base = NULL;
348 }
349 }
350 return -1;
351}
352
267/** perf_evlist__mmap - Create per cpu maps to receive events 353/** perf_evlist__mmap - Create per cpu maps to receive events
268 * 354 *
269 * @evlist - list of events 355 * @evlist - list of events
@@ -282,11 +368,11 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int cpu, int prot,
282int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) 368int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite)
283{ 369{
284 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 370 unsigned int page_size = sysconf(_SC_PAGE_SIZE);
285 int mask = pages * page_size - 1, cpu; 371 int mask = pages * page_size - 1;
286 struct perf_evsel *first_evsel, *evsel; 372 struct perf_evsel *evsel;
287 const struct cpu_map *cpus = evlist->cpus; 373 const struct cpu_map *cpus = evlist->cpus;
288 const struct thread_map *threads = evlist->threads; 374 const struct thread_map *threads = evlist->threads;
289 int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); 375 int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE);
290 376
291 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 377 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
292 return -ENOMEM; 378 return -ENOMEM;
@@ -296,42 +382,18 @@ int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite)
296 382
297 evlist->overwrite = overwrite; 383 evlist->overwrite = overwrite;
298 evlist->mmap_len = (pages + 1) * page_size; 384 evlist->mmap_len = (pages + 1) * page_size;
299 first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node);
300 385
301 list_for_each_entry(evsel, &evlist->entries, node) { 386 list_for_each_entry(evsel, &evlist->entries, node) {
302 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 387 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
303 evsel->sample_id == NULL && 388 evsel->sample_id == NULL &&
304 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0) 389 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0)
305 return -ENOMEM; 390 return -ENOMEM;
306
307 for (cpu = 0; cpu < cpus->nr; cpu++) {
308 for (thread = 0; thread < threads->nr; thread++) {
309 int fd = FD(evsel, cpu, thread);
310
311 if (evsel->idx || thread) {
312 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT,
313 FD(first_evsel, cpu, 0)) != 0)
314 goto out_unmap;
315 } else if (__perf_evlist__mmap(evlist, cpu, prot, mask, fd) < 0)
316 goto out_unmap;
317
318 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
319 perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
320 goto out_unmap;
321 }
322 }
323 } 391 }
324 392
325 return 0; 393 if (evlist->cpus->map[0] == -1)
394 return perf_evlist__mmap_per_thread(evlist, prot, mask);
326 395
327out_unmap: 396 return perf_evlist__mmap_per_cpu(evlist, prot, mask);
328 for (cpu = 0; cpu < cpus->nr; cpu++) {
329 if (evlist->mmap[cpu].base != NULL) {
330 munmap(evlist->mmap[cpu].base, evlist->mmap_len);
331 evlist->mmap[cpu].base = NULL;
332 }
333 }
334 return -1;
335} 397}
336 398
337int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, 399int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
@@ -342,7 +404,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
342 if (evlist->threads == NULL) 404 if (evlist->threads == NULL)
343 return -1; 405 return -1;
344 406
345 if (target_tid != -1) 407 if (cpu_list == NULL && target_tid != -1)
346 evlist->cpus = cpu_map__dummy_new(); 408 evlist->cpus = cpu_map__dummy_new();
347 else 409 else
348 evlist->cpus = cpu_map__new(cpu_list); 410 evlist->cpus = cpu_map__new(cpu_list);
@@ -392,3 +454,47 @@ int perf_evlist__set_filters(struct perf_evlist *evlist)
392 454
393 return 0; 455 return 0;
394} 456}
457
458bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist)
459{
460 struct perf_evsel *pos, *first;
461
462 pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
463
464 list_for_each_entry_continue(pos, &evlist->entries, node) {
465 if (first->attr.sample_type != pos->attr.sample_type)
466 return false;
467 }
468
469 return true;
470}
471
472u64 perf_evlist__sample_type(const struct perf_evlist *evlist)
473{
474 struct perf_evsel *first;
475
476 first = list_entry(evlist->entries.next, struct perf_evsel, node);
477 return first->attr.sample_type;
478}
479
480bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist)
481{
482 struct perf_evsel *pos, *first;
483
484 pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
485
486 list_for_each_entry_continue(pos, &evlist->entries, node) {
487 if (first->attr.sample_id_all != pos->attr.sample_id_all)
488 return false;
489 }
490
491 return true;
492}
493
494bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
495{
496 struct perf_evsel *first;
497
498 first = list_entry(evlist->entries.next, struct perf_evsel, node);
499 return first->attr.sample_id_all;
500}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 8b1cb7a4c5f1..b2b862374f37 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -17,6 +17,7 @@ struct perf_evlist {
17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; 17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
18 int nr_entries; 18 int nr_entries;
19 int nr_fds; 19 int nr_fds;
20 int nr_mmaps;
20 int mmap_len; 21 int mmap_len;
21 bool overwrite; 22 bool overwrite;
22 union perf_event event_copy; 23 union perf_event event_copy;
@@ -46,7 +47,7 @@ void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd);
46 47
47struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); 48struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
48 49
49union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *self, int cpu); 50union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
50 51
51int perf_evlist__alloc_mmap(struct perf_evlist *evlist); 52int perf_evlist__alloc_mmap(struct perf_evlist *evlist);
52int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite); 53int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
@@ -65,4 +66,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
65void perf_evlist__delete_maps(struct perf_evlist *evlist); 66void perf_evlist__delete_maps(struct perf_evlist *evlist);
66int perf_evlist__set_filters(struct perf_evlist *evlist); 67int perf_evlist__set_filters(struct perf_evlist *evlist);
67 68
69u64 perf_evlist__sample_type(const struct perf_evlist *evlist);
70bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist);
71
72bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
73bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
68#endif /* __PERF_EVLIST_H */ 74#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 662596afd7f1..0239eb87b232 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -15,6 +15,22 @@
15 15
16#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 16#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
17 17
18int __perf_evsel__sample_size(u64 sample_type)
19{
20 u64 mask = sample_type & PERF_SAMPLE_MASK;
21 int size = 0;
22 int i;
23
24 for (i = 0; i < 64; i++) {
25 if (mask & (1ULL << i))
26 size++;
27 }
28
29 size *= sizeof(u64);
30
31 return size;
32}
33
18void perf_evsel__init(struct perf_evsel *evsel, 34void perf_evsel__init(struct perf_evsel *evsel,
19 struct perf_event_attr *attr, int idx) 35 struct perf_event_attr *attr, int idx)
20{ 36{
@@ -35,7 +51,17 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
35 51
36int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) 52int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
37{ 53{
54 int cpu, thread;
38 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); 55 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
56
57 if (evsel->fd) {
58 for (cpu = 0; cpu < ncpus; cpu++) {
59 for (thread = 0; thread < nthreads; thread++) {
60 FD(evsel, cpu, thread) = -1;
61 }
62 }
63 }
64
39 return evsel->fd != NULL ? 0 : -ENOMEM; 65 return evsel->fd != NULL ? 0 : -ENOMEM;
40} 66}
41 67
@@ -175,7 +201,7 @@ int __perf_evsel__read(struct perf_evsel *evsel,
175} 201}
176 202
177static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, 203static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
178 struct thread_map *threads, bool group, bool inherit) 204 struct thread_map *threads, bool group)
179{ 205{
180 int cpu, thread; 206 int cpu, thread;
181 unsigned long flags = 0; 207 unsigned long flags = 0;
@@ -192,19 +218,6 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
192 218
193 for (cpu = 0; cpu < cpus->nr; cpu++) { 219 for (cpu = 0; cpu < cpus->nr; cpu++) {
194 int group_fd = -1; 220 int group_fd = -1;
195 /*
196 * Don't allow mmap() of inherited per-task counters. This
197 * would create a performance issue due to all children writing
198 * to the same buffer.
199 *
200 * FIXME:
201 * Proper fix is not to pass 'inherit' to perf_evsel__open*,
202 * but a 'flags' parameter, with 'group' folded there as well,
203 * then introduce a PERF_O_{MMAP,GROUP,INHERIT} enum, and if
204 * O_MMAP is set, emit a warning if cpu < 0 and O_INHERIT is
205 * set. Lets go for the minimal fix first tho.
206 */
207 evsel->attr.inherit = (cpus->map[cpu] >= 0) && inherit;
208 221
209 for (thread = 0; thread < threads->nr; thread++) { 222 for (thread = 0; thread < threads->nr; thread++) {
210 223
@@ -253,7 +266,7 @@ static struct {
253}; 266};
254 267
255int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, 268int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
256 struct thread_map *threads, bool group, bool inherit) 269 struct thread_map *threads, bool group)
257{ 270{
258 if (cpus == NULL) { 271 if (cpus == NULL) {
259 /* Work around old compiler warnings about strict aliasing */ 272 /* Work around old compiler warnings about strict aliasing */
@@ -263,19 +276,19 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
263 if (threads == NULL) 276 if (threads == NULL)
264 threads = &empty_thread_map.map; 277 threads = &empty_thread_map.map;
265 278
266 return __perf_evsel__open(evsel, cpus, threads, group, inherit); 279 return __perf_evsel__open(evsel, cpus, threads, group);
267} 280}
268 281
269int perf_evsel__open_per_cpu(struct perf_evsel *evsel, 282int perf_evsel__open_per_cpu(struct perf_evsel *evsel,
270 struct cpu_map *cpus, bool group, bool inherit) 283 struct cpu_map *cpus, bool group)
271{ 284{
272 return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group, inherit); 285 return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group);
273} 286}
274 287
275int perf_evsel__open_per_thread(struct perf_evsel *evsel, 288int perf_evsel__open_per_thread(struct perf_evsel *evsel,
276 struct thread_map *threads, bool group, bool inherit) 289 struct thread_map *threads, bool group)
277{ 290{
278 return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group, inherit); 291 return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group);
279} 292}
280 293
281static int perf_event__parse_id_sample(const union perf_event *event, u64 type, 294static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
@@ -316,8 +329,20 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
316 return 0; 329 return 0;
317} 330}
318 331
332static bool sample_overlap(const union perf_event *event,
333 const void *offset, u64 size)
334{
335 const void *base = event;
336
337 if (offset + size > base + event->header.size)
338 return true;
339
340 return false;
341}
342
319int perf_event__parse_sample(const union perf_event *event, u64 type, 343int perf_event__parse_sample(const union perf_event *event, u64 type,
320 bool sample_id_all, struct perf_sample *data) 344 int sample_size, bool sample_id_all,
345 struct perf_sample *data)
321{ 346{
322 const u64 *array; 347 const u64 *array;
323 348
@@ -332,6 +357,9 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
332 357
333 array = event->sample.array; 358 array = event->sample.array;
334 359
360 if (sample_size + sizeof(event->header) > event->header.size)
361 return -EFAULT;
362
335 if (type & PERF_SAMPLE_IP) { 363 if (type & PERF_SAMPLE_IP) {
336 data->ip = event->ip.ip; 364 data->ip = event->ip.ip;
337 array++; 365 array++;
@@ -382,14 +410,29 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
382 } 410 }
383 411
384 if (type & PERF_SAMPLE_CALLCHAIN) { 412 if (type & PERF_SAMPLE_CALLCHAIN) {
413 if (sample_overlap(event, array, sizeof(data->callchain->nr)))
414 return -EFAULT;
415
385 data->callchain = (struct ip_callchain *)array; 416 data->callchain = (struct ip_callchain *)array;
417
418 if (sample_overlap(event, array, data->callchain->nr))
419 return -EFAULT;
420
386 array += 1 + data->callchain->nr; 421 array += 1 + data->callchain->nr;
387 } 422 }
388 423
389 if (type & PERF_SAMPLE_RAW) { 424 if (type & PERF_SAMPLE_RAW) {
390 u32 *p = (u32 *)array; 425 u32 *p = (u32 *)array;
426
427 if (sample_overlap(event, array, sizeof(u32)))
428 return -EFAULT;
429
391 data->raw_size = *p; 430 data->raw_size = *p;
392 p++; 431 p++;
432
433 if (sample_overlap(event, p, data->raw_size))
434 return -EFAULT;
435
393 data->raw_data = p; 436 data->raw_data = p;
394 } 437 }
395 438
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 6710ab538342..7e9366e4490b 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -81,11 +81,11 @@ void perf_evsel__free_id(struct perf_evsel *evsel);
81void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); 81void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
82 82
83int perf_evsel__open_per_cpu(struct perf_evsel *evsel, 83int perf_evsel__open_per_cpu(struct perf_evsel *evsel,
84 struct cpu_map *cpus, bool group, bool inherit); 84 struct cpu_map *cpus, bool group);
85int perf_evsel__open_per_thread(struct perf_evsel *evsel, 85int perf_evsel__open_per_thread(struct perf_evsel *evsel,
86 struct thread_map *threads, bool group, bool inherit); 86 struct thread_map *threads, bool group);
87int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, 87int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
88 struct thread_map *threads, bool group, bool inherit); 88 struct thread_map *threads, bool group);
89 89
90#define perf_evsel__match(evsel, t, c) \ 90#define perf_evsel__match(evsel, t, c) \
91 (evsel->attr.type == PERF_TYPE_##t && \ 91 (evsel->attr.type == PERF_TYPE_##t && \
@@ -149,4 +149,11 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
149 return __perf_evsel__read(evsel, ncpus, nthreads, true); 149 return __perf_evsel__read(evsel, ncpus, nthreads, true);
150} 150}
151 151
152int __perf_evsel__sample_size(u64 sample_type);
153
154static inline int perf_evsel__sample_size(struct perf_evsel *evsel)
155{
156 return __perf_evsel__sample_size(evsel->attr.sample_type);
157}
158
152#endif /* __PERF_EVSEL_H */ 159#endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 93862a8027ea..afb0849fe530 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -193,9 +193,13 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
193 *linkname = malloc(size), *targetname; 193 *linkname = malloc(size), *targetname;
194 int len, err = -1; 194 int len, err = -1;
195 195
196 if (is_kallsyms) 196 if (is_kallsyms) {
197 if (symbol_conf.kptr_restrict) {
198 pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n");
199 return 0;
200 }
197 realname = (char *)name; 201 realname = (char *)name;
198 else 202 } else
199 realname = realpath(name, NULL); 203 realname = realpath(name, NULL);
200 204
201 if (realname == NULL || filename == NULL || linkname == NULL) 205 if (realname == NULL || filename == NULL || linkname == NULL)
@@ -934,37 +938,6 @@ out_delete_evlist:
934 return -ENOMEM; 938 return -ENOMEM;
935} 939}
936 940
937u64 perf_evlist__sample_type(struct perf_evlist *evlist)
938{
939 struct perf_evsel *pos;
940 u64 type = 0;
941
942 list_for_each_entry(pos, &evlist->entries, node) {
943 if (!type)
944 type = pos->attr.sample_type;
945 else if (type != pos->attr.sample_type)
946 die("non matching sample_type");
947 }
948
949 return type;
950}
951
952bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
953{
954 bool value = false, first = true;
955 struct perf_evsel *pos;
956
957 list_for_each_entry(pos, &evlist->entries, node) {
958 if (first) {
959 value = pos->attr.sample_id_all;
960 first = false;
961 } else if (value != pos->attr.sample_id_all)
962 die("non matching sample_id_all");
963 }
964
965 return value;
966}
967
968int perf_event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id, 941int perf_event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
969 perf_event__handler_t process, 942 perf_event__handler_t process,
970 struct perf_session *session) 943 struct perf_session *session)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 456661d7f10e..1886256768a1 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -64,8 +64,6 @@ int perf_header__write_pipe(int fd);
64int perf_header__push_event(u64 id, const char *name); 64int perf_header__push_event(u64 id, const char *name);
65char *perf_header__find_event(u64 id); 65char *perf_header__find_event(u64 id);
66 66
67u64 perf_evlist__sample_type(struct perf_evlist *evlist);
68bool perf_evlist__sample_id_all(const struct perf_evlist *evlist);
69void perf_header__set_feat(struct perf_header *header, int feat); 67void perf_header__set_feat(struct perf_header *header, int feat);
70void perf_header__clear_feat(struct perf_header *header, int feat); 68void perf_header__clear_feat(struct perf_header *header, int feat);
71bool perf_header__has_feat(const struct perf_header *header, int feat); 69bool perf_header__has_feat(const struct perf_header *header, int feat);
diff --git a/tools/perf/util/include/asm/alternative-asm.h b/tools/perf/util/include/asm/alternative-asm.h
new file mode 100644
index 000000000000..6789d788d494
--- /dev/null
+++ b/tools/perf/util/include/asm/alternative-asm.h
@@ -0,0 +1,8 @@
1#ifndef _PERF_ASM_ALTERNATIVE_ASM_H
2#define _PERF_ASM_ALTERNATIVE_ASM_H
3
4/* Just disable it so we can build arch/x86/lib/memcpy_64.S for perf bench: */
5
6#define altinstruction_entry #
7
8#endif
diff --git a/tools/perf/util/include/linux/const.h b/tools/perf/util/include/linux/const.h
new file mode 100644
index 000000000000..1b476c9ae649
--- /dev/null
+++ b/tools/perf/util/include/linux/const.h
@@ -0,0 +1 @@
#include "../../../../include/linux/const.h"
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h
index 356c7e467b83..1d928a0ce997 100644
--- a/tools/perf/util/include/linux/list.h
+++ b/tools/perf/util/include/linux/list.h
@@ -1,4 +1,6 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/prefetch.h>
3
2#include "../../../../include/linux/list.h" 4#include "../../../../include/linux/list.h"
3 5
4#ifndef PERF_LIST_H 6#ifndef PERF_LIST_H
@@ -23,5 +25,5 @@ static inline void list_del_range(struct list_head *begin,
23 * @head: the head for your list. 25 * @head: the head for your list.
24 */ 26 */
25#define list_for_each_from(pos, head) \ 27#define list_for_each_from(pos, head) \
26 for (; prefetch(pos->next), pos != (head); pos = pos->next) 28 for (; pos != (head); pos = pos->next)
27#endif 29#endif
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 952b4ae3d954..41982c373faf 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -31,34 +31,36 @@ char debugfs_path[MAXPATHLEN];
31#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 31#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
32 32
33static struct event_symbol event_symbols[] = { 33static struct event_symbol event_symbols[] = {
34 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 34 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" },
35 { CHW(INSTRUCTIONS), "instructions", "" }, 35 { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" },
36 { CHW(CACHE_REFERENCES), "cache-references", "" }, 36 { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" },
37 { CHW(CACHE_MISSES), "cache-misses", "" }, 37 { CHW(INSTRUCTIONS), "instructions", "" },
38 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 38 { CHW(CACHE_REFERENCES), "cache-references", "" },
39 { CHW(BRANCH_MISSES), "branch-misses", "" }, 39 { CHW(CACHE_MISSES), "cache-misses", "" },
40 { CHW(BUS_CYCLES), "bus-cycles", "" }, 40 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" },
41 41 { CHW(BRANCH_MISSES), "branch-misses", "" },
42 { CSW(CPU_CLOCK), "cpu-clock", "" }, 42 { CHW(BUS_CYCLES), "bus-cycles", "" },
43 { CSW(TASK_CLOCK), "task-clock", "" }, 43
44 { CSW(PAGE_FAULTS), "page-faults", "faults" }, 44 { CSW(CPU_CLOCK), "cpu-clock", "" },
45 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 45 { CSW(TASK_CLOCK), "task-clock", "" },
46 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 46 { CSW(PAGE_FAULTS), "page-faults", "faults" },
47 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 47 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" },
48 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 48 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" },
49 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, 49 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" },
50 { CSW(EMULATION_FAULTS), "emulation-faults", "" }, 50 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" },
51 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" },
52 { CSW(EMULATION_FAULTS), "emulation-faults", "" },
51}; 53};
52 54
53#define __PERF_EVENT_FIELD(config, name) \ 55#define __PERF_EVENT_FIELD(config, name) \
54 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 56 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
55 57
56#define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 58#define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW)
57#define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 59#define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG)
58#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 60#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
59#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 61#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
60 62
61static const char *hw_event_names[] = { 63static const char *hw_event_names[PERF_COUNT_HW_MAX] = {
62 "cycles", 64 "cycles",
63 "instructions", 65 "instructions",
64 "cache-references", 66 "cache-references",
@@ -66,11 +68,13 @@ static const char *hw_event_names[] = {
66 "branches", 68 "branches",
67 "branch-misses", 69 "branch-misses",
68 "bus-cycles", 70 "bus-cycles",
71 "stalled-cycles-frontend",
72 "stalled-cycles-backend",
69}; 73};
70 74
71static const char *sw_event_names[] = { 75static const char *sw_event_names[PERF_COUNT_SW_MAX] = {
72 "cpu-clock-msecs", 76 "cpu-clock",
73 "task-clock-msecs", 77 "task-clock",
74 "page-faults", 78 "page-faults",
75 "context-switches", 79 "context-switches",
76 "CPU-migrations", 80 "CPU-migrations",
@@ -307,7 +311,7 @@ const char *__event_name(int type, u64 config)
307 311
308 switch (type) { 312 switch (type) {
309 case PERF_TYPE_HARDWARE: 313 case PERF_TYPE_HARDWARE:
310 if (config < PERF_COUNT_HW_MAX) 314 if (config < PERF_COUNT_HW_MAX && hw_event_names[config])
311 return hw_event_names[config]; 315 return hw_event_names[config];
312 return "unknown-hardware"; 316 return "unknown-hardware";
313 317
@@ -333,7 +337,7 @@ const char *__event_name(int type, u64 config)
333 } 337 }
334 338
335 case PERF_TYPE_SOFTWARE: 339 case PERF_TYPE_SOFTWARE:
336 if (config < PERF_COUNT_SW_MAX) 340 if (config < PERF_COUNT_SW_MAX && sw_event_names[config])
337 return sw_event_names[config]; 341 return sw_event_names[config];
338 return "unknown-software"; 342 return "unknown-software";
339 343
@@ -648,13 +652,15 @@ static int check_events(const char *str, unsigned int i)
648 int n; 652 int n;
649 653
650 n = strlen(event_symbols[i].symbol); 654 n = strlen(event_symbols[i].symbol);
651 if (!strncmp(str, event_symbols[i].symbol, n)) 655 if (!strncasecmp(str, event_symbols[i].symbol, n))
652 return n; 656 return n;
653 657
654 n = strlen(event_symbols[i].alias); 658 n = strlen(event_symbols[i].alias);
655 if (n) 659 if (n) {
656 if (!strncmp(str, event_symbols[i].alias, n)) 660 if (!strncasecmp(str, event_symbols[i].alias, n))
657 return n; 661 return n;
662 }
663
658 return 0; 664 return 0;
659} 665}
660 666
@@ -718,15 +724,22 @@ parse_numeric_event(const char **strp, struct perf_event_attr *attr)
718 return EVT_FAILED; 724 return EVT_FAILED;
719} 725}
720 726
721static enum event_result 727static int
722parse_event_modifier(const char **strp, struct perf_event_attr *attr) 728parse_event_modifier(const char **strp, struct perf_event_attr *attr)
723{ 729{
724 const char *str = *strp; 730 const char *str = *strp;
725 int exclude = 0; 731 int exclude = 0;
726 int eu = 0, ek = 0, eh = 0, precise = 0; 732 int eu = 0, ek = 0, eh = 0, precise = 0;
727 733
728 if (*str++ != ':') 734 if (!*str)
735 return 0;
736
737 if (*str == ',')
729 return 0; 738 return 0;
739
740 if (*str++ != ':')
741 return -1;
742
730 while (*str) { 743 while (*str) {
731 if (*str == 'u') { 744 if (*str == 'u') {
732 if (!exclude) 745 if (!exclude)
@@ -747,14 +760,16 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
747 760
748 ++str; 761 ++str;
749 } 762 }
750 if (str >= *strp + 2) { 763 if (str < *strp + 2)
751 *strp = str; 764 return -1;
752 attr->exclude_user = eu; 765
753 attr->exclude_kernel = ek; 766 *strp = str;
754 attr->exclude_hv = eh; 767
755 attr->precise_ip = precise; 768 attr->exclude_user = eu;
756 return 1; 769 attr->exclude_kernel = ek;
757 } 770 attr->exclude_hv = eh;
771 attr->precise_ip = precise;
772
758 return 0; 773 return 0;
759} 774}
760 775
@@ -797,7 +812,12 @@ parse_event_symbols(const struct option *opt, const char **str,
797 return EVT_FAILED; 812 return EVT_FAILED;
798 813
799modifier: 814modifier:
800 parse_event_modifier(str, attr); 815 if (parse_event_modifier(str, attr) < 0) {
816 fprintf(stderr, "invalid event modifier: '%s'\n", *str);
817 fprintf(stderr, "Run 'perf list' for a list of valid events and modifiers\n");
818
819 return EVT_FAILED;
820 }
801 821
802 return ret; 822 return ret;
803} 823}
@@ -912,7 +932,7 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
912 932
913 snprintf(evt_path, MAXPATHLEN, "%s:%s", 933 snprintf(evt_path, MAXPATHLEN, "%s:%s",
914 sys_dirent.d_name, evt_dirent.d_name); 934 sys_dirent.d_name, evt_dirent.d_name);
915 printf(" %-42s [%s]\n", evt_path, 935 printf(" %-50s [%s]\n", evt_path,
916 event_type_descriptors[PERF_TYPE_TRACEPOINT]); 936 event_type_descriptors[PERF_TYPE_TRACEPOINT]);
917 } 937 }
918 closedir(evt_dir); 938 closedir(evt_dir);
@@ -977,7 +997,7 @@ void print_events_type(u8 type)
977 else 997 else
978 snprintf(name, sizeof(name), "%s", syms->symbol); 998 snprintf(name, sizeof(name), "%s", syms->symbol);
979 999
980 printf(" %-42s [%s]\n", name, 1000 printf(" %-50s [%s]\n", name,
981 event_type_descriptors[type]); 1001 event_type_descriptors[type]);
982 } 1002 }
983} 1003}
@@ -995,11 +1015,10 @@ int print_hwcache_events(const char *event_glob)
995 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 1015 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
996 char *name = event_cache_name(type, op, i); 1016 char *name = event_cache_name(type, op, i);
997 1017
998 if (event_glob != NULL && 1018 if (event_glob != NULL && !strglobmatch(name, event_glob))
999 !strglobmatch(name, event_glob))
1000 continue; 1019 continue;
1001 1020
1002 printf(" %-42s [%s]\n", name, 1021 printf(" %-50s [%s]\n", name,
1003 event_type_descriptors[PERF_TYPE_HW_CACHE]); 1022 event_type_descriptors[PERF_TYPE_HW_CACHE]);
1004 ++printed; 1023 ++printed;
1005 } 1024 }
@@ -1009,14 +1028,16 @@ int print_hwcache_events(const char *event_glob)
1009 return printed; 1028 return printed;
1010} 1029}
1011 1030
1031#define MAX_NAME_LEN 100
1032
1012/* 1033/*
1013 * Print the help text for the event symbols: 1034 * Print the help text for the event symbols:
1014 */ 1035 */
1015void print_events(const char *event_glob) 1036void print_events(const char *event_glob)
1016{ 1037{
1017 struct event_symbol *syms = event_symbols;
1018 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; 1038 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
1019 char name[40]; 1039 struct event_symbol *syms = event_symbols;
1040 char name[MAX_NAME_LEN];
1020 1041
1021 printf("\n"); 1042 printf("\n");
1022 printf("List of pre-defined events (to be used in -e):\n"); 1043 printf("List of pre-defined events (to be used in -e):\n");
@@ -1036,10 +1057,10 @@ void print_events(const char *event_glob)
1036 continue; 1057 continue;
1037 1058
1038 if (strlen(syms->alias)) 1059 if (strlen(syms->alias))
1039 sprintf(name, "%s OR %s", syms->symbol, syms->alias); 1060 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
1040 else 1061 else
1041 strcpy(name, syms->symbol); 1062 strncpy(name, syms->symbol, MAX_NAME_LEN);
1042 printf(" %-42s [%s]\n", name, 1063 printf(" %-50s [%s]\n", name,
1043 event_type_descriptors[type]); 1064 event_type_descriptors[type]);
1044 1065
1045 prev_type = type; 1066 prev_type = type;
@@ -1056,12 +1077,12 @@ void print_events(const char *event_glob)
1056 return; 1077 return;
1057 1078
1058 printf("\n"); 1079 printf("\n");
1059 printf(" %-42s [%s]\n", 1080 printf(" %-50s [%s]\n",
1060 "rNNN (see 'perf list --help' on how to encode it)", 1081 "rNNN (see 'perf list --help' on how to encode it)",
1061 event_type_descriptors[PERF_TYPE_RAW]); 1082 event_type_descriptors[PERF_TYPE_RAW]);
1062 printf("\n"); 1083 printf("\n");
1063 1084
1064 printf(" %-42s [%s]\n", 1085 printf(" %-50s [%s]\n",
1065 "mem:<addr>[:access]", 1086 "mem:<addr>[:access]",
1066 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1087 event_type_descriptors[PERF_TYPE_BREAKPOINT]);
1067 printf("\n"); 1088 printf("\n");
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index b7c85ce466a1..3b9d0b800d5c 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1471,6 +1471,38 @@ static int find_probe_point_by_func(struct probe_finder *pf)
1471 return _param.retval; 1471 return _param.retval;
1472} 1472}
1473 1473
1474struct pubname_callback_param {
1475 char *function;
1476 char *file;
1477 Dwarf_Die *cu_die;
1478 Dwarf_Die *sp_die;
1479 int found;
1480};
1481
1482static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
1483{
1484 struct pubname_callback_param *param = data;
1485
1486 if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
1487 if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
1488 return DWARF_CB_OK;
1489
1490 if (die_compare_name(param->sp_die, param->function)) {
1491 if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
1492 return DWARF_CB_OK;
1493
1494 if (param->file &&
1495 strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
1496 return DWARF_CB_OK;
1497
1498 param->found = 1;
1499 return DWARF_CB_ABORT;
1500 }
1501 }
1502
1503 return DWARF_CB_OK;
1504}
1505
1474/* Find probe points from debuginfo */ 1506/* Find probe points from debuginfo */
1475static int find_probes(int fd, struct probe_finder *pf) 1507static int find_probes(int fd, struct probe_finder *pf)
1476{ 1508{
@@ -1498,6 +1530,28 @@ static int find_probes(int fd, struct probe_finder *pf)
1498 1530
1499 off = 0; 1531 off = 0;
1500 line_list__init(&pf->lcache); 1532 line_list__init(&pf->lcache);
1533
1534 /* Fastpath: lookup by function name from .debug_pubnames section */
1535 if (pp->function) {
1536 struct pubname_callback_param pubname_param = {
1537 .function = pp->function,
1538 .file = pp->file,
1539 .cu_die = &pf->cu_die,
1540 .sp_die = &pf->sp_die,
1541 .found = 0,
1542 };
1543 struct dwarf_callback_param probe_param = {
1544 .data = pf,
1545 };
1546
1547 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
1548 if (pubname_param.found) {
1549 ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1550 if (ret)
1551 goto found;
1552 }
1553 }
1554
1501 /* Loop on CUs (Compilation Unit) */ 1555 /* Loop on CUs (Compilation Unit) */
1502 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1556 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1503 /* Get the DIE(Debugging Information Entry) of this CU */ 1557 /* Get the DIE(Debugging Information Entry) of this CU */
@@ -1525,6 +1579,8 @@ static int find_probes(int fd, struct probe_finder *pf)
1525 } 1579 }
1526 off = noff; 1580 off = noff;
1527 } 1581 }
1582
1583found:
1528 line_list__free(&pf->lcache); 1584 line_list__free(&pf->lcache);
1529 if (dwfl) 1585 if (dwfl)
1530 dwfl_end(dwfl); 1586 dwfl_end(dwfl);
@@ -1946,6 +2002,22 @@ int find_line_range(int fd, struct line_range *lr)
1946 return -EBADF; 2002 return -EBADF;
1947 } 2003 }
1948 2004
2005 /* Fastpath: lookup by function name from .debug_pubnames section */
2006 if (lr->function) {
2007 struct pubname_callback_param pubname_param = {
2008 .function = lr->function, .file = lr->file,
2009 .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
2010 struct dwarf_callback_param line_range_param = {
2011 .data = (void *)&lf, .retval = 0};
2012
2013 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
2014 if (pubname_param.found) {
2015 line_range_search_cb(&lf.sp_die, &line_range_param);
2016 if (lf.found)
2017 goto found;
2018 }
2019 }
2020
1949 /* Loop on CUs (Compilation Unit) */ 2021 /* Loop on CUs (Compilation Unit) */
1950 while (!lf.found && ret >= 0) { 2022 while (!lf.found && ret >= 0) {
1951 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0) 2023 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
@@ -1974,6 +2046,7 @@ int find_line_range(int fd, struct line_range *lr)
1974 off = noff; 2046 off = noff;
1975 } 2047 }
1976 2048
2049found:
1977 /* Store comp_dir */ 2050 /* Store comp_dir */
1978 if (lf.found) { 2051 if (lf.found) {
1979 comp_dir = cu_get_comp_dir(&lf.cu_die); 2052 comp_dir = cu_get_comp_dir(&lf.cu_die);
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index beaefc3c1223..605730a366db 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -49,6 +49,7 @@ struct probe_finder {
49 Dwarf_Addr addr; /* Address */ 49 Dwarf_Addr addr; /* Address */
50 const char *fname; /* Real file name */ 50 const char *fname; /* Real file name */
51 Dwarf_Die cu_die; /* Current CU */ 51 Dwarf_Die cu_die; /* Current CU */
52 Dwarf_Die sp_die;
52 struct list_head lcache; /* Line cache for lazy match */ 53 struct list_head lcache; /* Line cache for lazy match */
53 54
54 /* For variable searching */ 55 /* For variable searching */
@@ -83,6 +84,7 @@ struct line_finder {
83 int lno_s; /* Start line number */ 84 int lno_s; /* Start line number */
84 int lno_e; /* End line number */ 85 int lno_e; /* End line number */
85 Dwarf_Die cu_die; /* Current CU */ 86 Dwarf_Die cu_die; /* Current CU */
87 Dwarf_Die sp_die;
86 int found; 88 int found;
87}; 89};
88 90
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index a9f2d7e1204d..a9ac0504aabd 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -498,11 +498,11 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
498 struct cpu_map *cpus = NULL; 498 struct cpu_map *cpus = NULL;
499 struct thread_map *threads = NULL; 499 struct thread_map *threads = NULL;
500 PyObject *pcpus = NULL, *pthreads = NULL; 500 PyObject *pcpus = NULL, *pthreads = NULL;
501 int group = 0, overwrite = 0; 501 int group = 0, inherit = 0;
502 static char *kwlist[] = {"cpus", "threads", "group", "overwrite", NULL, NULL}; 502 static char *kwlist[] = {"cpus", "threads", "group", "inherit", NULL, NULL};
503 503
504 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, 504 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
505 &pcpus, &pthreads, &group, &overwrite)) 505 &pcpus, &pthreads, &group, &inherit))
506 return NULL; 506 return NULL;
507 507
508 if (pthreads != NULL) 508 if (pthreads != NULL)
@@ -511,7 +511,8 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
511 if (pcpus != NULL) 511 if (pcpus != NULL)
512 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 512 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
513 513
514 if (perf_evsel__open(evsel, cpus, threads, group, overwrite) < 0) { 514 evsel->attr.inherit = inherit;
515 if (perf_evsel__open(evsel, cpus, threads, group) < 0) {
515 PyErr_SetFromErrno(PyExc_OSError); 516 PyErr_SetFromErrno(PyExc_OSError);
516 return NULL; 517 return NULL;
517 } 518 }
@@ -673,13 +674,14 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
673 struct perf_evlist *evlist = &pevlist->evlist; 674 struct perf_evlist *evlist = &pevlist->evlist;
674 union perf_event *event; 675 union perf_event *event;
675 int sample_id_all = 1, cpu; 676 int sample_id_all = 1, cpu;
676 static char *kwlist[] = {"sample_id_all", NULL, NULL}; 677 static char *kwlist[] = {"cpu", "sample_id_all", NULL, NULL};
678 int err;
677 679
678 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, 680 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
679 &cpu, &sample_id_all)) 681 &cpu, &sample_id_all))
680 return NULL; 682 return NULL;
681 683
682 event = perf_evlist__read_on_cpu(evlist, cpu); 684 event = perf_evlist__mmap_read(evlist, cpu);
683 if (event != NULL) { 685 if (event != NULL) {
684 struct perf_evsel *first; 686 struct perf_evsel *first;
685 PyObject *pyevent = pyrf_event__new(event); 687 PyObject *pyevent = pyrf_event__new(event);
@@ -689,8 +691,12 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
689 return PyErr_NoMemory(); 691 return PyErr_NoMemory();
690 692
691 first = list_entry(evlist->entries.next, struct perf_evsel, node); 693 first = list_entry(evlist->entries.next, struct perf_evsel, node);
692 perf_event__parse_sample(event, first->attr.sample_type, sample_id_all, 694 err = perf_event__parse_sample(event, first->attr.sample_type,
693 &pevent->sample); 695 perf_evsel__sample_size(first),
696 sample_id_all, &pevent->sample);
697 if (err)
698 return PyErr_Format(PyExc_OSError,
699 "perf: can't parse sample, err=%d", err);
694 return pyevent; 700 return pyevent;
695 } 701 }
696 702
@@ -809,6 +815,9 @@ static struct {
809 { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS }, 815 { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
810 { "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS }, 816 { "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS },
811 817
818 { "COUNT_HW_STALLED_CYCLES_FRONTEND", PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
819 { "COUNT_HW_STALLED_CYCLES_BACKEND", PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
820
812 { "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK }, 821 { "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK },
813 { "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK }, 822 { "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK },
814 { "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS }, 823 { "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS },
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index caa224522fea..f5a8fbdd3f76 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -58,6 +58,16 @@ static int perf_session__open(struct perf_session *self, bool force)
58 goto out_close; 58 goto out_close;
59 } 59 }
60 60
61 if (!perf_evlist__valid_sample_type(self->evlist)) {
62 pr_err("non matching sample_type");
63 goto out_close;
64 }
65
66 if (!perf_evlist__valid_sample_id_all(self->evlist)) {
67 pr_err("non matching sample_id_all");
68 goto out_close;
69 }
70
61 self->size = input_stat.st_size; 71 self->size = input_stat.st_size;
62 return 0; 72 return 0;
63 73
@@ -97,6 +107,7 @@ out:
97void perf_session__update_sample_type(struct perf_session *self) 107void perf_session__update_sample_type(struct perf_session *self)
98{ 108{
99 self->sample_type = perf_evlist__sample_type(self->evlist); 109 self->sample_type = perf_evlist__sample_type(self->evlist);
110 self->sample_size = __perf_evsel__sample_size(self->sample_type);
100 self->sample_id_all = perf_evlist__sample_id_all(self->evlist); 111 self->sample_id_all = perf_evlist__sample_id_all(self->evlist);
101 perf_session__id_header_size(self); 112 perf_session__id_header_size(self);
102} 113}
@@ -479,6 +490,7 @@ static void flush_sample_queue(struct perf_session *s,
479 struct perf_sample sample; 490 struct perf_sample sample;
480 u64 limit = os->next_flush; 491 u64 limit = os->next_flush;
481 u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; 492 u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
493 int ret;
482 494
483 if (!ops->ordered_samples || !limit) 495 if (!ops->ordered_samples || !limit)
484 return; 496 return;
@@ -487,9 +499,12 @@ static void flush_sample_queue(struct perf_session *s,
487 if (iter->timestamp > limit) 499 if (iter->timestamp > limit)
488 break; 500 break;
489 501
490 perf_session__parse_sample(s, iter->event, &sample); 502 ret = perf_session__parse_sample(s, iter->event, &sample);
491 perf_session_deliver_event(s, iter->event, &sample, ops, 503 if (ret)
492 iter->file_offset); 504 pr_err("Can't parse sample, err = %d\n", ret);
505 else
506 perf_session_deliver_event(s, iter->event, &sample, ops,
507 iter->file_offset);
493 508
494 os->last_flush = iter->timestamp; 509 os->last_flush = iter->timestamp;
495 list_del(&iter->list); 510 list_del(&iter->list);
@@ -805,7 +820,9 @@ static int perf_session__process_event(struct perf_session *session,
805 /* 820 /*
806 * For all kernel events we get the sample data 821 * For all kernel events we get the sample data
807 */ 822 */
808 perf_session__parse_sample(session, event, &sample); 823 ret = perf_session__parse_sample(session, event, &sample);
824 if (ret)
825 return ret;
809 826
810 /* Preprocess sample records - precheck callchains */ 827 /* Preprocess sample records - precheck callchains */
811 if (perf_session__preprocess_sample(session, event, &sample)) 828 if (perf_session__preprocess_sample(session, event, &sample))
@@ -953,6 +970,30 @@ out_err:
953 return err; 970 return err;
954} 971}
955 972
973static union perf_event *
974fetch_mmaped_event(struct perf_session *session,
975 u64 head, size_t mmap_size, char *buf)
976{
977 union perf_event *event;
978
979 /*
980 * Ensure we have enough space remaining to read
981 * the size of the event in the headers.
982 */
983 if (head + sizeof(event->header) > mmap_size)
984 return NULL;
985
986 event = (union perf_event *)(buf + head);
987
988 if (session->header.needs_swap)
989 perf_event_header__bswap(&event->header);
990
991 if (head + event->header.size > mmap_size)
992 return NULL;
993
994 return event;
995}
996
956int __perf_session__process_events(struct perf_session *session, 997int __perf_session__process_events(struct perf_session *session,
957 u64 data_offset, u64 data_size, 998 u64 data_offset, u64 data_size,
958 u64 file_size, struct perf_event_ops *ops) 999 u64 file_size, struct perf_event_ops *ops)
@@ -1007,15 +1048,8 @@ remap:
1007 file_pos = file_offset + head; 1048 file_pos = file_offset + head;
1008 1049
1009more: 1050more:
1010 event = (union perf_event *)(buf + head); 1051 event = fetch_mmaped_event(session, head, mmap_size, buf);
1011 1052 if (!event) {
1012 if (session->header.needs_swap)
1013 perf_event_header__bswap(&event->header);
1014 size = event->header.size;
1015 if (size == 0)
1016 size = 8;
1017
1018 if (head + event->header.size > mmap_size) {
1019 if (mmaps[map_idx]) { 1053 if (mmaps[map_idx]) {
1020 munmap(mmaps[map_idx], mmap_size); 1054 munmap(mmaps[map_idx], mmap_size);
1021 mmaps[map_idx] = NULL; 1055 mmaps[map_idx] = NULL;
@@ -1156,6 +1190,18 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
1156 return ret; 1190 return ret;
1157} 1191}
1158 1192
1193struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1194 unsigned int type)
1195{
1196 struct perf_evsel *pos;
1197
1198 list_for_each_entry(pos, &session->evlist->entries, node) {
1199 if (pos->attr.type == type)
1200 return pos;
1201 }
1202 return NULL;
1203}
1204
1159void perf_session__print_symbols(union perf_event *event, 1205void perf_session__print_symbols(union perf_event *event,
1160 struct perf_sample *sample, 1206 struct perf_sample *sample,
1161 struct perf_session *session) 1207 struct perf_session *session)
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 1ac481fc1100..66d4e1490879 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -43,6 +43,7 @@ struct perf_session {
43 */ 43 */
44 struct hists hists; 44 struct hists hists;
45 u64 sample_type; 45 u64 sample_type;
46 int sample_size;
46 int fd; 47 int fd;
47 bool fd_pipe; 48 bool fd_pipe;
48 bool repipe; 49 bool repipe;
@@ -159,9 +160,13 @@ static inline int perf_session__parse_sample(struct perf_session *session,
159 struct perf_sample *sample) 160 struct perf_sample *sample)
160{ 161{
161 return perf_event__parse_sample(event, session->sample_type, 162 return perf_event__parse_sample(event, session->sample_type,
163 session->sample_size,
162 session->sample_id_all, sample); 164 session->sample_id_all, sample);
163} 165}
164 166
167struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
168 unsigned int type);
169
165void perf_session__print_symbols(union perf_event *event, 170void perf_session__print_symbols(union perf_event *event,
166 struct perf_sample *sample, 171 struct perf_sample *sample,
167 struct perf_session *session); 172 struct perf_session *session);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index f06c10f092ba..eec196329fd9 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -31,13 +31,13 @@
31#define NT_GNU_BUILD_ID 3 31#define NT_GNU_BUILD_ID 3
32#endif 32#endif
33 33
34static bool dso__build_id_equal(const struct dso *self, u8 *build_id); 34static bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
35static int elf_read_build_id(Elf *elf, void *bf, size_t size); 35static int elf_read_build_id(Elf *elf, void *bf, size_t size);
36static void dsos__add(struct list_head *head, struct dso *dso); 36static void dsos__add(struct list_head *head, struct dso *dso);
37static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 37static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
38static int dso__load_kernel_sym(struct dso *self, struct map *map, 38static int dso__load_kernel_sym(struct dso *dso, struct map *map,
39 symbol_filter_t filter); 39 symbol_filter_t filter);
40static int dso__load_guest_kernel_sym(struct dso *self, struct map *map, 40static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
41 symbol_filter_t filter); 41 symbol_filter_t filter);
42static int vmlinux_path__nr_entries; 42static int vmlinux_path__nr_entries;
43static char **vmlinux_path; 43static char **vmlinux_path;
@@ -49,27 +49,27 @@ struct symbol_conf symbol_conf = {
49 .symfs = "", 49 .symfs = "",
50}; 50};
51 51
52int dso__name_len(const struct dso *self) 52int dso__name_len(const struct dso *dso)
53{ 53{
54 if (verbose) 54 if (verbose)
55 return self->long_name_len; 55 return dso->long_name_len;
56 56
57 return self->short_name_len; 57 return dso->short_name_len;
58} 58}
59 59
60bool dso__loaded(const struct dso *self, enum map_type type) 60bool dso__loaded(const struct dso *dso, enum map_type type)
61{ 61{
62 return self->loaded & (1 << type); 62 return dso->loaded & (1 << type);
63} 63}
64 64
65bool dso__sorted_by_name(const struct dso *self, enum map_type type) 65bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
66{ 66{
67 return self->sorted_by_name & (1 << type); 67 return dso->sorted_by_name & (1 << type);
68} 68}
69 69
70static void dso__set_sorted_by_name(struct dso *self, enum map_type type) 70static void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
71{ 71{
72 self->sorted_by_name |= (1 << type); 72 dso->sorted_by_name |= (1 << type);
73} 73}
74 74
75bool symbol_type__is_a(char symbol_type, enum map_type map_type) 75bool symbol_type__is_a(char symbol_type, enum map_type map_type)
@@ -84,9 +84,9 @@ bool symbol_type__is_a(char symbol_type, enum map_type map_type)
84 } 84 }
85} 85}
86 86
87static void symbols__fixup_end(struct rb_root *self) 87static void symbols__fixup_end(struct rb_root *symbols)
88{ 88{
89 struct rb_node *nd, *prevnd = rb_first(self); 89 struct rb_node *nd, *prevnd = rb_first(symbols);
90 struct symbol *curr, *prev; 90 struct symbol *curr, *prev;
91 91
92 if (prevnd == NULL) 92 if (prevnd == NULL)
@@ -107,10 +107,10 @@ static void symbols__fixup_end(struct rb_root *self)
107 curr->end = roundup(curr->start, 4096); 107 curr->end = roundup(curr->start, 4096);
108} 108}
109 109
110static void __map_groups__fixup_end(struct map_groups *self, enum map_type type) 110static void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
111{ 111{
112 struct map *prev, *curr; 112 struct map *prev, *curr;
113 struct rb_node *nd, *prevnd = rb_first(&self->maps[type]); 113 struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
114 114
115 if (prevnd == NULL) 115 if (prevnd == NULL)
116 return; 116 return;
@@ -130,128 +130,128 @@ static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
130 curr->end = ~0ULL; 130 curr->end = ~0ULL;
131} 131}
132 132
133static void map_groups__fixup_end(struct map_groups *self) 133static void map_groups__fixup_end(struct map_groups *mg)
134{ 134{
135 int i; 135 int i;
136 for (i = 0; i < MAP__NR_TYPES; ++i) 136 for (i = 0; i < MAP__NR_TYPES; ++i)
137 __map_groups__fixup_end(self, i); 137 __map_groups__fixup_end(mg, i);
138} 138}
139 139
140static struct symbol *symbol__new(u64 start, u64 len, u8 binding, 140static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
141 const char *name) 141 const char *name)
142{ 142{
143 size_t namelen = strlen(name) + 1; 143 size_t namelen = strlen(name) + 1;
144 struct symbol *self = calloc(1, (symbol_conf.priv_size + 144 struct symbol *sym = calloc(1, (symbol_conf.priv_size +
145 sizeof(*self) + namelen)); 145 sizeof(*sym) + namelen));
146 if (self == NULL) 146 if (sym == NULL)
147 return NULL; 147 return NULL;
148 148
149 if (symbol_conf.priv_size) 149 if (symbol_conf.priv_size)
150 self = ((void *)self) + symbol_conf.priv_size; 150 sym = ((void *)sym) + symbol_conf.priv_size;
151
152 self->start = start;
153 self->end = len ? start + len - 1 : start;
154 self->binding = binding;
155 self->namelen = namelen - 1;
156 151
157 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n", __func__, name, start, self->end); 152 sym->start = start;
153 sym->end = len ? start + len - 1 : start;
154 sym->binding = binding;
155 sym->namelen = namelen - 1;
158 156
159 memcpy(self->name, name, namelen); 157 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
158 __func__, name, start, sym->end);
159 memcpy(sym->name, name, namelen);
160 160
161 return self; 161 return sym;
162} 162}
163 163
164void symbol__delete(struct symbol *self) 164void symbol__delete(struct symbol *sym)
165{ 165{
166 free(((void *)self) - symbol_conf.priv_size); 166 free(((void *)sym) - symbol_conf.priv_size);
167} 167}
168 168
169static size_t symbol__fprintf(struct symbol *self, FILE *fp) 169static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
170{ 170{
171 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n", 171 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
172 self->start, self->end, 172 sym->start, sym->end,
173 self->binding == STB_GLOBAL ? 'g' : 173 sym->binding == STB_GLOBAL ? 'g' :
174 self->binding == STB_LOCAL ? 'l' : 'w', 174 sym->binding == STB_LOCAL ? 'l' : 'w',
175 self->name); 175 sym->name);
176} 176}
177 177
178void dso__set_long_name(struct dso *self, char *name) 178void dso__set_long_name(struct dso *dso, char *name)
179{ 179{
180 if (name == NULL) 180 if (name == NULL)
181 return; 181 return;
182 self->long_name = name; 182 dso->long_name = name;
183 self->long_name_len = strlen(name); 183 dso->long_name_len = strlen(name);
184} 184}
185 185
186static void dso__set_short_name(struct dso *self, const char *name) 186static void dso__set_short_name(struct dso *dso, const char *name)
187{ 187{
188 if (name == NULL) 188 if (name == NULL)
189 return; 189 return;
190 self->short_name = name; 190 dso->short_name = name;
191 self->short_name_len = strlen(name); 191 dso->short_name_len = strlen(name);
192} 192}
193 193
194static void dso__set_basename(struct dso *self) 194static void dso__set_basename(struct dso *dso)
195{ 195{
196 dso__set_short_name(self, basename(self->long_name)); 196 dso__set_short_name(dso, basename(dso->long_name));
197} 197}
198 198
199struct dso *dso__new(const char *name) 199struct dso *dso__new(const char *name)
200{ 200{
201 struct dso *self = calloc(1, sizeof(*self) + strlen(name) + 1); 201 struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
202 202
203 if (self != NULL) { 203 if (dso != NULL) {
204 int i; 204 int i;
205 strcpy(self->name, name); 205 strcpy(dso->name, name);
206 dso__set_long_name(self, self->name); 206 dso__set_long_name(dso, dso->name);
207 dso__set_short_name(self, self->name); 207 dso__set_short_name(dso, dso->name);
208 for (i = 0; i < MAP__NR_TYPES; ++i) 208 for (i = 0; i < MAP__NR_TYPES; ++i)
209 self->symbols[i] = self->symbol_names[i] = RB_ROOT; 209 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
210 self->symtab_type = SYMTAB__NOT_FOUND; 210 dso->symtab_type = SYMTAB__NOT_FOUND;
211 self->loaded = 0; 211 dso->loaded = 0;
212 self->sorted_by_name = 0; 212 dso->sorted_by_name = 0;
213 self->has_build_id = 0; 213 dso->has_build_id = 0;
214 self->kernel = DSO_TYPE_USER; 214 dso->kernel = DSO_TYPE_USER;
215 INIT_LIST_HEAD(&self->node); 215 INIT_LIST_HEAD(&dso->node);
216 } 216 }
217 217
218 return self; 218 return dso;
219} 219}
220 220
221static void symbols__delete(struct rb_root *self) 221static void symbols__delete(struct rb_root *symbols)
222{ 222{
223 struct symbol *pos; 223 struct symbol *pos;
224 struct rb_node *next = rb_first(self); 224 struct rb_node *next = rb_first(symbols);
225 225
226 while (next) { 226 while (next) {
227 pos = rb_entry(next, struct symbol, rb_node); 227 pos = rb_entry(next, struct symbol, rb_node);
228 next = rb_next(&pos->rb_node); 228 next = rb_next(&pos->rb_node);
229 rb_erase(&pos->rb_node, self); 229 rb_erase(&pos->rb_node, symbols);
230 symbol__delete(pos); 230 symbol__delete(pos);
231 } 231 }
232} 232}
233 233
234void dso__delete(struct dso *self) 234void dso__delete(struct dso *dso)
235{ 235{
236 int i; 236 int i;
237 for (i = 0; i < MAP__NR_TYPES; ++i) 237 for (i = 0; i < MAP__NR_TYPES; ++i)
238 symbols__delete(&self->symbols[i]); 238 symbols__delete(&dso->symbols[i]);
239 if (self->sname_alloc) 239 if (dso->sname_alloc)
240 free((char *)self->short_name); 240 free((char *)dso->short_name);
241 if (self->lname_alloc) 241 if (dso->lname_alloc)
242 free(self->long_name); 242 free(dso->long_name);
243 free(self); 243 free(dso);
244} 244}
245 245
246void dso__set_build_id(struct dso *self, void *build_id) 246void dso__set_build_id(struct dso *dso, void *build_id)
247{ 247{
248 memcpy(self->build_id, build_id, sizeof(self->build_id)); 248 memcpy(dso->build_id, build_id, sizeof(dso->build_id));
249 self->has_build_id = 1; 249 dso->has_build_id = 1;
250} 250}
251 251
252static void symbols__insert(struct rb_root *self, struct symbol *sym) 252static void symbols__insert(struct rb_root *symbols, struct symbol *sym)
253{ 253{
254 struct rb_node **p = &self->rb_node; 254 struct rb_node **p = &symbols->rb_node;
255 struct rb_node *parent = NULL; 255 struct rb_node *parent = NULL;
256 const u64 ip = sym->start; 256 const u64 ip = sym->start;
257 struct symbol *s; 257 struct symbol *s;
@@ -265,17 +265,17 @@ static void symbols__insert(struct rb_root *self, struct symbol *sym)
265 p = &(*p)->rb_right; 265 p = &(*p)->rb_right;
266 } 266 }
267 rb_link_node(&sym->rb_node, parent, p); 267 rb_link_node(&sym->rb_node, parent, p);
268 rb_insert_color(&sym->rb_node, self); 268 rb_insert_color(&sym->rb_node, symbols);
269} 269}
270 270
271static struct symbol *symbols__find(struct rb_root *self, u64 ip) 271static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
272{ 272{
273 struct rb_node *n; 273 struct rb_node *n;
274 274
275 if (self == NULL) 275 if (symbols == NULL)
276 return NULL; 276 return NULL;
277 277
278 n = self->rb_node; 278 n = symbols->rb_node;
279 279
280 while (n) { 280 while (n) {
281 struct symbol *s = rb_entry(n, struct symbol, rb_node); 281 struct symbol *s = rb_entry(n, struct symbol, rb_node);
@@ -296,9 +296,9 @@ struct symbol_name_rb_node {
296 struct symbol sym; 296 struct symbol sym;
297}; 297};
298 298
299static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym) 299static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
300{ 300{
301 struct rb_node **p = &self->rb_node; 301 struct rb_node **p = &symbols->rb_node;
302 struct rb_node *parent = NULL; 302 struct rb_node *parent = NULL;
303 struct symbol_name_rb_node *symn, *s; 303 struct symbol_name_rb_node *symn, *s;
304 304
@@ -313,27 +313,29 @@ static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
313 p = &(*p)->rb_right; 313 p = &(*p)->rb_right;
314 } 314 }
315 rb_link_node(&symn->rb_node, parent, p); 315 rb_link_node(&symn->rb_node, parent, p);
316 rb_insert_color(&symn->rb_node, self); 316 rb_insert_color(&symn->rb_node, symbols);
317} 317}
318 318
319static void symbols__sort_by_name(struct rb_root *self, struct rb_root *source) 319static void symbols__sort_by_name(struct rb_root *symbols,
320 struct rb_root *source)
320{ 321{
321 struct rb_node *nd; 322 struct rb_node *nd;
322 323
323 for (nd = rb_first(source); nd; nd = rb_next(nd)) { 324 for (nd = rb_first(source); nd; nd = rb_next(nd)) {
324 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 325 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
325 symbols__insert_by_name(self, pos); 326 symbols__insert_by_name(symbols, pos);
326 } 327 }
327} 328}
328 329
329static struct symbol *symbols__find_by_name(struct rb_root *self, const char *name) 330static struct symbol *symbols__find_by_name(struct rb_root *symbols,
331 const char *name)
330{ 332{
331 struct rb_node *n; 333 struct rb_node *n;
332 334
333 if (self == NULL) 335 if (symbols == NULL)
334 return NULL; 336 return NULL;
335 337
336 n = self->rb_node; 338 n = symbols->rb_node;
337 339
338 while (n) { 340 while (n) {
339 struct symbol_name_rb_node *s; 341 struct symbol_name_rb_node *s;
@@ -353,29 +355,29 @@ static struct symbol *symbols__find_by_name(struct rb_root *self, const char *na
353 return NULL; 355 return NULL;
354} 356}
355 357
356struct symbol *dso__find_symbol(struct dso *self, 358struct symbol *dso__find_symbol(struct dso *dso,
357 enum map_type type, u64 addr) 359 enum map_type type, u64 addr)
358{ 360{
359 return symbols__find(&self->symbols[type], addr); 361 return symbols__find(&dso->symbols[type], addr);
360} 362}
361 363
362struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type, 364struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
363 const char *name) 365 const char *name)
364{ 366{
365 return symbols__find_by_name(&self->symbol_names[type], name); 367 return symbols__find_by_name(&dso->symbol_names[type], name);
366} 368}
367 369
368void dso__sort_by_name(struct dso *self, enum map_type type) 370void dso__sort_by_name(struct dso *dso, enum map_type type)
369{ 371{
370 dso__set_sorted_by_name(self, type); 372 dso__set_sorted_by_name(dso, type);
371 return symbols__sort_by_name(&self->symbol_names[type], 373 return symbols__sort_by_name(&dso->symbol_names[type],
372 &self->symbols[type]); 374 &dso->symbols[type]);
373} 375}
374 376
375int build_id__sprintf(const u8 *self, int len, char *bf) 377int build_id__sprintf(const u8 *build_id, int len, char *bf)
376{ 378{
377 char *bid = bf; 379 char *bid = bf;
378 const u8 *raw = self; 380 const u8 *raw = build_id;
379 int i; 381 int i;
380 382
381 for (i = 0; i < len; ++i) { 383 for (i = 0; i < len; ++i) {
@@ -384,24 +386,25 @@ int build_id__sprintf(const u8 *self, int len, char *bf)
384 bid += 2; 386 bid += 2;
385 } 387 }
386 388
387 return raw - self; 389 return raw - build_id;
388} 390}
389 391
390size_t dso__fprintf_buildid(struct dso *self, FILE *fp) 392size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
391{ 393{
392 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 394 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
393 395
394 build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id); 396 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
395 return fprintf(fp, "%s", sbuild_id); 397 return fprintf(fp, "%s", sbuild_id);
396} 398}
397 399
398size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp) 400size_t dso__fprintf_symbols_by_name(struct dso *dso,
401 enum map_type type, FILE *fp)
399{ 402{
400 size_t ret = 0; 403 size_t ret = 0;
401 struct rb_node *nd; 404 struct rb_node *nd;
402 struct symbol_name_rb_node *pos; 405 struct symbol_name_rb_node *pos;
403 406
404 for (nd = rb_first(&self->symbol_names[type]); nd; nd = rb_next(nd)) { 407 for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
405 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); 408 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
406 fprintf(fp, "%s\n", pos->sym.name); 409 fprintf(fp, "%s\n", pos->sym.name);
407 } 410 }
@@ -409,18 +412,18 @@ size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *
409 return ret; 412 return ret;
410} 413}
411 414
412size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp) 415size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
413{ 416{
414 struct rb_node *nd; 417 struct rb_node *nd;
415 size_t ret = fprintf(fp, "dso: %s (", self->short_name); 418 size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
416 419
417 if (self->short_name != self->long_name) 420 if (dso->short_name != dso->long_name)
418 ret += fprintf(fp, "%s, ", self->long_name); 421 ret += fprintf(fp, "%s, ", dso->long_name);
419 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], 422 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
420 self->loaded ? "" : "NOT "); 423 dso->loaded ? "" : "NOT ");
421 ret += dso__fprintf_buildid(self, fp); 424 ret += dso__fprintf_buildid(dso, fp);
422 ret += fprintf(fp, ")\n"); 425 ret += fprintf(fp, ")\n");
423 for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) { 426 for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
424 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 427 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
425 ret += symbol__fprintf(pos, fp); 428 ret += symbol__fprintf(pos, fp);
426 } 429 }
@@ -543,10 +546,10 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
543 * so that we can in the next step set the symbol ->end address and then 546 * so that we can in the next step set the symbol ->end address and then
544 * call kernel_maps__split_kallsyms. 547 * call kernel_maps__split_kallsyms.
545 */ 548 */
546static int dso__load_all_kallsyms(struct dso *self, const char *filename, 549static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
547 struct map *map) 550 struct map *map)
548{ 551{
549 struct process_kallsyms_args args = { .map = map, .dso = self, }; 552 struct process_kallsyms_args args = { .map = map, .dso = dso, };
550 return kallsyms__parse(filename, &args, map__process_kallsym_symbol); 553 return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
551} 554}
552 555
@@ -555,7 +558,7 @@ static int dso__load_all_kallsyms(struct dso *self, const char *filename,
555 * kernel range is broken in several maps, named [kernel].N, as we don't have 558 * kernel range is broken in several maps, named [kernel].N, as we don't have
556 * the original ELF section names vmlinux have. 559 * the original ELF section names vmlinux have.
557 */ 560 */
558static int dso__split_kallsyms(struct dso *self, struct map *map, 561static int dso__split_kallsyms(struct dso *dso, struct map *map,
559 symbol_filter_t filter) 562 symbol_filter_t filter)
560{ 563{
561 struct map_groups *kmaps = map__kmap(map)->kmaps; 564 struct map_groups *kmaps = map__kmap(map)->kmaps;
@@ -563,7 +566,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
563 struct map *curr_map = map; 566 struct map *curr_map = map;
564 struct symbol *pos; 567 struct symbol *pos;
565 int count = 0, moved = 0; 568 int count = 0, moved = 0;
566 struct rb_root *root = &self->symbols[map->type]; 569 struct rb_root *root = &dso->symbols[map->type];
567 struct rb_node *next = rb_first(root); 570 struct rb_node *next = rb_first(root);
568 int kernel_range = 0; 571 int kernel_range = 0;
569 572
@@ -582,7 +585,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
582 585
583 if (strcmp(curr_map->dso->short_name, module)) { 586 if (strcmp(curr_map->dso->short_name, module)) {
584 if (curr_map != map && 587 if (curr_map != map &&
585 self->kernel == DSO_TYPE_GUEST_KERNEL && 588 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
586 machine__is_default_guest(machine)) { 589 machine__is_default_guest(machine)) {
587 /* 590 /*
588 * We assume all symbols of a module are 591 * We assume all symbols of a module are
@@ -618,14 +621,14 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
618 pos->end = curr_map->map_ip(curr_map, pos->end); 621 pos->end = curr_map->map_ip(curr_map, pos->end);
619 } else if (curr_map != map) { 622 } else if (curr_map != map) {
620 char dso_name[PATH_MAX]; 623 char dso_name[PATH_MAX];
621 struct dso *dso; 624 struct dso *ndso;
622 625
623 if (count == 0) { 626 if (count == 0) {
624 curr_map = map; 627 curr_map = map;
625 goto filter_symbol; 628 goto filter_symbol;
626 } 629 }
627 630
628 if (self->kernel == DSO_TYPE_GUEST_KERNEL) 631 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
629 snprintf(dso_name, sizeof(dso_name), 632 snprintf(dso_name, sizeof(dso_name),
630 "[guest.kernel].%d", 633 "[guest.kernel].%d",
631 kernel_range++); 634 kernel_range++);
@@ -634,15 +637,15 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
634 "[kernel].%d", 637 "[kernel].%d",
635 kernel_range++); 638 kernel_range++);
636 639
637 dso = dso__new(dso_name); 640 ndso = dso__new(dso_name);
638 if (dso == NULL) 641 if (ndso == NULL)
639 return -1; 642 return -1;
640 643
641 dso->kernel = self->kernel; 644 ndso->kernel = dso->kernel;
642 645
643 curr_map = map__new2(pos->start, dso, map->type); 646 curr_map = map__new2(pos->start, ndso, map->type);
644 if (curr_map == NULL) { 647 if (curr_map == NULL) {
645 dso__delete(dso); 648 dso__delete(ndso);
646 return -1; 649 return -1;
647 } 650 }
648 651
@@ -665,7 +668,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
665 } 668 }
666 669
667 if (curr_map != map && 670 if (curr_map != map &&
668 self->kernel == DSO_TYPE_GUEST_KERNEL && 671 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
669 machine__is_default_guest(kmaps->machine)) { 672 machine__is_default_guest(kmaps->machine)) {
670 dso__set_loaded(curr_map->dso, curr_map->type); 673 dso__set_loaded(curr_map->dso, curr_map->type);
671 } 674 }
@@ -673,21 +676,42 @@ discard_symbol: rb_erase(&pos->rb_node, root);
673 return count + moved; 676 return count + moved;
674} 677}
675 678
676int dso__load_kallsyms(struct dso *self, const char *filename, 679static bool symbol__restricted_filename(const char *filename,
680 const char *restricted_filename)
681{
682 bool restricted = false;
683
684 if (symbol_conf.kptr_restrict) {
685 char *r = realpath(filename, NULL);
686
687 if (r != NULL) {
688 restricted = strcmp(r, restricted_filename) == 0;
689 free(r);
690 return restricted;
691 }
692 }
693
694 return restricted;
695}
696
697int dso__load_kallsyms(struct dso *dso, const char *filename,
677 struct map *map, symbol_filter_t filter) 698 struct map *map, symbol_filter_t filter)
678{ 699{
679 if (dso__load_all_kallsyms(self, filename, map) < 0) 700 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
701 return -1;
702
703 if (dso__load_all_kallsyms(dso, filename, map) < 0)
680 return -1; 704 return -1;
681 705
682 if (self->kernel == DSO_TYPE_GUEST_KERNEL) 706 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
683 self->symtab_type = SYMTAB__GUEST_KALLSYMS; 707 dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
684 else 708 else
685 self->symtab_type = SYMTAB__KALLSYMS; 709 dso->symtab_type = SYMTAB__KALLSYMS;
686 710
687 return dso__split_kallsyms(self, map, filter); 711 return dso__split_kallsyms(dso, map, filter);
688} 712}
689 713
690static int dso__load_perf_map(struct dso *self, struct map *map, 714static int dso__load_perf_map(struct dso *dso, struct map *map,
691 symbol_filter_t filter) 715 symbol_filter_t filter)
692{ 716{
693 char *line = NULL; 717 char *line = NULL;
@@ -695,7 +719,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map,
695 FILE *file; 719 FILE *file;
696 int nr_syms = 0; 720 int nr_syms = 0;
697 721
698 file = fopen(self->long_name, "r"); 722 file = fopen(dso->long_name, "r");
699 if (file == NULL) 723 if (file == NULL)
700 goto out_failure; 724 goto out_failure;
701 725
@@ -733,7 +757,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map,
733 if (filter && filter(map, sym)) 757 if (filter && filter(map, sym))
734 symbol__delete(sym); 758 symbol__delete(sym);
735 else { 759 else {
736 symbols__insert(&self->symbols[map->type], sym); 760 symbols__insert(&dso->symbols[map->type], sym);
737 nr_syms++; 761 nr_syms++;
738 } 762 }
739 } 763 }
@@ -752,7 +776,7 @@ out_failure:
752/** 776/**
753 * elf_symtab__for_each_symbol - iterate thru all the symbols 777 * elf_symtab__for_each_symbol - iterate thru all the symbols
754 * 778 *
755 * @self: struct elf_symtab instance to iterate 779 * @syms: struct elf_symtab instance to iterate
756 * @idx: uint32_t idx 780 * @idx: uint32_t idx
757 * @sym: GElf_Sym iterator 781 * @sym: GElf_Sym iterator
758 */ 782 */
@@ -852,7 +876,7 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
852 * And always look at the original dso, not at debuginfo packages, that 876 * And always look at the original dso, not at debuginfo packages, that
853 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). 877 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
854 */ 878 */
855static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, 879static int dso__synthesize_plt_symbols(struct dso *dso, struct map *map,
856 symbol_filter_t filter) 880 symbol_filter_t filter)
857{ 881{
858 uint32_t nr_rel_entries, idx; 882 uint32_t nr_rel_entries, idx;
@@ -871,7 +895,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
871 char name[PATH_MAX]; 895 char name[PATH_MAX];
872 896
873 snprintf(name, sizeof(name), "%s%s", 897 snprintf(name, sizeof(name), "%s%s",
874 symbol_conf.symfs, self->long_name); 898 symbol_conf.symfs, dso->long_name);
875 fd = open(name, O_RDONLY); 899 fd = open(name, O_RDONLY);
876 if (fd < 0) 900 if (fd < 0)
877 goto out; 901 goto out;
@@ -947,7 +971,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
947 if (filter && filter(map, f)) 971 if (filter && filter(map, f))
948 symbol__delete(f); 972 symbol__delete(f);
949 else { 973 else {
950 symbols__insert(&self->symbols[map->type], f); 974 symbols__insert(&dso->symbols[map->type], f);
951 ++nr; 975 ++nr;
952 } 976 }
953 } 977 }
@@ -969,7 +993,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
969 if (filter && filter(map, f)) 993 if (filter && filter(map, f))
970 symbol__delete(f); 994 symbol__delete(f);
971 else { 995 else {
972 symbols__insert(&self->symbols[map->type], f); 996 symbols__insert(&dso->symbols[map->type], f);
973 ++nr; 997 ++nr;
974 } 998 }
975 } 999 }
@@ -985,29 +1009,30 @@ out_close:
985 return nr; 1009 return nr;
986out: 1010out:
987 pr_debug("%s: problems reading %s PLT info.\n", 1011 pr_debug("%s: problems reading %s PLT info.\n",
988 __func__, self->long_name); 1012 __func__, dso->long_name);
989 return 0; 1013 return 0;
990} 1014}
991 1015
992static bool elf_sym__is_a(GElf_Sym *self, enum map_type type) 1016static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type)
993{ 1017{
994 switch (type) { 1018 switch (type) {
995 case MAP__FUNCTION: 1019 case MAP__FUNCTION:
996 return elf_sym__is_function(self); 1020 return elf_sym__is_function(sym);
997 case MAP__VARIABLE: 1021 case MAP__VARIABLE:
998 return elf_sym__is_object(self); 1022 return elf_sym__is_object(sym);
999 default: 1023 default:
1000 return false; 1024 return false;
1001 } 1025 }
1002} 1026}
1003 1027
1004static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type) 1028static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs,
1029 enum map_type type)
1005{ 1030{
1006 switch (type) { 1031 switch (type) {
1007 case MAP__FUNCTION: 1032 case MAP__FUNCTION:
1008 return elf_sec__is_text(self, secstrs); 1033 return elf_sec__is_text(shdr, secstrs);
1009 case MAP__VARIABLE: 1034 case MAP__VARIABLE:
1010 return elf_sec__is_data(self, secstrs); 1035 return elf_sec__is_data(shdr, secstrs);
1011 default: 1036 default:
1012 return false; 1037 return false;
1013 } 1038 }
@@ -1032,13 +1057,13 @@ static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
1032 return -1; 1057 return -1;
1033} 1058}
1034 1059
1035static int dso__load_sym(struct dso *self, struct map *map, const char *name, 1060static int dso__load_sym(struct dso *dso, struct map *map, const char *name,
1036 int fd, symbol_filter_t filter, int kmodule, 1061 int fd, symbol_filter_t filter, int kmodule,
1037 int want_symtab) 1062 int want_symtab)
1038{ 1063{
1039 struct kmap *kmap = self->kernel ? map__kmap(map) : NULL; 1064 struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
1040 struct map *curr_map = map; 1065 struct map *curr_map = map;
1041 struct dso *curr_dso = self; 1066 struct dso *curr_dso = dso;
1042 Elf_Data *symstrs, *secstrs; 1067 Elf_Data *symstrs, *secstrs;
1043 uint32_t nr_syms; 1068 uint32_t nr_syms;
1044 int err = -1; 1069 int err = -1;
@@ -1064,14 +1089,14 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1064 } 1089 }
1065 1090
1066 /* Always reject images with a mismatched build-id: */ 1091 /* Always reject images with a mismatched build-id: */
1067 if (self->has_build_id) { 1092 if (dso->has_build_id) {
1068 u8 build_id[BUILD_ID_SIZE]; 1093 u8 build_id[BUILD_ID_SIZE];
1069 1094
1070 if (elf_read_build_id(elf, build_id, 1095 if (elf_read_build_id(elf, build_id,
1071 BUILD_ID_SIZE) != BUILD_ID_SIZE) 1096 BUILD_ID_SIZE) != BUILD_ID_SIZE)
1072 goto out_elf_end; 1097 goto out_elf_end;
1073 1098
1074 if (!dso__build_id_equal(self, build_id)) 1099 if (!dso__build_id_equal(dso, build_id))
1075 goto out_elf_end; 1100 goto out_elf_end;
1076 } 1101 }
1077 1102
@@ -1112,13 +1137,14 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1112 nr_syms = shdr.sh_size / shdr.sh_entsize; 1137 nr_syms = shdr.sh_size / shdr.sh_entsize;
1113 1138
1114 memset(&sym, 0, sizeof(sym)); 1139 memset(&sym, 0, sizeof(sym));
1115 if (self->kernel == DSO_TYPE_USER) { 1140 if (dso->kernel == DSO_TYPE_USER) {
1116 self->adjust_symbols = (ehdr.e_type == ET_EXEC || 1141 dso->adjust_symbols = (ehdr.e_type == ET_EXEC ||
1117 elf_section_by_name(elf, &ehdr, &shdr, 1142 elf_section_by_name(elf, &ehdr, &shdr,
1118 ".gnu.prelink_undo", 1143 ".gnu.prelink_undo",
1119 NULL) != NULL); 1144 NULL) != NULL);
1120 } else self->adjust_symbols = 0; 1145 } else {
1121 1146 dso->adjust_symbols = 0;
1147 }
1122 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 1148 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
1123 struct symbol *f; 1149 struct symbol *f;
1124 const char *elf_name = elf_sym__name(&sym, symstrs); 1150 const char *elf_name = elf_sym__name(&sym, symstrs);
@@ -1168,22 +1194,22 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1168 (sym.st_value & 1)) 1194 (sym.st_value & 1))
1169 --sym.st_value; 1195 --sym.st_value;
1170 1196
1171 if (self->kernel != DSO_TYPE_USER || kmodule) { 1197 if (dso->kernel != DSO_TYPE_USER || kmodule) {
1172 char dso_name[PATH_MAX]; 1198 char dso_name[PATH_MAX];
1173 1199
1174 if (strcmp(section_name, 1200 if (strcmp(section_name,
1175 (curr_dso->short_name + 1201 (curr_dso->short_name +
1176 self->short_name_len)) == 0) 1202 dso->short_name_len)) == 0)
1177 goto new_symbol; 1203 goto new_symbol;
1178 1204
1179 if (strcmp(section_name, ".text") == 0) { 1205 if (strcmp(section_name, ".text") == 0) {
1180 curr_map = map; 1206 curr_map = map;
1181 curr_dso = self; 1207 curr_dso = dso;
1182 goto new_symbol; 1208 goto new_symbol;
1183 } 1209 }
1184 1210
1185 snprintf(dso_name, sizeof(dso_name), 1211 snprintf(dso_name, sizeof(dso_name),
1186 "%s%s", self->short_name, section_name); 1212 "%s%s", dso->short_name, section_name);
1187 1213
1188 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name); 1214 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1189 if (curr_map == NULL) { 1215 if (curr_map == NULL) {
@@ -1195,9 +1221,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1195 curr_dso = dso__new(dso_name); 1221 curr_dso = dso__new(dso_name);
1196 if (curr_dso == NULL) 1222 if (curr_dso == NULL)
1197 goto out_elf_end; 1223 goto out_elf_end;
1198 curr_dso->kernel = self->kernel; 1224 curr_dso->kernel = dso->kernel;
1199 curr_dso->long_name = self->long_name; 1225 curr_dso->long_name = dso->long_name;
1200 curr_dso->long_name_len = self->long_name_len; 1226 curr_dso->long_name_len = dso->long_name_len;
1201 curr_map = map__new2(start, curr_dso, 1227 curr_map = map__new2(start, curr_dso,
1202 map->type); 1228 map->type);
1203 if (curr_map == NULL) { 1229 if (curr_map == NULL) {
@@ -1206,9 +1232,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1206 } 1232 }
1207 curr_map->map_ip = identity__map_ip; 1233 curr_map->map_ip = identity__map_ip;
1208 curr_map->unmap_ip = identity__map_ip; 1234 curr_map->unmap_ip = identity__map_ip;
1209 curr_dso->symtab_type = self->symtab_type; 1235 curr_dso->symtab_type = dso->symtab_type;
1210 map_groups__insert(kmap->kmaps, curr_map); 1236 map_groups__insert(kmap->kmaps, curr_map);
1211 dsos__add(&self->node, curr_dso); 1237 dsos__add(&dso->node, curr_dso);
1212 dso__set_loaded(curr_dso, map->type); 1238 dso__set_loaded(curr_dso, map->type);
1213 } else 1239 } else
1214 curr_dso = curr_map->dso; 1240 curr_dso = curr_map->dso;
@@ -1250,7 +1276,7 @@ new_symbol:
1250 * For misannotated, zeroed, ASM function sizes. 1276 * For misannotated, zeroed, ASM function sizes.
1251 */ 1277 */
1252 if (nr > 0) { 1278 if (nr > 0) {
1253 symbols__fixup_end(&self->symbols[map->type]); 1279 symbols__fixup_end(&dso->symbols[map->type]);
1254 if (kmap) { 1280 if (kmap) {
1255 /* 1281 /*
1256 * We need to fixup this here too because we create new 1282 * We need to fixup this here too because we create new
@@ -1266,9 +1292,9 @@ out_close:
1266 return err; 1292 return err;
1267} 1293}
1268 1294
1269static bool dso__build_id_equal(const struct dso *self, u8 *build_id) 1295static bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
1270{ 1296{
1271 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0; 1297 return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
1272} 1298}
1273 1299
1274bool __dsos__read_build_ids(struct list_head *head, bool with_hits) 1300bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
@@ -1429,7 +1455,7 @@ out:
1429 return err; 1455 return err;
1430} 1456}
1431 1457
1432char dso__symtab_origin(const struct dso *self) 1458char dso__symtab_origin(const struct dso *dso)
1433{ 1459{
1434 static const char origin[] = { 1460 static const char origin[] = {
1435 [SYMTAB__KALLSYMS] = 'k', 1461 [SYMTAB__KALLSYMS] = 'k',
@@ -1444,12 +1470,12 @@ char dso__symtab_origin(const struct dso *self)
1444 [SYMTAB__GUEST_KMODULE] = 'G', 1470 [SYMTAB__GUEST_KMODULE] = 'G',
1445 }; 1471 };
1446 1472
1447 if (self == NULL || self->symtab_type == SYMTAB__NOT_FOUND) 1473 if (dso == NULL || dso->symtab_type == SYMTAB__NOT_FOUND)
1448 return '!'; 1474 return '!';
1449 return origin[self->symtab_type]; 1475 return origin[dso->symtab_type];
1450} 1476}
1451 1477
1452int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) 1478int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1453{ 1479{
1454 int size = PATH_MAX; 1480 int size = PATH_MAX;
1455 char *name; 1481 char *name;
@@ -1459,12 +1485,12 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1459 const char *root_dir; 1485 const char *root_dir;
1460 int want_symtab; 1486 int want_symtab;
1461 1487
1462 dso__set_loaded(self, map->type); 1488 dso__set_loaded(dso, map->type);
1463 1489
1464 if (self->kernel == DSO_TYPE_KERNEL) 1490 if (dso->kernel == DSO_TYPE_KERNEL)
1465 return dso__load_kernel_sym(self, map, filter); 1491 return dso__load_kernel_sym(dso, map, filter);
1466 else if (self->kernel == DSO_TYPE_GUEST_KERNEL) 1492 else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1467 return dso__load_guest_kernel_sym(self, map, filter); 1493 return dso__load_guest_kernel_sym(dso, map, filter);
1468 1494
1469 if (map->groups && map->groups->machine) 1495 if (map->groups && map->groups->machine)
1470 machine = map->groups->machine; 1496 machine = map->groups->machine;
@@ -1475,11 +1501,11 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1475 if (!name) 1501 if (!name)
1476 return -1; 1502 return -1;
1477 1503
1478 self->adjust_symbols = 0; 1504 dso->adjust_symbols = 0;
1479 1505
1480 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { 1506 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
1481 ret = dso__load_perf_map(self, map, filter); 1507 ret = dso__load_perf_map(dso, map, filter);
1482 self->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT : 1508 dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT :
1483 SYMTAB__NOT_FOUND; 1509 SYMTAB__NOT_FOUND;
1484 return ret; 1510 return ret;
1485 } 1511 }
@@ -1490,33 +1516,33 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1490 */ 1516 */
1491 want_symtab = 1; 1517 want_symtab = 1;
1492restart: 1518restart:
1493 for (self->symtab_type = SYMTAB__BUILD_ID_CACHE; 1519 for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE;
1494 self->symtab_type != SYMTAB__NOT_FOUND; 1520 dso->symtab_type != SYMTAB__NOT_FOUND;
1495 self->symtab_type++) { 1521 dso->symtab_type++) {
1496 switch (self->symtab_type) { 1522 switch (dso->symtab_type) {
1497 case SYMTAB__BUILD_ID_CACHE: 1523 case SYMTAB__BUILD_ID_CACHE:
1498 /* skip the locally configured cache if a symfs is given */ 1524 /* skip the locally configured cache if a symfs is given */
1499 if (symbol_conf.symfs[0] || 1525 if (symbol_conf.symfs[0] ||
1500 (dso__build_id_filename(self, name, size) == NULL)) { 1526 (dso__build_id_filename(dso, name, size) == NULL)) {
1501 continue; 1527 continue;
1502 } 1528 }
1503 break; 1529 break;
1504 case SYMTAB__FEDORA_DEBUGINFO: 1530 case SYMTAB__FEDORA_DEBUGINFO:
1505 snprintf(name, size, "%s/usr/lib/debug%s.debug", 1531 snprintf(name, size, "%s/usr/lib/debug%s.debug",
1506 symbol_conf.symfs, self->long_name); 1532 symbol_conf.symfs, dso->long_name);
1507 break; 1533 break;
1508 case SYMTAB__UBUNTU_DEBUGINFO: 1534 case SYMTAB__UBUNTU_DEBUGINFO:
1509 snprintf(name, size, "%s/usr/lib/debug%s", 1535 snprintf(name, size, "%s/usr/lib/debug%s",
1510 symbol_conf.symfs, self->long_name); 1536 symbol_conf.symfs, dso->long_name);
1511 break; 1537 break;
1512 case SYMTAB__BUILDID_DEBUGINFO: { 1538 case SYMTAB__BUILDID_DEBUGINFO: {
1513 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1539 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1514 1540
1515 if (!self->has_build_id) 1541 if (!dso->has_build_id)
1516 continue; 1542 continue;
1517 1543
1518 build_id__sprintf(self->build_id, 1544 build_id__sprintf(dso->build_id,
1519 sizeof(self->build_id), 1545 sizeof(dso->build_id),
1520 build_id_hex); 1546 build_id_hex);
1521 snprintf(name, size, 1547 snprintf(name, size,
1522 "%s/usr/lib/debug/.build-id/%.2s/%s.debug", 1548 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
@@ -1525,7 +1551,7 @@ restart:
1525 break; 1551 break;
1526 case SYMTAB__SYSTEM_PATH_DSO: 1552 case SYMTAB__SYSTEM_PATH_DSO:
1527 snprintf(name, size, "%s%s", 1553 snprintf(name, size, "%s%s",
1528 symbol_conf.symfs, self->long_name); 1554 symbol_conf.symfs, dso->long_name);
1529 break; 1555 break;
1530 case SYMTAB__GUEST_KMODULE: 1556 case SYMTAB__GUEST_KMODULE:
1531 if (map->groups && machine) 1557 if (map->groups && machine)
@@ -1533,12 +1559,12 @@ restart:
1533 else 1559 else
1534 root_dir = ""; 1560 root_dir = "";
1535 snprintf(name, size, "%s%s%s", symbol_conf.symfs, 1561 snprintf(name, size, "%s%s%s", symbol_conf.symfs,
1536 root_dir, self->long_name); 1562 root_dir, dso->long_name);
1537 break; 1563 break;
1538 1564
1539 case SYMTAB__SYSTEM_PATH_KMODULE: 1565 case SYMTAB__SYSTEM_PATH_KMODULE:
1540 snprintf(name, size, "%s%s", symbol_conf.symfs, 1566 snprintf(name, size, "%s%s", symbol_conf.symfs,
1541 self->long_name); 1567 dso->long_name);
1542 break; 1568 break;
1543 default:; 1569 default:;
1544 } 1570 }
@@ -1548,7 +1574,7 @@ restart:
1548 if (fd < 0) 1574 if (fd < 0)
1549 continue; 1575 continue;
1550 1576
1551 ret = dso__load_sym(self, map, name, fd, filter, 0, 1577 ret = dso__load_sym(dso, map, name, fd, filter, 0,
1552 want_symtab); 1578 want_symtab);
1553 close(fd); 1579 close(fd);
1554 1580
@@ -1560,7 +1586,8 @@ restart:
1560 continue; 1586 continue;
1561 1587
1562 if (ret > 0) { 1588 if (ret > 0) {
1563 int nr_plt = dso__synthesize_plt_symbols(self, map, filter); 1589 int nr_plt = dso__synthesize_plt_symbols(dso, map,
1590 filter);
1564 if (nr_plt > 0) 1591 if (nr_plt > 0)
1565 ret += nr_plt; 1592 ret += nr_plt;
1566 break; 1593 break;
@@ -1577,17 +1604,17 @@ restart:
1577 } 1604 }
1578 1605
1579 free(name); 1606 free(name);
1580 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 1607 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1581 return 0; 1608 return 0;
1582 return ret; 1609 return ret;
1583} 1610}
1584 1611
1585struct map *map_groups__find_by_name(struct map_groups *self, 1612struct map *map_groups__find_by_name(struct map_groups *mg,
1586 enum map_type type, const char *name) 1613 enum map_type type, const char *name)
1587{ 1614{
1588 struct rb_node *nd; 1615 struct rb_node *nd;
1589 1616
1590 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) { 1617 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
1591 struct map *map = rb_entry(nd, struct map, rb_node); 1618 struct map *map = rb_entry(nd, struct map, rb_node);
1592 1619
1593 if (map->dso && strcmp(map->dso->short_name, name) == 0) 1620 if (map->dso && strcmp(map->dso->short_name, name) == 0)
@@ -1597,28 +1624,28 @@ struct map *map_groups__find_by_name(struct map_groups *self,
1597 return NULL; 1624 return NULL;
1598} 1625}
1599 1626
1600static int dso__kernel_module_get_build_id(struct dso *self, 1627static int dso__kernel_module_get_build_id(struct dso *dso,
1601 const char *root_dir) 1628 const char *root_dir)
1602{ 1629{
1603 char filename[PATH_MAX]; 1630 char filename[PATH_MAX];
1604 /* 1631 /*
1605 * kernel module short names are of the form "[module]" and 1632 * kernel module short names are of the form "[module]" and
1606 * we need just "module" here. 1633 * we need just "module" here.
1607 */ 1634 */
1608 const char *name = self->short_name + 1; 1635 const char *name = dso->short_name + 1;
1609 1636
1610 snprintf(filename, sizeof(filename), 1637 snprintf(filename, sizeof(filename),
1611 "%s/sys/module/%.*s/notes/.note.gnu.build-id", 1638 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1612 root_dir, (int)strlen(name) - 1, name); 1639 root_dir, (int)strlen(name) - 1, name);
1613 1640
1614 if (sysfs__read_build_id(filename, self->build_id, 1641 if (sysfs__read_build_id(filename, dso->build_id,
1615 sizeof(self->build_id)) == 0) 1642 sizeof(dso->build_id)) == 0)
1616 self->has_build_id = true; 1643 dso->has_build_id = true;
1617 1644
1618 return 0; 1645 return 0;
1619} 1646}
1620 1647
1621static int map_groups__set_modules_path_dir(struct map_groups *self, 1648static int map_groups__set_modules_path_dir(struct map_groups *mg,
1622 const char *dir_name) 1649 const char *dir_name)
1623{ 1650{
1624 struct dirent *dent; 1651 struct dirent *dent;
@@ -1646,7 +1673,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *self,
1646 1673
1647 snprintf(path, sizeof(path), "%s/%s", 1674 snprintf(path, sizeof(path), "%s/%s",
1648 dir_name, dent->d_name); 1675 dir_name, dent->d_name);
1649 ret = map_groups__set_modules_path_dir(self, path); 1676 ret = map_groups__set_modules_path_dir(mg, path);
1650 if (ret < 0) 1677 if (ret < 0)
1651 goto out; 1678 goto out;
1652 } else { 1679 } else {
@@ -1661,7 +1688,8 @@ static int map_groups__set_modules_path_dir(struct map_groups *self,
1661 (int)(dot - dent->d_name), dent->d_name); 1688 (int)(dot - dent->d_name), dent->d_name);
1662 1689
1663 strxfrchar(dso_name, '-', '_'); 1690 strxfrchar(dso_name, '-', '_');
1664 map = map_groups__find_by_name(self, MAP__FUNCTION, dso_name); 1691 map = map_groups__find_by_name(mg, MAP__FUNCTION,
1692 dso_name);
1665 if (map == NULL) 1693 if (map == NULL)
1666 continue; 1694 continue;
1667 1695
@@ -1711,20 +1739,20 @@ static char *get_kernel_version(const char *root_dir)
1711 return strdup(name); 1739 return strdup(name);
1712} 1740}
1713 1741
1714static int machine__set_modules_path(struct machine *self) 1742static int machine__set_modules_path(struct machine *machine)
1715{ 1743{
1716 char *version; 1744 char *version;
1717 char modules_path[PATH_MAX]; 1745 char modules_path[PATH_MAX];
1718 1746
1719 version = get_kernel_version(self->root_dir); 1747 version = get_kernel_version(machine->root_dir);
1720 if (!version) 1748 if (!version)
1721 return -1; 1749 return -1;
1722 1750
1723 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", 1751 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1724 self->root_dir, version); 1752 machine->root_dir, version);
1725 free(version); 1753 free(version);
1726 1754
1727 return map_groups__set_modules_path_dir(&self->kmaps, modules_path); 1755 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path);
1728} 1756}
1729 1757
1730/* 1758/*
@@ -1734,23 +1762,23 @@ static int machine__set_modules_path(struct machine *self)
1734 */ 1762 */
1735static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) 1763static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1736{ 1764{
1737 struct map *self = calloc(1, (sizeof(*self) + 1765 struct map *map = calloc(1, (sizeof(*map) +
1738 (dso->kernel ? sizeof(struct kmap) : 0))); 1766 (dso->kernel ? sizeof(struct kmap) : 0)));
1739 if (self != NULL) { 1767 if (map != NULL) {
1740 /* 1768 /*
1741 * ->end will be filled after we load all the symbols 1769 * ->end will be filled after we load all the symbols
1742 */ 1770 */
1743 map__init(self, type, start, 0, 0, dso); 1771 map__init(map, type, start, 0, 0, dso);
1744 } 1772 }
1745 1773
1746 return self; 1774 return map;
1747} 1775}
1748 1776
1749struct map *machine__new_module(struct machine *self, u64 start, 1777struct map *machine__new_module(struct machine *machine, u64 start,
1750 const char *filename) 1778 const char *filename)
1751{ 1779{
1752 struct map *map; 1780 struct map *map;
1753 struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename); 1781 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
1754 1782
1755 if (dso == NULL) 1783 if (dso == NULL)
1756 return NULL; 1784 return NULL;
@@ -1759,15 +1787,15 @@ struct map *machine__new_module(struct machine *self, u64 start,
1759 if (map == NULL) 1787 if (map == NULL)
1760 return NULL; 1788 return NULL;
1761 1789
1762 if (machine__is_host(self)) 1790 if (machine__is_host(machine))
1763 dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE; 1791 dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE;
1764 else 1792 else
1765 dso->symtab_type = SYMTAB__GUEST_KMODULE; 1793 dso->symtab_type = SYMTAB__GUEST_KMODULE;
1766 map_groups__insert(&self->kmaps, map); 1794 map_groups__insert(&machine->kmaps, map);
1767 return map; 1795 return map;
1768} 1796}
1769 1797
1770static int machine__create_modules(struct machine *self) 1798static int machine__create_modules(struct machine *machine)
1771{ 1799{
1772 char *line = NULL; 1800 char *line = NULL;
1773 size_t n; 1801 size_t n;
@@ -1776,13 +1804,16 @@ static int machine__create_modules(struct machine *self)
1776 const char *modules; 1804 const char *modules;
1777 char path[PATH_MAX]; 1805 char path[PATH_MAX];
1778 1806
1779 if (machine__is_default_guest(self)) 1807 if (machine__is_default_guest(machine))
1780 modules = symbol_conf.default_guest_modules; 1808 modules = symbol_conf.default_guest_modules;
1781 else { 1809 else {
1782 sprintf(path, "%s/proc/modules", self->root_dir); 1810 sprintf(path, "%s/proc/modules", machine->root_dir);
1783 modules = path; 1811 modules = path;
1784 } 1812 }
1785 1813
1814 if (symbol__restricted_filename(path, "/proc/modules"))
1815 return -1;
1816
1786 file = fopen(modules, "r"); 1817 file = fopen(modules, "r");
1787 if (file == NULL) 1818 if (file == NULL)
1788 return -1; 1819 return -1;
@@ -1815,16 +1846,16 @@ static int machine__create_modules(struct machine *self)
1815 *sep = '\0'; 1846 *sep = '\0';
1816 1847
1817 snprintf(name, sizeof(name), "[%s]", line); 1848 snprintf(name, sizeof(name), "[%s]", line);
1818 map = machine__new_module(self, start, name); 1849 map = machine__new_module(machine, start, name);
1819 if (map == NULL) 1850 if (map == NULL)
1820 goto out_delete_line; 1851 goto out_delete_line;
1821 dso__kernel_module_get_build_id(map->dso, self->root_dir); 1852 dso__kernel_module_get_build_id(map->dso, machine->root_dir);
1822 } 1853 }
1823 1854
1824 free(line); 1855 free(line);
1825 fclose(file); 1856 fclose(file);
1826 1857
1827 return machine__set_modules_path(self); 1858 return machine__set_modules_path(machine);
1828 1859
1829out_delete_line: 1860out_delete_line:
1830 free(line); 1861 free(line);
@@ -1832,7 +1863,7 @@ out_failure:
1832 return -1; 1863 return -1;
1833} 1864}
1834 1865
1835int dso__load_vmlinux(struct dso *self, struct map *map, 1866int dso__load_vmlinux(struct dso *dso, struct map *map,
1836 const char *vmlinux, symbol_filter_t filter) 1867 const char *vmlinux, symbol_filter_t filter)
1837{ 1868{
1838 int err = -1, fd; 1869 int err = -1, fd;
@@ -1844,9 +1875,9 @@ int dso__load_vmlinux(struct dso *self, struct map *map,
1844 if (fd < 0) 1875 if (fd < 0)
1845 return -1; 1876 return -1;
1846 1877
1847 dso__set_long_name(self, (char *)vmlinux); 1878 dso__set_long_name(dso, (char *)vmlinux);
1848 dso__set_loaded(self, map->type); 1879 dso__set_loaded(dso, map->type);
1849 err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); 1880 err = dso__load_sym(dso, map, symfs_vmlinux, fd, filter, 0, 0);
1850 close(fd); 1881 close(fd);
1851 1882
1852 if (err > 0) 1883 if (err > 0)
@@ -1855,7 +1886,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map,
1855 return err; 1886 return err;
1856} 1887}
1857 1888
1858int dso__load_vmlinux_path(struct dso *self, struct map *map, 1889int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1859 symbol_filter_t filter) 1890 symbol_filter_t filter)
1860{ 1891{
1861 int i, err = 0; 1892 int i, err = 0;
@@ -1864,20 +1895,20 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
1864 pr_debug("Looking at the vmlinux_path (%d entries long)\n", 1895 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1865 vmlinux_path__nr_entries + 1); 1896 vmlinux_path__nr_entries + 1);
1866 1897
1867 filename = dso__build_id_filename(self, NULL, 0); 1898 filename = dso__build_id_filename(dso, NULL, 0);
1868 if (filename != NULL) { 1899 if (filename != NULL) {
1869 err = dso__load_vmlinux(self, map, filename, filter); 1900 err = dso__load_vmlinux(dso, map, filename, filter);
1870 if (err > 0) { 1901 if (err > 0) {
1871 dso__set_long_name(self, filename); 1902 dso__set_long_name(dso, filename);
1872 goto out; 1903 goto out;
1873 } 1904 }
1874 free(filename); 1905 free(filename);
1875 } 1906 }
1876 1907
1877 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1908 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1878 err = dso__load_vmlinux(self, map, vmlinux_path[i], filter); 1909 err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter);
1879 if (err > 0) { 1910 if (err > 0) {
1880 dso__set_long_name(self, strdup(vmlinux_path[i])); 1911 dso__set_long_name(dso, strdup(vmlinux_path[i]));
1881 break; 1912 break;
1882 } 1913 }
1883 } 1914 }
@@ -1885,7 +1916,7 @@ out:
1885 return err; 1916 return err;
1886} 1917}
1887 1918
1888static int dso__load_kernel_sym(struct dso *self, struct map *map, 1919static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1889 symbol_filter_t filter) 1920 symbol_filter_t filter)
1890{ 1921{
1891 int err; 1922 int err;
@@ -1912,10 +1943,10 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1912 } 1943 }
1913 1944
1914 if (symbol_conf.vmlinux_name != NULL) { 1945 if (symbol_conf.vmlinux_name != NULL) {
1915 err = dso__load_vmlinux(self, map, 1946 err = dso__load_vmlinux(dso, map,
1916 symbol_conf.vmlinux_name, filter); 1947 symbol_conf.vmlinux_name, filter);
1917 if (err > 0) { 1948 if (err > 0) {
1918 dso__set_long_name(self, 1949 dso__set_long_name(dso,
1919 strdup(symbol_conf.vmlinux_name)); 1950 strdup(symbol_conf.vmlinux_name));
1920 goto out_fixup; 1951 goto out_fixup;
1921 } 1952 }
@@ -1923,7 +1954,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1923 } 1954 }
1924 1955
1925 if (vmlinux_path != NULL) { 1956 if (vmlinux_path != NULL) {
1926 err = dso__load_vmlinux_path(self, map, filter); 1957 err = dso__load_vmlinux_path(dso, map, filter);
1927 if (err > 0) 1958 if (err > 0)
1928 goto out_fixup; 1959 goto out_fixup;
1929 } 1960 }
@@ -1937,13 +1968,13 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1937 * we have a build-id, so check if it is the same as the running kernel, 1968 * we have a build-id, so check if it is the same as the running kernel,
1938 * using it if it is. 1969 * using it if it is.
1939 */ 1970 */
1940 if (self->has_build_id) { 1971 if (dso->has_build_id) {
1941 u8 kallsyms_build_id[BUILD_ID_SIZE]; 1972 u8 kallsyms_build_id[BUILD_ID_SIZE];
1942 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 1973 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1943 1974
1944 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id, 1975 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1945 sizeof(kallsyms_build_id)) == 0) { 1976 sizeof(kallsyms_build_id)) == 0) {
1946 if (dso__build_id_equal(self, kallsyms_build_id)) { 1977 if (dso__build_id_equal(dso, kallsyms_build_id)) {
1947 kallsyms_filename = "/proc/kallsyms"; 1978 kallsyms_filename = "/proc/kallsyms";
1948 goto do_kallsyms; 1979 goto do_kallsyms;
1949 } 1980 }
@@ -1952,7 +1983,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1952 * Now look if we have it on the build-id cache in 1983 * Now look if we have it on the build-id cache in
1953 * $HOME/.debug/[kernel.kallsyms]. 1984 * $HOME/.debug/[kernel.kallsyms].
1954 */ 1985 */
1955 build_id__sprintf(self->build_id, sizeof(self->build_id), 1986 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1956 sbuild_id); 1987 sbuild_id);
1957 1988
1958 if (asprintf(&kallsyms_allocated_filename, 1989 if (asprintf(&kallsyms_allocated_filename,
@@ -1979,7 +2010,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1979 } 2010 }
1980 2011
1981do_kallsyms: 2012do_kallsyms:
1982 err = dso__load_kallsyms(self, kallsyms_filename, map, filter); 2013 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1983 if (err > 0) 2014 if (err > 0)
1984 pr_debug("Using %s for symbols\n", kallsyms_filename); 2015 pr_debug("Using %s for symbols\n", kallsyms_filename);
1985 free(kallsyms_allocated_filename); 2016 free(kallsyms_allocated_filename);
@@ -1987,7 +2018,7 @@ do_kallsyms:
1987 if (err > 0) { 2018 if (err > 0) {
1988out_fixup: 2019out_fixup:
1989 if (kallsyms_filename != NULL) 2020 if (kallsyms_filename != NULL)
1990 dso__set_long_name(self, strdup("[kernel.kallsyms]")); 2021 dso__set_long_name(dso, strdup("[kernel.kallsyms]"));
1991 map__fixup_start(map); 2022 map__fixup_start(map);
1992 map__fixup_end(map); 2023 map__fixup_end(map);
1993 } 2024 }
@@ -1995,8 +2026,8 @@ out_fixup:
1995 return err; 2026 return err;
1996} 2027}
1997 2028
1998static int dso__load_guest_kernel_sym(struct dso *self, struct map *map, 2029static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1999 symbol_filter_t filter) 2030 symbol_filter_t filter)
2000{ 2031{
2001 int err; 2032 int err;
2002 const char *kallsyms_filename = NULL; 2033 const char *kallsyms_filename = NULL;
@@ -2016,7 +2047,7 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
2016 * Or use file guest_kallsyms inputted by user on commandline 2047 * Or use file guest_kallsyms inputted by user on commandline
2017 */ 2048 */
2018 if (symbol_conf.default_guest_vmlinux_name != NULL) { 2049 if (symbol_conf.default_guest_vmlinux_name != NULL) {
2019 err = dso__load_vmlinux(self, map, 2050 err = dso__load_vmlinux(dso, map,
2020 symbol_conf.default_guest_vmlinux_name, filter); 2051 symbol_conf.default_guest_vmlinux_name, filter);
2021 goto out_try_fixup; 2052 goto out_try_fixup;
2022 } 2053 }
@@ -2029,7 +2060,7 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
2029 kallsyms_filename = path; 2060 kallsyms_filename = path;
2030 } 2061 }
2031 2062
2032 err = dso__load_kallsyms(self, kallsyms_filename, map, filter); 2063 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
2033 if (err > 0) 2064 if (err > 0)
2034 pr_debug("Using %s for symbols\n", kallsyms_filename); 2065 pr_debug("Using %s for symbols\n", kallsyms_filename);
2035 2066
@@ -2037,7 +2068,7 @@ out_try_fixup:
2037 if (err > 0) { 2068 if (err > 0) {
2038 if (kallsyms_filename != NULL) { 2069 if (kallsyms_filename != NULL) {
2039 machine__mmap_name(machine, path, sizeof(path)); 2070 machine__mmap_name(machine, path, sizeof(path));
2040 dso__set_long_name(self, strdup(path)); 2071 dso__set_long_name(dso, strdup(path));
2041 } 2072 }
2042 map__fixup_start(map); 2073 map__fixup_start(map);
2043 map__fixup_end(map); 2074 map__fixup_end(map);
@@ -2090,12 +2121,12 @@ size_t __dsos__fprintf(struct list_head *head, FILE *fp)
2090 return ret; 2121 return ret;
2091} 2122}
2092 2123
2093size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp) 2124size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
2094{ 2125{
2095 struct rb_node *nd; 2126 struct rb_node *nd;
2096 size_t ret = 0; 2127 size_t ret = 0;
2097 2128
2098 for (nd = rb_first(self); nd; nd = rb_next(nd)) { 2129 for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
2099 struct machine *pos = rb_entry(nd, struct machine, rb_node); 2130 struct machine *pos = rb_entry(nd, struct machine, rb_node);
2100 ret += __dsos__fprintf(&pos->kernel_dsos, fp); 2131 ret += __dsos__fprintf(&pos->kernel_dsos, fp);
2101 ret += __dsos__fprintf(&pos->user_dsos, fp); 2132 ret += __dsos__fprintf(&pos->user_dsos, fp);
@@ -2119,18 +2150,20 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
2119 return ret; 2150 return ret;
2120} 2151}
2121 2152
2122size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits) 2153size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp,
2154 bool with_hits)
2123{ 2155{
2124 return __dsos__fprintf_buildid(&self->kernel_dsos, fp, with_hits) + 2156 return __dsos__fprintf_buildid(&machine->kernel_dsos, fp, with_hits) +
2125 __dsos__fprintf_buildid(&self->user_dsos, fp, with_hits); 2157 __dsos__fprintf_buildid(&machine->user_dsos, fp, with_hits);
2126} 2158}
2127 2159
2128size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits) 2160size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
2161 FILE *fp, bool with_hits)
2129{ 2162{
2130 struct rb_node *nd; 2163 struct rb_node *nd;
2131 size_t ret = 0; 2164 size_t ret = 0;
2132 2165
2133 for (nd = rb_first(self); nd; nd = rb_next(nd)) { 2166 for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
2134 struct machine *pos = rb_entry(nd, struct machine, rb_node); 2167 struct machine *pos = rb_entry(nd, struct machine, rb_node);
2135 ret += machine__fprintf_dsos_buildid(pos, fp, with_hits); 2168 ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
2136 } 2169 }
@@ -2139,59 +2172,59 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_
2139 2172
2140struct dso *dso__new_kernel(const char *name) 2173struct dso *dso__new_kernel(const char *name)
2141{ 2174{
2142 struct dso *self = dso__new(name ?: "[kernel.kallsyms]"); 2175 struct dso *dso = dso__new(name ?: "[kernel.kallsyms]");
2143 2176
2144 if (self != NULL) { 2177 if (dso != NULL) {
2145 dso__set_short_name(self, "[kernel]"); 2178 dso__set_short_name(dso, "[kernel]");
2146 self->kernel = DSO_TYPE_KERNEL; 2179 dso->kernel = DSO_TYPE_KERNEL;
2147 } 2180 }
2148 2181
2149 return self; 2182 return dso;
2150} 2183}
2151 2184
2152static struct dso *dso__new_guest_kernel(struct machine *machine, 2185static struct dso *dso__new_guest_kernel(struct machine *machine,
2153 const char *name) 2186 const char *name)
2154{ 2187{
2155 char bf[PATH_MAX]; 2188 char bf[PATH_MAX];
2156 struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf))); 2189 struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf,
2157 2190 sizeof(bf)));
2158 if (self != NULL) { 2191 if (dso != NULL) {
2159 dso__set_short_name(self, "[guest.kernel]"); 2192 dso__set_short_name(dso, "[guest.kernel]");
2160 self->kernel = DSO_TYPE_GUEST_KERNEL; 2193 dso->kernel = DSO_TYPE_GUEST_KERNEL;
2161 } 2194 }
2162 2195
2163 return self; 2196 return dso;
2164} 2197}
2165 2198
2166void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine) 2199void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
2167{ 2200{
2168 char path[PATH_MAX]; 2201 char path[PATH_MAX];
2169 2202
2170 if (machine__is_default_guest(machine)) 2203 if (machine__is_default_guest(machine))
2171 return; 2204 return;
2172 sprintf(path, "%s/sys/kernel/notes", machine->root_dir); 2205 sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
2173 if (sysfs__read_build_id(path, self->build_id, 2206 if (sysfs__read_build_id(path, dso->build_id,
2174 sizeof(self->build_id)) == 0) 2207 sizeof(dso->build_id)) == 0)
2175 self->has_build_id = true; 2208 dso->has_build_id = true;
2176} 2209}
2177 2210
2178static struct dso *machine__create_kernel(struct machine *self) 2211static struct dso *machine__create_kernel(struct machine *machine)
2179{ 2212{
2180 const char *vmlinux_name = NULL; 2213 const char *vmlinux_name = NULL;
2181 struct dso *kernel; 2214 struct dso *kernel;
2182 2215
2183 if (machine__is_host(self)) { 2216 if (machine__is_host(machine)) {
2184 vmlinux_name = symbol_conf.vmlinux_name; 2217 vmlinux_name = symbol_conf.vmlinux_name;
2185 kernel = dso__new_kernel(vmlinux_name); 2218 kernel = dso__new_kernel(vmlinux_name);
2186 } else { 2219 } else {
2187 if (machine__is_default_guest(self)) 2220 if (machine__is_default_guest(machine))
2188 vmlinux_name = symbol_conf.default_guest_vmlinux_name; 2221 vmlinux_name = symbol_conf.default_guest_vmlinux_name;
2189 kernel = dso__new_guest_kernel(self, vmlinux_name); 2222 kernel = dso__new_guest_kernel(machine, vmlinux_name);
2190 } 2223 }
2191 2224
2192 if (kernel != NULL) { 2225 if (kernel != NULL) {
2193 dso__read_running_kernel_build_id(kernel, self); 2226 dso__read_running_kernel_build_id(kernel, machine);
2194 dsos__add(&self->kernel_dsos, kernel); 2227 dsos__add(&machine->kernel_dsos, kernel);
2195 } 2228 }
2196 return kernel; 2229 return kernel;
2197} 2230}
@@ -2230,47 +2263,52 @@ static u64 machine__get_kernel_start_addr(struct machine *machine)
2230 } 2263 }
2231 } 2264 }
2232 2265
2266 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
2267 return 0;
2268
2233 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) 2269 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
2234 return 0; 2270 return 0;
2235 2271
2236 return args.start; 2272 return args.start;
2237} 2273}
2238 2274
2239int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) 2275int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
2240{ 2276{
2241 enum map_type type; 2277 enum map_type type;
2242 u64 start = machine__get_kernel_start_addr(self); 2278 u64 start = machine__get_kernel_start_addr(machine);
2243 2279
2244 for (type = 0; type < MAP__NR_TYPES; ++type) { 2280 for (type = 0; type < MAP__NR_TYPES; ++type) {
2245 struct kmap *kmap; 2281 struct kmap *kmap;
2246 2282
2247 self->vmlinux_maps[type] = map__new2(start, kernel, type); 2283 machine->vmlinux_maps[type] = map__new2(start, kernel, type);
2248 if (self->vmlinux_maps[type] == NULL) 2284 if (machine->vmlinux_maps[type] == NULL)
2249 return -1; 2285 return -1;
2250 2286
2251 self->vmlinux_maps[type]->map_ip = 2287 machine->vmlinux_maps[type]->map_ip =
2252 self->vmlinux_maps[type]->unmap_ip = identity__map_ip; 2288 machine->vmlinux_maps[type]->unmap_ip =
2253 2289 identity__map_ip;
2254 kmap = map__kmap(self->vmlinux_maps[type]); 2290 kmap = map__kmap(machine->vmlinux_maps[type]);
2255 kmap->kmaps = &self->kmaps; 2291 kmap->kmaps = &machine->kmaps;
2256 map_groups__insert(&self->kmaps, self->vmlinux_maps[type]); 2292 map_groups__insert(&machine->kmaps,
2293 machine->vmlinux_maps[type]);
2257 } 2294 }
2258 2295
2259 return 0; 2296 return 0;
2260} 2297}
2261 2298
2262void machine__destroy_kernel_maps(struct machine *self) 2299void machine__destroy_kernel_maps(struct machine *machine)
2263{ 2300{
2264 enum map_type type; 2301 enum map_type type;
2265 2302
2266 for (type = 0; type < MAP__NR_TYPES; ++type) { 2303 for (type = 0; type < MAP__NR_TYPES; ++type) {
2267 struct kmap *kmap; 2304 struct kmap *kmap;
2268 2305
2269 if (self->vmlinux_maps[type] == NULL) 2306 if (machine->vmlinux_maps[type] == NULL)
2270 continue; 2307 continue;
2271 2308
2272 kmap = map__kmap(self->vmlinux_maps[type]); 2309 kmap = map__kmap(machine->vmlinux_maps[type]);
2273 map_groups__remove(&self->kmaps, self->vmlinux_maps[type]); 2310 map_groups__remove(&machine->kmaps,
2311 machine->vmlinux_maps[type]);
2274 if (kmap->ref_reloc_sym) { 2312 if (kmap->ref_reloc_sym) {
2275 /* 2313 /*
2276 * ref_reloc_sym is shared among all maps, so free just 2314 * ref_reloc_sym is shared among all maps, so free just
@@ -2284,25 +2322,25 @@ void machine__destroy_kernel_maps(struct machine *self)
2284 kmap->ref_reloc_sym = NULL; 2322 kmap->ref_reloc_sym = NULL;
2285 } 2323 }
2286 2324
2287 map__delete(self->vmlinux_maps[type]); 2325 map__delete(machine->vmlinux_maps[type]);
2288 self->vmlinux_maps[type] = NULL; 2326 machine->vmlinux_maps[type] = NULL;
2289 } 2327 }
2290} 2328}
2291 2329
2292int machine__create_kernel_maps(struct machine *self) 2330int machine__create_kernel_maps(struct machine *machine)
2293{ 2331{
2294 struct dso *kernel = machine__create_kernel(self); 2332 struct dso *kernel = machine__create_kernel(machine);
2295 2333
2296 if (kernel == NULL || 2334 if (kernel == NULL ||
2297 __machine__create_kernel_maps(self, kernel) < 0) 2335 __machine__create_kernel_maps(machine, kernel) < 0)
2298 return -1; 2336 return -1;
2299 2337
2300 if (symbol_conf.use_modules && machine__create_modules(self) < 0) 2338 if (symbol_conf.use_modules && machine__create_modules(machine) < 0)
2301 pr_debug("Problems creating module maps, continuing anyway...\n"); 2339 pr_debug("Problems creating module maps, continuing anyway...\n");
2302 /* 2340 /*
2303 * Now that we have all the maps created, just set the ->end of them: 2341 * Now that we have all the maps created, just set the ->end of them:
2304 */ 2342 */
2305 map_groups__fixup_end(&self->kmaps); 2343 map_groups__fixup_end(&machine->kmaps);
2306 return 0; 2344 return 0;
2307} 2345}
2308 2346
@@ -2366,11 +2404,11 @@ out_fail:
2366 return -1; 2404 return -1;
2367} 2405}
2368 2406
2369size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp) 2407size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp)
2370{ 2408{
2371 int i; 2409 int i;
2372 size_t printed = 0; 2410 size_t printed = 0;
2373 struct dso *kdso = self->vmlinux_maps[MAP__FUNCTION]->dso; 2411 struct dso *kdso = machine->vmlinux_maps[MAP__FUNCTION]->dso;
2374 2412
2375 if (kdso->has_build_id) { 2413 if (kdso->has_build_id) {
2376 char filename[PATH_MAX]; 2414 char filename[PATH_MAX];
@@ -2399,6 +2437,25 @@ static int setup_list(struct strlist **list, const char *list_str,
2399 return 0; 2437 return 0;
2400} 2438}
2401 2439
2440static bool symbol__read_kptr_restrict(void)
2441{
2442 bool value = false;
2443
2444 if (geteuid() != 0) {
2445 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
2446 if (fp != NULL) {
2447 char line[8];
2448
2449 if (fgets(line, sizeof(line), fp) != NULL)
2450 value = atoi(line) != 0;
2451
2452 fclose(fp);
2453 }
2454 }
2455
2456 return value;
2457}
2458
2402int symbol__init(void) 2459int symbol__init(void)
2403{ 2460{
2404 const char *symfs; 2461 const char *symfs;
@@ -2445,6 +2502,8 @@ int symbol__init(void)
2445 if (symfs != symbol_conf.symfs) 2502 if (symfs != symbol_conf.symfs)
2446 free((void *)symfs); 2503 free((void *)symfs);
2447 2504
2505 symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
2506
2448 symbol_conf.initialized = true; 2507 symbol_conf.initialized = true;
2449 return 0; 2508 return 0;
2450 2509
@@ -2467,9 +2526,9 @@ void symbol__exit(void)
2467 symbol_conf.initialized = false; 2526 symbol_conf.initialized = false;
2468} 2527}
2469 2528
2470int machines__create_kernel_maps(struct rb_root *self, pid_t pid) 2529int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
2471{ 2530{
2472 struct machine *machine = machines__findnew(self, pid); 2531 struct machine *machine = machines__findnew(machines, pid);
2473 2532
2474 if (machine == NULL) 2533 if (machine == NULL)
2475 return -1; 2534 return -1;
@@ -2520,7 +2579,7 @@ char *strxfrchar(char *s, char from, char to)
2520 return s; 2579 return s;
2521} 2580}
2522 2581
2523int machines__create_guest_kernel_maps(struct rb_root *self) 2582int machines__create_guest_kernel_maps(struct rb_root *machines)
2524{ 2583{
2525 int ret = 0; 2584 int ret = 0;
2526 struct dirent **namelist = NULL; 2585 struct dirent **namelist = NULL;
@@ -2531,7 +2590,7 @@ int machines__create_guest_kernel_maps(struct rb_root *self)
2531 if (symbol_conf.default_guest_vmlinux_name || 2590 if (symbol_conf.default_guest_vmlinux_name ||
2532 symbol_conf.default_guest_modules || 2591 symbol_conf.default_guest_modules ||
2533 symbol_conf.default_guest_kallsyms) { 2592 symbol_conf.default_guest_kallsyms) {
2534 machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID); 2593 machines__create_kernel_maps(machines, DEFAULT_GUEST_KERNEL_ID);
2535 } 2594 }
2536 2595
2537 if (symbol_conf.guestmount) { 2596 if (symbol_conf.guestmount) {
@@ -2552,7 +2611,7 @@ int machines__create_guest_kernel_maps(struct rb_root *self)
2552 pr_debug("Can't access file %s\n", path); 2611 pr_debug("Can't access file %s\n", path);
2553 goto failure; 2612 goto failure;
2554 } 2613 }
2555 machines__create_kernel_maps(self, pid); 2614 machines__create_kernel_maps(machines, pid);
2556 } 2615 }
2557failure: 2616failure:
2558 free(namelist); 2617 free(namelist);
@@ -2561,23 +2620,23 @@ failure:
2561 return ret; 2620 return ret;
2562} 2621}
2563 2622
2564void machines__destroy_guest_kernel_maps(struct rb_root *self) 2623void machines__destroy_guest_kernel_maps(struct rb_root *machines)
2565{ 2624{
2566 struct rb_node *next = rb_first(self); 2625 struct rb_node *next = rb_first(machines);
2567 2626
2568 while (next) { 2627 while (next) {
2569 struct machine *pos = rb_entry(next, struct machine, rb_node); 2628 struct machine *pos = rb_entry(next, struct machine, rb_node);
2570 2629
2571 next = rb_next(&pos->rb_node); 2630 next = rb_next(&pos->rb_node);
2572 rb_erase(&pos->rb_node, self); 2631 rb_erase(&pos->rb_node, machines);
2573 machine__delete(pos); 2632 machine__delete(pos);
2574 } 2633 }
2575} 2634}
2576 2635
2577int machine__load_kallsyms(struct machine *self, const char *filename, 2636int machine__load_kallsyms(struct machine *machine, const char *filename,
2578 enum map_type type, symbol_filter_t filter) 2637 enum map_type type, symbol_filter_t filter)
2579{ 2638{
2580 struct map *map = self->vmlinux_maps[type]; 2639 struct map *map = machine->vmlinux_maps[type];
2581 int ret = dso__load_kallsyms(map->dso, filename, map, filter); 2640 int ret = dso__load_kallsyms(map->dso, filename, map, filter);
2582 2641
2583 if (ret > 0) { 2642 if (ret > 0) {
@@ -2587,16 +2646,16 @@ int machine__load_kallsyms(struct machine *self, const char *filename,
2587 * kernel, with modules between them, fixup the end of all 2646 * kernel, with modules between them, fixup the end of all
2588 * sections. 2647 * sections.
2589 */ 2648 */
2590 __map_groups__fixup_end(&self->kmaps, type); 2649 __map_groups__fixup_end(&machine->kmaps, type);
2591 } 2650 }
2592 2651
2593 return ret; 2652 return ret;
2594} 2653}
2595 2654
2596int machine__load_vmlinux_path(struct machine *self, enum map_type type, 2655int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
2597 symbol_filter_t filter) 2656 symbol_filter_t filter)
2598{ 2657{
2599 struct map *map = self->vmlinux_maps[type]; 2658 struct map *map = machine->vmlinux_maps[type];
2600 int ret = dso__load_vmlinux_path(map->dso, map, filter); 2659 int ret = dso__load_vmlinux_path(map->dso, map, filter);
2601 2660
2602 if (ret > 0) { 2661 if (ret > 0) {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 713b0b40cc4a..325ee36a9d29 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -62,7 +62,7 @@ struct symbol {
62 char name[0]; 62 char name[0];
63}; 63};
64 64
65void symbol__delete(struct symbol *self); 65void symbol__delete(struct symbol *sym);
66 66
67struct strlist; 67struct strlist;
68 68
@@ -75,7 +75,8 @@ struct symbol_conf {
75 use_callchain, 75 use_callchain,
76 exclude_other, 76 exclude_other,
77 show_cpu_utilization, 77 show_cpu_utilization,
78 initialized; 78 initialized,
79 kptr_restrict;
79 const char *vmlinux_name, 80 const char *vmlinux_name,
80 *kallsyms_name, 81 *kallsyms_name,
81 *source_prefix, 82 *source_prefix,
@@ -96,9 +97,9 @@ struct symbol_conf {
96 97
97extern struct symbol_conf symbol_conf; 98extern struct symbol_conf symbol_conf;
98 99
99static inline void *symbol__priv(struct symbol *self) 100static inline void *symbol__priv(struct symbol *sym)
100{ 101{
101 return ((void *)self) - symbol_conf.priv_size; 102 return ((void *)sym) - symbol_conf.priv_size;
102} 103}
103 104
104struct ref_reloc_sym { 105struct ref_reloc_sym {
@@ -155,43 +156,45 @@ struct dso {
155 156
156struct dso *dso__new(const char *name); 157struct dso *dso__new(const char *name);
157struct dso *dso__new_kernel(const char *name); 158struct dso *dso__new_kernel(const char *name);
158void dso__delete(struct dso *self); 159void dso__delete(struct dso *dso);
159 160
160int dso__name_len(const struct dso *self); 161int dso__name_len(const struct dso *dso);
161 162
162bool dso__loaded(const struct dso *self, enum map_type type); 163bool dso__loaded(const struct dso *dso, enum map_type type);
163bool dso__sorted_by_name(const struct dso *self, enum map_type type); 164bool dso__sorted_by_name(const struct dso *dso, enum map_type type);
164 165
165static inline void dso__set_loaded(struct dso *self, enum map_type type) 166static inline void dso__set_loaded(struct dso *dso, enum map_type type)
166{ 167{
167 self->loaded |= (1 << type); 168 dso->loaded |= (1 << type);
168} 169}
169 170
170void dso__sort_by_name(struct dso *self, enum map_type type); 171void dso__sort_by_name(struct dso *dso, enum map_type type);
171 172
172struct dso *__dsos__findnew(struct list_head *head, const char *name); 173struct dso *__dsos__findnew(struct list_head *head, const char *name);
173 174
174int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); 175int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
175int dso__load_vmlinux(struct dso *self, struct map *map, 176int dso__load_vmlinux(struct dso *dso, struct map *map,
176 const char *vmlinux, symbol_filter_t filter); 177 const char *vmlinux, symbol_filter_t filter);
177int dso__load_vmlinux_path(struct dso *self, struct map *map, 178int dso__load_vmlinux_path(struct dso *dso, struct map *map,
178 symbol_filter_t filter); 179 symbol_filter_t filter);
179int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, 180int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
180 symbol_filter_t filter); 181 symbol_filter_t filter);
181int machine__load_kallsyms(struct machine *self, const char *filename, 182int machine__load_kallsyms(struct machine *machine, const char *filename,
182 enum map_type type, symbol_filter_t filter); 183 enum map_type type, symbol_filter_t filter);
183int machine__load_vmlinux_path(struct machine *self, enum map_type type, 184int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
184 symbol_filter_t filter); 185 symbol_filter_t filter);
185 186
186size_t __dsos__fprintf(struct list_head *head, FILE *fp); 187size_t __dsos__fprintf(struct list_head *head, FILE *fp);
187 188
188size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits); 189size_t machine__fprintf_dsos_buildid(struct machine *machine,
189size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); 190 FILE *fp, bool with_hits);
190size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); 191size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp);
191 192size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
192size_t dso__fprintf_buildid(struct dso *self, FILE *fp); 193 FILE *fp, bool with_hits);
193size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp); 194size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
194size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); 195size_t dso__fprintf_symbols_by_name(struct dso *dso,
196 enum map_type type, FILE *fp);
197size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
195 198
196enum symtab_type { 199enum symtab_type {
197 SYMTAB__KALLSYMS = 0, 200 SYMTAB__KALLSYMS = 0,
@@ -207,34 +210,36 @@ enum symtab_type {
207 SYMTAB__NOT_FOUND, 210 SYMTAB__NOT_FOUND,
208}; 211};
209 212
210char dso__symtab_origin(const struct dso *self); 213char dso__symtab_origin(const struct dso *dso);
211void dso__set_long_name(struct dso *self, char *name); 214void dso__set_long_name(struct dso *dso, char *name);
212void dso__set_build_id(struct dso *self, void *build_id); 215void dso__set_build_id(struct dso *dso, void *build_id);
213void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine); 216void dso__read_running_kernel_build_id(struct dso *dso,
214struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); 217 struct machine *machine);
215struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type, 218struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
219 u64 addr);
220struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
216 const char *name); 221 const char *name);
217 222
218int filename__read_build_id(const char *filename, void *bf, size_t size); 223int filename__read_build_id(const char *filename, void *bf, size_t size);
219int sysfs__read_build_id(const char *filename, void *bf, size_t size); 224int sysfs__read_build_id(const char *filename, void *bf, size_t size);
220bool __dsos__read_build_ids(struct list_head *head, bool with_hits); 225bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
221int build_id__sprintf(const u8 *self, int len, char *bf); 226int build_id__sprintf(const u8 *build_id, int len, char *bf);
222int kallsyms__parse(const char *filename, void *arg, 227int kallsyms__parse(const char *filename, void *arg,
223 int (*process_symbol)(void *arg, const char *name, 228 int (*process_symbol)(void *arg, const char *name,
224 char type, u64 start, u64 end)); 229 char type, u64 start, u64 end));
225 230
226void machine__destroy_kernel_maps(struct machine *self); 231void machine__destroy_kernel_maps(struct machine *machine);
227int __machine__create_kernel_maps(struct machine *self, struct dso *kernel); 232int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel);
228int machine__create_kernel_maps(struct machine *self); 233int machine__create_kernel_maps(struct machine *machine);
229 234
230int machines__create_kernel_maps(struct rb_root *self, pid_t pid); 235int machines__create_kernel_maps(struct rb_root *machines, pid_t pid);
231int machines__create_guest_kernel_maps(struct rb_root *self); 236int machines__create_guest_kernel_maps(struct rb_root *machines);
232void machines__destroy_guest_kernel_maps(struct rb_root *self); 237void machines__destroy_guest_kernel_maps(struct rb_root *machines);
233 238
234int symbol__init(void); 239int symbol__init(void);
235void symbol__exit(void); 240void symbol__exit(void);
236bool symbol_type__is_a(char symbol_type, enum map_type map_type); 241bool symbol_type__is_a(char symbol_type, enum map_type map_type);
237 242
238size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp); 243size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
239 244
240#endif /* __PERF_SYMBOL */ 245#endif /* __PERF_SYMBOL */
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c
index 8c17a8730e4a..0229723aceb3 100644
--- a/tools/perf/util/ui/browsers/annotate.c
+++ b/tools/perf/util/ui/browsers/annotate.c
@@ -5,7 +5,6 @@
5#include "../../hist.h" 5#include "../../hist.h"
6#include "../../sort.h" 6#include "../../sort.h"
7#include "../../symbol.h" 7#include "../../symbol.h"
8#include "../../annotate.h"
9#include <pthread.h> 8#include <pthread.h>
10 9
11static void ui__error_window(const char *fmt, ...) 10static void ui__error_window(const char *fmt, ...)
@@ -256,10 +255,9 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
256 int refresh) 255 int refresh)
257{ 256{
258 struct objdump_line *pos, *n; 257 struct objdump_line *pos, *n;
259 struct annotation *notes = symbol__annotation(sym); 258 struct annotation *notes;
260 struct annotate_browser browser = { 259 struct annotate_browser browser = {
261 .b = { 260 .b = {
262 .entries = &notes->src->source,
263 .refresh = ui_browser__list_head_refresh, 261 .refresh = ui_browser__list_head_refresh,
264 .seek = ui_browser__list_head_seek, 262 .seek = ui_browser__list_head_seek,
265 .write = annotate_browser__write, 263 .write = annotate_browser__write,
@@ -281,6 +279,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
281 279
282 ui_helpline__push("Press <- or ESC to exit"); 280 ui_helpline__push("Press <- or ESC to exit");
283 281
282 notes = symbol__annotation(sym);
283
284 list_for_each_entry(pos, &notes->src->source, node) { 284 list_for_each_entry(pos, &notes->src->source, node) {
285 struct objdump_line_rb_node *rbpos; 285 struct objdump_line_rb_node *rbpos;
286 size_t line_len = strlen(pos->line); 286 size_t line_len = strlen(pos->line);
@@ -291,6 +291,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
291 rbpos->idx = browser.b.nr_entries++; 291 rbpos->idx = browser.b.nr_entries++;
292 } 292 }
293 293
294 browser.b.entries = &notes->src->source,
294 browser.b.width += 18; /* Percentage */ 295 browser.b.width += 18; /* Percentage */
295 ret = annotate_browser__run(&browser, evidx, refresh); 296 ret = annotate_browser__run(&browser, evidx, refresh);
296 list_for_each_entry_safe(pos, n, &notes->src->source, node) { 297 list_for_each_entry_safe(pos, n, &notes->src->source, node) {
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c
index 798efdca3ead..5d767c622dfc 100644
--- a/tools/perf/util/ui/browsers/hists.c
+++ b/tools/perf/util/ui/browsers/hists.c
@@ -851,7 +851,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
851 goto out_free_stack; 851 goto out_free_stack;
852 case 'a': 852 case 'a':
853 if (browser->selection == NULL || 853 if (browser->selection == NULL ||
854 browser->selection->map == NULL || 854 browser->selection->sym == NULL ||
855 browser->selection->map->dso->annotate_warned) 855 browser->selection->map->dso->annotate_warned)
856 continue; 856 continue;
857 goto do_annotate; 857 goto do_annotate;