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 "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 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 409
				      map__rip_2objdump(map, addr), NULL,
				      true, true);
410 411 412 413 414 415 416
		if (srcline != SRCLINE_UNKNOWN)
			ret = fprintf(fp, "%s%s", prefix, srcline);
		free_srcline(srcline);
	}
	return ret;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return mg;
}

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

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

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

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

	return NULL;
}

571
struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
572
					 struct map **mapp)
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);
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
struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
					       enum map_type type,
					       const char *name,
600
					       struct map **mapp)
601
{
602
	struct symbol *sym = maps__find_symbol_by_name(&mg->maps[type], name, mapp);
603 604 605 606

	return sym;
}

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

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

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

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

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

641 642
	pthread_rwlock_unlock(&maps->lock);

643 644 645
	return printed;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		if (err)
736
			goto out;
737 738
	}

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

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

762 763
	pthread_rwlock_rdlock(&maps->lock);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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