map.c 19.7 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 <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
10
#include "map.h"
11
#include "thread.h"
12
#include "vdso.h"
13
#include "build-id.h"
14
#include "util.h"
15
#include "debug.h"
16
#include "machine.h"
17
#include <linux/string.h>
18
#include "srcline.h"
19
#include "namespaces.h"
20
#include "unwind.h"
21

22 23
static void __maps__insert(struct maps *maps, struct map *map);

24 25 26 27 28
const char *map_type__name[MAP__NR_TYPES] = {
	[MAP__FUNCTION] = "Functions",
	[MAP__VARIABLE] = "Variables",
};

29
static inline int is_anon_memory(const char *filename, u32 flags)
30
{
31
	return flags & MAP_HUGETLB ||
32
	       !strcmp(filename, "//anon") ||
33 34
	       !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) ||
	       !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1);
35 36
}

37 38
static inline int is_no_dso_memory(const char *filename)
{
39
	return !strncmp(filename, "[stack", 6) ||
40
	       !strncmp(filename, "/SYSV",5)   ||
41 42 43
	       !strcmp(filename, "[heap]");
}

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
static inline int is_android_lib(const char *filename)
{
	return !strncmp(filename, "/data/app-lib", 13) ||
	       !strncmp(filename, "/system/lib", 11);
}

static inline bool replace_android_lib(const char *filename, char *newfilename)
{
	const char *libname;
	char *app_abi;
	size_t app_abi_length, new_length;
	size_t lib_length = 0;

	libname  = strrchr(filename, '/');
	if (libname)
		lib_length = strlen(libname);

	app_abi = getenv("APP_ABI");
	if (!app_abi)
		return false;

	app_abi_length = strlen(app_abi);

	if (!strncmp(filename, "/data/app-lib", 13)) {
		char *apk_path;

		if (!app_abi_length)
			return false;

		new_length = 7 + app_abi_length + lib_length;

		apk_path = getenv("APK_PATH");
		if (apk_path) {
			new_length += strlen(apk_path) + 1;
			if (new_length > PATH_MAX)
				return false;
			snprintf(newfilename, new_length,
				 "%s/libs/%s/%s", apk_path, app_abi, libname);
		} else {
			if (new_length > PATH_MAX)
				return false;
			snprintf(newfilename, new_length,
				 "libs/%s/%s", app_abi, libname);
		}
		return true;
	}

	if (!strncmp(filename, "/system/lib/", 11)) {
		char *ndk, *app;
		const char *arch;
		size_t ndk_length;
		size_t app_length;

		ndk = getenv("NDK_ROOT");
		app = getenv("APP_PLATFORM");

		if (!(ndk && app))
			return false;

		ndk_length = strlen(ndk);
		app_length = strlen(app);

		if (!(ndk_length && app_length && app_abi_length))
			return false;

		arch = !strncmp(app_abi, "arm", 3) ? "arm" :
		       !strncmp(app_abi, "mips", 4) ? "mips" :
		       !strncmp(app_abi, "x86", 3) ? "x86" : NULL;

		if (!arch)
			return false;

		new_length = 27 + ndk_length +
			     app_length + lib_length
			   + strlen(arch);

		if (new_length > PATH_MAX)
			return false;
		snprintf(newfilename, new_length,
			"%s/platforms/%s/arch-%s/usr/lib/%s",
			ndk, app, arch, libname);

		return true;
	}
	return false;
}

131
void map__init(struct map *map, enum map_type type,
132
	       u64 start, u64 end, u64 pgoff, struct dso *dso)
133
{
134 135 136 137
	map->type     = type;
	map->start    = start;
	map->end      = end;
	map->pgoff    = pgoff;
138
	map->reloc    = 0;
139
	map->dso      = dso__get(dso);
140 141 142 143 144
	map->map_ip   = map__map_ip;
	map->unmap_ip = map__unmap_ip;
	RB_CLEAR_NODE(&map->rb_node);
	map->groups   = NULL;
	map->erange_warned = false;
145
	refcount_set(&map->refcnt, 1);
146 147
}

