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