map.c 19.4 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
#include "thread.h"
11
#include "strlist.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 "unwind.h"
19

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

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

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

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

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

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

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

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

157
		android = is_android_lib(filename);
158
		anon = is_anon_memory(filename);
159
		vdso = is_vdso_map(filename);
160
		no_dso = is_no_dso_memory(filename);
161

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

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

174 175 176 177 178
		if (android) {
			if (replace_android_lib(filename, newfilename))
				filename = newfilename;
		}

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

185
		if (dso == NULL)
186 187
			goto out_delete;

188
		map__init(map, type, start, start + len, pgoff, dso);
189

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

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

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

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

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

void map__delete(struct map *map)
{
	map__exit(map);
251
	free(map);
252 253
}

254 255 256 257 258 259
void map__put(struct map *map)
{
	if (map && atomic_dec_and_test(&map->refcnt))
		map__delete(map);
}

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

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

280 281
#define DSO__DELETED "(deleted)"

282
int map__load(struct map *map, symbol_filter_t filter)
283
{
284
	const char *name = map->dso->long_name;
285
	int nr;
286

287
	if (dso__loaded(map->dso, map->type))
288 289
		return 0;

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

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

323 324 325
	return 0;
}

326 327 328 329 330
int __weak arch__compare_symbol_names(const char *namea, const char *nameb)
{
	return strcmp(namea, nameb);
}

331
struct symbol *map__find_symbol(struct map *map, u64 addr,
332
				symbol_filter_t filter)
333
{
334
	if (map__load(map, filter) < 0)
335 336
		return NULL;

337
	return dso__find_symbol(map->dso, map->type, addr);
338 339
}

340
struct symbol *map__find_symbol_by_name(struct map *map, const char *name,
341 342
					symbol_filter_t filter)
{
343
	if (map__load(map, filter) < 0)
344 345
		return NULL;

346 347
	if (!dso__sorted_by_name(map->dso, map->type))
		dso__sort_by_name(map->dso, map->type);
348

349
	return dso__find_symbol_by_name(map->dso, map->type, name);
350 351
}

352
struct map *map__clone(struct map *from)
353
{
354 355 356 357 358 359 360 361 362 363
	struct map *map = memdup(from, sizeof(*map));

	if (map != NULL) {
		atomic_set(&map->refcnt, 1);
		RB_CLEAR_NODE(&map->rb_node);
		dso__get(map->dso);
		map->groups = NULL;
	}

	return map;
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
}

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

380
size_t map__fprintf(struct map *map, FILE *fp)
381
{
382
	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
383
		       map->start, map->end, map->pgoff, map->dso->name);
384
}
385

386 387
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
{
388
	const char *dsoname = "[unknown]";
389

390 391 392 393 394
	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;
395
	}
396 397 398 399

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

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

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

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

