Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / tools / perf / util / map.c
1 #include "symbol.h"
2 #include <errno.h>
3 #include <inttypes.h>
4 #include <limits.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include "map.h"
10
11 const char *map_type__name[MAP__NR_TYPES] = {
12         [MAP__FUNCTION] = "Functions",
13         [MAP__VARIABLE] = "Variables",
14 };
15
16 static inline int is_anon_memory(const char *filename)
17 {
18         return strcmp(filename, "//anon") == 0;
19 }
20
21 void map__init(struct map *self, enum map_type type,
22                u64 start, u64 end, u64 pgoff, struct dso *dso)
23 {
24         self->type     = type;
25         self->start    = start;
26         self->end      = end;
27         self->pgoff    = pgoff;
28         self->dso      = dso;
29         self->map_ip   = map__map_ip;
30         self->unmap_ip = map__unmap_ip;
31         RB_CLEAR_NODE(&self->rb_node);
32         self->groups   = NULL;
33         self->referenced = false;
34 }
35
36 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
37                      u64 pgoff, u32 pid, char *filename,
38                      enum map_type type)
39 {
40         struct map *self = malloc(sizeof(*self));
41
42         if (self != NULL) {
43                 char newfilename[PATH_MAX];
44                 struct dso *dso;
45                 int anon;
46
47                 anon = is_anon_memory(filename);
48
49                 if (anon) {
50                         snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
51                         filename = newfilename;
52                 }
53
54                 dso = __dsos__findnew(dsos__list, filename);
55                 if (dso == NULL)
56                         goto out_delete;
57
58                 map__init(self, type, start, start + len, pgoff, dso);
59
60                 if (anon) {
61 set_identity:
62                         self->map_ip = self->unmap_ip = identity__map_ip;
63                 } else if (strcmp(filename, "[vdso]") == 0) {
64                         dso__set_loaded(dso, self->type);
65                         goto set_identity;
66                 }
67         }
68         return self;
69 out_delete:
70         free(self);
71         return NULL;
72 }
73
74 void map__delete(struct map *self)
75 {
76         free(self);
77 }
78
79 void map__fixup_start(struct map *self)
80 {
81         struct rb_root *symbols = &self->dso->symbols[self->type];
82         struct rb_node *nd = rb_first(symbols);
83         if (nd != NULL) {
84                 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
85                 self->start = sym->start;
86         }
87 }
88
89 void map__fixup_end(struct map *self)
90 {
91         struct rb_root *symbols = &self->dso->symbols[self->type];
92         struct rb_node *nd = rb_last(symbols);
93         if (nd != NULL) {
94                 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
95                 self->end = sym->end;
96         }
97 }
98
99 #define DSO__DELETED "(deleted)"
100
101 int map__load(struct map *self, symbol_filter_t filter)
102 {
103         const char *name = self->dso->long_name;
104         int nr;
105
106         if (dso__loaded(self->dso, self->type))
107                 return 0;
108
109         nr = dso__load(self->dso, self, filter);
110         if (nr < 0) {
111                 if (self->dso->has_build_id) {
112                         char sbuild_id[BUILD_ID_SIZE * 2 + 1];
113
114                         build_id__sprintf(self->dso->build_id,
115                                           sizeof(self->dso->build_id),
116                                           sbuild_id);
117                         pr_warning("%s with build id %s not found",
118                                    name, sbuild_id);
119                 } else
120                         pr_warning("Failed to open %s", name);
121
122                 pr_warning(", continuing without symbols\n");
123                 return -1;
124         } else if (nr == 0) {
125                 const size_t len = strlen(name);
126                 const size_t real_len = len - sizeof(DSO__DELETED);
127
128                 if (len > sizeof(DSO__DELETED) &&
129                     strcmp(name + real_len + 1, DSO__DELETED) == 0) {
130                         pr_warning("%.*s was updated, restart the long "
131                                    "running apps that use it!\n",
132                                    (int)real_len, name);
133                 } else {
134                         pr_warning("no symbols found in %s, maybe install "
135                                    "a debug package?\n", name);
136                 }
137
138                 return -1;
139         }
140         /*
141          * Only applies to the kernel, as its symtabs aren't relative like the
142          * module ones.
143          */
144         if (self->dso->kernel)
145                 map__reloc_vmlinux(self);
146
147         return 0;
148 }
149
150 struct symbol *map__find_symbol(struct map *self, u64 addr,
151                                 symbol_filter_t filter)
152 {
153         if (map__load(self, filter) < 0)
154                 return NULL;
155
156         return dso__find_symbol(self->dso, self->type, addr);
157 }
158
159 struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
160                                         symbol_filter_t filter)
161 {
162         if (map__load(self, filter) < 0)
163                 return NULL;
164
165         if (!dso__sorted_by_name(self->dso, self->type))
166                 dso__sort_by_name(self->dso, self->type);
167
168         return dso__find_symbol_by_name(self->dso, self->type, name);
169 }
170
171 struct map *map__clone(struct map *self)
172 {
173         struct map *map = malloc(sizeof(*self));
174
175         if (!map)
176                 return NULL;
177
178         memcpy(map, self, sizeof(*self));
179
180         return map;
181 }
182
183 int map__overlap(struct map *l, struct map *r)
184 {
185         if (l->start > r->start) {
186                 struct map *t = l;
187                 l = r;
188                 r = t;
189         }
190
191         if (l->end > r->start)
192                 return 1;
193
194         return 0;
195 }
196
197 size_t map__fprintf(struct map *self, FILE *fp)
198 {
199         return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
200                        self->start, self->end, self->pgoff, self->dso->name);
201 }
202
203 /*
204  * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
205  * map->dso->adjust_symbols==1 for ET_EXEC-like cases.
206  */
207 u64 map__rip_2objdump(struct map *map, u64 rip)
208 {
209         u64 addr = map->dso->adjust_symbols ?
210                         map->unmap_ip(map, rip) :       /* RIP -> IP */
211                         rip;
212         return addr;
213 }
214
215 u64 map__objdump_2ip(struct map *map, u64 addr)
216 {
217         u64 ip = map->dso->adjust_symbols ?
218                         addr :
219                         map->unmap_ip(map, addr);       /* RIP -> IP */
220         return ip;
221 }
222
223 void map_groups__init(struct map_groups *self)
224 {
225         int i;
226         for (i = 0; i < MAP__NR_TYPES; ++i) {
227                 self->maps[i] = RB_ROOT;
228                 INIT_LIST_HEAD(&self->removed_maps[i]);
229         }
230         self->machine = NULL;
231 }
232
233 static void maps__delete(struct rb_root *self)
234 {
235         struct rb_node *next = rb_first(self);
236
237         while (next) {
238                 struct map *pos = rb_entry(next, struct map, rb_node);
239
240                 next = rb_next(&pos->rb_node);
241                 rb_erase(&pos->rb_node, self);
242                 map__delete(pos);
243         }
244 }
245
246 static void maps__delete_removed(struct list_head *self)
247 {
248         struct map *pos, *n;
249
250         list_for_each_entry_safe(pos, n, self, node) {
251                 list_del(&pos->node);
252                 map__delete(pos);
253         }
254 }
255
256 void map_groups__exit(struct map_groups *self)
257 {
258         int i;
259
260         for (i = 0; i < MAP__NR_TYPES; ++i) {
261                 maps__delete(&self->maps[i]);
262                 maps__delete_removed(&self->removed_maps[i]);
263         }
264 }
265
266 void map_groups__flush(struct map_groups *self)
267 {
268         int type;
269
270         for (type = 0; type < MAP__NR_TYPES; type++) {
271                 struct rb_root *root = &self->maps[type];
272                 struct rb_node *next = rb_first(root);
273
274                 while (next) {
275                         struct map *pos = rb_entry(next, struct map, rb_node);
276                         next = rb_next(&pos->rb_node);
277                         rb_erase(&pos->rb_node, root);
278                         /*
279                          * We may have references to this map, for
280                          * instance in some hist_entry instances, so
281                          * just move them to a separate list.
282                          */
283                         list_add_tail(&pos->node, &self->removed_maps[pos->type]);
284                 }
285         }
286 }
287
288 struct symbol *map_groups__find_symbol(struct map_groups *self,
289                                        enum map_type type, u64 addr,
290                                        struct map **mapp,
291                                        symbol_filter_t filter)
292 {
293         struct map *map = map_groups__find(self, type, addr);
294
295         if (map != NULL) {
296                 if (mapp != NULL)
297                         *mapp = map;
298                 return map__find_symbol(map, map->map_ip(map, addr), filter);
299         }
300
301         return NULL;
302 }
303
304 struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
305                                                enum map_type type,
306                                                const char *name,
307                                                struct map **mapp,
308                                                symbol_filter_t filter)
309 {
310         struct rb_node *nd;
311
312         for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
313                 struct map *pos = rb_entry(nd, struct map, rb_node);
314                 struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
315
316                 if (sym == NULL)
317                         continue;
318                 if (mapp != NULL)
319                         *mapp = pos;
320                 return sym;
321         }
322
323         return NULL;
324 }
325
326 size_t __map_groups__fprintf_maps(struct map_groups *self,
327                                   enum map_type type, int verbose, FILE *fp)
328 {
329         size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
330         struct rb_node *nd;
331
332         for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
333                 struct map *pos = rb_entry(nd, struct map, rb_node);
334                 printed += fprintf(fp, "Map:");
335                 printed += map__fprintf(pos, fp);
336                 if (verbose > 2) {
337                         printed += dso__fprintf(pos->dso, type, fp);
338                         printed += fprintf(fp, "--\n");
339                 }
340         }
341
342         return printed;
343 }
344
345 size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp)
346 {
347         size_t printed = 0, i;
348         for (i = 0; i < MAP__NR_TYPES; ++i)
349                 printed += __map_groups__fprintf_maps(self, i, verbose, fp);
350         return printed;
351 }
352
353 static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
354                                                  enum map_type type,
355                                                  int verbose, FILE *fp)
356 {
357         struct map *pos;
358         size_t printed = 0;
359
360         list_for_each_entry(pos, &self->removed_maps[type], node) {
361                 printed += fprintf(fp, "Map:");
362                 printed += map__fprintf(pos, fp);
363                 if (verbose > 1) {
364                         printed += dso__fprintf(pos->dso, type, fp);
365                         printed += fprintf(fp, "--\n");
366                 }
367         }
368         return printed;
369 }
370
371 static size_t map_groups__fprintf_removed_maps(struct map_groups *self,
372                                                int verbose, FILE *fp)
373 {
374         size_t printed = 0, i;
375         for (i = 0; i < MAP__NR_TYPES; ++i)
376                 printed += __map_groups__fprintf_removed_maps(self, i, verbose, fp);
377         return printed;
378 }
379
380 size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp)
381 {
382         size_t printed = map_groups__fprintf_maps(self, verbose, fp);
383         printed += fprintf(fp, "Removed maps:\n");
384         return printed + map_groups__fprintf_removed_maps(self, verbose, fp);
385 }
386
387 int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
388                                    int verbose, FILE *fp)
389 {
390         struct rb_root *root = &self->maps[map->type];
391         struct rb_node *next = rb_first(root);
392         int err = 0;
393
394         while (next) {
395                 struct map *pos = rb_entry(next, struct map, rb_node);
396                 next = rb_next(&pos->rb_node);
397
398                 if (!map__overlap(pos, map))
399                         continue;
400
401                 if (verbose >= 2) {
402                         fputs("overlapping maps:\n", fp);
403                         map__fprintf(map, fp);
404                         map__fprintf(pos, fp);
405                 }
406
407                 rb_erase(&pos->rb_node, root);
408                 /*
409                  * Now check if we need to create new maps for areas not
410                  * overlapped by the new map:
411                  */
412                 if (map->start > pos->start) {
413                         struct map *before = map__clone(pos);
414
415                         if (before == NULL) {
416                                 err = -ENOMEM;
417                                 goto move_map;
418                         }
419
420                         before->end = map->start - 1;
421                         map_groups__insert(self, before);
422                         if (verbose >= 2)
423                                 map__fprintf(before, fp);
424                 }
425
426                 if (map->end < pos->end) {
427                         struct map *after = map__clone(pos);
428
429                         if (after == NULL) {
430                                 err = -ENOMEM;
431                                 goto move_map;
432                         }
433
434                         after->start = map->end + 1;
435                         map_groups__insert(self, after);
436                         if (verbose >= 2)
437                                 map__fprintf(after, fp);
438                 }
439 move_map:
440                 /*
441                  * If we have references, just move them to a separate list.
442                  */
443                 if (pos->referenced)
444                         list_add_tail(&pos->node, &self->removed_maps[map->type]);
445                 else
446                         map__delete(pos);
447
448                 if (err)
449                         return err;
450         }
451
452         return 0;
453 }
454
455 /*
456  * XXX This should not really _copy_ te maps, but refcount them.
457  */
458 int map_groups__clone(struct map_groups *self,
459                       struct map_groups *parent, enum map_type type)
460 {
461         struct rb_node *nd;
462         for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
463                 struct map *map = rb_entry(nd, struct map, rb_node);
464                 struct map *new = map__clone(map);
465                 if (new == NULL)
466                         return -ENOMEM;
467                 map_groups__insert(self, new);
468         }
469         return 0;
470 }
471
472 static u64 map__reloc_map_ip(struct map *map, u64 ip)
473 {
474         return ip + (s64)map->pgoff;
475 }
476
477 static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
478 {
479         return ip - (s64)map->pgoff;
480 }
481
482 void map__reloc_vmlinux(struct map *self)
483 {
484         struct kmap *kmap = map__kmap(self);
485         s64 reloc;
486
487         if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
488                 return;
489
490         reloc = (kmap->ref_reloc_sym->unrelocated_addr -
491                  kmap->ref_reloc_sym->addr);
492
493         if (!reloc)
494                 return;
495
496         self->map_ip   = map__reloc_map_ip;
497         self->unmap_ip = map__reloc_unmap_ip;
498         self->pgoff    = reloc;
499 }
500
501 void maps__insert(struct rb_root *maps, struct map *map)
502 {
503         struct rb_node **p = &maps->rb_node;
504         struct rb_node *parent = NULL;
505         const u64 ip = map->start;
506         struct map *m;
507
508         while (*p != NULL) {
509                 parent = *p;
510                 m = rb_entry(parent, struct map, rb_node);
511                 if (ip < m->start)
512                         p = &(*p)->rb_left;
513                 else
514                         p = &(*p)->rb_right;
515         }
516
517         rb_link_node(&map->rb_node, parent, p);
518         rb_insert_color(&map->rb_node, maps);
519 }
520
521 void maps__remove(struct rb_root *self, struct map *map)
522 {
523         rb_erase(&map->rb_node, self);
524 }
525
526 struct map *maps__find(struct rb_root *maps, u64 ip)
527 {
528         struct rb_node **p = &maps->rb_node;
529         struct rb_node *parent = NULL;
530         struct map *m;
531
532         while (*p != NULL) {
533                 parent = *p;
534                 m = rb_entry(parent, struct map, rb_node);
535                 if (ip < m->start)
536                         p = &(*p)->rb_left;
537                 else if (ip > m->end)
538                         p = &(*p)->rb_right;
539                 else
540                         return m;
541         }
542
543         return NULL;
544 }
545
546 int machine__init(struct machine *self, const char *root_dir, pid_t pid)
547 {
548         map_groups__init(&self->kmaps);
549         RB_CLEAR_NODE(&self->rb_node);
550         INIT_LIST_HEAD(&self->user_dsos);
551         INIT_LIST_HEAD(&self->kernel_dsos);
552
553         self->kmaps.machine = self;
554         self->pid           = pid;
555         self->root_dir      = strdup(root_dir);
556         return self->root_dir == NULL ? -ENOMEM : 0;
557 }
558
559 static void dsos__delete(struct list_head *self)
560 {
561         struct dso *pos, *n;
562
563         list_for_each_entry_safe(pos, n, self, node) {
564                 list_del(&pos->node);
565                 dso__delete(pos);
566         }
567 }
568
569 void machine__exit(struct machine *self)
570 {
571         map_groups__exit(&self->kmaps);
572         dsos__delete(&self->user_dsos);
573         dsos__delete(&self->kernel_dsos);
574         free(self->root_dir);
575         self->root_dir = NULL;
576 }
577
578 void machine__delete(struct machine *self)
579 {
580         machine__exit(self);
581         free(self);
582 }
583
584 struct machine *machines__add(struct rb_root *self, pid_t pid,
585                               const char *root_dir)
586 {
587         struct rb_node **p = &self->rb_node;
588         struct rb_node *parent = NULL;
589         struct machine *pos, *machine = malloc(sizeof(*machine));
590
591         if (!machine)
592                 return NULL;
593
594         if (machine__init(machine, root_dir, pid) != 0) {
595                 free(machine);
596                 return NULL;
597         }
598
599         while (*p != NULL) {
600                 parent = *p;
601                 pos = rb_entry(parent, struct machine, rb_node);
602                 if (pid < pos->pid)
603                         p = &(*p)->rb_left;
604                 else
605                         p = &(*p)->rb_right;
606         }
607
608         rb_link_node(&machine->rb_node, parent, p);
609         rb_insert_color(&machine->rb_node, self);
610
611         return machine;
612 }
613
614 struct machine *machines__find(struct rb_root *self, pid_t pid)
615 {
616         struct rb_node **p = &self->rb_node;
617         struct rb_node *parent = NULL;
618         struct machine *machine;
619         struct machine *default_machine = NULL;
620
621         while (*p != NULL) {
622                 parent = *p;
623                 machine = rb_entry(parent, struct machine, rb_node);
624                 if (pid < machine->pid)
625                         p = &(*p)->rb_left;
626                 else if (pid > machine->pid)
627                         p = &(*p)->rb_right;
628                 else
629                         return machine;
630                 if (!machine->pid)
631                         default_machine = machine;
632         }
633
634         return default_machine;
635 }
636
637 struct machine *machines__findnew(struct rb_root *self, pid_t pid)
638 {
639         char path[PATH_MAX];
640         const char *root_dir;
641         struct machine *machine = machines__find(self, pid);
642
643         if (!machine || machine->pid != pid) {
644                 if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID)
645                         root_dir = "";
646                 else {
647                         if (!symbol_conf.guestmount)
648                                 goto out;
649                         sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
650                         if (access(path, R_OK)) {
651                                 pr_err("Can't access file %s\n", path);
652                                 goto out;
653                         }
654                         root_dir = path;
655                 }
656                 machine = machines__add(self, pid, root_dir);
657         }
658
659 out:
660         return machine;
661 }
662
663 void machines__process(struct rb_root *self, machine__process_t process, void *data)
664 {
665         struct rb_node *nd;
666
667         for (nd = rb_first(self); nd; nd = rb_next(nd)) {
668                 struct machine *pos = rb_entry(nd, struct machine, rb_node);
669                 process(pos, data);
670         }
671 }
672
673 char *machine__mmap_name(struct machine *self, char *bf, size_t size)
674 {
675         if (machine__is_host(self))
676                 snprintf(bf, size, "[%s]", "kernel.kallsyms");
677         else if (machine__is_default_guest(self))
678                 snprintf(bf, size, "[%s]", "guest.kernel.kallsyms");
679         else
680                 snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid);
681
682         return bf;
683 }