map.c 15.6 KB
Newer Older
1
#include "symbol.h"
2
#include <errno.h>
3
#include <inttypes.h>
4
#include <limits.h>
5 6 7
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
8
#include <unistd.h>
9
#include "map.h"
10

11 12 13 14 15
const char *map_type__name[MAP__NR_TYPES] = {
	[MAP__FUNCTION] = "Functions",
	[MAP__VARIABLE] = "Variables",
};

16 17 18 19 20
static inline int is_anon_memory(const char *filename)
{
	return strcmp(filename, "//anon") == 0;
}

21 22 23 24 25 26 27
static inline int is_no_dso_memory(const char *filename)
{
	return !strcmp(filename, "[stack]") ||
	       !strcmp(filename, "[vdso]")  ||
	       !strcmp(filename, "[heap]");
}

28 29
void map__init(struct map *self, enum map_type type,
	       u64 start, u64 end, u64 pgoff, struct dso *dso)
30
{
31
	self->type     = type;
32 33 34 35 36 37 38
	self->start    = start;
	self->end      = end;
	self->pgoff    = pgoff;
	self->dso      = dso;
	self->map_ip   = map__map_ip;
	self->unmap_ip = map__unmap_ip;
	RB_CLEAR_NODE(&self->rb_node);
39
	self->groups   = NULL;
40
	self->referenced = false;
41 42
}

43 44
struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
		     u64 pgoff, u32 pid, char *filename,
45
		     enum map_type type)
46 47 48 49 50
{
	struct map *self = malloc(sizeof(*self));

	if (self != NULL) {
		char newfilename[PATH_MAX];
51
		struct dso *dso;
52
		int anon, no_dso;
53 54

		anon = is_anon_memory(filename);
55
		no_dso = is_no_dso_memory(filename);
56 57

		if (anon) {
58
			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
59 60 61
			filename = newfilename;
		}

62
		dso = __dsos__findnew(dsos__list, filename);
63
		if (dso == NULL)
64 65
			goto out_delete;

66
		map__init(self, type, start, start + len, pgoff, dso);
67

68
		if (anon || no_dso) {
69
			self->map_ip = self->unmap_ip = identity__map_ip;
70 71 72 73 74 75 76 77

			/*
			 * Set memory without DSO as loaded. All map__find_*
			 * functions still return NULL, and we avoid the
			 * unnecessary map__load warning.
			 */
			if (no_dso)
				dso__set_loaded(dso, self->type);
78
		}
79 80 81 82 83 84 85
	}
	return self;
out_delete:
	free(self);
	return NULL;
}

86 87 88 89 90
void map__delete(struct map *self)
{
	free(self);
}

91
void map__fixup_start(struct map *self)
92
{
93
	struct rb_root *symbols = &self->dso->symbols[self->type];
94
	struct rb_node *nd = rb_first(symbols);
95 96 97 98 99 100
	if (nd != NULL) {
		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
		self->start = sym->start;
	}
}

101
void map__fixup_end(struct map *self)
102
{
103
	struct rb_root *symbols = &self->dso->symbols[self->type];
104
	struct rb_node *nd = rb_last(symbols);
105 106 107 108 109 110
	if (nd != NULL) {
		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
		self->end = sym->end;
	}
}

111 112
#define DSO__DELETED "(deleted)"

113
int map__load(struct map *self, symbol_filter_t filter)
114
{
115
	const char *name = self->dso->long_name;
116
	int nr;
117

118 119 120
	if (dso__loaded(self->dso, self->type))
		return 0;

121
	nr = dso__load(self->dso, self, filter);
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
	if (nr < 0) {
		if (self->dso->has_build_id) {
			char sbuild_id[BUILD_ID_SIZE * 2 + 1];

			build_id__sprintf(self->dso->build_id,
					  sizeof(self->dso->build_id),
					  sbuild_id);
			pr_warning("%s with build id %s not found",
				   name, sbuild_id);
		} else
			pr_warning("Failed to open %s", name);

		pr_warning(", continuing without symbols\n");
		return -1;
	} else if (nr == 0) {
		const size_t len = strlen(name);
		const size_t real_len = len - sizeof(DSO__DELETED);

		if (len > sizeof(DSO__DELETED) &&
		    strcmp(name + real_len + 1, DSO__DELETED) == 0) {
142 143
			pr_warning("%.*s was updated (is prelink enabled?). "
				"Restart the long running apps that use it!\n",
144 145 146 147
				   (int)real_len, name);
		} else {
			pr_warning("no symbols found in %s, maybe install "
				   "a debug package?\n", name);
148
		}
149 150

		return -1;
151
	}
152 153 154 155 156 157
	/*
	 * Only applies to the kernel, as its symtabs aren't relative like the
	 * module ones.
	 */
	if (self->dso->kernel)
		map__reloc_vmlinux(self);
158

159 160 161
	return 0;
}

