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 <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 "strlist.h"
13
#include "vdso.h"
14
#include "build-id.h"
15
#include "util.h"
16
#include "debug.h"
17
#include "machine.h"
18
#include <linux/string.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 329 330 331 332
int __weak arch__compare_symbol_names(const char *namea, const char *nameb)
{
	return strcmp(namea, nameb);
}

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

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

341
struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
342
{
343
	if (map__load(map) < 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
	struct map *map = memdup(from, sizeof(*map));

	if (map != NULL) {
357
		refcount_set(&map->refcnt, 1);
358 359 360 361 362 363
		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
	if (map && map->dso) {
391 392
		if (symbol_conf.show_kernel_path && map->dso->long_name)
			dsoname = map->dso->long_name;
393
		else
394
			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
	refcount_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 && refcount_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
	struct map *map = map_groups__find(mg, type, addr);
559

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

	return NULL;
}

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

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

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

581
		sym = map__find_symbol_by_name(pos, name);
582 583 584 585 586

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

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

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

	return sym;
}

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

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

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

628 629 630
	pthread_rwlock_rdlock(&maps->lock);

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

640 641
	pthread_rwlock_unlock(&maps->lock);

642 643 644
	return printed;
}

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

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

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

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

672 673 674 675 676
	pthread_rwlock_wrlock(&maps->lock);

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

677 678 679 680 681 682 683 684
	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) {
685 686 687 688 689 690 691 692 693 694

			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);
			}
695 696
		}

697
		rb_erase_init(&pos->rb_node, root);
698 699 700 701 702 703 704
		/*
		 * 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);

705 706
			if (before == NULL) {
				err = -ENOMEM;
707
				goto put_map;
708
			}
709

710
			before->end = map->start;
711
			__map_groups__insert(pos->groups, before);
712
			if (verbose >= 2 && !use_browser)
713
				map__fprintf(before, fp);
714
			map__put(before);
715 716 717 718 719
		}

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

720 721
			if (after == NULL) {
				err = -ENOMEM;
722
				goto put_map;
723
			}
724

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

		if (err)
735
			goto out;
736 737
	}

738 739 740 741 742 743 744 745 746 747
	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);
748 749 750 751 752
}

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

761 762
	pthread_rwlock_rdlock(&maps->lock);

763
	for (map = maps__first(maps); map; map = map__next(map)) {
764 765
		struct map *new = map__clone(map);
		if (new == NULL)
766
			goto out_unlock;
767 768 769 770 771

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

772
		map_groups__insert(mg, new);
773
		map__put(new);
774
	}
775 776 777 778 779

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

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

803 804 805 806 807 808 809 810
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)
811
{
812
	rb_erase_init(&map->rb_node, &maps->entries);
813
	map__put(map);
814 815
}

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

823
struct map *maps__find(struct maps *maps, u64 ip)
824
{
825
	struct rb_node **p, *parent = NULL;
826 827
	struct map *m;

828 829 830
	pthread_rwlock_rdlock(&maps->lock);

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

842 843 844 845
	m = NULL;
out:
	pthread_rwlock_unlock(&maps->lock);
	return m;
846
}
847

848
struct map *maps__first(struct maps *maps)
849
{
850
	struct rb_node *first = rb_first(&maps->entries);
851 852 853 854 855 856

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

857
struct map *map__next(struct map *map)
858 859 860 861 862 863 864
{
	struct rb_node *next = rb_next(&map->rb_node);

	if (next)
		return rb_entry(next, struct map, rb_node);
	return NULL;
}
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884

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