148
struct map *map__new(struct machine *machine, u64 start, u64 len,
149
		     u64 pgoff, u32 d_maj, u32 d_min, u64 ino,
150
		     u64 ino_gen, u32 prot, u32 flags, char *filename,
151
		     enum map_type type, struct thread *thread)
152
{
153
	struct map *map = malloc(sizeof(*map));
154 155
	struct nsinfo *nsi = NULL;
	struct nsinfo *nnsi;
156

157
	if (map != NULL) {
158
		char newfilename[PATH_MAX];
159
		struct dso *dso;
160
		int anon, no_dso, vdso, android;
161

162
		android = is_android_lib(filename);
163
		anon = is_anon_memory(filename, flags);
164
		vdso = is_vdso_map(filename);
165
		no_dso = is_no_dso_memory(filename);
166

167 168 169 170
		map->maj = d_maj;
		map->min = d_min;
		map->ino = ino;
		map->ino_generation = ino_gen;
171 172
		map->prot = prot;
		map->flags = flags;
173
		nsi = nsinfo__get(thread->nsinfo);
174

175 176 177
		if ((anon || no_dso) && nsi && type == MAP__FUNCTION) {
			snprintf(newfilename, sizeof(newfilename),
				 "/tmp/perf-%d.map", nsi->pid);
178 179 180
			filename = newfilename;
		}

181 182 183 184 185
		if (android) {
			if (replace_android_lib(filename, newfilename))
				filename = newfilename;
		}

186
		if (vdso) {
187 188 189 190 191 192 193 194 195 196
			/* The vdso maps are always on the host and not the
			 * container.  Ensure that we don't use setns to look
			 * them up.
			 */
			nnsi = nsinfo__copy(nsi);
			if (nnsi) {
				nsinfo__put(nsi);
				nnsi->need_setns = false;
				nsi = nnsi;
			}
197
			pgoff = 0;
198
			dso = machine__findnew_vdso(machine, thread);
199
		} else
200
			dso = machine__findnew_dso(machine, filename);
201

202
		if (dso == NULL)
203 204
			goto out_delete;

205
		map__init(map, type, start, start + len, pgoff, dso);
206

207
		if (anon || no_dso) {
208
			map->map_ip = map->unmap_ip = identity__map_ip;
209 210 211 212 213 214

			/*
			 * Set memory without DSO as loaded. All map__find_*
			 * functions still return NULL, and we avoid the
			 * unnecessary map__load warning.
			 */
215
			if (type != MAP__FUNCTION)
216
				dso__set_loaded(dso, map->type);
217
		}
218
		dso->nsinfo = nsi;
219
		dso__put(dso);
220
	}
221
	return map;
222
out_delete:
223
	nsinfo__put(nsi);
224
	free(map);
225 226 227
	return NULL;
}

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
/*
 * Constructor variant for modules (where we know from /proc/modules where
 * they are loaded) and for vmlinux, where only after we load all the
 * symbols we'll know where it starts and ends.
 */
struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
{
	struct map *map = calloc(1, (sizeof(*map) +
				     (dso->kernel ? sizeof(struct kmap) : 0)));
	if (map != NULL) {
		/*
		 * ->end will be filled after we load all the symbols
		 */
		map__init(map, type, start, 0, 0, dso);
	}

	return map;
}

247 248 249 250 251 252 253 254 255 256 257
/*
 * Use this and __map__is_kmodule() for map instances that are in
 * machine->kmaps, and thus have map->groups->machine all properly set, to
 * disambiguate between the kernel and modules.
 *
 * When the need arises, introduce map__is_{kernel,kmodule)() that
 * checks (map->groups != NULL && map->groups->machine != NULL &&
 * map->dso->kernel) before calling __map__is_{kernel,kmodule}())
 */
bool __map__is_kernel(const struct map *map)
{
258
	return __machine__kernel_map(map->groups->machine, map->type) == map;
259 260
}

261
static void map__exit(struct map *map)
262
{
263
	BUG_ON(!RB_EMPTY_NODE(&map->rb_node));
264 265 266 267 268 269
	dso__zput(map->dso);
}

void map__delete(struct map *map)
{
	map__exit(map);
270
	free(map);
271 272
}

