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