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