273 274
void map__put(struct map *map)
{
275
	if (map && refcount_dec_and_test(&map->refcnt))
276 277 278
		map__delete(map);
}

279
void map__fixup_start(struct map *map)
280
{
281
	struct rb_root *symbols = &map->dso->symbols[map->type];
282
	struct rb_node *nd = rb_first(symbols);
283 284
	if (nd != NULL) {
		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
285
		map->start = sym->start;
286 287 288
	}
}

289
void map__fixup_end(struct map *map)
290
{
291
	struct rb_root *symbols = &map->dso->symbols[map->type];
292
	struct rb_node *nd = rb_last(symbols);
293 294
	if (nd != NULL) {
		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
295
		map->end = sym->end;
296 297 298
	}
}

299 300
#define DSO__DELETED "(deleted)"

301
int map__load(struct map *map)
302
{
303
	const char *name = map->dso->long_name;
304
	int nr;
305

306
	if (dso__loaded(map->dso, map->type))
307 308
		return 0;

309
	nr = dso__load(map->dso, map);
310
	if (nr < 0) {
311
		if (map->dso->has_build_id) {
312
			char sbuild_id[SBUILD_ID_SIZE];
313

314 315
			build_id__sprintf(map->dso->build_id,
					  sizeof(map->dso->build_id),
316 317 318 319 320 321 322 323 324
					  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) {
325
#ifdef HAVE_LIBELF_SUPPORT
326 327 328 329 330
		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) {
331 332
			pr_warning("%.*s was updated (is prelink enabled?). "
				"Restart the long running apps that use it!\n",
333 334 335 336
				   (int)real_len, name);
		} else {
			pr_warning("no symbols found in %s, maybe install "
				   "a debug package?\n", name);
337
		}
338
#endif
339
		return -1;
340 341
	}

342 343 344
	return 0;
}

345
struct symbol *map__find_symbol(struct map *map, u64 addr)
346
{
347
	if (map__load(map) < 0)
348 349
		return NULL;

350
	return dso__find_symbol(map->dso, map->type, addr);
351 352
}

353
struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
354
{
355
	if (map__load(map) < 0)
356 357
		return NULL;

358 359
	if (!dso__sorted_by_name(map->dso, map->type))
		dso__sort_by_name(map->dso, map->type);
360

361
	return dso__find_symbol_by_name(map->dso, map->type, name);
362 363
}

364
struct map *map__clone(struct map *from)
365
{
366 367 368
	struct map *map = memdup(from, sizeof(*map));

	if (map != NULL) {
369
		refcount_set(&map->refcnt, 1);
370 371 372 373 374 375
		RB_CLEAR_NODE(&map->rb_node);
		dso__get(map->dso);
		map->groups = NULL;
	}

	return map;
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
}

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;
}

392
size_t map__fprintf(struct map *map, FILE *fp)
393
{
394
	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
395
		       map->start, map->end, map->pgoff, map->dso->name);
396
}
397

398 399
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
{
400
	const char *dsoname = "[unknown]";
401

402
	if (map && map->dso) {
403 404
		if (symbol_conf.show_kernel_path && map->dso->long_name)
			dsoname = map->dso->long_name;
405
		else
406
			dsoname = map->dso->name;
407
	}
408 409 410 411

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

412 413 414 415 416 417 418 419
int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
			 FILE *fp)
{
	char *srcline;
	int ret = 0;

	if (map && map->dso) {
		srcline = get_srcline(map->dso,
420 421
				      map__rip_2objdump(map, addr), NULL,
				      true, true);
422 423 424 425 426 427 428
		if (srcline != SRCLINE_UNKNOWN)
			ret = fprintf(fp, "%s%s", prefix, srcline);
		free_srcline(srcline);
	}
	return ret;
}

429 430 431 432 433
/**
 * map__rip_2objdump - convert symbol start address to objdump address.
 * @map: memory map
 * @rip: symbol start address
 *
434
 * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
435 436
 * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
 * relative to section start.
437 438
 *
 * Return: Address suitable for passing to "objdump --start-address="
439 440 441
 */
