map.c 19.3 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 "unwind.h"
20

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

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

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

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

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

130
void map__init(struct map *map, enum map_type type,
131
	       u64 start, u64 end, u64 pgoff, struct dso *dso)
132
{
133 134 135 136
	map->type     = type;
	map->start    = start;
	map->end      = end;
	map->pgoff    = pgoff;
137
	map->reloc    = 0;
138
	map->dso      = dso__get(dso);
139 140 141 142 143
	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;
144
	refcount_set(&map->refcnt, 1);
145 146
}

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

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

159
		android = is_android_lib(filename);
160
		anon = is_anon_memory(filename, flags);
161
		vdso = is_vdso_map(filename);
162
		no_dso = is_no_dso_memory(filename);
163

164 165 166 167
		map->maj = d_maj;
		map->min = d_min;
		map->ino = ino;
		map->ino_generation = ino_gen;
168 169
		map->prot = prot;
		map->flags = flags;
170

171
		if ((anon || no_dso) && type == MAP__FUNCTION) {
172
			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
173 174 175
			filename = newfilename;
		}

176 177 178 179 180
		if (android) {
			if (replace_android_lib(filename, newfilename))
				filename = newfilename;
		}

181 182
		if (vdso) {
			pgoff = 0;
183
			dso = machine__findnew_vdso(machine, thread);
184
		} else
185
			dso = machine__findnew_dso(machine, filename);
186

187
		if (dso == NULL)
188 189
			goto out_delete;

190
		map__init(map, type, start, start + len, pgoff, dso);
191

192
		if (anon || no_dso) {
193
			map->map_ip = map->unmap_ip = identity__map_ip;
194 195 196 197 198 199

			/*
			 * Set memory without DSO as loaded. All map__find_*
			 * functions still return NULL, and we avoid the
			 * unnecessary map__load warning.
			 */
200
			if (type != MAP__FUNCTION)
201
				dso__set_loaded(dso, map->type);
202
		}
203
		dso__put(dso);
204
	}
205
	return map;
206
out_delete:
207
	free(map);
208 209 210
	return NULL;
}

211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
/*
 * 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;
}

230 231 232 233 234 235 236 237 238 239 240
/*
 * 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)
{
241
	return __machine__kernel_map(map->groups->machine, map->type) == map;
242 243
}

244
static void map__exit(struct map *map)
245
{
246
	BUG_ON(!RB_EMPTY_NODE(&map->rb_node));
247 248 249 250 251 252
	dso__zput(map->dso);
}

void map__delete(struct map *map)
{
	map__exit(map);
253
	free(map);
254 255
}

256 257
void map__put(struct map *map)
{
258
	if (map && refcount_dec_and_test(&map->refcnt))
259 260 261
		map__delete(map);
}

262
void map__fixup_start(struct map *map)
263
{
264
	struct rb_root *symbols = &map->dso->symbols[map->type];
265
	struct rb_node *nd = rb_first(symbols);
266 267
	if (nd != NULL) {
		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
268
		map->start = sym->start;
269 270 271
	}
}

272
void map__fixup_end(struct map *map)
273
{
274
	struct rb_root *symbols = &map->dso->symbols[map->type];
275
	struct rb_node *nd = rb_last(symbols);
276 277
	if (nd != NULL) {
		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
278
		map->end = sym->end;
279 280 281
	}
}

282 283
#define DSO__DELETED "(deleted)"

284
int map__load(struct map *map)
285
{
286
	const char *name = map->dso->long_name;
287
	int nr;
288

289
	if (dso__loaded(map->dso, map->type))
290 291
		return 0;

292
	nr = dso__load(map->dso, map);
293
	if (nr < 0) {
294
		if (map->dso->has_build_id) {
295
			char sbuild_id[SBUILD_ID_SIZE];
296

297 298
			build_id__sprintf(map->dso->build_id,
					  sizeof(map->dso->build_id),
299 300 301 302 303 304 305 306 307
					  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) {
308
#ifdef HAVE_LIBELF_SUPPORT
309 310 311 312 313
		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) {
314 315
			pr_warning("%.*s was updated (is prelink enabled?). "
				"Restart the long running apps that use it!\n",
316 317 318 319
				   (int)real_len, name);
		} else {
			pr_warning("no symbols found in %s, maybe install "
				   "a debug package?\n", name);
320
		}
321
#endif
322
		return -1;
323 324
	}

325 326 327
	return 0;
}

328
struct symbol *map__find_symbol(struct map *map, u64 addr)
329
{
330
	if (map__load(map) < 0)
331 332
		return NULL;

333
	return dso__find_symbol(map->dso, map->type, addr);
334 335
}

336
struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
337
{
338
	if (map__load(map) < 0)
339 340
		return NULL;

341 342
	if (!dso__sorted_by_name(map->dso, map->type))
		dso__sort_by_name(map->dso, map->type);
343

344
	return dso__find_symbol_by_name(map->dso, map->type, name);
345 346
}

347
struct map *map__clone(struct map *from)
348
{
349 350 351
	struct map *map = memdup(from, sizeof(*map));

	if (map != NULL) {
352
		refcount_set(&map->refcnt, 1);
353 354 355 356 357 358
		RB_CLEAR_NODE(&map->rb_node);
		dso__get(map->dso);
		map->groups = NULL;
	}

	return map;
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
}

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

375
size_t map__fprintf(struct map *map, FILE *fp)
376
{
377
	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
378
		       map->start, map->end, map->pgoff, map->dso->name);
379
}
380

381 382
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
{
383
	const char *dsoname = "[unknown]";
384

385
	if (map && map->dso) {
386 387
		if (symbol_conf.show_kernel_path && map->dso->long_name)
			dsoname = map->dso->long_name;
388
		else
389
			dsoname = map->dso->name;
390
	}
391 392 393 394

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

395 396 397 398 399 400 401 402
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,
403 404
				      map__rip_2objdump(map, addr), NULL,
				      true, true);
405 406 407 408 409 410 411
		if (srcline != SRCLINE_UNKNOWN)
			ret = fprintf(fp, "%s%s", prefix, srcline);
		free_srcline(srcline);
	}
	return ret;
}

412 413 414 415 416
/**
 * map__rip_2objdump - convert symbol start address to objdump address.
 * @map: memory map
 * @rip: symbol start address
 *
417
 * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
418 419
 * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
 * relative to section start.
420 421
 *
 * Return: Address suitable for passing to "objdump --start-address="
422 423 424
 */
