map.c 18.2 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

227 228 229 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)
{
	return map->groups->machine->vmlinux_maps[map->type] == map;
}

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

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

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

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

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

279 280
#define DSO__DELETED "(deleted)"

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

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

289
	nr = dso__load(map->dso, map, filter);
290
	if (nr < 0) {
291
		if (map->dso->has_build_id) {
292 293
			char sbuild_id[BUILD_ID_SIZE * 2 + 1];

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

322 323 324
	return 0;
}

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

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

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

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

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

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

351
struct map *map__clone(struct map *map)
352
{
353
	return memdup(map, sizeof(*map));
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
}

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

370
size_t map__fprintf(struct map *map, FILE *fp)
371
{
372
	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
373
		       map->start, map->end, map->pgoff, map->dso->name);
374
}
375

376 377
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
{
378
	const char *dsoname = "[unknown]";
379

380 381 382 383 384
	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;
385
	}
386 387 388 389

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

390 391 392 393 394 395 396 397
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,
398
				      map__rip_2objdump(map, addr), NULL, true);
399 400 401 402 403 404 405
		if (srcline != SRCLINE_UNKNOWN)
			ret = fprintf(fp, "%s%s", prefix, srcline);
		free_srcline(srcline);
	}
	return ret;
}

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

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

425
	return map->unmap_ip(map, rip) - map->reloc;
426
}
427

428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
/**
 * 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);

448
	return ip + map->reloc;
449 450
}

451 452 453
static void maps__init(struct maps *maps)
{
	maps->entries = RB_ROOT;
454
	pthread_rwlock_init(&maps->lock, NULL);
455 456
}

457
void map_groups__init(struct map_groups *mg, struct machine *machine)
458 459 460
{
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i) {
461
		maps__init(&mg->maps[i]);
462
	}
463
	mg->machine = machine;
464
	atomic_set(&mg->refcnt, 1);
465 466
}

467
static void __maps__purge(struct maps *maps)
468
{
469 470
	struct rb_root *root = &maps->entries;
	struct rb_node *next = rb_first(root);
471 472 473 474 475

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

		next = rb_next(&pos->rb_node);
476
		rb_erase_init(&pos->rb_node, root);
477
		map__put(pos);
478 479 480
	}
}

481 482
static void maps__exit(struct maps *maps)
{
483 484 485
	pthread_rwlock_wrlock(&maps->lock);
	__maps__purge(maps);
	pthread_rwlock_unlock(&maps->lock);
486 487
}

488
void map_groups__exit(struct map_groups *mg)
489 490 491
{
	int i;

492 493
	for (i = 0; i < MAP__NR_TYPES; ++i)
		maps__exit(&mg->maps[i]);
494 495
}

496 497 498 499 500 501 502 503 504 505 506 507
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;
}

508
struct map_groups *map_groups__new(struct machine *machine)
509 510 511 512
{
	struct map_groups *mg = malloc(sizeof(*mg));

	if (mg != NULL)
513
		map_groups__init(mg, machine);
514 515 516 517 518 519 520 521 522 523

	return mg;
}

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

524 525
void map_groups__put(struct map_groups *mg)
{
526
	if (mg && atomic_dec_and_test(&mg->refcnt))
527 528 529
		map_groups__delete(mg);
}

530
struct symbol *map_groups__find_symbol(struct map_groups *mg,
531
				       enum map_type type, u64 addr,
532
				       struct map **mapp,
533 534
				       symbol_filter_t filter)
{
535
	struct map *map = map_groups__find(mg, type, addr);
536

537 538
	/* Ensure map is loaded before using map->map_ip */
	if (map != NULL && map__load(map, filter) >= 0) {
539 540
		if (mapp != NULL)
			*mapp = map;
541
		return map__find_symbol(map, map->map_ip(map, addr), filter);
542 543 544 545 546
	}

	return NULL;
}

547
struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
548 549 550 551 552
					       enum map_type type,
					       const char *name,
					       struct map **mapp,
					       symbol_filter_t filter)
{
553 554
	struct maps *maps = &mg->maps[type];
	struct symbol *sym;
555 556
	struct rb_node *nd;

557 558 559
	pthread_rwlock_rdlock(&maps->lock);

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

		sym = map__find_symbol_by_name(pos, name, filter);
563 564 565 566 567

		if (sym == NULL)
			continue;
		if (mapp != NULL)
			*mapp = pos;
568
		goto out;
569
	}
570

571 572 573 574
	sym = NULL;
out:
	pthread_rwlock_unlock(&maps->lock);
	return sym;
575 576
}

577 578
int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter)
{
579
	if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
580 581 582 583 584 585 586 587 588 589 590 591 592 593
		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;
}