162 163
struct symbol *map__find_symbol(struct map *self, u64 addr,
				symbol_filter_t filter)
164
{
165
	if (map__load(self, filter) < 0)
166 167
		return NULL;

168
	return dso__find_symbol(self->dso, self->type, addr);
169 170
}

171 172 173
struct symbol *map__find_symbol_by_name(struct map *self, const char *name,
					symbol_filter_t filter)
{
174
	if (map__load(self, filter) < 0)
175 176 177 178 179 180 181 182
		return NULL;

	if (!dso__sorted_by_name(self->dso, self->type))
		dso__sort_by_name(self->dso, self->type);

	return dso__find_symbol_by_name(self->dso, self->type, name);
}

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
struct map *map__clone(struct map *self)
{
	struct map *map = malloc(sizeof(*self));

	if (!map)
		return NULL;

	memcpy(map, self, sizeof(*self));

	return map;
}

int map__overlap(struct map *l, struct map *r)
{
	if (l->start > r->start) {
		struct map *t = l;
		l = r;
		r = t;
	}

	if (l->end > r->start)
		return 1;

	return 0;
}

size_t map__fprintf(struct map *self, FILE *fp)
{
211
	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
212 213
		       self->start, self->end, self->pgoff, self->dso->name);
}
214

215 216 217 218
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
{
	const char *dsoname;

219 220 221 222 223 224
	if (map && map->dso && (map->dso->name || map->dso->long_name)) {
		if (symbol_conf.show_kernel_path && map->dso->long_name)
			dsoname = map->dso->long_name;
		else if (map->dso->name)
			dsoname = map->dso->name;
	} else
225 226 227 228 229
		dsoname = "[unknown]";

	return fprintf(fp, "%s", dsoname);
}

230 231 232 233 234 235 236 237 238 239 240
/*
 * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
 * map->dso->adjust_symbols==1 for ET_EXEC-like cases.
 */
u64 map__rip_2objdump(struct map *map, u64 rip)
{
	u64 addr = map->dso->adjust_symbols ?
			map->unmap_ip(map, rip) :	/* RIP -> IP */
			rip;
	return addr;
}
241 242 243 244 245 246 247 248

u64 map__objdump_2ip(struct map *map, u64 addr)
{
	u64 ip = map->dso->adjust_symbols ?
			addr :
			map->unmap_ip(map, addr);	/* RIP -> IP */
	return ip;
}
249

250
void map_groups__init(struct map_groups *mg)
251 252 253
{
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i) {
254 255
		mg->maps[i] = RB_ROOT;
		INIT_LIST_HEAD(&mg->removed_maps[i]);
256
	}
257
	mg->machine = NULL;
258 259
}

260
static void maps__delete(struct rb_root *maps)
261
{
262
	struct rb_node *next = rb_first(maps);
263 264 265 266 267

	while (next) {
		struct map *pos = rb_entry(next, struct map, rb_node);

		next = rb_next(&pos->rb_node);
268
		rb_erase(&pos->rb_node, maps);
269 270 271 272
		map__delete(pos);
	}
}

273
static void maps__delete_removed(struct list_head *maps)
274 275 276
{
	struct map *pos, *n;

277
	list_for_each_entry_safe(pos, n, maps, node) {
278 279 280 281 282
		list_del(&pos->node);
		map__delete(pos);
	}
}

