at v3.6-rc2 17 kB view raw
1#include "symbol.h" 2#include <errno.h> 3#include <inttypes.h> 4#include <limits.h> 5#include <stdlib.h> 6#include <string.h> 7#include <stdio.h> 8#include <unistd.h> 9#include "map.h" 10#include "thread.h" 11#include "strlist.h" 12 13const char *map_type__name[MAP__NR_TYPES] = { 14 [MAP__FUNCTION] = "Functions", 15 [MAP__VARIABLE] = "Variables", 16}; 17 18static inline int is_anon_memory(const char *filename) 19{ 20 return strcmp(filename, "//anon") == 0; 21} 22 23static inline int is_no_dso_memory(const char *filename) 24{ 25 return !strcmp(filename, "[stack]") || 26 !strcmp(filename, "[vdso]") || 27 !strcmp(filename, "[heap]"); 28} 29 30void map__init(struct map *self, enum map_type type, 31 u64 start, u64 end, u64 pgoff, struct dso *dso) 32{ 33 self->type = type; 34 self->start = start; 35 self->end = end; 36 self->pgoff = pgoff; 37 self->dso = dso; 38 self->map_ip = map__map_ip; 39 self->unmap_ip = map__unmap_ip; 40 RB_CLEAR_NODE(&self->rb_node); 41 self->groups = NULL; 42 self->referenced = false; 43 self->erange_warned = false; 44} 45 46struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, 47 u64 pgoff, u32 pid, char *filename, 48 enum map_type type) 49{ 50 struct map *self = malloc(sizeof(*self)); 51 52 if (self != NULL) { 53 char newfilename[PATH_MAX]; 54 struct dso *dso; 55 int anon, no_dso; 56 57 anon = is_anon_memory(filename); 58 no_dso = is_no_dso_memory(filename); 59 60 if (anon) { 61 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); 62 filename = newfilename; 63 } 64 65 dso = __dsos__findnew(dsos__list, filename); 66 if (dso == NULL) 67 goto out_delete; 68 69 map__init(self, type, start, start + len, pgoff, dso); 70 71 if (anon || no_dso) { 72 self->map_ip = self->unmap_ip = identity__map_ip; 73 74 /* 75 * Set memory without DSO as loaded. All map__find_* 76 * functions still return NULL, and we avoid the 77 * unnecessary map__load warning. 78 */ 79 if (no_dso) 80 dso__set_loaded(dso, self->type); 81 } 82 } 83 return self; 84out_delete: 85 free(self); 86 return NULL; 87} 88 89void map__delete(struct map *self) 90{ 91 free(self); 92} 93 94void map__fixup_start(struct map *self) 95{ 96 struct rb_root *symbols = &self->dso->symbols[self->type]; 97 struct rb_node *nd = rb_first(symbols); 98 if (nd != NULL) { 99 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 100 self->start = sym->start; 101 } 102} 103 104void map__fixup_end(struct map *self) 105{ 106 struct rb_root *symbols = &self->dso->symbols[self->type]; 107 struct rb_node *nd = rb_last(symbols); 108 if (nd != NULL) { 109 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 110 self->end = sym->end; 111 } 112} 113 114#define DSO__DELETED "(deleted)" 115 116int map__load(struct map *self, symbol_filter_t filter) 117{ 118 const char *name = self->dso->long_name; 119 int nr; 120 121 if (dso__loaded(self->dso, self->type)) 122 return 0; 123 124 nr = dso__load(self->dso, self, filter); 125 if (nr < 0) { 126 if (self->dso->has_build_id) { 127 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 128 129 build_id__sprintf(self->dso->build_id, 130 sizeof(self->dso->build_id), 131 sbuild_id); 132 pr_warning("%s with build id %s not found", 133 name, sbuild_id); 134 } else 135 pr_warning("Failed to open %s", name); 136 137 pr_warning(", continuing without symbols\n"); 138 return -1; 139 } else if (nr == 0) { 140 const size_t len = strlen(name); 141 const size_t real_len = len - sizeof(DSO__DELETED); 142 143 if (len > sizeof(DSO__DELETED) && 144 strcmp(name + real_len + 1, DSO__DELETED) == 0) { 145 pr_warning("%.*s was updated (is prelink enabled?). " 146 "Restart the long running apps that use it!\n", 147 (int)real_len, name); 148 } else { 149 pr_warning("no symbols found in %s, maybe install " 150 "a debug package?\n", name); 151 } 152 153 return -1; 154 } 155 /* 156 * Only applies to the kernel, as its symtabs aren't relative like the 157 * module ones. 158 */ 159 if (self->dso->kernel) 160 map__reloc_vmlinux(self); 161 162 return 0; 163} 164 165struct symbol *map__find_symbol(struct map *self, u64 addr, 166 symbol_filter_t filter) 167{ 168 if (map__load(self, filter) < 0) 169 return NULL; 170 171 return dso__find_symbol(self->dso, self->type, addr); 172} 173 174struct symbol *map__find_symbol_by_name(struct map *self, const char *name, 175 symbol_filter_t filter) 176{ 177 if (map__load(self, filter) < 0) 178 return NULL; 179 180 if (!dso__sorted_by_name(self->dso, self->type)) 181 dso__sort_by_name(self->dso, self->type); 182 183 return dso__find_symbol_by_name(self->dso, self->type, name); 184} 185 186struct map *map__clone(struct map *self) 187{ 188 struct map *map = malloc(sizeof(*self)); 189 190 if (!map) 191 return NULL; 192 193 memcpy(map, self, sizeof(*self)); 194 195 return map; 196} 197 198int map__overlap(struct map *l, struct map *r) 199{ 200 if (l->start > r->start) { 201 struct map *t = l; 202 l = r; 203 r = t; 204 } 205 206 if (l->end > r->start) 207 return 1; 208 209 return 0; 210} 211 212size_t map__fprintf(struct map *self, FILE *fp) 213{ 214 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", 215 self->start, self->end, self->pgoff, self->dso->name); 216} 217 218size_t map__fprintf_dsoname(struct map *map, FILE *fp) 219{ 220 const char *dsoname; 221 222 if (map && map->dso && (map->dso->name || map->dso->long_name)) { 223 if (symbol_conf.show_kernel_path && map->dso->long_name) 224 dsoname = map->dso->long_name; 225 else if (map->dso->name) 226 dsoname = map->dso->name; 227 } else 228 dsoname = "[unknown]"; 229 230 return fprintf(fp, "%s", dsoname); 231} 232 233/* 234 * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN. 235 * map->dso->adjust_symbols==1 for ET_EXEC-like cases. 236 */ 237u64 map__rip_2objdump(struct map *map, u64 rip) 238{ 239 u64 addr = map->dso->adjust_symbols ? 240 map->unmap_ip(map, rip) : /* RIP -> IP */ 241 rip; 242 return addr; 243} 244 245u64 map__objdump_2ip(struct map *map, u64 addr) 246{ 247 u64 ip = map->dso->adjust_symbols ? 248 addr : 249 map->unmap_ip(map, addr); /* RIP -> IP */ 250 return ip; 251} 252 253void map_groups__init(struct map_groups *mg) 254{ 255 int i; 256 for (i = 0; i < MAP__NR_TYPES; ++i) { 257 mg->maps[i] = RB_ROOT; 258 INIT_LIST_HEAD(&mg->removed_maps[i]); 259 } 260 mg->machine = NULL; 261} 262 263static void maps__delete(struct rb_root *maps) 264{ 265 struct rb_node *next = rb_first(maps); 266 267 while (next) { 268 struct map *pos = rb_entry(next, struct map, rb_node); 269 270 next = rb_next(&pos->rb_node); 271 rb_erase(&pos->rb_node, maps); 272 map__delete(pos); 273 } 274} 275 276static void maps__delete_removed(struct list_head *maps) 277{ 278 struct map *pos, *n; 279 280 list_for_each_entry_safe(pos, n, maps, node) { 281 list_del(&pos->node); 282 map__delete(pos); 283 } 284} 285 286void map_groups__exit(struct map_groups *mg) 287{ 288 int i; 289 290 for (i = 0; i < MAP__NR_TYPES; ++i) { 291 maps__delete(&mg->maps[i]); 292 maps__delete_removed(&mg->removed_maps[i]); 293 } 294} 295 296void map_groups__flush(struct map_groups *mg) 297{ 298 int type; 299 300 for (type = 0; type < MAP__NR_TYPES; type++) { 301 struct rb_root *root = &mg->maps[type]; 302 struct rb_node *next = rb_first(root); 303 304 while (next) { 305 struct map *pos = rb_entry(next, struct map, rb_node); 306 next = rb_next(&pos->rb_node); 307 rb_erase(&pos->rb_node, root); 308 /* 309 * We may have references to this map, for 310 * instance in some hist_entry instances, so 311 * just move them to a separate list. 312 */ 313 list_add_tail(&pos->node, &mg->removed_maps[pos->type]); 314 } 315 } 316} 317 318struct symbol *map_groups__find_symbol(struct map_groups *mg, 319 enum map_type type, u64 addr, 320 struct map **mapp, 321 symbol_filter_t filter) 322{ 323 struct map *map = map_groups__find(mg, type, addr); 324 325 if (map != NULL) { 326 if (mapp != NULL) 327 *mapp = map; 328 return map__find_symbol(map, map->map_ip(map, addr), filter); 329 } 330 331 return NULL; 332} 333 334struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, 335 enum map_type type, 336 const char *name, 337 struct map **mapp, 338 symbol_filter_t filter) 339{ 340 struct rb_node *nd; 341 342 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) { 343 struct map *pos = rb_entry(nd, struct map, rb_node); 344 struct symbol *sym = map__find_symbol_by_name(pos, name, filter); 345 346 if (sym == NULL) 347 continue; 348 if (mapp != NULL) 349 *mapp = pos; 350 return sym; 351 } 352 353 return NULL; 354} 355 356size_t __map_groups__fprintf_maps(struct map_groups *mg, 357 enum map_type type, int verbose, FILE *fp) 358{ 359 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); 360 struct rb_node *nd; 361 362 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) { 363 struct map *pos = rb_entry(nd, struct map, rb_node); 364 printed += fprintf(fp, "Map:"); 365 printed += map__fprintf(pos, fp); 366 if (verbose > 2) { 367 printed += dso__fprintf(pos->dso, type, fp); 368 printed += fprintf(fp, "--\n"); 369 } 370 } 371 372 return printed; 373} 374 375size_t map_groups__fprintf_maps(struct map_groups *mg, int verbose, FILE *fp) 376{ 377 size_t printed = 0, i; 378 for (i = 0; i < MAP__NR_TYPES; ++i) 379 printed += __map_groups__fprintf_maps(mg, i, verbose, fp); 380 return printed; 381} 382 383static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg, 384 enum map_type type, 385 int verbose, FILE *fp) 386{ 387 struct map *pos; 388 size_t printed = 0; 389 390 list_for_each_entry(pos, &mg->removed_maps[type], node) { 391 printed += fprintf(fp, "Map:"); 392 printed += map__fprintf(pos, fp); 393 if (verbose > 1) { 394 printed += dso__fprintf(pos->dso, type, fp); 395 printed += fprintf(fp, "--\n"); 396 } 397 } 398 return printed; 399} 400 401static size_t map_groups__fprintf_removed_maps(struct map_groups *mg, 402 int verbose, FILE *fp) 403{ 404 size_t printed = 0, i; 405 for (i = 0; i < MAP__NR_TYPES; ++i) 406 printed += __map_groups__fprintf_removed_maps(mg, i, verbose, fp); 407 return printed; 408} 409 410size_t map_groups__fprintf(struct map_groups *mg, int verbose, FILE *fp) 411{ 412 size_t printed = map_groups__fprintf_maps(mg, verbose, fp); 413 printed += fprintf(fp, "Removed maps:\n"); 414 return printed + map_groups__fprintf_removed_maps(mg, verbose, fp); 415} 416 417int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, 418 int verbose, FILE *fp) 419{ 420 struct rb_root *root = &mg->maps[map->type]; 421 struct rb_node *next = rb_first(root); 422 int err = 0; 423 424 while (next) { 425 struct map *pos = rb_entry(next, struct map, rb_node); 426 next = rb_next(&pos->rb_node); 427 428 if (!map__overlap(pos, map)) 429 continue; 430 431 if (verbose >= 2) { 432 fputs("overlapping maps:\n", fp); 433 map__fprintf(map, fp); 434 map__fprintf(pos, fp); 435 } 436 437 rb_erase(&pos->rb_node, root); 438 /* 439 * Now check if we need to create new maps for areas not 440 * overlapped by the new map: 441 */ 442 if (map->start > pos->start) { 443 struct map *before = map__clone(pos); 444 445 if (before == NULL) { 446 err = -ENOMEM; 447 goto move_map; 448 } 449 450 before->end = map->start - 1; 451 map_groups__insert(mg, before); 452 if (verbose >= 2) 453 map__fprintf(before, fp); 454 } 455 456 if (map->end < pos->end) { 457 struct map *after = map__clone(pos); 458 459 if (after == NULL) { 460 err = -ENOMEM; 461 goto move_map; 462 } 463 464 after->start = map->end + 1; 465 map_groups__insert(mg, after); 466 if (verbose >= 2) 467 map__fprintf(after, fp); 468 } 469move_map: 470 /* 471 * If we have references, just move them to a separate list. 472 */ 473 if (pos->referenced) 474 list_add_tail(&pos->node, &mg->removed_maps[map->type]); 475 else 476 map__delete(pos); 477 478 if (err) 479 return err; 480 } 481 482 return 0; 483} 484 485/* 486 * XXX This should not really _copy_ te maps, but refcount them. 487 */ 488int map_groups__clone(struct map_groups *mg, 489 struct map_groups *parent, enum map_type type) 490{ 491 struct rb_node *nd; 492 for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) { 493 struct map *map = rb_entry(nd, struct map, rb_node); 494 struct map *new = map__clone(map); 495 if (new == NULL) 496 return -ENOMEM; 497 map_groups__insert(mg, new); 498 } 499 return 0; 500} 501 502static u64 map__reloc_map_ip(struct map *map, u64 ip) 503{ 504 return ip + (s64)map->pgoff; 505} 506 507static u64 map__reloc_unmap_ip(struct map *map, u64 ip) 508{ 509 return ip - (s64)map->pgoff; 510} 511 512void map__reloc_vmlinux(struct map *self) 513{ 514 struct kmap *kmap = map__kmap(self); 515 s64 reloc; 516 517 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr) 518 return; 519 520 reloc = (kmap->ref_reloc_sym->unrelocated_addr - 521 kmap->ref_reloc_sym->addr); 522 523 if (!reloc) 524 return; 525 526 self->map_ip = map__reloc_map_ip; 527 self->unmap_ip = map__reloc_unmap_ip; 528 self->pgoff = reloc; 529} 530 531void maps__insert(struct rb_root *maps, struct map *map) 532{ 533 struct rb_node **p = &maps->rb_node; 534 struct rb_node *parent = NULL; 535 const u64 ip = map->start; 536 struct map *m; 537 538 while (*p != NULL) { 539 parent = *p; 540 m = rb_entry(parent, struct map, rb_node); 541 if (ip < m->start) 542 p = &(*p)->rb_left; 543 else 544 p = &(*p)->rb_right; 545 } 546 547 rb_link_node(&map->rb_node, parent, p); 548 rb_insert_color(&map->rb_node, maps); 549} 550 551void maps__remove(struct rb_root *self, struct map *map) 552{ 553 rb_erase(&map->rb_node, self); 554} 555 556struct map *maps__find(struct rb_root *maps, u64 ip) 557{ 558 struct rb_node **p = &maps->rb_node; 559 struct rb_node *parent = NULL; 560 struct map *m; 561 562 while (*p != NULL) { 563 parent = *p; 564 m = rb_entry(parent, struct map, rb_node); 565 if (ip < m->start) 566 p = &(*p)->rb_left; 567 else if (ip > m->end) 568 p = &(*p)->rb_right; 569 else 570 return m; 571 } 572 573 return NULL; 574} 575 576int machine__init(struct machine *self, const char *root_dir, pid_t pid) 577{ 578 map_groups__init(&self->kmaps); 579 RB_CLEAR_NODE(&self->rb_node); 580 INIT_LIST_HEAD(&self->user_dsos); 581 INIT_LIST_HEAD(&self->kernel_dsos); 582 583 self->threads = RB_ROOT; 584 INIT_LIST_HEAD(&self->dead_threads); 585 self->last_match = NULL; 586 587 self->kmaps.machine = self; 588 self->pid = pid; 589 self->root_dir = strdup(root_dir); 590 if (self->root_dir == NULL) 591 return -ENOMEM; 592 593 if (pid != HOST_KERNEL_ID) { 594 struct thread *thread = machine__findnew_thread(self, pid); 595 char comm[64]; 596 597 if (thread == NULL) 598 return -ENOMEM; 599 600 snprintf(comm, sizeof(comm), "[guest/%d]", pid); 601 thread__set_comm(thread, comm); 602 } 603 604 return 0; 605} 606 607static void dsos__delete(struct list_head *self) 608{ 609 struct dso *pos, *n; 610 611 list_for_each_entry_safe(pos, n, self, node) { 612 list_del(&pos->node); 613 dso__delete(pos); 614 } 615} 616 617void machine__exit(struct machine *self) 618{ 619 map_groups__exit(&self->kmaps); 620 dsos__delete(&self->user_dsos); 621 dsos__delete(&self->kernel_dsos); 622 free(self->root_dir); 623 self->root_dir = NULL; 624} 625 626void machine__delete(struct machine *self) 627{ 628 machine__exit(self); 629 free(self); 630} 631 632struct machine *machines__add(struct rb_root *self, pid_t pid, 633 const char *root_dir) 634{ 635 struct rb_node **p = &self->rb_node; 636 struct rb_node *parent = NULL; 637 struct machine *pos, *machine = malloc(sizeof(*machine)); 638 639 if (!machine) 640 return NULL; 641 642 if (machine__init(machine, root_dir, pid) != 0) { 643 free(machine); 644 return NULL; 645 } 646 647 while (*p != NULL) { 648 parent = *p; 649 pos = rb_entry(parent, struct machine, rb_node); 650 if (pid < pos->pid) 651 p = &(*p)->rb_left; 652 else 653 p = &(*p)->rb_right; 654 } 655 656 rb_link_node(&machine->rb_node, parent, p); 657 rb_insert_color(&machine->rb_node, self); 658 659 return machine; 660} 661 662struct machine *machines__find(struct rb_root *self, pid_t pid) 663{ 664 struct rb_node **p = &self->rb_node; 665 struct rb_node *parent = NULL; 666 struct machine *machine; 667 struct machine *default_machine = NULL; 668 669 while (*p != NULL) { 670 parent = *p; 671 machine = rb_entry(parent, struct machine, rb_node); 672 if (pid < machine->pid) 673 p = &(*p)->rb_left; 674 else if (pid > machine->pid) 675 p = &(*p)->rb_right; 676 else 677 return machine; 678 if (!machine->pid) 679 default_machine = machine; 680 } 681 682 return default_machine; 683} 684 685struct machine *machines__findnew(struct rb_root *self, pid_t pid) 686{ 687 char path[PATH_MAX]; 688 const char *root_dir = ""; 689 struct machine *machine = machines__find(self, pid); 690 691 if (machine && (machine->pid == pid)) 692 goto out; 693 694 if ((pid != HOST_KERNEL_ID) && 695 (pid != DEFAULT_GUEST_KERNEL_ID) && 696 (symbol_conf.guestmount)) { 697 sprintf(path, "%s/%d", symbol_conf.guestmount, pid); 698 if (access(path, R_OK)) { 699 static struct strlist *seen; 700 701 if (!seen) 702 seen = strlist__new(true, NULL); 703 704 if (!strlist__has_entry(seen, path)) { 705 pr_err("Can't access file %s\n", path); 706 strlist__add(seen, path); 707 } 708 machine = NULL; 709 goto out; 710 } 711 root_dir = path; 712 } 713 714 machine = machines__add(self, pid, root_dir); 715 716out: 717 return machine; 718} 719 720void machines__process(struct rb_root *self, machine__process_t process, void *data) 721{ 722 struct rb_node *nd; 723 724 for (nd = rb_first(self); nd; nd = rb_next(nd)) { 725 struct machine *pos = rb_entry(nd, struct machine, rb_node); 726 process(pos, data); 727 } 728} 729 730char *machine__mmap_name(struct machine *self, char *bf, size_t size) 731{ 732 if (machine__is_host(self)) 733 snprintf(bf, size, "[%s]", "kernel.kallsyms"); 734 else if (machine__is_default_guest(self)) 735 snprintf(bf, size, "[%s]", "guest.kernel.kallsyms"); 736 else 737 snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid); 738 739 return bf; 740} 741 742void machines__set_id_hdr_size(struct rb_root *machines, u16 id_hdr_size) 743{ 744 struct rb_node *node; 745 struct machine *machine; 746 747 for (node = rb_first(machines); node; node = rb_next(node)) { 748 machine = rb_entry(node, struct machine, rb_node); 749 machine->id_hdr_size = id_hdr_size; 750 } 751 752 return; 753}