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