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 "namespaces.h"
20
#include "unwind.h"
21

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

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

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

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

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

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

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

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

	app_abi_length = strlen(app_abi);

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

		if (!app_abi_length)
			return false;

		new_length = 7 + app_abi_length + lib_length;

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

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

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

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

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

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

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

		if (!arch)
			return false;

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

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

		return true;
	}
	return false;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

void map__delete(struct map *map)
{
	map__exit(map);
255
	free(map);
256 257
}

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

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

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

284 285
#define DSO__DELETED "(deleted)"

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

291
	if (dso__loaded(map->dso, map->type))
292 293
		return 0;

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

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

327 328 329
	return 0;
}

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

335
	return dso__find_symbol(map->dso, map->type, addr);
336 337
}

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

343 344
	if (!dso__sorted_by_name(map->dso, map->type))
		dso__sort_by_name(map->dso, map->type);
345

346
	return dso__find_symbol_by_name(map->dso, map->type, name);
347 348
}

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

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

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

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

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

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

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

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

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

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

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

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

440
	return map->unmap_ip(map, rip) - map->reloc;
441
}
442

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

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

470
	return ip + map->reloc;
471 472
}

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

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

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

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

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

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

510
void map_groups__exit(struct map_groups *mg)
511 512 513
{
	int i;

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

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

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

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

	return mg;
}

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

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

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

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

	return NULL;
}

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

574 575 576
	pthread_rwlock_rdlock(&maps->lock);

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

579
		sym = map__find_symbol_by_name(pos, name);
580 581 582 583 584

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

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

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

	return sym;
}

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

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

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

626 627 628
	pthread_rwlock_rdlock(&maps->lock);

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

638 639
	pthread_rwlock_unlock(&maps->lock);

640 641 642
	return printed;
}

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

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

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

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

670 671 672 673 674
	pthread_rwlock_wrlock(&maps->lock);

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

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

			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);
			}
693 694
		}

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

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

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

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

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

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

		if (err)
733
			goto out;
734 735
	}

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

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

759 760
	pthread_rwlock_rdlock(&maps->lock);

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

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

770
		map_groups__insert(mg, new);
771
		map__put(new);
772
	}
773 774 775 776 777

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

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

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

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

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

826 827 828
	pthread_rwlock_rdlock(&maps->lock);

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

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

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

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

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

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

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