283
void map_groups__exit(struct map_groups *mg)
284 285 286 287
{
	int i;

	for (i = 0; i < MAP__NR_TYPES; ++i) {
288 289
		maps__delete(&mg->maps[i]);
		maps__delete_removed(&mg->removed_maps[i]);
290 291 292
	}
}

293
void map_groups__flush(struct map_groups *mg)
294 295 296 297
{
	int type;

	for (type = 0; type < MAP__NR_TYPES; type++) {
298
		struct rb_root *root = &mg->maps[type];
299 300 301 302 303 304 305 306 307 308 309
		struct rb_node *next = rb_first(root);

		while (next) {
			struct map *pos = rb_entry(next, struct map, rb_node);
			next = rb_next(&pos->rb_node);
			rb_erase(&pos->rb_node, root);
			/*
			 * We may have references to this map, for
			 * instance in some hist_entry instances, so
			 * just move them to a separate list.
			 */
310
			list_add_tail(&pos->node, &mg->removed_maps[pos->type]);
311 312 313 314
		}
	}
}

315
struct symbol *map_groups__find_symbol(struct map_groups *mg,
316
				       enum map_type type, u64 addr,
317
				       struct map **mapp,
318 319
				       symbol_filter_t filter)
{
320
	struct map *map = map_groups__find(mg, type, addr);
321

322 323 324
	if (map != NULL) {
		if (mapp != NULL)
			*mapp = map;
325
		return map__find_symbol(map, map->map_ip(map, addr), filter);
326 327 328 329 330
	}

	return NULL;
}

331
struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
332 333 334 335 336 337 338
					       enum map_type type,
					       const char *name,
					       struct map **mapp,
					       symbol_filter_t filter)
{
	struct rb_node *nd;

339
	for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
340 341 342 343 344 345 346 347 348
		struct map *pos = rb_entry(nd, struct map, rb_node);
		struct symbol *sym = map__find_symbol_by_name(pos, name, filter);

		if (sym == NULL)
			continue;
		if (mapp != NULL)
			*mapp = pos;
		return sym;
	}
349 350 351 352

	return NULL;
}

353
size_t __map_groups__fprintf_maps(struct map_groups *mg,
354 355 356 357 358
				  enum map_type type, int verbose, FILE *fp)
{
	size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
	struct rb_node *nd;

359
	for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
360 361 362 363 364 365 366 367 368 369 370 371
		struct map *pos = rb_entry(nd, struct map, rb_node);
		printed += fprintf(fp, "Map:");
		printed += map__fprintf(pos, fp);
		if (verbose > 2) {
			printed += dso__fprintf(pos->dso, type, fp);
			printed += fprintf(fp, "--\n");
		}
	}

	return printed;
}

372
size_t map_groups__fprintf_maps(struct map_groups *mg, int verbose, FILE *fp)
373 374 375
{
	size_t printed = 0, i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
376
		printed += __map_groups__fprintf_maps(mg, i, verbose, fp);
377 378 379
	return printed;
}

380
static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
381 382 383 384 385 386
						 enum map_type type,
						 int verbose, FILE *fp)
{
	struct map *pos;
	size_t printed = 0;

387
	list_for_each_entry(pos, &mg->removed_maps[type], node) {
388 389 390 391 392 393 394 395 396 397
		printed += fprintf(fp, "Map:");
		printed += map__fprintf(pos, fp);
		if (verbose > 1) {
			printed += dso__fprintf(pos->dso, type, fp);
			printed += fprintf(fp, "--\n");
		}
	}
	return printed;
}

398
static size_t map_groups__fprintf_removed_maps(struct map_groups *mg,
399 400 401 402
					       int verbose, FILE *fp)
{
	size_t printed = 0, i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
403
		printed += __map_groups__fprintf_removed_maps(mg, i, verbose, fp);
404 405 406
	return printed;
}

407
size_t map_groups__fprintf(struct map_groups *mg, int verbose, FILE *fp)
408
{
409
	size_t printed = map_groups__fprintf_maps(mg, verbose, fp);
410
	printed += fprintf(fp, "Removed maps:\n");
411
	return printed + map_groups__fprintf_removed_maps(mg, verbose, fp);
412 413
}