u64 map__rip_2objdump(struct map *map, u64 rip)
{
425 426 427 428 429 430
	if (!map->dso->adjust_symbols)
		return rip;

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

431 432 433 434 435 436 437
	/*
	 * 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;

438
	return map->unmap_ip(map, rip) - map->reloc;
439
}
440

441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
/**
 * 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);

461 462 463 464 465 466 467
	/*
	 * 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);

468
	return ip + map->reloc;
469 470
}

471 472 473
static void maps__init(struct maps *maps)
{
	maps->entries = RB_ROOT;
474
	pthread_rwlock_init(&maps->lock, NULL);
475 476
}

477
void map_groups__init(struct map_groups *mg, struct machine *machine)
478 479 480
{
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i) {
481
		maps__init(&mg->maps[i]);
482
	}
483
	mg->machine = machine;
484
	refcount_set(&mg->refcnt, 1);
485 486
}

487
static void __maps__purge(struct maps *maps)
488
{
489 490
	struct rb_root *root = &maps->entries;
	struct rb_node *next = rb_first(root);
491 492 493 494 495

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

		next = rb_next(&pos->rb_node);
496
		rb_erase_init(&pos->rb_node, root);
497
		map__put(pos);
498 499 500
	}
}

501 502
static void maps__exit(struct maps *maps)
{
503 504 505
	pthread_rwlock_wrlock(&maps->lock);
	__maps__purge(maps);
	pthread_rwlock_unlock(&maps->lock);
506 507
}

508
void map_groups__exit(struct map_groups *mg)
509 510 511
{
	int i;

512 513
	for (i = 0; i < MAP__NR_TYPES; ++i)
		maps__exit(&mg->maps[i]);
514 515
}

516 517 518 519 520 521 522 523 524 525 526 527
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;
}

528
struct map_groups *map_groups__new(struct machine *machine)
529 530 531 532
{
	struct map_groups *mg = malloc(sizeof(*mg));

	if (mg != NULL)
533
		map_groups__init(mg, machine);
534 535 536 537 538 539 540 541 542 543

	return mg;
}

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

544 545
void map_groups__put(struct map_groups *mg)
{
546
	if (mg && refcount_dec_and_test(&mg->refcnt))
547 548 549
		map_groups__delete(mg);
}

550
struct symbol *map_groups__find_symbol(struct map_groups *mg,
551
				       enum map_type type, u64 addr,
552
				       struct map **mapp)
553
{
554
	struct map *map = map_groups__find(mg, type, addr);
555

556
	/* Ensure map is loaded before using map->map_ip */
557
	if (map != NULL && map__load(map) >= 0) {
558 559
		if (mapp != NULL)
			*mapp = map;
560
		return map__find_symbol(map, map->map_ip(map, addr));
561 562 563 564 565
	}

	return NULL;
}

566
struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
567
					 struct map **mapp)
568
{
569
	struct symbol *sym;
570 571
	struct rb_node *nd;

572 573 574
	pthread_rwlock_rdlock(&maps->lock);

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

577
		sym = map__find_symbol_by_name(pos, name);
578 579 580 581 582

		if (sym == NULL)
			continue;
		if (mapp != NULL)
			*mapp = pos;
583
		goto out;
584
	}
585

586 587 588 589
	sym = NULL;
out:
	pthread_rwlock_unlock(&maps->lock);
	return sym;
590 591
}

592 593 594
struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
					       enum map_type type,
					       const char *name,
595
					       struct map **mapp)
596
{
597
	struct symbol *sym = maps__find_symbol_by_name(&mg->maps[type], name, mapp);
598 599 600 601

	return sym;
}

602
int map_groups__find_ams(struct addr_map_symbol *ams)
603
{
604
	if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
605 606 607 608 609 610 611 612 613
		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);
