1// SPDX-License-Identifier: GPL-2.0 2#include "symbol.h" 3#include <assert.h> 4#include <errno.h> 5#include <inttypes.h> 6#include <limits.h> 7#include <stdlib.h> 8#include <string.h> 9#include <stdio.h> 10#include <unistd.h> 11#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ 12#include "dso.h" 13#include "map.h" 14#include "map_symbol.h" 15#include "thread.h" 16#include "vdso.h" 17#include "build-id.h" 18#include "debug.h" 19#include "machine.h" 20#include <linux/string.h> 21#include <linux/zalloc.h> 22#include "srcline.h" 23#include "namespaces.h" 24#include "unwind.h" 25#include "srccode.h" 26#include "ui/ui.h" 27 28static void __maps__insert(struct maps *maps, struct map *map); 29 30static inline int is_android_lib(const char *filename) 31{ 32 return strstarts(filename, "/data/app-lib/") || 33 strstarts(filename, "/system/lib/"); 34} 35 36static inline bool replace_android_lib(const char *filename, char *newfilename) 37{ 38 const char *libname; 39 char *app_abi; 40 size_t app_abi_length, new_length; 41 size_t lib_length = 0; 42 43 libname = strrchr(filename, '/'); 44 if (libname) 45 lib_length = strlen(libname); 46 47 app_abi = getenv("APP_ABI"); 48 if (!app_abi) 49 return false; 50 51 app_abi_length = strlen(app_abi); 52 53 if (strstarts(filename, "/data/app-lib/")) { 54 char *apk_path; 55 56 if (!app_abi_length) 57 return false; 58 59 new_length = 7 + app_abi_length + lib_length; 60 61 apk_path = getenv("APK_PATH"); 62 if (apk_path) { 63 new_length += strlen(apk_path) + 1; 64 if (new_length > PATH_MAX) 65 return false; 66 snprintf(newfilename, new_length, 67 "%s/libs/%s/%s", apk_path, app_abi, libname); 68 } else { 69 if (new_length > PATH_MAX) 70 return false; 71 snprintf(newfilename, new_length, 72 "libs/%s/%s", app_abi, libname); 73 } 74 return true; 75 } 76 77 if (strstarts(filename, "/system/lib/")) { 78 char *ndk, *app; 79 const char *arch; 80 int ndk_length, app_length; 81 82 ndk = getenv("NDK_ROOT"); 83 app = getenv("APP_PLATFORM"); 84 85 if (!(ndk && app)) 86 return false; 87 88 ndk_length = strlen(ndk); 89 app_length = strlen(app); 90 91 if (!(ndk_length && app_length && app_abi_length)) 92 return false; 93 94 arch = !strncmp(app_abi, "arm", 3) ? "arm" : 95 !strncmp(app_abi, "mips", 4) ? "mips" : 96 !strncmp(app_abi, "x86", 3) ? "x86" : NULL; 97 98 if (!arch) 99 return false; 100 101 new_length = 27 + ndk_length + 102 app_length + lib_length 103 + strlen(arch); 104 105 if (new_length > PATH_MAX) 106 return false; 107 snprintf(newfilename, new_length, 108 "%.*s/platforms/%.*s/arch-%s/usr/lib/%s", 109 ndk_length, ndk, app_length, app, arch, libname); 110 111 return true; 112 } 113 return false; 114} 115 116void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso) 117{ 118 map->start = start; 119 map->end = end; 120 map->pgoff = pgoff; 121 map->reloc = 0; 122 map->dso = dso__get(dso); 123 map->map_ip = map__map_ip; 124 map->unmap_ip = map__unmap_ip; 125 RB_CLEAR_NODE(&map->rb_node); 126 map->erange_warned = false; 127 refcount_set(&map->refcnt, 1); 128} 129 130struct map *map__new(struct machine *machine, u64 start, u64 len, 131 u64 pgoff, struct dso_id *id, 132 u32 prot, u32 flags, char *filename, 133 struct thread *thread) 134{ 135 struct map *map = malloc(sizeof(*map)); 136 struct nsinfo *nsi = NULL; 137 struct nsinfo *nnsi; 138 139 if (map != NULL) { 140 char newfilename[PATH_MAX]; 141 struct dso *dso; 142 int anon, no_dso, vdso, android; 143 144 android = is_android_lib(filename); 145 anon = is_anon_memory(filename) || flags & MAP_HUGETLB; 146 vdso = is_vdso_map(filename); 147 no_dso = is_no_dso_memory(filename); 148 map->prot = prot; 149 map->flags = flags; 150 nsi = nsinfo__get(thread->nsinfo); 151 152 if ((anon || no_dso) && nsi && (prot & PROT_EXEC)) { 153 snprintf(newfilename, sizeof(newfilename), 154 "/tmp/perf-%d.map", nsi->pid); 155 filename = newfilename; 156 } 157 158 if (android) { 159 if (replace_android_lib(filename, newfilename)) 160 filename = newfilename; 161 } 162 163 if (vdso) { 164 /* The vdso maps are always on the host and not the 165 * container. Ensure that we don't use setns to look 166 * them up. 167 */ 168 nnsi = nsinfo__copy(nsi); 169 if (nnsi) { 170 nsinfo__put(nsi); 171 nnsi->need_setns = false; 172 nsi = nnsi; 173 } 174 pgoff = 0; 175 dso = machine__findnew_vdso(machine, thread); 176 } else 177 dso = machine__findnew_dso_id(machine, filename, id); 178 179 if (dso == NULL) 180 goto out_delete; 181 182 map__init(map, start, start + len, pgoff, dso); 183 184 if (anon || no_dso) { 185 map->map_ip = map->unmap_ip = identity__map_ip; 186 187 /* 188 * Set memory without DSO as loaded. All map__find_* 189 * functions still return NULL, and we avoid the 190 * unnecessary map__load warning. 191 */ 192 if (!(prot & PROT_EXEC)) 193 dso__set_loaded(dso); 194 } 195 dso->nsinfo = nsi; 196 dso__put(dso); 197 } 198 return map; 199out_delete: 200 nsinfo__put(nsi); 201 free(map); 202 return NULL; 203} 204 205/* 206 * Constructor variant for modules (where we know from /proc/modules where 207 * they are loaded) and for vmlinux, where only after we load all the 208 * symbols we'll know where it starts and ends. 209 */ 210struct map *map__new2(u64 start, struct dso *dso) 211{ 212 struct map *map = calloc(1, (sizeof(*map) + 213 (dso->kernel ? sizeof(struct kmap) : 0))); 214 if (map != NULL) { 215 /* 216 * ->end will be filled after we load all the symbols 217 */ 218 map__init(map, start, 0, 0, dso); 219 } 220 221 return map; 222} 223 224bool __map__is_kernel(const struct map *map) 225{ 226 if (!map->dso->kernel) 227 return false; 228 return machine__kernel_map(map__kmaps((struct map *)map)->machine) == map; 229} 230 231bool __map__is_extra_kernel_map(const struct map *map) 232{ 233 struct kmap *kmap = __map__kmap((struct map *)map); 234 235 return kmap && kmap->name[0]; 236} 237 238bool __map__is_bpf_prog(const struct map *map) 239{ 240 const char *name; 241 242 if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) 243 return true; 244 245 /* 246 * If PERF_RECORD_BPF_EVENT is not included, the dso will not have 247 * type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can 248 * guess the type based on name. 249 */ 250 name = map->dso->short_name; 251 return name && (strstr(name, "bpf_prog_") == name); 252} 253 254bool __map__is_bpf_image(const struct map *map) 255{ 256 const char *name; 257 258 if (map->dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE) 259 return true; 260 261 /* 262 * If PERF_RECORD_KSYMBOL is not included, the dso will not have 263 * type of DSO_BINARY_TYPE__BPF_IMAGE. In such cases, we can 264 * guess the type based on name. 265 */ 266 name = map->dso->short_name; 267 return name && is_bpf_image(name); 268} 269 270bool __map__is_ool(const struct map *map) 271{ 272 return map->dso && map->dso->binary_type == DSO_BINARY_TYPE__OOL; 273} 274 275bool map__has_symbols(const struct map *map) 276{ 277 return dso__has_symbols(map->dso); 278} 279 280static void map__exit(struct map *map) 281{ 282 BUG_ON(refcount_read(&map->refcnt) != 0); 283 dso__zput(map->dso); 284} 285 286void map__delete(struct map *map) 287{ 288 map__exit(map); 289 free(map); 290} 291 292void map__put(struct map *map) 293{ 294 if (map && refcount_dec_and_test(&map->refcnt)) 295 map__delete(map); 296} 297 298void map__fixup_start(struct map *map) 299{ 300 struct rb_root_cached *symbols = &map->dso->symbols; 301 struct rb_node *nd = rb_first_cached(symbols); 302 if (nd != NULL) { 303 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 304 map->start = sym->start; 305 } 306} 307 308void map__fixup_end(struct map *map) 309{ 310 struct rb_root_cached *symbols = &map->dso->symbols; 311 struct rb_node *nd = rb_last(&symbols->rb_root); 312 if (nd != NULL) { 313 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 314 map->end = sym->end; 315 } 316} 317 318#define DSO__DELETED "(deleted)" 319 320int map__load(struct map *map) 321{ 322 const char *name = map->dso->long_name; 323 int nr; 324 325 if (dso__loaded(map->dso)) 326 return 0; 327 328 nr = dso__load(map->dso, map); 329 if (nr < 0) { 330 if (map->dso->has_build_id) { 331 char sbuild_id[SBUILD_ID_SIZE]; 332 333 build_id__sprintf(&map->dso->bid, sbuild_id); 334 pr_debug("%s with build id %s not found", name, sbuild_id); 335 } else 336 pr_debug("Failed to open %s", name); 337 338 pr_debug(", continuing without symbols\n"); 339 return -1; 340 } else if (nr == 0) { 341#ifdef HAVE_LIBELF_SUPPORT 342 const size_t len = strlen(name); 343 const size_t real_len = len - sizeof(DSO__DELETED); 344 345 if (len > sizeof(DSO__DELETED) && 346 strcmp(name + real_len + 1, DSO__DELETED) == 0) { 347 pr_debug("%.*s was updated (is prelink enabled?). " 348 "Restart the long running apps that use it!\n", 349 (int)real_len, name); 350 } else { 351 pr_debug("no symbols found in %s, maybe install a debug package?\n", name); 352 } 353#endif 354 return -1; 355 } 356 357 return 0; 358} 359 360struct symbol *map__find_symbol(struct map *map, u64 addr) 361{ 362 if (map__load(map) < 0) 363 return NULL; 364 365 return dso__find_symbol(map->dso, addr); 366} 367 368struct symbol *map__find_symbol_by_name(struct map *map, const char *name) 369{ 370 if (map__load(map) < 0) 371 return NULL; 372 373 if (!dso__sorted_by_name(map->dso)) 374 dso__sort_by_name(map->dso); 375 376 return dso__find_symbol_by_name(map->dso, name); 377} 378 379struct map *map__clone(struct map *from) 380{ 381 size_t size = sizeof(struct map); 382 struct map *map; 383 384 if (from->dso && from->dso->kernel) 385 size += sizeof(struct kmap); 386 387 map = memdup(from, size); 388 if (map != NULL) { 389 refcount_set(&map->refcnt, 1); 390 RB_CLEAR_NODE(&map->rb_node); 391 dso__get(map->dso); 392 } 393 394 return map; 395} 396 397size_t map__fprintf(struct map *map, FILE *fp) 398{ 399 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", 400 map->start, map->end, map->pgoff, map->dso->name); 401} 402 403size_t map__fprintf_dsoname(struct map *map, FILE *fp) 404{ 405 char buf[symbol_conf.pad_output_len_dso + 1]; 406 const char *dsoname = "[unknown]"; 407 408 if (map && map->dso) { 409 if (symbol_conf.show_kernel_path && map->dso->long_name) 410 dsoname = map->dso->long_name; 411 else 412 dsoname = map->dso->name; 413 } 414 415 if (symbol_conf.pad_output_len_dso) { 416 scnprintf_pad(buf, symbol_conf.pad_output_len_dso, "%s", dsoname); 417 dsoname = buf; 418 } 419 420 return fprintf(fp, "%s", dsoname); 421} 422 423char *map__srcline(struct map *map, u64 addr, struct symbol *sym) 424{ 425 if (map == NULL) 426 return SRCLINE_UNKNOWN; 427 return get_srcline(map->dso, map__rip_2objdump(map, addr), sym, true, true, addr); 428} 429 430int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, 431 FILE *fp) 432{ 433 int ret = 0; 434 435 if (map && map->dso) { 436 char *srcline = map__srcline(map, addr, NULL); 437 if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) 438 ret = fprintf(fp, "%s%s", prefix, srcline); 439 free_srcline(srcline); 440 } 441 return ret; 442} 443 444void srccode_state_free(struct srccode_state *state) 445{ 446 zfree(&state->srcfile); 447 state->line = 0; 448} 449 450/** 451 * map__rip_2objdump - convert symbol start address to objdump address. 452 * @map: memory map 453 * @rip: symbol start address 454 * 455 * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN. 456 * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is 457 * relative to section start. 458 * 459 * Return: Address suitable for passing to "objdump --start-address=" 460 */ 461u64 map__rip_2objdump(struct map *map, u64 rip) 462{ 463 struct kmap *kmap = __map__kmap(map); 464 465 /* 466 * vmlinux does not have program headers for PTI entry trampolines and 467 * kcore may not either. However the trampoline object code is on the 468 * main kernel map, so just use that instead. 469 */ 470 if (kmap && is_entry_trampoline(kmap->name) && kmap->kmaps && kmap->kmaps->machine) { 471 struct map *kernel_map = machine__kernel_map(kmap->kmaps->machine); 472 473 if (kernel_map) 474 map = kernel_map; 475 } 476 477 if (!map->dso->adjust_symbols) 478 return rip; 479 480 if (map->dso->rel) 481 return rip - map->pgoff; 482 483 /* 484 * kernel modules also have DSO_TYPE_USER in dso->kernel, 485 * but all kernel modules are ET_REL, so won't get here. 486 */ 487 if (map->dso->kernel == DSO_SPACE__USER) 488 return rip + map->dso->text_offset; 489 490 return map->unmap_ip(map, rip) - map->reloc; 491} 492 493/** 494 * map__objdump_2mem - convert objdump address to a memory address. 495 * @map: memory map 496 * @ip: objdump address 497 * 498 * Closely related to map__rip_2objdump(), this function takes an address from 499 * objdump and converts it to a memory address. Note this assumes that @map 500 * contains the address. To be sure the result is valid, check it forwards 501 * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip 502 * 503 * Return: Memory address. 504 */ 505u64 map__objdump_2mem(struct map *map, u64 ip) 506{ 507 if (!map->dso->adjust_symbols) 508 return map->unmap_ip(map, ip); 509 510 if (map->dso->rel) 511 return map->unmap_ip(map, ip + map->pgoff); 512 513 /* 514 * kernel modules also have DSO_TYPE_USER in dso->kernel, 515 * but all kernel modules are ET_REL, so won't get here. 516 */ 517 if (map->dso->kernel == DSO_SPACE__USER) 518 return map->unmap_ip(map, ip - map->dso->text_offset); 519 520 return ip + map->reloc; 521} 522 523void maps__init(struct maps *maps, struct machine *machine) 524{ 525 maps->entries = RB_ROOT; 526 init_rwsem(&maps->lock); 527 maps->machine = machine; 528 maps->last_search_by_name = NULL; 529 maps->nr_maps = 0; 530 maps->maps_by_name = NULL; 531 refcount_set(&maps->refcnt, 1); 532} 533 534static void __maps__free_maps_by_name(struct maps *maps) 535{ 536 /* 537 * Free everything to try to do it from the rbtree in the next search 538 */ 539 zfree(&maps->maps_by_name); 540 maps->nr_maps_allocated = 0; 541} 542 543void maps__insert(struct maps *maps, struct map *map) 544{ 545 down_write(&maps->lock); 546 __maps__insert(maps, map); 547 ++maps->nr_maps; 548 549 if (map->dso && map->dso->kernel) { 550 struct kmap *kmap = map__kmap(map); 551 552 if (kmap) 553 kmap->kmaps = maps; 554 else 555 pr_err("Internal error: kernel dso with non kernel map\n"); 556 } 557 558 559 /* 560 * If we already performed some search by name, then we need to add the just 561 * inserted map and resort. 562 */ 563 if (maps->maps_by_name) { 564 if (maps->nr_maps > maps->nr_maps_allocated) { 565 int nr_allocate = maps->nr_maps * 2; 566 struct map **maps_by_name = realloc(maps->maps_by_name, nr_allocate * sizeof(map)); 567 568 if (maps_by_name == NULL) { 569 __maps__free_maps_by_name(maps); 570 up_write(&maps->lock); 571 return; 572 } 573 574 maps->maps_by_name = maps_by_name; 575 maps->nr_maps_allocated = nr_allocate; 576 } 577 maps->maps_by_name[maps->nr_maps - 1] = map; 578 __maps__sort_by_name(maps); 579 } 580 up_write(&maps->lock); 581} 582 583static void __maps__remove(struct maps *maps, struct map *map) 584{ 585 rb_erase_init(&map->rb_node, &maps->entries); 586 map__put(map); 587} 588 589void maps__remove(struct maps *maps, struct map *map) 590{ 591 down_write(&maps->lock); 592 if (maps->last_search_by_name == map) 593 maps->last_search_by_name = NULL; 594 595 __maps__remove(maps, map); 596 --maps->nr_maps; 597 if (maps->maps_by_name) 598 __maps__free_maps_by_name(maps); 599 up_write(&maps->lock); 600} 601 602static void __maps__purge(struct maps *maps) 603{ 604 struct map *pos, *next; 605 606 maps__for_each_entry_safe(maps, pos, next) { 607 rb_erase_init(&pos->rb_node, &maps->entries); 608 map__put(pos); 609 } 610} 611 612void maps__exit(struct maps *maps) 613{ 614 down_write(&maps->lock); 615 __maps__purge(maps); 616 up_write(&maps->lock); 617} 618 619bool maps__empty(struct maps *maps) 620{ 621 return !maps__first(maps); 622} 623 624struct maps *maps__new(struct machine *machine) 625{ 626 struct maps *maps = zalloc(sizeof(*maps)); 627 628 if (maps != NULL) 629 maps__init(maps, machine); 630 631 return maps; 632} 633 634void maps__delete(struct maps *maps) 635{ 636 maps__exit(maps); 637 unwind__finish_access(maps); 638 free(maps); 639} 640 641void maps__put(struct maps *maps) 642{ 643 if (maps && refcount_dec_and_test(&maps->refcnt)) 644 maps__delete(maps); 645} 646 647struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp) 648{ 649 struct map *map = maps__find(maps, addr); 650 651 /* Ensure map is loaded before using map->map_ip */ 652 if (map != NULL && map__load(map) >= 0) { 653 if (mapp != NULL) 654 *mapp = map; 655 return map__find_symbol(map, map->map_ip(map, addr)); 656 } 657 658 return NULL; 659} 660 661static bool map__contains_symbol(struct map *map, struct symbol *sym) 662{ 663 u64 ip = map->unmap_ip(map, sym->start); 664 665 return ip >= map->start && ip < map->end; 666} 667 668struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, struct map **mapp) 669{ 670 struct symbol *sym; 671 struct map *pos; 672 673 down_read(&maps->lock); 674 675 maps__for_each_entry(maps, pos) { 676 sym = map__find_symbol_by_name(pos, name); 677 678 if (sym == NULL) 679 continue; 680 if (!map__contains_symbol(pos, sym)) { 681 sym = NULL; 682 continue; 683 } 684 if (mapp != NULL) 685 *mapp = pos; 686 goto out; 687 } 688 689 sym = NULL; 690out: 691 up_read(&maps->lock); 692 return sym; 693} 694 695int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) 696{ 697 if (ams->addr < ams->ms.map->start || ams->addr >= ams->ms.map->end) { 698 if (maps == NULL) 699 return -1; 700 ams->ms.map = maps__find(maps, ams->addr); 701 if (ams->ms.map == NULL) 702 return -1; 703 } 704 705 ams->al_addr = ams->ms.map->map_ip(ams->ms.map, ams->addr); 706 ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr); 707 708 return ams->ms.sym ? 0 : -1; 709} 710 711size_t maps__fprintf(struct maps *maps, FILE *fp) 712{ 713 size_t printed = 0; 714 struct map *pos; 715 716 down_read(&maps->lock); 717 718 maps__for_each_entry(maps, pos) { 719 printed += fprintf(fp, "Map:"); 720 printed += map__fprintf(pos, fp); 721 if (verbose > 2) { 722 printed += dso__fprintf(pos->dso, fp); 723 printed += fprintf(fp, "--\n"); 724 } 725 } 726 727 up_read(&maps->lock); 728 729 return printed; 730} 731 732int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) 733{ 734 struct rb_root *root; 735 struct rb_node *next, *first; 736 int err = 0; 737 738 down_write(&maps->lock); 739 740 root = &maps->entries; 741 742 /* 743 * Find first map where end > map->start. 744 * Same as find_vma() in kernel. 745 */ 746 next = root->rb_node; 747 first = NULL; 748 while (next) { 749 struct map *pos = rb_entry(next, struct map, rb_node); 750 751 if (pos->end > map->start) { 752 first = next; 753 if (pos->start <= map->start) 754 break; 755 next = next->rb_left; 756 } else 757 next = next->rb_right; 758 } 759 760 next = first; 761 while (next) { 762 struct map *pos = rb_entry(next, struct map, rb_node); 763 next = rb_next(&pos->rb_node); 764 765 /* 766 * Stop if current map starts after map->end. 767 * Maps are ordered by start: next will not overlap for sure. 768 */ 769 if (pos->start >= map->end) 770 break; 771 772 if (verbose >= 2) { 773 774 if (use_browser) { 775 pr_debug("overlapping maps in %s (disable tui for more info)\n", 776 map->dso->name); 777 } else { 778 fputs("overlapping maps:\n", fp); 779 map__fprintf(map, fp); 780 map__fprintf(pos, fp); 781 } 782 } 783 784 rb_erase_init(&pos->rb_node, root); 785 /* 786 * Now check if we need to create new maps for areas not 787 * overlapped by the new map: 788 */ 789 if (map->start > pos->start) { 790 struct map *before = map__clone(pos); 791 792 if (before == NULL) { 793 err = -ENOMEM; 794 goto put_map; 795 } 796 797 before->end = map->start; 798 __maps__insert(maps, before); 799 if (verbose >= 2 && !use_browser) 800 map__fprintf(before, fp); 801 map__put(before); 802 } 803 804 if (map->end < pos->end) { 805 struct map *after = map__clone(pos); 806 807 if (after == NULL) { 808 err = -ENOMEM; 809 goto put_map; 810 } 811 812 after->start = map->end; 813 after->pgoff += map->end - pos->start; 814 assert(pos->map_ip(pos, map->end) == after->map_ip(after, map->end)); 815 __maps__insert(maps, after); 816 if (verbose >= 2 && !use_browser) 817 map__fprintf(after, fp); 818 map__put(after); 819 } 820put_map: 821 map__put(pos); 822 823 if (err) 824 goto out; 825 } 826 827 err = 0; 828out: 829 up_write(&maps->lock); 830 return err; 831} 832 833/* 834 * XXX This should not really _copy_ te maps, but refcount them. 835 */ 836int maps__clone(struct thread *thread, struct maps *parent) 837{ 838 struct maps *maps = thread->maps; 839 int err; 840 struct map *map; 841 842 down_read(&parent->lock); 843 844 maps__for_each_entry(parent, map) { 845 struct map *new = map__clone(map); 846 847 if (new == NULL) { 848 err = -ENOMEM; 849 goto out_unlock; 850 } 851 852 err = unwind__prepare_access(maps, new, NULL); 853 if (err) 854 goto out_unlock; 855 856 maps__insert(maps, new); 857 map__put(new); 858 } 859 860 err = 0; 861out_unlock: 862 up_read(&parent->lock); 863 return err; 864} 865 866static void __maps__insert(struct maps *maps, struct map *map) 867{ 868 struct rb_node **p = &maps->entries.rb_node; 869 struct rb_node *parent = NULL; 870 const u64 ip = map->start; 871 struct map *m; 872 873 while (*p != NULL) { 874 parent = *p; 875 m = rb_entry(parent, struct map, rb_node); 876 if (ip < m->start) 877 p = &(*p)->rb_left; 878 else 879 p = &(*p)->rb_right; 880 } 881 882 rb_link_node(&map->rb_node, parent, p); 883 rb_insert_color(&map->rb_node, &maps->entries); 884 map__get(map); 885} 886 887struct map *maps__find(struct maps *maps, u64 ip) 888{ 889 struct rb_node *p; 890 struct map *m; 891 892 down_read(&maps->lock); 893 894 p = maps->entries.rb_node; 895 while (p != NULL) { 896 m = rb_entry(p, struct map, rb_node); 897 if (ip < m->start) 898 p = p->rb_left; 899 else if (ip >= m->end) 900 p = p->rb_right; 901 else 902 goto out; 903 } 904 905 m = NULL; 906out: 907 up_read(&maps->lock); 908 return m; 909} 910 911struct map *maps__first(struct maps *maps) 912{ 913 struct rb_node *first = rb_first(&maps->entries); 914 915 if (first) 916 return rb_entry(first, struct map, rb_node); 917 return NULL; 918} 919 920static struct map *__map__next(struct map *map) 921{ 922 struct rb_node *next = rb_next(&map->rb_node); 923 924 if (next) 925 return rb_entry(next, struct map, rb_node); 926 return NULL; 927} 928 929struct map *map__next(struct map *map) 930{ 931 return map ? __map__next(map) : NULL; 932} 933 934struct kmap *__map__kmap(struct map *map) 935{ 936 if (!map->dso || !map->dso->kernel) 937 return NULL; 938 return (struct kmap *)(map + 1); 939} 940 941struct kmap *map__kmap(struct map *map) 942{ 943 struct kmap *kmap = __map__kmap(map); 944 945 if (!kmap) 946 pr_err("Internal error: map__kmap with a non-kernel map\n"); 947 return kmap; 948} 949 950struct maps *map__kmaps(struct map *map) 951{ 952 struct kmap *kmap = map__kmap(map); 953 954 if (!kmap || !kmap->kmaps) { 955 pr_err("Internal error: map__kmaps with a non-kernel map\n"); 956 return NULL; 957 } 958 return kmap->kmaps; 959} 960