u64 map__rip_2objdump(struct map *map, u64 rip)
{
442 443 444 445 446 447
	if (!map->dso->adjust_symbols)
		return rip;

	if (map->dso->rel)
		return rip - map->pgoff;

448 449 450 451 452 453 454
	/*
	 * kernel modules also have DSO_TYPE_USER in dso->kernel,
	 * but all kernel modules are ET_REL, so won't get here.
	 */
	if (map->dso->kernel == DSO_TYPE_USER)
		return rip + map->dso->text_offset;

455
	return map->unmap_ip(map, rip) - map->reloc;
456
}
457

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
/**
 * map__objdump_2mem - convert objdump address to a memory address.
 * @map: memory map
 * @ip: objdump address
 *
 * Closely related to map__rip_2objdump(), this function takes an address from
 * objdump and converts it to a memory address.  Note this assumes that @map
 * contains the address.  To be sure the result is valid, check it forwards
 * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
 *
 * Return: Memory address.
 */
u64 map__objdump_2mem(struct map *map, u64 ip)
{
	if (!map->dso->adjust_symbols)
		return map->unmap_ip(map, ip);

	if (map->dso->rel)
		return map->unmap_ip(map, ip + map->pgoff);

478 479 480 481 482 483 484
	/*
	 * kernel modules also have DSO_TYPE_USER in dso->kernel,
	 * but all kernel modules are ET_REL, so won't get here.
	 */
	if (map->dso->kernel == DSO_TYPE_USER)
		return map->unmap_ip(map, ip - map->dso->text_offset);

485
	return ip + map->reloc;
486 487
}

488 489 490
static void maps__init(struct maps *maps)
{
	maps->entries = RB_ROOT;
491
	pthread_rwlock_init(&maps->lock, NULL);
492 493
}

494
void map_groups__init(struct map_groups *mg, struct machine *machine)
495 496 497
{
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i) {
498
		maps__init(&mg->maps[i]);
499
	}
500
	mg->machine = machine;
501
	refcount_set(&mg->refcnt, 1);
502 503
}

504
static void __maps__purge(struct maps *maps)
505
{
506 507
	struct rb_root *root = &maps->entries;
	struct rb_node *next = rb_first(root);
508 509 510 511 512

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

		next = rb_next(&pos->rb_node);
513
		rb_erase_init(&pos->rb_node, root);
514
		map__put(pos);
515 516 517
	}
}

518 519
static void maps__exit(struct maps *maps)
{
520 521 522
	pthread_rwlock_wrlock(&maps->lock);
	__maps__purge(maps);
	pthread_rwlock_unlock(&maps->lock);
523 524
}

525
void map_groups__exit(struct map_groups *mg)
526 527 528
{
	int i;

529 530
	for (i = 0; i < MAP__NR_TYPES; ++i)
		maps__exit(&mg->maps[i]);
531 532
}

533 534 535 536 537 538 539 540 541 542 543 544
bool map_groups__empty(struct map_groups *mg)
{
	int i;

	for (i = 0; i < MAP__NR_TYPES; ++i) {
		if (maps__first(&mg->maps[i]))
			return false;
	}

	return true;
}

545
struct map_groups *map_groups__new(struct machine *machine)
546 547 548 549
{
	struct map_groups *mg = malloc(sizeof(*mg));

	if (mg != NULL)
550
		map_groups__init(mg, machine);
551 552 553 554 555 556 557 558 559 560

	return mg;
}

void map_groups__delete(struct map_groups *mg)
{
	map_groups__exit(mg);
	free(mg);
}

561 562
void map_groups__put(struct map_groups *mg)
{
563
	if (mg && refcount_dec_and_test(&mg->refcnt))
564 565 566
		map_groups__delete(mg);
}

567
struct symbol *map_groups__find_symbol(struct map_groups *mg,
568
				       enum map_type type, u64 addr,
569
				       struct map **mapp)
570
{
571
	struct map *map = map_groups__find(mg, type, addr);
572

573
	/* Ensure map is loaded before using map->map_ip */
574
	if (map != NULL && map__load(map) >= 0) {
575 576
		if (mapp != NULL)
			*mapp = map;
577
		return map__find_symbol(map, map->map_ip(map, addr));
578 579 580 581 582
	}

	return NULL;
}

