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