root/tools/perf/util/map.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_anon_memory
  2. is_no_dso_memory
  3. is_android_lib
  4. replace_android_lib
  5. map__init
  6. map__new
  7. map__new2
  8. __map__is_kernel
  9. __map__is_extra_kernel_map
  10. __map__is_bpf_prog
  11. map__has_symbols
  12. map__exit
  13. map__delete
  14. map__put
  15. map__fixup_start
  16. map__fixup_end
  17. map__load
  18. map__find_symbol
  19. map__find_symbol_by_name
  20. map__clone
  21. map__fprintf
  22. map__fprintf_dsoname
  23. map__srcline
  24. map__fprintf_srcline
  25. map__fprintf_srccode
  26. srccode_state_free
  27. map__rip_2objdump
  28. map__objdump_2mem
  29. maps__init
  30. map_groups__init
  31. map_groups__insert
  32. __maps__purge
  33. __maps__purge_names
  34. maps__exit
  35. map_groups__exit
  36. map_groups__empty
  37. map_groups__new
  38. map_groups__delete
  39. map_groups__put
  40. map_groups__find_symbol
  41. map__contains_symbol
  42. maps__find_symbol_by_name
  43. map_groups__find_symbol_by_name
  44. map_groups__find_ams
  45. maps__fprintf
  46. map_groups__fprintf
  47. __map_groups__insert
  48. maps__fixup_overlappings
  49. map_groups__fixup_overlappings
  50. map_groups__clone
  51. __maps__insert
  52. __maps__insert_name
  53. maps__insert
  54. __maps__remove
  55. maps__remove
  56. maps__find
  57. maps__first
  58. map__next
  59. __map__kmap
  60. map__kmap
  61. map__kmaps

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

/* [<][>][^][v][top][bottom][index][help] */