583
struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
584
					 struct map **mapp)
585
{
586
	struct symbol *sym;
587 588
	struct rb_node *nd;

589 590 591
	pthread_rwlock_rdlock(&maps->lock);

	for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
592
		struct map *pos = rb_entry(nd, struct map, rb_node);
593

594
		sym = map__find_symbol_by_name(pos, name);
595 596 597 598 599

		if (sym == NULL)
			continue;
		if (mapp != NULL)
			*mapp = pos;
600
		goto out;
601
	}
602

603 604 605 606
	sym = NULL;
out:
	pthread_rwlock_unlock(&maps->lock);
	return sym;
607 608
}

609 610 611
struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
					       enum map_type type,
					       const char *name,
612
					       struct map **mapp)
613
{
614
	struct symbol *sym = maps__find_symbol_by_name(&mg->maps[type], name, mapp);
615 616 617 618

	return sym;
}

619
int map_groups__find_ams(struct addr_map_symbol *ams)
620
{
621
	if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
622 623 624 625 626 627 628 629 630
		if (ams->map->groups == NULL)
			return -1;
		ams->map = map_groups__find(ams->map->groups, ams->map->type,
					    ams->addr);
		if (ams->map == NULL)
			return -1;
	}

	ams->al_addr = ams->map->map_ip(ams->map, ams->addr);
631
	ams->sym = map__find_symbol(ams->map, ams->al_addr);
632 633 634 635

	return ams->sym ? 0 : -1;
}

636
static size_t maps__fprintf(struct maps *maps, FILE *fp)
637
{
638
	size_t printed = 0;
639 640
	struct rb_node *nd;

641 642 643
	pthread_rwlock_rdlock(&maps->lock);

	for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
644 645 646 647
		struct map *pos = rb_entry(nd, struct map, rb_node);
		printed += fprintf(fp, "Map:");
		printed += map__fprintf(pos, fp);
		if (verbose > 2) {
648
			printed += dso__fprintf(pos->dso, pos->type, fp);
649 650 651 652
			printed += fprintf(fp, "--\n");
		}
	}

653 654
	pthread_rwlock_unlock(&maps->lock);

655 656 657
	return printed;
}

658 659 660 661 662 663 664
size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
				  FILE *fp)
{
	size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
	return printed += maps__fprintf(&mg->maps[type], fp);
}

665
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
666 667 668
{
	size_t printed = 0, i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
669
		printed += __map_groups__fprintf_maps(mg, i, fp);
670 671 672
	return printed;
}

673 674 675 676 677 678
static void __map_groups__insert(struct map_groups *mg, struct map *map)
{
	__maps__insert(&mg->maps[map->type], map);
	map->groups = mg;
}

679
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
680
{
681 682
	struct rb_root *root;
	struct rb_node *next;
683
	int err = 0;
684

685 686 687 688 689
	pthread_rwlock_wrlock(&maps->lock);

	root = &maps->entries;
	next = rb_first(root);

690 691 692 693 694 695 696 697
	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) {
698 699 700 701 702 703 704 705 706 707

			if (use_browser) {
				pr_warning("overlapping maps in %s "
					   "(disable tui for more info)\n",
					   map->dso->name);
			} else {
				fputs("overlapping maps:\n", fp);
				map__fprintf(map, fp);
				map__fprintf(pos, fp);
			}
708 709
		}

710
		rb_erase_init(&pos->rb_node, root);
711 712 713 714 715 716 717
		/*
		 * 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);

718 719
			if (before == NULL) {
				err = -ENOMEM;
720
				goto put_map;
721
			}
722

723
			before->end = map->start;
724
			__map_groups__insert(pos->groups, before);
725
			if (verbose >= 2 && !use_browser)
726
				map__fprintf(before, fp);
727
			map__put(before);
728 729 730 731 732
		}

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

733 734
			if (after == NULL) {
				err = -ENOMEM;
735
				goto put_map;
736
			}
737

738
			after->start = map->end;
739
			__map_groups__insert(pos->groups, after);
740
			if (verbose >= 2 && !use_browser)
741
				map__fprintf(after, fp);
742
			map__put(after);
743
		}
744
put_map:
745
		map__put(pos);
746 747

		if (err)
748
			goto out;
749 750
	}

751 752 753 754 755 756 757 758 759 760
	err = 0;
out:
	pthread_rwlock_unlock(&maps->lock);
	return err;
}

int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
				   FILE *fp)
{
	return maps__fixup_overlappings(&mg->maps[map->type], map, fp);
761 762 763 764 765
}

/*
 * XXX This should not really _copy_ te maps, but refcount them.
 */
