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