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