614
	ams->sym = map__find_symbol(ams->map, ams->al_addr);
615 616 617 618

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

619
static size_t maps__fprintf(struct maps *maps, FILE *fp)
620
{
621
	size_t printed = 0;
622 623
	struct rb_node *nd;

624 625 626
	pthread_rwlock_rdlock(&maps->lock);

	for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
627 628 629 630
		struct map *pos = rb_entry(nd, struct map, rb_node);
		printed += fprintf(fp, "Map:");
		printed += map__fprintf(pos, fp);
		if (verbose > 2) {
631
			printed += dso__fprintf(pos->dso, pos->type, fp);
632 633 634 635
			printed += fprintf(fp, "--\n");
		}
	}

636 637
	pthread_rwlock_unlock(&maps->lock);

638 639 640
	return printed;
}

641 642 643 644 645 646 647
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);
}

648
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
649 650 651
{
	size_t printed = 0, i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
652
		printed += __map_groups__fprintf_maps(mg, i, fp);
653 654 655
	return printed;
}

656 657 658 659 660 661
static void __map_groups__insert(struct map_groups *mg, struct map *map)
{
	__maps__insert(&mg->maps[map->type], map);
	map->groups = mg;
}

662
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
663
{
664 665
	struct rb_root *root;
	struct rb_node *next;
666
	int err = 0;
667

668 669 670 671 672
	pthread_rwlock_wrlock(&maps->lock);

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

673 674 675 676 677 678 679 680
	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) {
681 682 683 684 685 686 687 688 689 690

			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);
			}
691 692
		}

693
		rb_erase_init(&pos->rb_node, root);
694 695 696 697 698 699 700
		/*
		 * 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);

701 702
			if (before == NULL) {
				err = -ENOMEM;
703
				goto put_map;
704
			}
705

706
			before->end = map->start;
707
			__map_groups__insert(pos->groups, before);
708
			if (verbose >= 2 && !use_browser)
709
				map__fprintf(before, fp);
710
			map__put(before);
711 712 713 714 715
		}

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

716 717
			if (after == NULL) {
				err = -ENOMEM;
718
				goto put_map;
719
			}
720

721
			after->start = map->end;
722
			__map_groups__insert(pos->groups, after);
723
			if (verbose >= 2 && !use_browser)
724
				map__fprintf(after, fp);
725
			map__put(after);
726
		}
727
put_map:
728
		map__put(pos);
729 730

		if (err)
731
			goto out;
732 733
	}

734 735 736 737 738 739 740 741 742 743
	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);
744 745 746 747 748
}

/*
 * XXX This should not really _copy_ te maps, but refcount them.
 */
749
int map_groups__clone(struct thread *thread,
750 751
		      struct map_groups *parent, enum map_type type)
{
752
	struct map_groups *mg = thread->mg;
753
	int err = -ENOMEM;
754
	struct map *map;
755
	struct maps *maps = &parent->maps[type];
756

757 758
	pthread_rwlock_rdlock(&maps->lock);

759
	for (map = maps__first(maps); map; map = map__next(map)) {
760 761
		struct map *new = map__clone(map);
		if (new == NULL)
762
			goto out_unlock;
763 764 765 766 767

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

768
		map_groups__insert(mg, new);
769
		map__put(new);
770
	}
771 772 773 774 775

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

778
static void __maps__insert(struct maps *maps, struct map *map)
779
{
780
	struct rb_node **p = &maps->entries.rb_node;
781 782 783 784 785 786 787 788 789 790 791 792 793 794
	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);
795
	rb_insert_color(&map->rb_node, &maps->entries);
796
	map__get(map);
797 798
}

799 800 801 802 803 804 805 806
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)
807
{
808
	rb_erase_init(&map->rb_node, &maps->entries);
809
	map__put(map);
810 811
}

812 813 814 815 816 817 818
void maps__remove(struct maps *maps, struct map *map)
{
	pthread_rwlock_wrlock(&maps->lock);
	__maps__remove(maps, map);
	pthread_rwlock_unlock(&maps->lock);
}

819
struct map *maps__find(struct maps *maps, u64 ip)
820
{
821
	struct rb_node **p, *parent = NULL;
822 823
	struct map *m;

824 825 826
	pthread_rwlock_rdlock(&maps->lock);

	p = &maps->entries.rb_node;
827 828 829 830 831
	while (*p != NULL) {
		parent = *p;
		m = rb_entry(parent, struct map, rb_node);
		if (ip < m->start)
			p = &(*p)->rb_left;
832
		else if (ip >= m->end)
833 834
			p = &(*p)->rb_right;
		else
835
			goto out;
836 837
	}

838 839 840 841
	m = NULL;
out:
	pthread_rwlock_unlock(&maps->lock);
	return m;
842
}
843

844
struct map *maps__first(struct maps *maps)
845
{
846
	struct rb_node *first = rb_first(&maps->entries);
847 848 849 850 851 852

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

853
struct map *map__next(struct map *map)
854 855 856 857 858 859 860
{
	struct rb_node *next = rb_next(&map->rb_node);

	if (next)
		return rb_entry(next, struct map, rb_node);
	return NULL;
}
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880

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