414
int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
415 416
				   int verbose, FILE *fp)
{
417
	struct rb_root *root = &mg->maps[map->type];
418
	struct rb_node *next = rb_first(root);
419
	int err = 0;
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441

	while (next) {
		struct map *pos = rb_entry(next, struct map, rb_node);
		next = rb_next(&pos->rb_node);

		if (!map__overlap(pos, map))
			continue;

		if (verbose >= 2) {
			fputs("overlapping maps:\n", fp);
			map__fprintf(map, fp);
			map__fprintf(pos, fp);
		}

		rb_erase(&pos->rb_node, root);
		/*
		 * Now check if we need to create new maps for areas not
		 * overlapped by the new map:
		 */
		if (map->start > pos->start) {
			struct map *before = map__clone(pos);

442 443 444 445
			if (before == NULL) {
				err = -ENOMEM;
				goto move_map;
			}
446 447

			before->end = map->start - 1;
448
			map_groups__insert(mg, before);
449 450 451 452 453 454 455
			if (verbose >= 2)
				map__fprintf(before, fp);
		}

		if (map->end < pos->end) {
			struct map *after = map__clone(pos);

456 457 458 459
			if (after == NULL) {
				err = -ENOMEM;
				goto move_map;
			}
460 461

			after->start = map->end + 1;
462
			map_groups__insert(mg, after);
463 464 465
			if (verbose >= 2)
				map__fprintf(after, fp);
		}
466 467 468 469 470
move_map:
		/*
		 * If we have references, just move them to a separate list.
		 */
		if (pos->referenced)
471
			list_add_tail(&pos->node, &mg->removed_maps[map->type]);
472 473 474 475 476
		else
			map__delete(pos);

		if (err)
			return err;
477 478 479 480 481 482 483 484
	}

	return 0;
}

/*
 * XXX This should not really _copy_ te maps, but refcount them.
 */
485
int map_groups__clone(struct map_groups *mg,
486 487 488 489 490 491 492 493
		      struct map_groups *parent, enum map_type type)
{
	struct rb_node *nd;
	for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
		struct map *map = rb_entry(nd, struct map, rb_node);
		struct map *new = map__clone(map);
		if (new == NULL)
			return -ENOMEM;
494
		map_groups__insert(mg, new);
495 496 497 498
	}
	return 0;
}

499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
static u64 map__reloc_map_ip(struct map *map, u64 ip)
{
	return ip + (s64)map->pgoff;
}

static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
{
	return ip - (s64)map->pgoff;
}

void map__reloc_vmlinux(struct map *self)
{
	struct kmap *kmap = map__kmap(self);
	s64 reloc;

	if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
		return;

	reloc = (kmap->ref_reloc_sym->unrelocated_addr -
		 kmap->ref_reloc_sym->addr);

	if (!reloc)
		return;

	self->map_ip   = map__reloc_map_ip;
	self->unmap_ip = map__reloc_unmap_ip;
	self->pgoff    = reloc;
}

void maps__insert(struct rb_root *maps, struct map *map)
{
	struct rb_node **p = &maps->rb_node;
	struct rb_node *parent = NULL;
	const u64 ip = map->start;
	struct map *m;

	while (*p != NULL) {
		parent = *p;
		m = rb_entry(parent, struct map, rb_node);
		if (ip < m->start)
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}

	rb_link_node(&map->rb_node, parent, p);
	rb_insert_color(&map->rb_node, maps);
}

548 549 550 551 552
void maps__remove(struct rb_root *self, struct map *map)
{
	rb_erase(&map->rb_node, self);
}

553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
struct map *maps__find(struct rb_root *maps, u64 ip)
{
	struct rb_node **p = &maps->rb_node;
	struct rb_node *parent = NULL;
	struct map *m;

	while (*p != NULL) {
		parent = *p;
		m = rb_entry(parent, struct map, rb_node);
		if (ip < m->start)
			p = &(*p)->rb_left;
		else if (ip > m->end)
			p = &(*p)->rb_right;
		else
			return m;
	}

	return NULL;
}
572

