1 #include <linux/types.h> 2 #include "event.h" 3 #include "debug.h" 4 #include "hist.h" 5 #include "machine.h" 6 #include "sort.h" 7 #include "string.h" 8 #include "strlist.h" 9 #include "thread.h" 10 #include "thread_map.h" 11 #include "symbol/kallsyms.h" 12 13 static const char *perf_event__names[] = { 14 [0] = "TOTAL", 15 [PERF_RECORD_MMAP] = "MMAP", 16 [PERF_RECORD_MMAP2] = "MMAP2", 17 [PERF_RECORD_LOST] = "LOST", 18 [PERF_RECORD_COMM] = "COMM", 19 [PERF_RECORD_EXIT] = "EXIT", 20 [PERF_RECORD_THROTTLE] = "THROTTLE", 21 [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE", 22 [PERF_RECORD_FORK] = "FORK", 23 [PERF_RECORD_READ] = "READ", 24 [PERF_RECORD_SAMPLE] = "SAMPLE", 25 [PERF_RECORD_HEADER_ATTR] = "ATTR", 26 [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", 27 [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", 28 [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", 29 [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", 30 }; 31 32 const char *perf_event__name(unsigned int id) 33 { 34 if (id >= ARRAY_SIZE(perf_event__names)) 35 return "INVALID"; 36 if (!perf_event__names[id]) 37 return "UNKNOWN"; 38 return perf_event__names[id]; 39 } 40 41 static struct perf_sample synth_sample = { 42 .pid = -1, 43 .tid = -1, 44 .time = -1, 45 .stream_id = -1, 46 .cpu = -1, 47 .period = 1, 48 }; 49 50 static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) 51 { 52 char filename[PATH_MAX]; 53 char bf[BUFSIZ]; 54 FILE *fp; 55 size_t size = 0; 56 pid_t tgid = -1; 57 58 snprintf(filename, sizeof(filename), "/proc/%d/status", pid); 59 60 fp = fopen(filename, "r"); 61 if (fp == NULL) { 62 pr_debug("couldn't open %s\n", filename); 63 return 0; 64 } 65 66 while (!comm[0] || (tgid < 0)) { 67 if (fgets(bf, sizeof(bf), fp) == NULL) { 68 pr_warning("couldn't get COMM and pgid, malformed %s\n", 69 filename); 70 break; 71 } 72 73 if (memcmp(bf, "Name:", 5) == 0) { 74 char *name = bf + 5; 75 while (*name && isspace(*name)) 76 ++name; 77 size = strlen(name) - 1; 78 if (size >= len) 79 size = len - 1; 80 memcpy(comm, name, size); 81 comm[size] = '\0'; 82 83 } else if (memcmp(bf, "Tgid:", 5) == 0) { 84 char *tgids = bf + 5; 85 while (*tgids && isspace(*tgids)) 86 ++tgids; 87 tgid = atoi(tgids); 88 } 89 } 90 91 fclose(fp); 92 93 return tgid; 94 } 95 96 static pid_t perf_event__synthesize_comm(struct perf_tool *tool, 97 union perf_event *event, pid_t pid, 98 perf_event__handler_t process, 99 struct machine *machine) 100 { 101 size_t size; 102 pid_t tgid; 103 104 memset(&event->comm, 0, sizeof(event->comm)); 105 106 if (machine__is_host(machine)) 107 tgid = perf_event__get_comm_tgid(pid, event->comm.comm, 108 sizeof(event->comm.comm)); 109 else 110 tgid = machine->pid; 111 112 if (tgid < 0) 113 goto out; 114 115 event->comm.pid = tgid; 116 event->comm.header.type = PERF_RECORD_COMM; 117 118 size = strlen(event->comm.comm) + 1; 119 size = PERF_ALIGN(size, sizeof(u64)); 120 memset(event->comm.comm + size, 0, machine->id_hdr_size); 121 event->comm.header.size = (sizeof(event->comm) - 122 (sizeof(event->comm.comm) - size) + 123 machine->id_hdr_size); 124 event->comm.tid = pid; 125 126 if (process(tool, event, &synth_sample, machine) != 0) 127 return -1; 128 129 out: 130 return tgid; 131 } 132 133 static int perf_event__synthesize_fork(struct perf_tool *tool, 134 union perf_event *event, pid_t pid, 135 pid_t tgid, perf_event__handler_t process, 136 struct machine *machine) 137 { 138 memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); 139 140 /* this is really a clone event but we use fork to synthesize it */ 141 event->fork.ppid = tgid; 142 event->fork.ptid = tgid; 143 event->fork.pid = tgid; 144 event->fork.tid = pid; 145 event->fork.header.type = PERF_RECORD_FORK; 146 147 event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size); 148 149 if (process(tool, event, &synth_sample, machine) != 0) 150 return -1; 151 152 return 0; 153 } 154 155 int perf_event__synthesize_mmap_events(struct perf_tool *tool, 156 union perf_event *event, 157 pid_t pid, pid_t tgid, 158 perf_event__handler_t process, 159 struct machine *machine, 160 bool mmap_data) 161 { 162 char filename[PATH_MAX]; 163 FILE *fp; 164 int rc = 0; 165 166 if (machine__is_default_guest(machine)) 167 return 0; 168 169 snprintf(filename, sizeof(filename), "%s/proc/%d/maps", 170 machine->root_dir, pid); 171 172 fp = fopen(filename, "r"); 173 if (fp == NULL) { 174 /* 175 * We raced with a task exiting - just return: 176 */ 177 pr_debug("couldn't open %s\n", filename); 178 return -1; 179 } 180 181 event->header.type = PERF_RECORD_MMAP; 182 183 while (1) { 184 char bf[BUFSIZ]; 185 char prot[5]; 186 char execname[PATH_MAX]; 187 char anonstr[] = "//anon"; 188 size_t size; 189 ssize_t n; 190 191 if (fgets(bf, sizeof(bf), fp) == NULL) 192 break; 193 194 /* ensure null termination since stack will be reused. */ 195 strcpy(execname, ""); 196 197 /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ 198 n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n", 199 &event->mmap.start, &event->mmap.len, prot, 200 &event->mmap.pgoff, 201 execname); 202 /* 203 * Anon maps don't have the execname. 204 */ 205 if (n < 4) 206 continue; 207 /* 208 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c 209 */ 210 if (machine__is_host(machine)) 211 event->header.misc = PERF_RECORD_MISC_USER; 212 else 213 event->header.misc = PERF_RECORD_MISC_GUEST_USER; 214 215 if (prot[2] != 'x') { 216 if (!mmap_data || prot[0] != 'r') 217 continue; 218 219 event->header.misc |= PERF_RECORD_MISC_MMAP_DATA; 220 } 221 222 if (!strcmp(execname, "")) 223 strcpy(execname, anonstr); 224 225 size = strlen(execname) + 1; 226 memcpy(event->mmap.filename, execname, size); 227 size = PERF_ALIGN(size, sizeof(u64)); 228 event->mmap.len -= event->mmap.start; 229 event->mmap.header.size = (sizeof(event->mmap) - 230 (sizeof(event->mmap.filename) - size)); 231 memset(event->mmap.filename + size, 0, machine->id_hdr_size); 232 event->mmap.header.size += machine->id_hdr_size; 233 event->mmap.pid = tgid; 234 event->mmap.tid = pid; 235 236 if (process(tool, event, &synth_sample, machine) != 0) { 237 rc = -1; 238 break; 239 } 240 } 241 242 fclose(fp); 243 return rc; 244 } 245 246 int perf_event__synthesize_modules(struct perf_tool *tool, 247 perf_event__handler_t process, 248 struct machine *machine) 249 { 250 int rc = 0; 251 struct rb_node *nd; 252 struct map_groups *kmaps = &machine->kmaps; 253 union perf_event *event = zalloc((sizeof(event->mmap) + 254 machine->id_hdr_size)); 255 if (event == NULL) { 256 pr_debug("Not enough memory synthesizing mmap event " 257 "for kernel modules\n"); 258 return -1; 259 } 260 261 event->header.type = PERF_RECORD_MMAP; 262 263 /* 264 * kernel uses 0 for user space maps, see kernel/perf_event.c 265 * __perf_event_mmap 266 */ 267 if (machine__is_host(machine)) 268 event->header.misc = PERF_RECORD_MISC_KERNEL; 269 else 270 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; 271 272 for (nd = rb_first(&kmaps->maps[MAP__FUNCTION]); 273 nd; nd = rb_next(nd)) { 274 size_t size; 275 struct map *pos = rb_entry(nd, struct map, rb_node); 276 277 if (pos->dso->kernel) 278 continue; 279 280 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); 281 event->mmap.header.type = PERF_RECORD_MMAP; 282 event->mmap.header.size = (sizeof(event->mmap) - 283 (sizeof(event->mmap.filename) - size)); 284 memset(event->mmap.filename + size, 0, machine->id_hdr_size); 285 event->mmap.header.size += machine->id_hdr_size; 286 event->mmap.start = pos->start; 287 event->mmap.len = pos->end - pos->start; 288 event->mmap.pid = machine->pid; 289 290 memcpy(event->mmap.filename, pos->dso->long_name, 291 pos->dso->long_name_len + 1); 292 if (process(tool, event, &synth_sample, machine) != 0) { 293 rc = -1; 294 break; 295 } 296 } 297 298 free(event); 299 return rc; 300 } 301 302 static int __event__synthesize_thread(union perf_event *comm_event, 303 union perf_event *mmap_event, 304 union perf_event *fork_event, 305 pid_t pid, int full, 306 perf_event__handler_t process, 307 struct perf_tool *tool, 308 struct machine *machine, bool mmap_data) 309 { 310 char filename[PATH_MAX]; 311 DIR *tasks; 312 struct dirent dirent, *next; 313 pid_t tgid; 314 315 /* special case: only send one comm event using passed in pid */ 316 if (!full) { 317 tgid = perf_event__synthesize_comm(tool, comm_event, pid, 318 process, machine); 319 320 if (tgid == -1) 321 return -1; 322 323 return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 324 process, machine, mmap_data); 325 } 326 327 if (machine__is_default_guest(machine)) 328 return 0; 329 330 snprintf(filename, sizeof(filename), "%s/proc/%d/task", 331 machine->root_dir, pid); 332 333 tasks = opendir(filename); 334 if (tasks == NULL) { 335 pr_debug("couldn't open %s\n", filename); 336 return 0; 337 } 338 339 while (!readdir_r(tasks, &dirent, &next) && next) { 340 char *end; 341 int rc = 0; 342 pid_t _pid; 343 344 _pid = strtol(dirent.d_name, &end, 10); 345 if (*end) 346 continue; 347 348 tgid = perf_event__synthesize_comm(tool, comm_event, _pid, 349 process, machine); 350 if (tgid == -1) 351 return -1; 352 353 if (_pid == pid) { 354 /* process the parent's maps too */ 355 rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 356 process, machine, mmap_data); 357 } else { 358 /* only fork the tid's map, to save time */ 359 rc = perf_event__synthesize_fork(tool, fork_event, _pid, tgid, 360 process, machine); 361 } 362 363 if (rc) 364 return rc; 365 } 366 367 closedir(tasks); 368 return 0; 369 } 370 371 int perf_event__synthesize_thread_map(struct perf_tool *tool, 372 struct thread_map *threads, 373 perf_event__handler_t process, 374 struct machine *machine, 375 bool mmap_data) 376 { 377 union perf_event *comm_event, *mmap_event, *fork_event; 378 int err = -1, thread, j; 379 380 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); 381 if (comm_event == NULL) 382 goto out; 383 384 mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); 385 if (mmap_event == NULL) 386 goto out_free_comm; 387 388 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); 389 if (fork_event == NULL) 390 goto out_free_mmap; 391 392 err = 0; 393 for (thread = 0; thread < threads->nr; ++thread) { 394 if (__event__synthesize_thread(comm_event, mmap_event, 395 fork_event, 396 threads->map[thread], 0, 397 process, tool, machine, 398 mmap_data)) { 399 err = -1; 400 break; 401 } 402 403 /* 404 * comm.pid is set to thread group id by 405 * perf_event__synthesize_comm 406 */ 407 if ((int) comm_event->comm.pid != threads->map[thread]) { 408 bool need_leader = true; 409 410 /* is thread group leader in thread_map? */ 411 for (j = 0; j < threads->nr; ++j) { 412 if ((int) comm_event->comm.pid == threads->map[j]) { 413 need_leader = false; 414 break; 415 } 416 } 417 418 /* if not, generate events for it */ 419 if (need_leader && 420 __event__synthesize_thread(comm_event, mmap_event, 421 fork_event, 422 comm_event->comm.pid, 0, 423 process, tool, machine, 424 mmap_data)) { 425 err = -1; 426 break; 427 } 428 } 429 } 430 free(fork_event); 431 out_free_mmap: 432 free(mmap_event); 433 out_free_comm: 434 free(comm_event); 435 out: 436 return err; 437 } 438 439 int perf_event__synthesize_threads(struct perf_tool *tool, 440 perf_event__handler_t process, 441 struct machine *machine, bool mmap_data) 442 { 443 DIR *proc; 444 char proc_path[PATH_MAX]; 445 struct dirent dirent, *next; 446 union perf_event *comm_event, *mmap_event, *fork_event; 447 int err = -1; 448 449 if (machine__is_default_guest(machine)) 450 return 0; 451 452 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); 453 if (comm_event == NULL) 454 goto out; 455 456 mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); 457 if (mmap_event == NULL) 458 goto out_free_comm; 459 460 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); 461 if (fork_event == NULL) 462 goto out_free_mmap; 463 464 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); 465 proc = opendir(proc_path); 466 467 if (proc == NULL) 468 goto out_free_fork; 469 470 while (!readdir_r(proc, &dirent, &next) && next) { 471 char *end; 472 pid_t pid = strtol(dirent.d_name, &end, 10); 473 474 if (*end) /* only interested in proper numerical dirents */ 475 continue; 476 /* 477 * We may race with exiting thread, so don't stop just because 478 * one thread couldn't be synthesized. 479 */ 480 __event__synthesize_thread(comm_event, mmap_event, fork_event, pid, 481 1, process, tool, machine, mmap_data); 482 } 483 484 err = 0; 485 closedir(proc); 486 out_free_fork: 487 free(fork_event); 488 out_free_mmap: 489 free(mmap_event); 490 out_free_comm: 491 free(comm_event); 492 out: 493 return err; 494 } 495 496 struct process_symbol_args { 497 const char *name; 498 u64 start; 499 }; 500 501 static int find_symbol_cb(void *arg, const char *name, char type, 502 u64 start) 503 { 504 struct process_symbol_args *args = arg; 505 506 /* 507 * Must be a function or at least an alias, as in PARISC64, where "_text" is 508 * an 'A' to the same address as "_stext". 509 */ 510 if (!(symbol_type__is_a(type, MAP__FUNCTION) || 511 type == 'A') || strcmp(name, args->name)) 512 return 0; 513 514 args->start = start; 515 return 1; 516 } 517 518 u64 kallsyms__get_function_start(const char *kallsyms_filename, 519 const char *symbol_name) 520 { 521 struct process_symbol_args args = { .name = symbol_name, }; 522 523 if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0) 524 return 0; 525 526 return args.start; 527 } 528 529 int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, 530 perf_event__handler_t process, 531 struct machine *machine) 532 { 533 size_t size; 534 const char *mmap_name; 535 char name_buff[PATH_MAX]; 536 struct map *map; 537 struct kmap *kmap; 538 int err; 539 /* 540 * We should get this from /sys/kernel/sections/.text, but till that is 541 * available use this, and after it is use this as a fallback for older 542 * kernels. 543 */ 544 union perf_event *event = zalloc((sizeof(event->mmap) + 545 machine->id_hdr_size)); 546 if (event == NULL) { 547 pr_debug("Not enough memory synthesizing mmap event " 548 "for kernel modules\n"); 549 return -1; 550 } 551 552 mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff)); 553 if (machine__is_host(machine)) { 554 /* 555 * kernel uses PERF_RECORD_MISC_USER for user space maps, 556 * see kernel/perf_event.c __perf_event_mmap 557 */ 558 event->header.misc = PERF_RECORD_MISC_KERNEL; 559 } else { 560 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; 561 } 562 563 map = machine->vmlinux_maps[MAP__FUNCTION]; 564 kmap = map__kmap(map); 565 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), 566 "%s%s", mmap_name, kmap->ref_reloc_sym->name) + 1; 567 size = PERF_ALIGN(size, sizeof(u64)); 568 event->mmap.header.type = PERF_RECORD_MMAP; 569 event->mmap.header.size = (sizeof(event->mmap) - 570 (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); 571 event->mmap.pgoff = kmap->ref_reloc_sym->addr; 572 event->mmap.start = map->start; 573 event->mmap.len = map->end - event->mmap.start; 574 event->mmap.pid = machine->pid; 575 576 err = process(tool, event, &synth_sample, machine); 577 free(event); 578 579 return err; 580 } 581 582 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp) 583 { 584 return fprintf(fp, ": %s:%d\n", event->comm.comm, event->comm.tid); 585 } 586 587 int perf_event__process_comm(struct perf_tool *tool __maybe_unused, 588 union perf_event *event, 589 struct perf_sample *sample, 590 struct machine *machine) 591 { 592 return machine__process_comm_event(machine, event, sample); 593 } 594 595 int perf_event__process_lost(struct perf_tool *tool __maybe_unused, 596 union perf_event *event, 597 struct perf_sample *sample, 598 struct machine *machine) 599 { 600 return machine__process_lost_event(machine, event, sample); 601 } 602 603 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) 604 { 605 return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n", 606 event->mmap.pid, event->mmap.tid, event->mmap.start, 607 event->mmap.len, event->mmap.pgoff, 608 (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', 609 event->mmap.filename); 610 } 611 612 size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) 613 { 614 return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 615 " %02x:%02x %"PRIu64" %"PRIu64"]: %c %s\n", 616 event->mmap2.pid, event->mmap2.tid, event->mmap2.start, 617 event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, 618 event->mmap2.min, event->mmap2.ino, 619 event->mmap2.ino_generation, 620 (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', 621 event->mmap2.filename); 622 } 623 624 int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, 625 union perf_event *event, 626 struct perf_sample *sample, 627 struct machine *machine) 628 { 629 return machine__process_mmap_event(machine, event, sample); 630 } 631 632 int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, 633 union perf_event *event, 634 struct perf_sample *sample, 635 struct machine *machine) 636 { 637 return machine__process_mmap2_event(machine, event, sample); 638 } 639 640 size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) 641 { 642 return fprintf(fp, "(%d:%d):(%d:%d)\n", 643 event->fork.pid, event->fork.tid, 644 event->fork.ppid, event->fork.ptid); 645 } 646 647 int perf_event__process_fork(struct perf_tool *tool __maybe_unused, 648 union perf_event *event, 649 struct perf_sample *sample, 650 struct machine *machine) 651 { 652 return machine__process_fork_event(machine, event, sample); 653 } 654 655 int perf_event__process_exit(struct perf_tool *tool __maybe_unused, 656 union perf_event *event, 657 struct perf_sample *sample, 658 struct machine *machine) 659 { 660 return machine__process_exit_event(machine, event, sample); 661 } 662 663 size_t perf_event__fprintf(union perf_event *event, FILE *fp) 664 { 665 size_t ret = fprintf(fp, "PERF_RECORD_%s", 666 perf_event__name(event->header.type)); 667 668 switch (event->header.type) { 669 case PERF_RECORD_COMM: 670 ret += perf_event__fprintf_comm(event, fp); 671 break; 672 case PERF_RECORD_FORK: 673 case PERF_RECORD_EXIT: 674 ret += perf_event__fprintf_task(event, fp); 675 break; 676 case PERF_RECORD_MMAP: 677 ret += perf_event__fprintf_mmap(event, fp); 678 break; 679 case PERF_RECORD_MMAP2: 680 ret += perf_event__fprintf_mmap2(event, fp); 681 break; 682 default: 683 ret += fprintf(fp, "\n"); 684 } 685 686 return ret; 687 } 688 689 int perf_event__process(struct perf_tool *tool __maybe_unused, 690 union perf_event *event, 691 struct perf_sample *sample, 692 struct machine *machine) 693 { 694 return machine__process_event(machine, event, sample); 695 } 696 697 void thread__find_addr_map(struct thread *thread, 698 struct machine *machine, u8 cpumode, 699 enum map_type type, u64 addr, 700 struct addr_location *al) 701 { 702 struct map_groups *mg = &thread->mg; 703 bool load_map = false; 704 705 al->machine = machine; 706 al->thread = thread; 707 al->addr = addr; 708 al->cpumode = cpumode; 709 al->filtered = 0; 710 711 if (machine == NULL) { 712 al->map = NULL; 713 return; 714 } 715 716 if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { 717 al->level = 'k'; 718 mg = &machine->kmaps; 719 load_map = true; 720 } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { 721 al->level = '.'; 722 } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { 723 al->level = 'g'; 724 mg = &machine->kmaps; 725 load_map = true; 726 } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) { 727 al->level = 'u'; 728 } else { 729 al->level = 'H'; 730 al->map = NULL; 731 732 if ((cpumode == PERF_RECORD_MISC_GUEST_USER || 733 cpumode == PERF_RECORD_MISC_GUEST_KERNEL) && 734 !perf_guest) 735 al->filtered |= (1 << HIST_FILTER__GUEST); 736 if ((cpumode == PERF_RECORD_MISC_USER || 737 cpumode == PERF_RECORD_MISC_KERNEL) && 738 !perf_host) 739 al->filtered |= (1 << HIST_FILTER__HOST); 740 741 return; 742 } 743 try_again: 744 al->map = map_groups__find(mg, type, al->addr); 745 if (al->map == NULL) { 746 /* 747 * If this is outside of all known maps, and is a negative 748 * address, try to look it up in the kernel dso, as it might be 749 * a vsyscall or vdso (which executes in user-mode). 750 * 751 * XXX This is nasty, we should have a symbol list in the 752 * "[vdso]" dso, but for now lets use the old trick of looking 753 * in the whole kernel symbol list. 754 */ 755 if ((long long)al->addr < 0 && 756 cpumode == PERF_RECORD_MISC_USER && 757 machine && mg != &machine->kmaps) { 758 mg = &machine->kmaps; 759 goto try_again; 760 } 761 } else { 762 /* 763 * Kernel maps might be changed when loading symbols so loading 764 * must be done prior to using kernel maps. 765 */ 766 if (load_map) 767 map__load(al->map, machine->symbol_filter); 768 al->addr = al->map->map_ip(al->map, al->addr); 769 } 770 } 771 772 void thread__find_addr_location(struct thread *thread, struct machine *machine, 773 u8 cpumode, enum map_type type, u64 addr, 774 struct addr_location *al) 775 { 776 thread__find_addr_map(thread, machine, cpumode, type, addr, al); 777 if (al->map != NULL) 778 al->sym = map__find_symbol(al->map, al->addr, 779 machine->symbol_filter); 780 else 781 al->sym = NULL; 782 } 783 784 int perf_event__preprocess_sample(const union perf_event *event, 785 struct machine *machine, 786 struct addr_location *al, 787 struct perf_sample *sample) 788 { 789 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 790 struct thread *thread = machine__findnew_thread(machine, sample->pid, 791 sample->pid); 792 793 if (thread == NULL) 794 return -1; 795 796 dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid); 797 /* 798 * Have we already created the kernel maps for this machine? 799 * 800 * This should have happened earlier, when we processed the kernel MMAP 801 * events, but for older perf.data files there was no such thing, so do 802 * it now. 803 */ 804 if (cpumode == PERF_RECORD_MISC_KERNEL && 805 machine->vmlinux_maps[MAP__FUNCTION] == NULL) 806 machine__create_kernel_maps(machine); 807 808 thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, 809 sample->ip, al); 810 dump_printf(" ...... dso: %s\n", 811 al->map ? al->map->dso->long_name : 812 al->level == 'H' ? "[hypervisor]" : "<not found>"); 813 814 if (thread__is_filtered(thread)) 815 al->filtered |= (1 << HIST_FILTER__THREAD); 816 817 al->sym = NULL; 818 al->cpu = sample->cpu; 819 820 if (al->map) { 821 struct dso *dso = al->map->dso; 822 823 if (symbol_conf.dso_list && 824 (!dso || !(strlist__has_entry(symbol_conf.dso_list, 825 dso->short_name) || 826 (dso->short_name != dso->long_name && 827 strlist__has_entry(symbol_conf.dso_list, 828 dso->long_name))))) { 829 al->filtered |= (1 << HIST_FILTER__DSO); 830 } 831 832 al->sym = map__find_symbol(al->map, al->addr, 833 machine->symbol_filter); 834 } 835 836 if (symbol_conf.sym_list && 837 (!al->sym || !strlist__has_entry(symbol_conf.sym_list, 838 al->sym->name))) { 839 al->filtered |= (1 << HIST_FILTER__SYMBOL); 840 } 841 842 return 0; 843 } 844