1 // SPDX-License-Identifier: GPL-2.0 2 #include <sys/sysmacros.h> 3 #include <sys/types.h> 4 #include <errno.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <fcntl.h> 9 #include <unistd.h> 10 #include <inttypes.h> 11 #include <byteswap.h> 12 #include <sys/stat.h> 13 #include <sys/mman.h> 14 #include <linux/stringify.h> 15 16 #include "util.h" 17 #include "event.h" 18 #include "debug.h" 19 #include "evlist.h" 20 #include "symbol.h" 21 #include <elf.h> 22 23 #include "tsc.h" 24 #include "session.h" 25 #include "jit.h" 26 #include "jitdump.h" 27 #include "genelf.h" 28 #include "../builtin.h" 29 30 #include "sane_ctype.h" 31 32 struct jit_buf_desc { 33 struct perf_data *output; 34 struct perf_session *session; 35 struct machine *machine; 36 union jr_entry *entry; 37 void *buf; 38 uint64_t sample_type; 39 size_t bufsize; 40 FILE *in; 41 bool needs_bswap; /* handles cross-endianess */ 42 bool use_arch_timestamp; 43 void *debug_data; 44 void *unwinding_data; 45 uint64_t unwinding_size; 46 uint64_t unwinding_mapped_size; 47 uint64_t eh_frame_hdr_size; 48 size_t nr_debug_entries; 49 uint32_t code_load_count; 50 u64 bytes_written; 51 struct rb_root code_root; 52 char dir[PATH_MAX]; 53 }; 54 55 struct debug_line_info { 56 unsigned long vma; 57 unsigned int lineno; 58 /* The filename format is unspecified, absolute path, relative etc. */ 59 char const filename[0]; 60 }; 61 62 struct jit_tool { 63 struct perf_tool tool; 64 struct perf_data output; 65 struct perf_data input; 66 u64 bytes_written; 67 }; 68 69 #define hmax(a, b) ((a) > (b) ? (a) : (b)) 70 #define get_jit_tool(t) (container_of(tool, struct jit_tool, tool)) 71 72 static int 73 jit_emit_elf(char *filename, 74 const char *sym, 75 uint64_t code_addr, 76 const void *code, 77 int csize, 78 void *debug, 79 int nr_debug_entries, 80 void *unwinding, 81 uint32_t unwinding_header_size, 82 uint32_t unwinding_size) 83 { 84 int ret, fd; 85 86 if (verbose > 0) 87 fprintf(stderr, "write ELF image %s\n", filename); 88 89 fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644); 90 if (fd == -1) { 91 pr_warning("cannot create jit ELF %s: %s\n", filename, strerror(errno)); 92 return -1; 93 } 94 95 ret = jit_write_elf(fd, code_addr, sym, (const void *)code, csize, debug, nr_debug_entries, 96 unwinding, unwinding_header_size, unwinding_size); 97 98 close(fd); 99 100 if (ret) 101 unlink(filename); 102 103 return ret; 104 } 105 106 static void 107 jit_close(struct jit_buf_desc *jd) 108 { 109 if (!(jd && jd->in)) 110 return; 111 funlockfile(jd->in); 112 fclose(jd->in); 113 jd->in = NULL; 114 } 115 116 static int 117 jit_validate_events(struct perf_session *session) 118 { 119 struct perf_evsel *evsel; 120 121 /* 122 * check that all events use CLOCK_MONOTONIC 123 */ 124 evlist__for_each_entry(session->evlist, evsel) { 125 if (evsel->attr.use_clockid == 0 || evsel->attr.clockid != CLOCK_MONOTONIC) 126 return -1; 127 } 128 return 0; 129 } 130 131 static int 132 jit_open(struct jit_buf_desc *jd, const char *name) 133 { 134 struct jitheader header; 135 struct jr_prefix *prefix; 136 ssize_t bs, bsz = 0; 137 void *n, *buf = NULL; 138 int ret, retval = -1; 139 140 jd->in = fopen(name, "r"); 141 if (!jd->in) 142 return -1; 143 144 bsz = hmax(sizeof(header), sizeof(*prefix)); 145 146 buf = malloc(bsz); 147 if (!buf) 148 goto error; 149 150 /* 151 * protect from writer modifying the file while we are reading it 152 */ 153 flockfile(jd->in); 154 155 ret = fread(buf, sizeof(header), 1, jd->in); 156 if (ret != 1) 157 goto error; 158 159 memcpy(&header, buf, sizeof(header)); 160 161 if (header.magic != JITHEADER_MAGIC) { 162 if (header.magic != JITHEADER_MAGIC_SW) 163 goto error; 164 jd->needs_bswap = true; 165 } 166 167 if (jd->needs_bswap) { 168 header.version = bswap_32(header.version); 169 header.total_size = bswap_32(header.total_size); 170 header.pid = bswap_32(header.pid); 171 header.elf_mach = bswap_32(header.elf_mach); 172 header.timestamp = bswap_64(header.timestamp); 173 header.flags = bswap_64(header.flags); 174 } 175 176 jd->use_arch_timestamp = header.flags & JITDUMP_FLAGS_ARCH_TIMESTAMP; 177 178 if (verbose > 2) 179 pr_debug("version=%u\nhdr.size=%u\nts=0x%llx\npid=%d\nelf_mach=%d\nuse_arch_timestamp=%d\n", 180 header.version, 181 header.total_size, 182 (unsigned long long)header.timestamp, 183 header.pid, 184 header.elf_mach, 185 jd->use_arch_timestamp); 186 187 if (header.version > JITHEADER_VERSION) { 188 pr_err("wrong jitdump version %u, expected " __stringify(JITHEADER_VERSION), 189 header.version); 190 goto error; 191 } 192 193 if (header.flags & JITDUMP_FLAGS_RESERVED) { 194 pr_err("jitdump file contains invalid or unsupported flags 0x%llx\n", 195 (unsigned long long)header.flags & JITDUMP_FLAGS_RESERVED); 196 goto error; 197 } 198 199 if (jd->use_arch_timestamp && !jd->session->time_conv.time_mult) { 200 pr_err("jitdump file uses arch timestamps but there is no timestamp conversion\n"); 201 goto error; 202 } 203 204 /* 205 * validate event is using the correct clockid 206 */ 207 if (!jd->use_arch_timestamp && jit_validate_events(jd->session)) { 208 pr_err("error, jitted code must be sampled with perf record -k 1\n"); 209 goto error; 210 } 211 212 bs = header.total_size - sizeof(header); 213 214 if (bs > bsz) { 215 n = realloc(buf, bs); 216 if (!n) 217 goto error; 218 bsz = bs; 219 buf = n; 220 /* read extra we do not know about */ 221 ret = fread(buf, bs - bsz, 1, jd->in); 222 if (ret != 1) 223 goto error; 224 } 225 /* 226 * keep dirname for generating files and mmap records 227 */ 228 strcpy(jd->dir, name); 229 dirname(jd->dir); 230 231 return 0; 232 error: 233 funlockfile(jd->in); 234 fclose(jd->in); 235 return retval; 236 } 237 238 static union jr_entry * 239 jit_get_next_entry(struct jit_buf_desc *jd) 240 { 241 struct jr_prefix *prefix; 242 union jr_entry *jr; 243 void *addr; 244 size_t bs, size; 245 int id, ret; 246 247 if (!(jd && jd->in)) 248 return NULL; 249 250 if (jd->buf == NULL) { 251 size_t sz = getpagesize(); 252 if (sz < sizeof(*prefix)) 253 sz = sizeof(*prefix); 254 255 jd->buf = malloc(sz); 256 if (jd->buf == NULL) 257 return NULL; 258 259 jd->bufsize = sz; 260 } 261 262 prefix = jd->buf; 263 264 /* 265 * file is still locked at this point 266 */ 267 ret = fread(prefix, sizeof(*prefix), 1, jd->in); 268 if (ret != 1) 269 return NULL; 270 271 if (jd->needs_bswap) { 272 prefix->id = bswap_32(prefix->id); 273 prefix->total_size = bswap_32(prefix->total_size); 274 prefix->timestamp = bswap_64(prefix->timestamp); 275 } 276 id = prefix->id; 277 size = prefix->total_size; 278 279 bs = (size_t)size; 280 if (bs < sizeof(*prefix)) 281 return NULL; 282 283 if (id >= JIT_CODE_MAX) { 284 pr_warning("next_entry: unknown record type %d, skipping\n", id); 285 } 286 if (bs > jd->bufsize) { 287 void *n; 288 n = realloc(jd->buf, bs); 289 if (!n) 290 return NULL; 291 jd->buf = n; 292 jd->bufsize = bs; 293 } 294 295 addr = ((void *)jd->buf) + sizeof(*prefix); 296 297 ret = fread(addr, bs - sizeof(*prefix), 1, jd->in); 298 if (ret != 1) 299 return NULL; 300 301 jr = (union jr_entry *)jd->buf; 302 303 switch(id) { 304 case JIT_CODE_DEBUG_INFO: 305 if (jd->needs_bswap) { 306 uint64_t n; 307 jr->info.code_addr = bswap_64(jr->info.code_addr); 308 jr->info.nr_entry = bswap_64(jr->info.nr_entry); 309 for (n = 0 ; n < jr->info.nr_entry; n++) { 310 jr->info.entries[n].addr = bswap_64(jr->info.entries[n].addr); 311 jr->info.entries[n].lineno = bswap_32(jr->info.entries[n].lineno); 312 jr->info.entries[n].discrim = bswap_32(jr->info.entries[n].discrim); 313 } 314 } 315 break; 316 case JIT_CODE_UNWINDING_INFO: 317 if (jd->needs_bswap) { 318 jr->unwinding.unwinding_size = bswap_64(jr->unwinding.unwinding_size); 319 jr->unwinding.eh_frame_hdr_size = bswap_64(jr->unwinding.eh_frame_hdr_size); 320 jr->unwinding.mapped_size = bswap_64(jr->unwinding.mapped_size); 321 } 322 break; 323 case JIT_CODE_CLOSE: 324 break; 325 case JIT_CODE_LOAD: 326 if (jd->needs_bswap) { 327 jr->load.pid = bswap_32(jr->load.pid); 328 jr->load.tid = bswap_32(jr->load.tid); 329 jr->load.vma = bswap_64(jr->load.vma); 330 jr->load.code_addr = bswap_64(jr->load.code_addr); 331 jr->load.code_size = bswap_64(jr->load.code_size); 332 jr->load.code_index= bswap_64(jr->load.code_index); 333 } 334 jd->code_load_count++; 335 break; 336 case JIT_CODE_MOVE: 337 if (jd->needs_bswap) { 338 jr->move.pid = bswap_32(jr->move.pid); 339 jr->move.tid = bswap_32(jr->move.tid); 340 jr->move.vma = bswap_64(jr->move.vma); 341 jr->move.old_code_addr = bswap_64(jr->move.old_code_addr); 342 jr->move.new_code_addr = bswap_64(jr->move.new_code_addr); 343 jr->move.code_size = bswap_64(jr->move.code_size); 344 jr->move.code_index = bswap_64(jr->move.code_index); 345 } 346 break; 347 case JIT_CODE_MAX: 348 default: 349 /* skip unknown record (we have read them) */ 350 break; 351 } 352 return jr; 353 } 354 355 static int 356 jit_inject_event(struct jit_buf_desc *jd, union perf_event *event) 357 { 358 ssize_t size; 359 360 size = perf_data__write(jd->output, event, event->header.size); 361 if (size < 0) 362 return -1; 363 364 jd->bytes_written += size; 365 return 0; 366 } 367 368 static uint64_t convert_timestamp(struct jit_buf_desc *jd, uint64_t timestamp) 369 { 370 struct perf_tsc_conversion tc; 371 372 if (!jd->use_arch_timestamp) 373 return timestamp; 374 375 tc.time_shift = jd->session->time_conv.time_shift; 376 tc.time_mult = jd->session->time_conv.time_mult; 377 tc.time_zero = jd->session->time_conv.time_zero; 378 379 if (!tc.time_mult) 380 return 0; 381 382 return tsc_to_perf_time(timestamp, &tc); 383 } 384 385 static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr) 386 { 387 struct perf_sample sample; 388 union perf_event *event; 389 struct perf_tool *tool = jd->session->tool; 390 uint64_t code, addr; 391 uintptr_t uaddr; 392 char *filename; 393 struct stat st; 394 size_t size; 395 u16 idr_size; 396 const char *sym; 397 uint32_t count; 398 int ret, csize, usize; 399 pid_t pid, tid; 400 struct { 401 u32 pid, tid; 402 u64 time; 403 } *id; 404 405 pid = jr->load.pid; 406 tid = jr->load.tid; 407 csize = jr->load.code_size; 408 usize = jd->unwinding_mapped_size; 409 addr = jr->load.code_addr; 410 sym = (void *)((unsigned long)jr + sizeof(jr->load)); 411 code = (unsigned long)jr + jr->load.p.total_size - csize; 412 count = jr->load.code_index; 413 idr_size = jd->machine->id_hdr_size; 414 415 event = calloc(1, sizeof(*event) + idr_size); 416 if (!event) 417 return -1; 418 419 filename = event->mmap2.filename; 420 size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%u.so", 421 jd->dir, 422 pid, 423 count); 424 425 size++; /* for \0 */ 426 427 size = PERF_ALIGN(size, sizeof(u64)); 428 uaddr = (uintptr_t)code; 429 ret = jit_emit_elf(filename, sym, addr, (const void *)uaddr, csize, jd->debug_data, jd->nr_debug_entries, 430 jd->unwinding_data, jd->eh_frame_hdr_size, jd->unwinding_size); 431 432 if (jd->debug_data && jd->nr_debug_entries) { 433 free(jd->debug_data); 434 jd->debug_data = NULL; 435 jd->nr_debug_entries = 0; 436 } 437 438 if (jd->unwinding_data && jd->eh_frame_hdr_size) { 439 free(jd->unwinding_data); 440 jd->unwinding_data = NULL; 441 jd->eh_frame_hdr_size = 0; 442 jd->unwinding_mapped_size = 0; 443 jd->unwinding_size = 0; 444 } 445 446 if (ret) { 447 free(event); 448 return -1; 449 } 450 if (stat(filename, &st)) 451 memset(&st, 0, sizeof(st)); 452 453 event->mmap2.header.type = PERF_RECORD_MMAP2; 454 event->mmap2.header.misc = PERF_RECORD_MISC_USER; 455 event->mmap2.header.size = (sizeof(event->mmap2) - 456 (sizeof(event->mmap2.filename) - size) + idr_size); 457 458 event->mmap2.pgoff = GEN_ELF_TEXT_OFFSET; 459 event->mmap2.start = addr; 460 event->mmap2.len = usize ? ALIGN_8(csize) + usize : csize; 461 event->mmap2.pid = pid; 462 event->mmap2.tid = tid; 463 event->mmap2.ino = st.st_ino; 464 event->mmap2.maj = major(st.st_dev); 465 event->mmap2.min = minor(st.st_dev); 466 event->mmap2.prot = st.st_mode; 467 event->mmap2.flags = MAP_SHARED; 468 event->mmap2.ino_generation = 1; 469 470 id = (void *)((unsigned long)event + event->mmap.header.size - idr_size); 471 if (jd->sample_type & PERF_SAMPLE_TID) { 472 id->pid = pid; 473 id->tid = tid; 474 } 475 if (jd->sample_type & PERF_SAMPLE_TIME) 476 id->time = convert_timestamp(jd, jr->load.p.timestamp); 477 478 /* 479 * create pseudo sample to induce dso hit increment 480 * use first address as sample address 481 */ 482 memset(&sample, 0, sizeof(sample)); 483 sample.cpumode = PERF_RECORD_MISC_USER; 484 sample.pid = pid; 485 sample.tid = tid; 486 sample.time = id->time; 487 sample.ip = addr; 488 489 ret = perf_event__process_mmap2(tool, event, &sample, jd->machine); 490 if (ret) 491 return ret; 492 493 ret = jit_inject_event(jd, event); 494 /* 495 * mark dso as use to generate buildid in the header 496 */ 497 if (!ret) 498 build_id__mark_dso_hit(tool, event, &sample, NULL, jd->machine); 499 500 return ret; 501 } 502 503 static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr) 504 { 505 struct perf_sample sample; 506 union perf_event *event; 507 struct perf_tool *tool = jd->session->tool; 508 char *filename; 509 size_t size; 510 struct stat st; 511 int usize; 512 u16 idr_size; 513 int ret; 514 pid_t pid, tid; 515 struct { 516 u32 pid, tid; 517 u64 time; 518 } *id; 519 520 pid = jr->move.pid; 521 tid = jr->move.tid; 522 usize = jd->unwinding_mapped_size; 523 idr_size = jd->machine->id_hdr_size; 524 525 /* 526 * +16 to account for sample_id_all (hack) 527 */ 528 event = calloc(1, sizeof(*event) + 16); 529 if (!event) 530 return -1; 531 532 filename = event->mmap2.filename; 533 size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%"PRIu64, 534 jd->dir, 535 pid, 536 jr->move.code_index); 537 538 size++; /* for \0 */ 539 540 if (stat(filename, &st)) 541 memset(&st, 0, sizeof(st)); 542 543 size = PERF_ALIGN(size, sizeof(u64)); 544 545 event->mmap2.header.type = PERF_RECORD_MMAP2; 546 event->mmap2.header.misc = PERF_RECORD_MISC_USER; 547 event->mmap2.header.size = (sizeof(event->mmap2) - 548 (sizeof(event->mmap2.filename) - size) + idr_size); 549 event->mmap2.pgoff = GEN_ELF_TEXT_OFFSET; 550 event->mmap2.start = jr->move.new_code_addr; 551 event->mmap2.len = usize ? ALIGN_8(jr->move.code_size) + usize 552 : jr->move.code_size; 553 event->mmap2.pid = pid; 554 event->mmap2.tid = tid; 555 event->mmap2.ino = st.st_ino; 556 event->mmap2.maj = major(st.st_dev); 557 event->mmap2.min = minor(st.st_dev); 558 event->mmap2.prot = st.st_mode; 559 event->mmap2.flags = MAP_SHARED; 560 event->mmap2.ino_generation = 1; 561 562 id = (void *)((unsigned long)event + event->mmap.header.size - idr_size); 563 if (jd->sample_type & PERF_SAMPLE_TID) { 564 id->pid = pid; 565 id->tid = tid; 566 } 567 if (jd->sample_type & PERF_SAMPLE_TIME) 568 id->time = convert_timestamp(jd, jr->load.p.timestamp); 569 570 /* 571 * create pseudo sample to induce dso hit increment 572 * use first address as sample address 573 */ 574 memset(&sample, 0, sizeof(sample)); 575 sample.cpumode = PERF_RECORD_MISC_USER; 576 sample.pid = pid; 577 sample.tid = tid; 578 sample.time = id->time; 579 sample.ip = jr->move.new_code_addr; 580 581 ret = perf_event__process_mmap2(tool, event, &sample, jd->machine); 582 if (ret) 583 return ret; 584 585 ret = jit_inject_event(jd, event); 586 if (!ret) 587 build_id__mark_dso_hit(tool, event, &sample, NULL, jd->machine); 588 589 return ret; 590 } 591 592 static int jit_repipe_debug_info(struct jit_buf_desc *jd, union jr_entry *jr) 593 { 594 void *data; 595 size_t sz; 596 597 if (!(jd && jr)) 598 return -1; 599 600 sz = jr->prefix.total_size - sizeof(jr->info); 601 data = malloc(sz); 602 if (!data) 603 return -1; 604 605 memcpy(data, &jr->info.entries, sz); 606 607 jd->debug_data = data; 608 609 /* 610 * we must use nr_entry instead of size here because 611 * we cannot distinguish actual entry from padding otherwise 612 */ 613 jd->nr_debug_entries = jr->info.nr_entry; 614 615 return 0; 616 } 617 618 static int 619 jit_repipe_unwinding_info(struct jit_buf_desc *jd, union jr_entry *jr) 620 { 621 void *unwinding_data; 622 uint32_t unwinding_data_size; 623 624 if (!(jd && jr)) 625 return -1; 626 627 unwinding_data_size = jr->prefix.total_size - sizeof(jr->unwinding); 628 unwinding_data = malloc(unwinding_data_size); 629 if (!unwinding_data) 630 return -1; 631 632 memcpy(unwinding_data, &jr->unwinding.unwinding_data, 633 unwinding_data_size); 634 635 jd->eh_frame_hdr_size = jr->unwinding.eh_frame_hdr_size; 636 jd->unwinding_size = jr->unwinding.unwinding_size; 637 jd->unwinding_mapped_size = jr->unwinding.mapped_size; 638 jd->unwinding_data = unwinding_data; 639 640 return 0; 641 } 642 643 static int 644 jit_process_dump(struct jit_buf_desc *jd) 645 { 646 union jr_entry *jr; 647 int ret = 0; 648 649 while ((jr = jit_get_next_entry(jd))) { 650 switch(jr->prefix.id) { 651 case JIT_CODE_LOAD: 652 ret = jit_repipe_code_load(jd, jr); 653 break; 654 case JIT_CODE_MOVE: 655 ret = jit_repipe_code_move(jd, jr); 656 break; 657 case JIT_CODE_DEBUG_INFO: 658 ret = jit_repipe_debug_info(jd, jr); 659 break; 660 case JIT_CODE_UNWINDING_INFO: 661 ret = jit_repipe_unwinding_info(jd, jr); 662 break; 663 default: 664 ret = 0; 665 continue; 666 } 667 } 668 return ret; 669 } 670 671 static int 672 jit_inject(struct jit_buf_desc *jd, char *path) 673 { 674 int ret; 675 676 if (verbose > 0) 677 fprintf(stderr, "injecting: %s\n", path); 678 679 ret = jit_open(jd, path); 680 if (ret) 681 return -1; 682 683 ret = jit_process_dump(jd); 684 685 jit_close(jd); 686 687 if (verbose > 0) 688 fprintf(stderr, "injected: %s (%d)\n", path, ret); 689 690 return 0; 691 } 692 693 /* 694 * File must be with pattern .../jit-XXXX.dump 695 * where XXXX is the PID of the process which did the mmap() 696 * as captured in the RECORD_MMAP record 697 */ 698 static int 699 jit_detect(char *mmap_name, pid_t pid) 700 { 701 char *p; 702 char *end = NULL; 703 pid_t pid2; 704 705 if (verbose > 2) 706 fprintf(stderr, "jit marker trying : %s\n", mmap_name); 707 /* 708 * get file name 709 */ 710 p = strrchr(mmap_name, '/'); 711 if (!p) 712 return -1; 713 714 /* 715 * match prefix 716 */ 717 if (strncmp(p, "/jit-", 5)) 718 return -1; 719 720 /* 721 * skip prefix 722 */ 723 p += 5; 724 725 /* 726 * must be followed by a pid 727 */ 728 if (!isdigit(*p)) 729 return -1; 730 731 pid2 = (int)strtol(p, &end, 10); 732 if (!end) 733 return -1; 734 735 /* 736 * pid does not match mmap pid 737 * pid==0 in system-wide mode (synthesized) 738 */ 739 if (pid && pid2 != pid) 740 return -1; 741 /* 742 * validate suffix 743 */ 744 if (strcmp(end, ".dump")) 745 return -1; 746 747 if (verbose > 0) 748 fprintf(stderr, "jit marker found: %s\n", mmap_name); 749 750 return 0; 751 } 752 753 int 754 jit_process(struct perf_session *session, 755 struct perf_data *output, 756 struct machine *machine, 757 char *filename, 758 pid_t pid, 759 u64 *nbytes) 760 { 761 struct perf_evsel *first; 762 struct jit_buf_desc jd; 763 int ret; 764 765 /* 766 * first, detect marker mmap (i.e., the jitdump mmap) 767 */ 768 if (jit_detect(filename, pid)) 769 return 0; 770 771 memset(&jd, 0, sizeof(jd)); 772 773 jd.session = session; 774 jd.output = output; 775 jd.machine = machine; 776 777 /* 778 * track sample_type to compute id_all layout 779 * perf sets the same sample type to all events as of now 780 */ 781 first = perf_evlist__first(session->evlist); 782 jd.sample_type = first->attr.sample_type; 783 784 *nbytes = 0; 785 786 ret = jit_inject(&jd, filename); 787 if (!ret) { 788 *nbytes = jd.bytes_written; 789 ret = 1; 790 } 791 792 return ret; 793 } 794