573 574 575 576 577 578 579
int machine__init(struct machine *self, const char *root_dir, pid_t pid)
{
	map_groups__init(&self->kmaps);
	RB_CLEAR_NODE(&self->rb_node);
	INIT_LIST_HEAD(&self->user_dsos);
	INIT_LIST_HEAD(&self->kernel_dsos);

580 581 582 583
	self->threads = RB_ROOT;
	INIT_LIST_HEAD(&self->dead_threads);
	self->last_match = NULL;

584 585 586 587 588 589
	self->kmaps.machine = self;
	self->pid	    = pid;
	self->root_dir      = strdup(root_dir);
	return self->root_dir == NULL ? -ENOMEM : 0;
}

590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
static void dsos__delete(struct list_head *self)
{
	struct dso *pos, *n;

	list_for_each_entry_safe(pos, n, self, node) {
		list_del(&pos->node);
		dso__delete(pos);
	}
}

void machine__exit(struct machine *self)
{
	map_groups__exit(&self->kmaps);
	dsos__delete(&self->user_dsos);
	dsos__delete(&self->kernel_dsos);
	free(self->root_dir);
	self->root_dir = NULL;
}

609 610 611 612 613 614
void machine__delete(struct machine *self)
{
	machine__exit(self);
	free(self);
}

615 616
struct machine *machines__add(struct rb_root *self, pid_t pid,
			      const char *root_dir)
617
{
618
	struct rb_node **p = &self->rb_node;
619
	struct rb_node *parent = NULL;
620
	struct machine *pos, *machine = malloc(sizeof(*machine));
621

622
	if (!machine)
623 624
		return NULL;

625 626 627 628
	if (machine__init(machine, root_dir, pid) != 0) {
		free(machine);
		return NULL;
	}
629 630 631

	while (*p != NULL) {
		parent = *p;
632
		pos = rb_entry(parent, struct machine, rb_node);
633 634 635 636 637 638
		if (pid < pos->pid)
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}

639 640
	rb_link_node(&machine->rb_node, parent, p);
	rb_insert_color(&machine->rb_node, self);
641

642
	return machine;
643 644
}

645
struct machine *machines__find(struct rb_root *self, pid_t pid)
646
{
647
	struct rb_node **p = &self->rb_node;
648
	struct rb_node *parent = NULL;
649 650
	struct machine *machine;
	struct machine *default_machine = NULL;
651 652 653

	while (*p != NULL) {
		parent = *p;
654 655
		machine = rb_entry(parent, struct machine, rb_node);
		if (pid < machine->pid)
656
			p = &(*p)->rb_left;
657
		else if (pid > machine->pid)
658 659
			p = &(*p)->rb_right;
		else
660 661 662
			return machine;
		if (!machine->pid)
			default_machine = machine;
663 664
	}

665
	return default_machine;
666 667
}

668
struct machine *machines__findnew(struct rb_root *self, pid_t pid)
669 670 671
{
	char path[PATH_MAX];
	const char *root_dir;
672
	struct machine *machine = machines__find(self, pid);
673

674
	if (!machine || machine->pid != pid) {
675 676 677 678 679 680
		if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID)
			root_dir = "";
		else {
			if (!symbol_conf.guestmount)
				goto out;
			sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
681
			if (access(path, R_OK)) {
682 683 684 685 686
				pr_err("Can't access file %s\n", path);
				goto out;
			}
			root_dir = path;
		}
687
		machine = machines__add(self, pid, root_dir);
688 689 690
	}

out:
691
	return machine;
692 693
}

694
void machines__process(struct rb_root *self, machine__process_t process, void *data)
695 696 697
{
	struct rb_node *nd;

698 699
	for (nd = rb_first(self); nd; nd = rb_next(nd)) {
		struct machine *pos = rb_entry(nd, struct machine, rb_node);
700 701 702 703
		process(pos, data);
	}
}

704
char *machine__mmap_name(struct machine *self, char *bf, size_t size)
705
{
706
	if (machine__is_host(self))
707
		snprintf(bf, size, "[%s]", "kernel.kallsyms");
708
	else if (machine__is_default_guest(self))
709
		snprintf(bf, size, "[%s]", "guest.kernel.kallsyms");
710
	else
711
		snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid);
712

713
	return bf;
714
}