766
int map_groups__clone(struct thread *thread,
767 768
		      struct map_groups *parent, enum map_type type)
{
769
	struct map_groups *mg = thread->mg;
770
	int err = -ENOMEM;
771
	struct map *map;
772
	struct maps *maps = &parent->maps[type];
773

774 775
	pthread_rwlock_rdlock(&maps->lock);

776
	for (map = maps__first(maps); map; map = map__next(map)) {
777 778
		struct map *new = map__clone(map);
		if (new == NULL)
779
			goto out_unlock;
780 781 782 783 784

		err = unwind__prepare_access(thread, new, NULL);
		if (err)
			goto out_unlock;

785
		map_groups__insert(mg, new);
786
		map__put(new);
787
	}
788 789 790 791 792

	err = 0;
out_unlock:
	pthread_rwlock_unlock(&maps->lock);
	return err;
793 794
}

795
static void __maps__insert(struct maps *maps, struct map *map)
796
{
797
	struct rb_node **p = &maps->entries.rb_node;
798 799 800 801 802 803 804 805 806 807 808 809 810 811
	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);
812
	rb_insert_color(&map->rb_node, &maps->entries);
813
	map__get(map);
814 815
}

816 817 818 819 820 821 822 823
void maps__insert(struct maps *maps, struct map *map)
{
	pthread_rwlock_wrlock(&maps->lock);
	__maps__insert(maps, map);
	pthread_rwlock_unlock(&maps->lock);
}

static void __maps__remove(struct maps *maps, struct map *map)
824
{
825
	rb_erase_init(&map->rb_node, &maps->entries);
826
	map__put(map);
827 828
}

829 830 831 832 833 834 835
void maps__remove(struct maps *maps, struct map *map)
{
	pthread_rwlock_wrlock(&maps->lock);
	__maps__remove(maps, map);
	pthread_rwlock_unlock(&maps->lock);
}

836
struct map *maps__find(struct maps *maps, u64 ip)
837
{
838
	struct rb_node **p, *parent = NULL;
839 840
	struct map *m;

841 842 843
	pthread_rwlock_rdlock(&maps->lock);

	p = &maps->entries.rb_node;
844 845 846 847 848
	while (*p != NULL) {
		parent = *p;
		m = rb_entry(parent, struct map, rb_node);
		if (ip < m->start)
			p = &(*p)->rb_left;
849
		else if (ip >= m->end)
850 851
			p = &(*p)->rb_right;
		else
852
			goto out;
853 854
	}

855 856 857 858
	m = NULL;
out:
	pthread_rwlock_unlock(&maps->lock);
	return m;
859
}
860

861
struct map *maps__first(struct maps *maps)
862
{
863
	struct rb_node *first = rb_first(&maps->entries);
864 865 866 867 868 869

	if (first)
		return rb_entry(first, struct map, rb_node);
	return NULL;
}

870
struct map *map__next(struct map *map)
871 872 873 874 875 876 877
{
	struct rb_node *next = rb_next(&map->rb_node);

	if (next)
		return rb_entry(next, struct map, rb_node);
	return NULL;
}
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897

struct kmap *map__kmap(struct map *map)
{
	if (!map->dso || !map->dso->kernel) {
		pr_err("Internal error: map__kmap with a non-kernel map\n");
		return NULL;
	}
	return (struct kmap *)(map + 1);
}

struct map_groups *map__kmaps(struct map *map)
{
	struct kmap *kmap = map__kmap(map);

	if (!kmap || !kmap->kmaps) {
		pr_err("Internal error: map__kmaps with a non-kernel map\n");
		return NULL;
	}
	return kmap->kmaps;
}