Home | History | Annotate | Download | only in util
      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 #include <linux/string.h>
     15 
     16 const char *map_type__name[MAP__NR_TYPES] = {
     17 	[MAP__FUNCTION] = "Functions",
     18 	[MAP__VARIABLE] = "Variables",
     19 };
     20 
     21 static inline int is_anon_memory(const char *filename)
     22 {
     23 	return !strcmp(filename, "//anon") ||
     24 	       !strcmp(filename, "/dev/zero (deleted)") ||
     25 	       !strcmp(filename, "/anon_hugepage (deleted)");
     26 }
     27 
     28 static inline int is_no_dso_memory(const char *filename)
     29 {
     30 	return !strncmp(filename, "[stack", 6) ||
     31 	       !strcmp(filename, "[heap]");
     32 }
     33 
     34 void map__init(struct map *map, enum map_type type,
     35 	       u64 start, u64 end, u64 pgoff, struct dso *dso)
     36 {
     37 	map->type     = type;
     38 	map->start    = start;
     39 	map->end      = end;
     40 	map->pgoff    = pgoff;
     41 	map->dso      = dso;
     42 	map->map_ip   = map__map_ip;
     43 	map->unmap_ip = map__unmap_ip;
     44 	RB_CLEAR_NODE(&map->rb_node);
     45 	map->groups   = NULL;
     46 	map->referenced = false;
     47 	map->erange_warned = false;
     48 }
     49 
     50 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
     51 		     u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino,
     52 		     u64 ino_gen, char *filename,
     53 		     enum map_type type)
     54 {
     55 	struct map *map = malloc(sizeof(*map));
     56 
     57 	if (map != NULL) {
     58 		char newfilename[PATH_MAX];
     59 		struct dso *dso;
     60 		int anon, no_dso, vdso;
     61 
     62 		anon = is_anon_memory(filename);
     63 		vdso = is_vdso_map(filename);
     64 		no_dso = is_no_dso_memory(filename);
     65 
     66 		map->maj = d_maj;
     67 		map->min = d_min;
     68 		map->ino = ino;
     69 		map->ino_generation = ino_gen;
     70 
     71 		if (anon) {
     72 			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
     73 			filename = newfilename;
     74 		}
     75 
     76 		if (vdso) {
     77 			pgoff = 0;
     78 			dso = vdso__dso_findnew(dsos__list);
     79 		} else
     80 			dso = __dsos__findnew(dsos__list, filename);
     81 
     82 		if (dso == NULL)
     83 			goto out_delete;
     84 
     85 		map__init(map, type, start, start + len, pgoff, dso);
     86 
     87 		if (anon || no_dso) {
     88 			map->map_ip = map->unmap_ip = identity__map_ip;
     89 
     90 			/*
     91 			 * Set memory without DSO as loaded. All map__find_*
     92 			 * functions still return NULL, and we avoid the
     93 			 * unnecessary map__load warning.
     94 			 */
     95 			if (no_dso)
     96 				dso__set_loaded(dso, map->type);
     97 		}
     98 	}
     99 	return map;
    100 out_delete:
    101 	free(map);
    102 	return NULL;
    103 }
    104 
    105 /*
    106  * Constructor variant for modules (where we know from /proc/modules where
    107  * they are loaded) and for vmlinux, where only after we load all the
    108  * symbols we'll know where it starts and ends.
    109  */
    110 struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
    111 {
    112 	struct map *map = calloc(1, (sizeof(*map) +
    113 				     (dso->kernel ? sizeof(struct kmap) : 0)));
    114 	if (map != NULL) {
    115 		/*
    116 		 * ->end will be filled after we load all the symbols
    117 		 */
    118 		map__init(map, type, start, 0, 0, dso);
    119 	}
    120 
    121 	return map;
    122 }
    123 
    124 void map__delete(struct map *map)
    125 {
    126 	free(map);
    127 }
    128 
    129 void map__fixup_start(struct map *map)
    130 {
    131 	struct rb_root *symbols = &map->dso->symbols[map->type];
    132 	struct rb_node *nd = rb_first(symbols);
    133 	if (nd != NULL) {
    134 		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
    135 		map->start = sym->start;
    136 	}
    137 }
    138 
    139 void map__fixup_end(struct map *map)
    140 {
    141 	struct rb_root *symbols = &map->dso->symbols[map->type];
    142 	struct rb_node *nd = rb_last(symbols);
    143 	if (nd != NULL) {
    144 		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
    145 		map->end = sym->end;
    146 	}
    147 }
    148 
    149 #define DSO__DELETED "(deleted)"
    150 
    151 int map__load(struct map *map, symbol_filter_t filter)
    152 {
    153 	const char *name = map->dso->long_name;
    154 	int nr;
    155 
    156 	if (dso__loaded(map->dso, map->type))
    157 		return 0;
    158 
    159 	nr = dso__load(map->dso, map, filter);
    160 	if (nr < 0) {
    161 		if (map->dso->has_build_id) {
    162 			char sbuild_id[BUILD_ID_SIZE * 2 + 1];
    163 
    164 			build_id__sprintf(map->dso->build_id,
    165 					  sizeof(map->dso->build_id),
    166 					  sbuild_id);
    167 			pr_warning("%s with build id %s not found",
    168 				   name, sbuild_id);
    169 		} else
    170 			pr_warning("Failed to open %s", name);
    171 
    172 		pr_warning(", continuing without symbols\n");
    173 		return -1;
    174 	} else if (nr == 0) {
    175 #ifdef LIBELF_SUPPORT
    176 		const size_t len = strlen(name);
    177 		const size_t real_len = len - sizeof(DSO__DELETED);
    178 
    179 		if (len > sizeof(DSO__DELETED) &&
    180 		    strcmp(name + real_len + 1, DSO__DELETED) == 0) {
    181 			pr_warning("%.*s was updated (is prelink enabled?). "
    182 				"Restart the long running apps that use it!\n",
    183 				   (int)real_len, name);
    184 		} else {
    185 			pr_warning("no symbols found in %s, maybe install "
    186 				   "a debug package?\n", name);
    187 		}
    188 #endif
    189 		return -1;
    190 	}
    191 
    192 	return 0;
    193 }
    194 
    195 struct symbol *map__find_symbol(struct map *map, u64 addr,
    196 				symbol_filter_t filter)
    197 {
    198 	if (map__load(map, filter) < 0)
    199 		return NULL;
    200 
    201 	return dso__find_symbol(map->dso, map->type, addr);
    202 }
    203 
    204 struct symbol *map__find_symbol_by_name(struct map *map, const char *name,
    205 					symbol_filter_t filter)
    206 {
    207 	if (map__load(map, filter) < 0)
    208 		return NULL;
    209 
    210 	if (!dso__sorted_by_name(map->dso, map->type))
    211 		dso__sort_by_name(map->dso, map->type);
    212 
    213 	return dso__find_symbol_by_name(map->dso, map->type, name);
    214 }
    215 
    216 struct map *map__clone(struct map *map)
    217 {
    218 	return memdup(map, sizeof(*map));
    219 }
    220 
    221 int map__overlap(struct map *l, struct map *r)
    222 {
    223 	if (l->start > r->start) {
    224 		struct map *t = l;
    225 		l = r;
    226 		r = t;
    227 	}
    228 
    229 	if (l->end > r->start)
    230 		return 1;
    231 
    232 	return 0;
    233 }
    234 
    235 size_t map__fprintf(struct map *map, FILE *fp)
    236 {
    237 	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
    238 		       map->start, map->end, map->pgoff, map->dso->name);
    239 }
    240 
    241 size_t map__fprintf_dsoname(struct map *map, FILE *fp)
    242 {
    243 	const char *dsoname = "[unknown]";
    244 
    245 	if (map && map->dso && (map->dso->name || map->dso->long_name)) {
    246 		if (symbol_conf.show_kernel_path && map->dso->long_name)
    247 			dsoname = map->dso->long_name;
    248 		else if (map->dso->name)
    249 			dsoname = map->dso->name;
    250 	}
    251 
    252 	return fprintf(fp, "%s", dsoname);
    253 }
    254 
    255 /*
    256  * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
    257  * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
    258  * relative to section start.
    259  */
    260 u64 map__rip_2objdump(struct map *map, u64 rip)
    261 {
    262 	if (!map->dso->adjust_symbols)
    263 		return rip;
    264 
    265 	if (map->dso->rel)
    266 		return rip - map->pgoff;
    267 
    268 	return map->unmap_ip(map, rip);
    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 void maps__insert(struct rb_root *maps, struct map *map)
    521 {
    522 	struct rb_node **p = &maps->rb_node;
    523 	struct rb_node *parent = NULL;
    524 	const u64 ip = map->start;
    525 	struct map *m;
    526 
    527 	while (*p != NULL) {
    528 		parent = *p;
    529 		m = rb_entry(parent, struct map, rb_node);
    530 		if (ip < m->start)
    531 			p = &(*p)->rb_left;
    532 		else
    533 			p = &(*p)->rb_right;
    534 	}
    535 
    536 	rb_link_node(&map->rb_node, parent, p);
    537 	rb_insert_color(&map->rb_node, maps);
    538 }
    539 
    540 void maps__remove(struct rb_root *maps, struct map *map)
    541 {
    542 	rb_erase(&map->rb_node, maps);
    543 }
    544 
    545 struct map *maps__find(struct rb_root *maps, u64 ip)
    546 {
    547 	struct rb_node **p = &maps->rb_node;
    548 	struct rb_node *parent = NULL;
    549 	struct map *m;
    550 
    551 	while (*p != NULL) {
    552 		parent = *p;
    553 		m = rb_entry(parent, struct map, rb_node);
    554 		if (ip < m->start)
    555 			p = &(*p)->rb_left;
    556 		else if (ip > m->end)
    557 			p = &(*p)->rb_right;
    558 		else
    559 			return m;
    560 	}
    561 
    562 	return NULL;
    563 }
    564 
    565 struct map *maps__first(struct rb_root *maps)
    566 {
    567 	struct rb_node *first = rb_first(maps);
    568 
    569 	if (first)
    570 		return rb_entry(first, struct map, rb_node);
    571 	return NULL;
    572 }
    573 
    574 struct map *maps__next(struct map *map)
    575 {
    576 	struct rb_node *next = rb_next(&map->rb_node);
    577 
    578 	if (next)
    579 		return rb_entry(next, struct map, rb_node);
    580 	return NULL;
    581 }
    582