435 436 437 438 439 440 441
	/*
	 * 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;

442
	return map->unmap_ip(map, rip) - map->reloc;
443
}
444

445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
/**
 * 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);

465 466 467 468 469 470 471
	/*
	 * 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);

472
	return ip + map->reloc;
473 474
}

475 476 477
static void maps__init(struct maps *maps)
{
	maps->entries = RB_ROOT;
478
	pthread_rwlock_init(&maps->lock, NULL);
479 480
}

481
void map_groups__init(struct map_groups *mg, struct machine *machine)
482 483 484
{
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i) {
485
		maps__init(&mg->maps[i]);
486
	}
487
	mg->machine = machine;
488
	atomic_set(&mg->refcnt, 1);
489 490
}

491
static void __maps__purge(struct maps *maps)
492
{
493 494
	struct rb_root *root = &maps->entries;
	struct rb_node *next = rb_first(root);
495 496 497 498 499

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

		next = rb_next(&pos->rb_node);
500
		rb_erase_init(&pos->rb_node, root);
501
		map__put(pos);
502 503 504
	}
}

505 506
static void maps__exit(struct maps *maps)
{
507 508 509
	pthread_rwlock_wrlock(&maps->lock);
	__maps__purge(maps);
	pthread_rwlock_unlock(&maps->lock);
510 511
}

512
void map_groups__exit(struct map_groups *mg)
513 514 515
{
	int i;

516 517
	for (i = 0; i < MAP__NR_TYPES; ++i)
		maps__exit(&mg->maps[i]);
518 519
}

520 521 522 523 524 525 526 527 528 529 530 531
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;
}

532
struct map_groups *map_groups__new(struct machine *machine)
533 534 535 536
{
	struct map_groups *mg = malloc(sizeof(*mg));

	if (mg != NULL)
537
		map_groups__init(mg, machine);
538 539 540 541 542 543 544 545 546 547

	return mg;
}

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

548 549
void map_groups__put(struct map_groups *mg)
{
550
	if (mg && atomic_dec_and_test(&mg->refcnt))
551 552 553
		map_groups__delete(mg);
}

554
struct symbol *map_groups__find_symbol(struct map_groups *mg,
555
				       enum map_type type, u64 addr,
556
				       struct map **mapp,
557 558
				       symbol_filter_t filter)
{
559
	struct map *map = map_groups__find(mg, type, addr);
560

561 562
	/* Ensure map is loaded before using map->map_ip */
	if (map != NULL && map__load(map, filter) >= 0) {
563 564
		if (mapp != NULL)
			*mapp = map;
565
		return map__find_symbol(map, map->map_ip(map, addr), filter);
566 567 568 569 570
	}

	return NULL;
}

571 572
struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
					 struct map **mapp, symbol_filter_t filter)
573
{
574
	struct symbol *sym;
575 576
	struct rb_node *nd;

577 578 579
	pthread_rwlock_rdlock(&maps->lock);

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

		sym = map__find_symbol_by_name(pos, name, filter);
583 584 585 586 587

		if (sym == NULL)
			continue;
		if (mapp != NULL)
			*mapp = pos;
588
		goto out;
589
	}
590

591 592 593 594
	sym = NULL;
out:
	pthread_rwlock_unlock(&maps->lock);
	return sym;
595 596
}

597 598 599 600 601 602 603 604 605 606 607
struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
					       enum map_type type,
					       const char *name,
					       struct map **mapp,
					       symbol_filter_t filter)
{
	struct symbol *sym = maps__find_symbol_by_name(&mg->maps[type], name, mapp, filter);

	return sym;
}

608 609
int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter)
{
610
	if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
611 612 613 614 615 616 617 618 619 620 621 622 623 624
		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);
	ams->sym = map__find_symbol(ams->map, ams->al_addr, filter);

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

625
static size_t maps__fprintf(struct maps *maps, FILE *fp)
626
{
627
	size_t printed = 0;
628 629
	struct rb_node *nd;

630 631 632
	pthread_rwlock_rdlock(&maps->lock);

	for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
633 634 635 636
		struct map *pos = rb_entry(nd, struct map, rb_node);
		printed += fprintf(fp, "Map:");
		printed += map__fprintf(pos, fp);
		if (verbose > 2) {
637
			printed += dso__fprintf(pos->dso, pos->type, fp);
638 639 640 641
			printed += fprintf(fp, "--\n");
		}
	}

642 643
	pthread_rwlock_unlock(&maps->lock);

644 645 646
	return printed;
}

647 648 649 650 651 652 653
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);
}

654
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
655 656 657
{
	size_t printed = 0, i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
658
		printed += __map_groups__fprintf_maps(mg, i, fp);
659 660 661
	return printed;
}

662 663 664 665 666 667
static void __map_groups__insert(struct map_groups *mg, struct map *map)
{
	__maps__insert(&mg->maps[map->type], map);
	map->groups = mg;
}

668
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
669
{
670 671
	struct rb_root *root;
	struct rb_node *next;
672
	int err = 0;
673

674 675 676 677 678
	pthread_rwlock_wrlock(&maps->lock);

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

679 680 681 682 683 684 685 686 687 688 689 690 691
	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);
		}

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

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

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

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

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

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

		if (err)
730
			goto out;
731 732
	}

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

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

756 757
	pthread_rwlock_rdlock(&maps->lock);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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