594
static size_t maps__fprintf(struct maps *maps, FILE *fp)
595
{
596
	size_t printed = 0;
597 598
	struct rb_node *nd;

599 600 601
	pthread_rwlock_rdlock(&maps->lock);

	for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
602 603 604 605
		struct map *pos = rb_entry(nd, struct map, rb_node);
		printed += fprintf(fp, "Map:");
		printed += map__fprintf(pos, fp);
		if (verbose > 2) {
606
			printed += dso__fprintf(pos->dso, pos->type, fp);
607 608 609 610
			printed += fprintf(fp, "--\n");
		}
	}

611 612
	pthread_rwlock_unlock(&maps->lock);

613 614 615
	return printed;
}

616 617 618 619 620 621 622
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);
}

623
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
624 625 626
{
	size_t printed = 0, i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
627
		printed += __map_groups__fprintf_maps(mg, i, fp);
628 629 630
	return printed;
}

631
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
632
{
633 634
	struct rb_root *root;
	struct rb_node *next;
635
	int err = 0;
636

637 638 639 640 641
	pthread_rwlock_wrlock(&maps->lock);

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

642 643 644 645 646 647 648 649 650 651 652 653 654
	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);
		}

655
		rb_erase_init(&pos->rb_node, root);
656 657 658 659 660 661 662
		/*
		 * 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);

663 664
			if (before == NULL) {
				err = -ENOMEM;
665
				goto put_map;
666
			}
667

668
			before->end = map->start;
669
			__maps__insert(maps, before);
670 671 672 673 674 675 676
			if (verbose >= 2)
				map__fprintf(before, fp);
		}

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

677 678
			if (after == NULL) {
				err = -ENOMEM;
679
				goto put_map;
680
			}
681

682
			after->start = map->end;
683
			__maps__insert(maps, after);
684 685 686
			if (verbose >= 2)
				map__fprintf(after, fp);
		}
687
put_map:
688
		map__put(pos);
689 690

		if (err)
691
			goto out;
692 693
	}

694 695 696 697 698 699 700 701 702 703
	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);
704 705 706 707 708
}

/*
 * XXX This should not really _copy_ te maps, but refcount them.
 */
709
int map_groups__clone(struct map_groups *mg,
710 711
		      struct map_groups *parent, enum map_type type)
{
712
	int err = -ENOMEM;
713
	struct map *map;
714
	struct maps *maps = &parent->maps[type];
715

716 717
	pthread_rwlock_rdlock(&maps->lock);

718
	for (map = maps__first(maps); map; map = map__next(map)) {
719 720
		struct map *new = map__clone(map);
		if (new == NULL)
721
			goto out_unlock;
722
		map_groups__insert(mg, new);
723
	}
724 725 726 727 728

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

731
static void __maps__insert(struct maps *maps, struct map *map)
732
{
733
	struct rb_node **p = &maps->entries.rb_node;
734 735 736 737 738 739 740 741 742 743 744 745 746 747
	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);
748
	rb_insert_color(&map->rb_node, &maps->entries);
749
	map__get(map);
750 751
}

752 753 754 755 756 757 758 759
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)
760
{
761
	rb_erase_init(&map->rb_node, &maps->entries);
762
	map__put(map);
763 764
}

765 766 767 768 769 770 771
void maps__remove(struct maps *maps, struct map *map)
{
	pthread_rwlock_wrlock(&maps->lock);
	__maps__remove(maps, map);
	pthread_rwlock_unlock(&maps->lock);
}

772
struct map *maps__find(struct maps *maps, u64 ip)
773
{
774
	struct rb_node **p, *parent = NULL;
775 776
	struct map *m;

777 778 779
	pthread_rwlock_rdlock(&maps->lock);

	p = &maps->entries.rb_node;
780 781 782 783 784
	while (*p != NULL) {
		parent = *p;
		m = rb_entry(parent, struct map, rb_node);
		if (ip < m->start)
			p = &(*p)->rb_left;
785
		else if (ip >= m->end)
786 787
			p = &(*p)->rb_right;
		else
788
			goto out;
789 790
	}

791 792 793 794
	m = NULL;
out:
	pthread_rwlock_unlock(&maps->lock);
	return m;
795
}
796

797
struct map *maps__first(struct maps *maps)
798
{
799
	struct rb_node *first = rb_first(&maps->entries);
800 801 802 803 804 805

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

806
struct map *map__next(struct map *map)
807 808 809 810 811 812 813
{
	struct rb_node *next = rb_next(&map->rb_node);

	if (next)
		return rb_entry(next, struct map, rb_node);
	return NULL;
}
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833

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