Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / tools / perf / util / event.c
1 #include <linux/types.h>
2 #include "event.h"
3 #include "debug.h"
4 #include "hist.h"
5 #include "machine.h"
6 #include "sort.h"
7 #include "string.h"
8 #include "strlist.h"
9 #include "thread.h"
10 #include "thread_map.h"
11 #include "symbol/kallsyms.h"
12
13 static const char *perf_event__names[] = {
14         [0]                                     = "TOTAL",
15         [PERF_RECORD_MMAP]                      = "MMAP",
16         [PERF_RECORD_MMAP2]                     = "MMAP2",
17         [PERF_RECORD_LOST]                      = "LOST",
18         [PERF_RECORD_COMM]                      = "COMM",
19         [PERF_RECORD_EXIT]                      = "EXIT",
20         [PERF_RECORD_THROTTLE]                  = "THROTTLE",
21         [PERF_RECORD_UNTHROTTLE]                = "UNTHROTTLE",
22         [PERF_RECORD_FORK]                      = "FORK",
23         [PERF_RECORD_READ]                      = "READ",
24         [PERF_RECORD_SAMPLE]                    = "SAMPLE",
25         [PERF_RECORD_HEADER_ATTR]               = "ATTR",
26         [PERF_RECORD_HEADER_EVENT_TYPE]         = "EVENT_TYPE",
27         [PERF_RECORD_HEADER_TRACING_DATA]       = "TRACING_DATA",
28         [PERF_RECORD_HEADER_BUILD_ID]           = "BUILD_ID",
29         [PERF_RECORD_FINISHED_ROUND]            = "FINISHED_ROUND",
30 };
31
32 const char *perf_event__name(unsigned int id)
33 {
34         if (id >= ARRAY_SIZE(perf_event__names))
35                 return "INVALID";
36         if (!perf_event__names[id])
37                 return "UNKNOWN";
38         return perf_event__names[id];
39 }
40
41 static struct perf_sample synth_sample = {
42         .pid       = -1,
43         .tid       = -1,
44         .time      = -1,
45         .stream_id = -1,
46         .cpu       = -1,
47         .period    = 1,
48 };
49
50 static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len)
51 {
52         char filename[PATH_MAX];
53         char bf[BUFSIZ];
54         FILE *fp;
55         size_t size = 0;
56         pid_t tgid = -1;
57
58         snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
59
60         fp = fopen(filename, "r");
61         if (fp == NULL) {
62                 pr_debug("couldn't open %s\n", filename);
63                 return 0;
64         }
65
66         while (!comm[0] || (tgid < 0)) {
67                 if (fgets(bf, sizeof(bf), fp) == NULL) {
68                         pr_warning("couldn't get COMM and pgid, malformed %s\n",
69                                    filename);
70                         break;
71                 }
72
73                 if (memcmp(bf, "Name:", 5) == 0) {
74                         char *name = bf + 5;
75                         while (*name && isspace(*name))
76                                 ++name;
77                         size = strlen(name) - 1;
78                         if (size >= len)
79                                 size = len - 1;
80                         memcpy(comm, name, size);
81                         comm[size] = '\0';
82
83                 } else if (memcmp(bf, "Tgid:", 5) == 0) {
84                         char *tgids = bf + 5;
85                         while (*tgids && isspace(*tgids))
86                                 ++tgids;
87                         tgid = atoi(tgids);
88                 }
89         }
90
91         fclose(fp);
92
93         return tgid;
94 }
95
96 static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
97                                          union perf_event *event, pid_t pid,
98                                          perf_event__handler_t process,
99                                          struct machine *machine)
100 {
101         size_t size;
102         pid_t tgid;
103
104         memset(&event->comm, 0, sizeof(event->comm));
105
106         if (machine__is_host(machine))
107                 tgid = perf_event__get_comm_tgid(pid, event->comm.comm,
108                                                  sizeof(event->comm.comm));
109         else
110                 tgid = machine->pid;
111
112         if (tgid < 0)
113                 goto out;
114
115         event->comm.pid = tgid;
116         event->comm.header.type = PERF_RECORD_COMM;
117
118         size = strlen(event->comm.comm) + 1;
119         size = PERF_ALIGN(size, sizeof(u64));
120         memset(event->comm.comm + size, 0, machine->id_hdr_size);
121         event->comm.header.size = (sizeof(event->comm) -
122                                 (sizeof(event->comm.comm) - size) +
123                                 machine->id_hdr_size);
124         event->comm.tid = pid;
125
126         if (process(tool, event, &synth_sample, machine) != 0)
127                 return -1;
128
129 out:
130         return tgid;
131 }
132
133 static int perf_event__synthesize_fork(struct perf_tool *tool,
134                                        union perf_event *event, pid_t pid,
135                                        pid_t tgid, perf_event__handler_t process,
136                                        struct machine *machine)
137 {
138         memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size);
139
140         /* this is really a clone event but we use fork to synthesize it */
141         event->fork.ppid = tgid;
142         event->fork.ptid = tgid;
143         event->fork.pid  = tgid;
144         event->fork.tid  = pid;
145         event->fork.header.type = PERF_RECORD_FORK;
146
147         event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size);
148
149         if (process(tool, event, &synth_sample, machine) != 0)
150                 return -1;
151
152         return 0;
153 }
154
155 int perf_event__synthesize_mmap_events(struct perf_tool *tool,
156                                        union perf_event *event,
157                                        pid_t pid, pid_t tgid,
158                                        perf_event__handler_t process,
159                                        struct machine *machine,
160                                        bool mmap_data)
161 {
162         char filename[PATH_MAX];
163         FILE *fp;
164         int rc = 0;
165
166         if (machine__is_default_guest(machine))
167                 return 0;
168
169         snprintf(filename, sizeof(filename), "%s/proc/%d/maps",
170                  machine->root_dir, pid);
171
172         fp = fopen(filename, "r");
173         if (fp == NULL) {
174                 /*
175                  * We raced with a task exiting - just return:
176                  */
177                 pr_debug("couldn't open %s\n", filename);
178                 return -1;
179         }
180
181         event->header.type = PERF_RECORD_MMAP;
182
183         while (1) {
184                 char bf[BUFSIZ];
185                 char prot[5];
186                 char execname[PATH_MAX];
187                 char anonstr[] = "//anon";
188                 size_t size;
189                 ssize_t n;
190
191                 if (fgets(bf, sizeof(bf), fp) == NULL)
192                         break;
193
194                 /* ensure null termination since stack will be reused. */
195                 strcpy(execname, "");
196
197                 /* 00400000-0040c000 r-xp 00000000 fd:01 41038  /bin/cat */
198                 n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n",
199                        &event->mmap.start, &event->mmap.len, prot,
200                        &event->mmap.pgoff,
201                        execname);
202                 /*
203                  * Anon maps don't have the execname.
204                  */
205                 if (n < 4)
206                         continue;
207                 /*
208                  * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
209                  */
210                 if (machine__is_host(machine))
211                         event->header.misc = PERF_RECORD_MISC_USER;
212                 else
213                         event->header.misc = PERF_RECORD_MISC_GUEST_USER;
214
215                 if (prot[2] != 'x') {
216                         if (!mmap_data || prot[0] != 'r')
217                                 continue;
218
219                         event->header.misc |= PERF_RECORD_MISC_MMAP_DATA;
220                 }
221
222                 if (!strcmp(execname, ""))
223                         strcpy(execname, anonstr);
224
225                 size = strlen(execname) + 1;
226                 memcpy(event->mmap.filename, execname, size);
227                 size = PERF_ALIGN(size, sizeof(u64));
228                 event->mmap.len -= event->mmap.start;
229                 event->mmap.header.size = (sizeof(event->mmap) -
230                                         (sizeof(event->mmap.filename) - size));
231                 memset(event->mmap.filename + size, 0, machine->id_hdr_size);
232                 event->mmap.header.size += machine->id_hdr_size;
233                 event->mmap.pid = tgid;
234                 event->mmap.tid = pid;
235
236                 if (process(tool, event, &synth_sample, machine) != 0) {
237                         rc = -1;
238                         break;
239                 }
240         }
241
242         fclose(fp);
243         return rc;
244 }
245
246 int perf_event__synthesize_modules(struct perf_tool *tool,
247                                    perf_event__handler_t process,
248                                    struct machine *machine)
249 {
250         int rc = 0;
251         struct rb_node *nd;
252         struct map_groups *kmaps = &machine->kmaps;
253         union perf_event *event = zalloc((sizeof(event->mmap) +
254                                           machine->id_hdr_size));
255         if (event == NULL) {
256                 pr_debug("Not enough memory synthesizing mmap event "
257                          "for kernel modules\n");
258                 return -1;
259         }
260
261         event->header.type = PERF_RECORD_MMAP;
262
263         /*
264          * kernel uses 0 for user space maps, see kernel/perf_event.c
265          * __perf_event_mmap
266          */
267         if (machine__is_host(machine))
268                 event->header.misc = PERF_RECORD_MISC_KERNEL;
269         else
270                 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
271
272         for (nd = rb_first(&kmaps->maps[MAP__FUNCTION]);
273              nd; nd = rb_next(nd)) {
274                 size_t size;
275                 struct map *pos = rb_entry(nd, struct map, rb_node);
276
277                 if (pos->dso->kernel)
278                         continue;
279
280                 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
281                 event->mmap.header.type = PERF_RECORD_MMAP;
282                 event->mmap.header.size = (sizeof(event->mmap) -
283                                         (sizeof(event->mmap.filename) - size));
284                 memset(event->mmap.filename + size, 0, machine->id_hdr_size);
285                 event->mmap.header.size += machine->id_hdr_size;
286                 event->mmap.start = pos->start;
287                 event->mmap.len   = pos->end - pos->start;
288                 event->mmap.pid   = machine->pid;
289
290                 memcpy(event->mmap.filename, pos->dso->long_name,
291                        pos->dso->long_name_len + 1);
292                 if (process(tool, event, &synth_sample, machine) != 0) {
293                         rc = -1;
294                         break;
295                 }
296         }
297
298         free(event);
299         return rc;
300 }
301
302 static int __event__synthesize_thread(union perf_event *comm_event,
303                                       union perf_event *mmap_event,
304                                       union perf_event *fork_event,
305                                       pid_t pid, int full,
306                                           perf_event__handler_t process,
307                                       struct perf_tool *tool,
308                                       struct machine *machine, bool mmap_data)
309 {
310         char filename[PATH_MAX];
311         DIR *tasks;
312         struct dirent dirent, *next;
313         pid_t tgid;
314
315         /* special case: only send one comm event using passed in pid */
316         if (!full) {
317                 tgid = perf_event__synthesize_comm(tool, comm_event, pid,
318                                                    process, machine);
319
320                 if (tgid == -1)
321                         return -1;
322
323                 return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
324                                                           process, machine, mmap_data);
325         }
326
327         if (machine__is_default_guest(machine))
328                 return 0;
329
330         snprintf(filename, sizeof(filename), "%s/proc/%d/task",
331                  machine->root_dir, pid);
332
333         tasks = opendir(filename);
334         if (tasks == NULL) {
335                 pr_debug("couldn't open %s\n", filename);
336                 return 0;
337         }
338
339         while (!readdir_r(tasks, &dirent, &next) && next) {
340                 char *end;
341                 int rc = 0;
342                 pid_t _pid;
343
344                 _pid = strtol(dirent.d_name, &end, 10);
345                 if (*end)
346                         continue;
347
348                 tgid = perf_event__synthesize_comm(tool, comm_event, _pid,
349                                                    process, machine);
350                 if (tgid == -1)
351                         return -1;
352
353                 if (_pid == pid) {
354                         /* process the parent's maps too */
355                         rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
356                                                 process, machine, mmap_data);
357                 } else {
358                         /* only fork the tid's map, to save time */
359                         rc = perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
360                                                  process, machine);
361                 }
362
363                 if (rc)
364                         return rc;
365         }
366
367         closedir(tasks);
368         return 0;
369 }
370
371 int perf_event__synthesize_thread_map(struct perf_tool *tool,
372                                       struct thread_map *threads,
373                                       perf_event__handler_t process,
374                                       struct machine *machine,
375                                       bool mmap_data)
376 {
377         union perf_event *comm_event, *mmap_event, *fork_event;
378         int err = -1, thread, j;
379
380         comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
381         if (comm_event == NULL)
382                 goto out;
383
384         mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size);
385         if (mmap_event == NULL)
386                 goto out_free_comm;
387
388         fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
389         if (fork_event == NULL)
390                 goto out_free_mmap;
391
392         err = 0;
393         for (thread = 0; thread < threads->nr; ++thread) {
394                 if (__event__synthesize_thread(comm_event, mmap_event,
395                                                fork_event,
396                                                threads->map[thread], 0,
397                                                process, tool, machine,
398                                                mmap_data)) {
399                         err = -1;
400                         break;
401                 }
402
403                 /*
404                  * comm.pid is set to thread group id by
405                  * perf_event__synthesize_comm
406                  */
407                 if ((int) comm_event->comm.pid != threads->map[thread]) {
408                         bool need_leader = true;
409
410                         /* is thread group leader in thread_map? */
411                         for (j = 0; j < threads->nr; ++j) {
412                                 if ((int) comm_event->comm.pid == threads->map[j]) {
413                                         need_leader = false;
414                                         break;
415                                 }
416                         }
417
418                         /* if not, generate events for it */
419                         if (need_leader &&
420                             __event__synthesize_thread(comm_event, mmap_event,
421                                                        fork_event,
422                                                        comm_event->comm.pid, 0,
423                                                        process, tool, machine,
424                                                        mmap_data)) {
425                                 err = -1;
426                                 break;
427                         }
428                 }
429         }
430         free(fork_event);
431 out_free_mmap:
432         free(mmap_event);
433 out_free_comm:
434         free(comm_event);
435 out:
436         return err;
437 }
438
439 int perf_event__synthesize_threads(struct perf_tool *tool,
440                                    perf_event__handler_t process,
441                                    struct machine *machine, bool mmap_data)
442 {
443         DIR *proc;
444         char proc_path[PATH_MAX];
445         struct dirent dirent, *next;
446         union perf_event *comm_event, *mmap_event, *fork_event;
447         int err = -1;
448
449         if (machine__is_default_guest(machine))
450                 return 0;
451
452         comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
453         if (comm_event == NULL)
454                 goto out;
455
456         mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size);
457         if (mmap_event == NULL)
458                 goto out_free_comm;
459
460         fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
461         if (fork_event == NULL)
462                 goto out_free_mmap;
463
464         snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
465         proc = opendir(proc_path);
466
467         if (proc == NULL)
468                 goto out_free_fork;
469
470         while (!readdir_r(proc, &dirent, &next) && next) {
471                 char *end;
472                 pid_t pid = strtol(dirent.d_name, &end, 10);
473
474                 if (*end) /* only interested in proper numerical dirents */
475                         continue;
476                 /*
477                  * We may race with exiting thread, so don't stop just because
478                  * one thread couldn't be synthesized.
479                  */
480                 __event__synthesize_thread(comm_event, mmap_event, fork_event, pid,
481                                            1, process, tool, machine, mmap_data);
482         }
483
484         err = 0;
485         closedir(proc);
486 out_free_fork:
487         free(fork_event);
488 out_free_mmap:
489         free(mmap_event);
490 out_free_comm:
491         free(comm_event);
492 out:
493         return err;
494 }
495
496 struct process_symbol_args {
497         const char *name;
498         u64        start;
499 };
500
501 static int find_symbol_cb(void *arg, const char *name, char type,
502                           u64 start)
503 {
504         struct process_symbol_args *args = arg;
505
506         /*
507          * Must be a function or at least an alias, as in PARISC64, where "_text" is
508          * an 'A' to the same address as "_stext".
509          */
510         if (!(symbol_type__is_a(type, MAP__FUNCTION) ||
511               type == 'A') || strcmp(name, args->name))
512                 return 0;
513
514         args->start = start;
515         return 1;
516 }
517
518 u64 kallsyms__get_function_start(const char *kallsyms_filename,
519                                  const char *symbol_name)
520 {
521         struct process_symbol_args args = { .name = symbol_name, };
522
523         if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0)
524                 return 0;
525
526         return args.start;
527 }
528
529 int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
530                                        perf_event__handler_t process,
531                                        struct machine *machine)
532 {
533         size_t size;
534         const char *mmap_name;
535         char name_buff[PATH_MAX];
536         struct map *map;
537         struct kmap *kmap;
538         int err;
539         /*
540          * We should get this from /sys/kernel/sections/.text, but till that is
541          * available use this, and after it is use this as a fallback for older
542          * kernels.
543          */
544         union perf_event *event = zalloc((sizeof(event->mmap) +
545                                           machine->id_hdr_size));
546         if (event == NULL) {
547                 pr_debug("Not enough memory synthesizing mmap event "
548                          "for kernel modules\n");
549                 return -1;
550         }
551
552         mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
553         if (machine__is_host(machine)) {
554                 /*
555                  * kernel uses PERF_RECORD_MISC_USER for user space maps,
556                  * see kernel/perf_event.c __perf_event_mmap
557                  */
558                 event->header.misc = PERF_RECORD_MISC_KERNEL;
559         } else {
560                 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
561         }
562
563         map = machine->vmlinux_maps[MAP__FUNCTION];
564         kmap = map__kmap(map);
565         size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
566                         "%s%s", mmap_name, kmap->ref_reloc_sym->name) + 1;
567         size = PERF_ALIGN(size, sizeof(u64));
568         event->mmap.header.type = PERF_RECORD_MMAP;
569         event->mmap.header.size = (sizeof(event->mmap) -
570                         (sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
571         event->mmap.pgoff = kmap->ref_reloc_sym->addr;
572         event->mmap.start = map->start;
573         event->mmap.len   = map->end - event->mmap.start;
574         event->mmap.pid   = machine->pid;
575
576         err = process(tool, event, &synth_sample, machine);
577         free(event);
578
579         return err;
580 }
581
582 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
583 {
584         return fprintf(fp, ": %s:%d\n", event->comm.comm, event->comm.tid);
585 }
586
587 int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
588                              union perf_event *event,
589                              struct perf_sample *sample,
590                              struct machine *machine)
591 {
592         return machine__process_comm_event(machine, event, sample);
593 }
594
595 int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
596                              union perf_event *event,
597                              struct perf_sample *sample,
598                              struct machine *machine)
599 {
600         return machine__process_lost_event(machine, event, sample);
601 }
602
603 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
604 {
605         return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n",
606                        event->mmap.pid, event->mmap.tid, event->mmap.start,
607                        event->mmap.len, event->mmap.pgoff,
608                        (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
609                        event->mmap.filename);
610 }
611
612 size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
613 {
614         return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64
615                            " %02x:%02x %"PRIu64" %"PRIu64"]: %c %s\n",
616                        event->mmap2.pid, event->mmap2.tid, event->mmap2.start,
617                        event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj,
618                        event->mmap2.min, event->mmap2.ino,
619                        event->mmap2.ino_generation,
620                        (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
621                        event->mmap2.filename);
622 }
623
624 int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
625                              union perf_event *event,
626                              struct perf_sample *sample,
627                              struct machine *machine)
628 {
629         return machine__process_mmap_event(machine, event, sample);
630 }
631
632 int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused,
633                              union perf_event *event,
634                              struct perf_sample *sample,
635                              struct machine *machine)
636 {
637         return machine__process_mmap2_event(machine, event, sample);
638 }
639
640 size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
641 {
642         return fprintf(fp, "(%d:%d):(%d:%d)\n",
643                        event->fork.pid, event->fork.tid,
644                        event->fork.ppid, event->fork.ptid);
645 }
646
647 int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
648                              union perf_event *event,
649                              struct perf_sample *sample,
650                              struct machine *machine)
651 {
652         return machine__process_fork_event(machine, event, sample);
653 }
654
655 int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
656                              union perf_event *event,
657                              struct perf_sample *sample,
658                              struct machine *machine)
659 {
660         return machine__process_exit_event(machine, event, sample);
661 }
662
663 size_t perf_event__fprintf(union perf_event *event, FILE *fp)
664 {
665         size_t ret = fprintf(fp, "PERF_RECORD_%s",
666                              perf_event__name(event->header.type));
667
668         switch (event->header.type) {
669         case PERF_RECORD_COMM:
670                 ret += perf_event__fprintf_comm(event, fp);
671                 break;
672         case PERF_RECORD_FORK:
673         case PERF_RECORD_EXIT:
674                 ret += perf_event__fprintf_task(event, fp);
675                 break;
676         case PERF_RECORD_MMAP:
677                 ret += perf_event__fprintf_mmap(event, fp);
678                 break;
679         case PERF_RECORD_MMAP2:
680                 ret += perf_event__fprintf_mmap2(event, fp);
681                 break;
682         default:
683                 ret += fprintf(fp, "\n");
684         }
685
686         return ret;
687 }
688
689 int perf_event__process(struct perf_tool *tool __maybe_unused,
690                         union perf_event *event,
691                         struct perf_sample *sample,
692                         struct machine *machine)
693 {
694         return machine__process_event(machine, event, sample);
695 }
696
697 void thread__find_addr_map(struct thread *thread,
698                            struct machine *machine, u8 cpumode,
699                            enum map_type type, u64 addr,
700                            struct addr_location *al)
701 {
702         struct map_groups *mg = &thread->mg;
703         bool load_map = false;
704
705         al->machine = machine;
706         al->thread = thread;
707         al->addr = addr;
708         al->cpumode = cpumode;
709         al->filtered = 0;
710
711         if (machine == NULL) {
712                 al->map = NULL;
713                 return;
714         }
715
716         if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
717                 al->level = 'k';
718                 mg = &machine->kmaps;
719                 load_map = true;
720         } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
721                 al->level = '.';
722         } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
723                 al->level = 'g';
724                 mg = &machine->kmaps;
725                 load_map = true;
726         } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) {
727                 al->level = 'u';
728         } else {
729                 al->level = 'H';
730                 al->map = NULL;
731
732                 if ((cpumode == PERF_RECORD_MISC_GUEST_USER ||
733                         cpumode == PERF_RECORD_MISC_GUEST_KERNEL) &&
734                         !perf_guest)
735                         al->filtered |= (1 << HIST_FILTER__GUEST);
736                 if ((cpumode == PERF_RECORD_MISC_USER ||
737                         cpumode == PERF_RECORD_MISC_KERNEL) &&
738                         !perf_host)
739                         al->filtered |= (1 << HIST_FILTER__HOST);
740
741                 return;
742         }
743 try_again:
744         al->map = map_groups__find(mg, type, al->addr);
745         if (al->map == NULL) {
746                 /*
747                  * If this is outside of all known maps, and is a negative
748                  * address, try to look it up in the kernel dso, as it might be
749                  * a vsyscall or vdso (which executes in user-mode).
750                  *
751                  * XXX This is nasty, we should have a symbol list in the
752                  * "[vdso]" dso, but for now lets use the old trick of looking
753                  * in the whole kernel symbol list.
754                  */
755                 if ((long long)al->addr < 0 &&
756                     cpumode == PERF_RECORD_MISC_USER &&
757                     machine && mg != &machine->kmaps) {
758                         mg = &machine->kmaps;
759                         goto try_again;
760                 }
761         } else {
762                 /*
763                  * Kernel maps might be changed when loading symbols so loading
764                  * must be done prior to using kernel maps.
765                  */
766                 if (load_map)
767                         map__load(al->map, machine->symbol_filter);
768                 al->addr = al->map->map_ip(al->map, al->addr);
769         }
770 }
771
772 void thread__find_addr_location(struct thread *thread, struct machine *machine,
773                                 u8 cpumode, enum map_type type, u64 addr,
774                                 struct addr_location *al)
775 {
776         thread__find_addr_map(thread, machine, cpumode, type, addr, al);
777         if (al->map != NULL)
778                 al->sym = map__find_symbol(al->map, al->addr,
779                                            machine->symbol_filter);
780         else
781                 al->sym = NULL;
782 }
783
784 int perf_event__preprocess_sample(const union perf_event *event,
785                                   struct machine *machine,
786                                   struct addr_location *al,
787                                   struct perf_sample *sample)
788 {
789         u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
790         struct thread *thread = machine__findnew_thread(machine, sample->pid,
791                                                         sample->pid);
792
793         if (thread == NULL)
794                 return -1;
795
796         dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
797         /*
798          * Have we already created the kernel maps for this machine?
799          *
800          * This should have happened earlier, when we processed the kernel MMAP
801          * events, but for older perf.data files there was no such thing, so do
802          * it now.
803          */
804         if (cpumode == PERF_RECORD_MISC_KERNEL &&
805             machine->vmlinux_maps[MAP__FUNCTION] == NULL)
806                 machine__create_kernel_maps(machine);
807
808         thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
809                               sample->ip, al);
810         dump_printf(" ...... dso: %s\n",
811                     al->map ? al->map->dso->long_name :
812                         al->level == 'H' ? "[hypervisor]" : "<not found>");
813
814         if (thread__is_filtered(thread))
815                 al->filtered |= (1 << HIST_FILTER__THREAD);
816
817         al->sym = NULL;
818         al->cpu = sample->cpu;
819
820         if (al->map) {
821                 struct dso *dso = al->map->dso;
822
823                 if (symbol_conf.dso_list &&
824                     (!dso || !(strlist__has_entry(symbol_conf.dso_list,
825                                                   dso->short_name) ||
826                                (dso->short_name != dso->long_name &&
827                                 strlist__has_entry(symbol_conf.dso_list,
828                                                    dso->long_name))))) {
829                         al->filtered |= (1 << HIST_FILTER__DSO);
830                 }
831
832                 al->sym = map__find_symbol(al->map, al->addr,
833                                            machine->symbol_filter);
834         }
835
836         if (symbol_conf.sym_list &&
837                 (!al->sym || !strlist__has_entry(symbol_conf.sym_list,
838                                                 al->sym->name))) {
839                 al->filtered |= (1 << HIST_FILTER__SYMBOL);
840         }
841
842         return 0;
843 }