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