0001
0002 #include <sys/sysmacros.h>
0003 #include <sys/types.h>
0004 #include <errno.h>
0005 #include <libgen.h>
0006 #include <stdio.h>
0007 #include <stdlib.h>
0008 #include <string.h>
0009 #include <fcntl.h>
0010 #include <unistd.h>
0011 #include <inttypes.h>
0012 #include <byteswap.h>
0013 #include <sys/stat.h>
0014 #include <sys/mman.h>
0015 #include <linux/stringify.h>
0016
0017 #include "build-id.h"
0018 #include "event.h"
0019 #include "debug.h"
0020 #include "evlist.h"
0021 #include "namespaces.h"
0022 #include "symbol.h"
0023 #include <elf.h>
0024
0025 #include "tsc.h"
0026 #include "session.h"
0027 #include "jit.h"
0028 #include "jitdump.h"
0029 #include "genelf.h"
0030 #include "thread.h"
0031
0032 #include <linux/ctype.h>
0033 #include <linux/zalloc.h>
0034
0035 struct jit_buf_desc {
0036 struct perf_data *output;
0037 struct perf_session *session;
0038 struct machine *machine;
0039 struct nsinfo *nsi;
0040 union jr_entry *entry;
0041 void *buf;
0042 uint64_t sample_type;
0043 size_t bufsize;
0044 FILE *in;
0045 bool needs_bswap;
0046 bool use_arch_timestamp;
0047 void *debug_data;
0048 void *unwinding_data;
0049 uint64_t unwinding_size;
0050 uint64_t unwinding_mapped_size;
0051 uint64_t eh_frame_hdr_size;
0052 size_t nr_debug_entries;
0053 uint32_t code_load_count;
0054 u64 bytes_written;
0055 struct rb_root code_root;
0056 char dir[PATH_MAX];
0057 };
0058
0059 struct debug_line_info {
0060 unsigned long vma;
0061 unsigned int lineno;
0062
0063 char const filename[];
0064 };
0065
0066 struct jit_tool {
0067 struct perf_tool tool;
0068 struct perf_data output;
0069 struct perf_data input;
0070 u64 bytes_written;
0071 };
0072
0073 #define hmax(a, b) ((a) > (b) ? (a) : (b))
0074 #define get_jit_tool(t) (container_of(tool, struct jit_tool, tool))
0075
0076 static int
0077 jit_emit_elf(struct jit_buf_desc *jd,
0078 char *filename,
0079 const char *sym,
0080 uint64_t code_addr,
0081 const void *code,
0082 int csize,
0083 void *debug,
0084 int nr_debug_entries,
0085 void *unwinding,
0086 uint32_t unwinding_header_size,
0087 uint32_t unwinding_size)
0088 {
0089 int ret, fd, saved_errno;
0090 struct nscookie nsc;
0091
0092 if (verbose > 0)
0093 fprintf(stderr, "write ELF image %s\n", filename);
0094
0095 nsinfo__mountns_enter(jd->nsi, &nsc);
0096 fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644);
0097 saved_errno = errno;
0098 nsinfo__mountns_exit(&nsc);
0099 if (fd == -1) {
0100 pr_warning("cannot create jit ELF %s: %s\n", filename, strerror(saved_errno));
0101 return -1;
0102 }
0103
0104 ret = jit_write_elf(fd, code_addr, sym, (const void *)code, csize, debug, nr_debug_entries,
0105 unwinding, unwinding_header_size, unwinding_size);
0106
0107 close(fd);
0108
0109 if (ret) {
0110 nsinfo__mountns_enter(jd->nsi, &nsc);
0111 unlink(filename);
0112 nsinfo__mountns_exit(&nsc);
0113 }
0114
0115 return ret;
0116 }
0117
0118 static void
0119 jit_close(struct jit_buf_desc *jd)
0120 {
0121 if (!(jd && jd->in))
0122 return;
0123 funlockfile(jd->in);
0124 fclose(jd->in);
0125 jd->in = NULL;
0126 }
0127
0128 static int
0129 jit_validate_events(struct perf_session *session)
0130 {
0131 struct evsel *evsel;
0132
0133
0134
0135
0136 evlist__for_each_entry(session->evlist, evsel) {
0137 if (evsel->core.attr.use_clockid == 0 || evsel->core.attr.clockid != CLOCK_MONOTONIC)
0138 return -1;
0139 }
0140 return 0;
0141 }
0142
0143 static int
0144 jit_open(struct jit_buf_desc *jd, const char *name)
0145 {
0146 struct jitheader header;
0147 struct nscookie nsc;
0148 struct jr_prefix *prefix;
0149 ssize_t bs, bsz = 0;
0150 void *n, *buf = NULL;
0151 int ret, retval = -1;
0152
0153 nsinfo__mountns_enter(jd->nsi, &nsc);
0154 jd->in = fopen(name, "r");
0155 nsinfo__mountns_exit(&nsc);
0156 if (!jd->in)
0157 return -1;
0158
0159 bsz = hmax(sizeof(header), sizeof(*prefix));
0160
0161 buf = malloc(bsz);
0162 if (!buf)
0163 goto error;
0164
0165
0166
0167
0168 flockfile(jd->in);
0169
0170 ret = fread(buf, sizeof(header), 1, jd->in);
0171 if (ret != 1)
0172 goto error;
0173
0174 memcpy(&header, buf, sizeof(header));
0175
0176 if (header.magic != JITHEADER_MAGIC) {
0177 if (header.magic != JITHEADER_MAGIC_SW)
0178 goto error;
0179 jd->needs_bswap = true;
0180 }
0181
0182 if (jd->needs_bswap) {
0183 header.version = bswap_32(header.version);
0184 header.total_size = bswap_32(header.total_size);
0185 header.pid = bswap_32(header.pid);
0186 header.elf_mach = bswap_32(header.elf_mach);
0187 header.timestamp = bswap_64(header.timestamp);
0188 header.flags = bswap_64(header.flags);
0189 }
0190
0191 jd->use_arch_timestamp = header.flags & JITDUMP_FLAGS_ARCH_TIMESTAMP;
0192
0193 if (verbose > 2)
0194 pr_debug("version=%u\nhdr.size=%u\nts=0x%llx\npid=%d\nelf_mach=%d\nuse_arch_timestamp=%d\n",
0195 header.version,
0196 header.total_size,
0197 (unsigned long long)header.timestamp,
0198 header.pid,
0199 header.elf_mach,
0200 jd->use_arch_timestamp);
0201
0202 if (header.version > JITHEADER_VERSION) {
0203 pr_err("wrong jitdump version %u, expected " __stringify(JITHEADER_VERSION),
0204 header.version);
0205 goto error;
0206 }
0207
0208 if (header.flags & JITDUMP_FLAGS_RESERVED) {
0209 pr_err("jitdump file contains invalid or unsupported flags 0x%llx\n",
0210 (unsigned long long)header.flags & JITDUMP_FLAGS_RESERVED);
0211 goto error;
0212 }
0213
0214 if (jd->use_arch_timestamp && !jd->session->time_conv.time_mult) {
0215 pr_err("jitdump file uses arch timestamps but there is no timestamp conversion\n");
0216 goto error;
0217 }
0218
0219
0220
0221
0222 if (!jd->use_arch_timestamp && jit_validate_events(jd->session)) {
0223 pr_err("error, jitted code must be sampled with perf record -k 1\n");
0224 goto error;
0225 }
0226
0227 bs = header.total_size - sizeof(header);
0228
0229 if (bs > bsz) {
0230 n = realloc(buf, bs);
0231 if (!n)
0232 goto error;
0233 bsz = bs;
0234 buf = n;
0235
0236 ret = fread(buf, bs - bsz, 1, jd->in);
0237 if (ret != 1)
0238 goto error;
0239 }
0240
0241
0242
0243 strcpy(jd->dir, name);
0244 dirname(jd->dir);
0245
0246 return 0;
0247 error:
0248 funlockfile(jd->in);
0249 fclose(jd->in);
0250 return retval;
0251 }
0252
0253 static union jr_entry *
0254 jit_get_next_entry(struct jit_buf_desc *jd)
0255 {
0256 struct jr_prefix *prefix;
0257 union jr_entry *jr;
0258 void *addr;
0259 size_t bs, size;
0260 int id, ret;
0261
0262 if (!(jd && jd->in))
0263 return NULL;
0264
0265 if (jd->buf == NULL) {
0266 size_t sz = getpagesize();
0267 if (sz < sizeof(*prefix))
0268 sz = sizeof(*prefix);
0269
0270 jd->buf = malloc(sz);
0271 if (jd->buf == NULL)
0272 return NULL;
0273
0274 jd->bufsize = sz;
0275 }
0276
0277 prefix = jd->buf;
0278
0279
0280
0281
0282 ret = fread(prefix, sizeof(*prefix), 1, jd->in);
0283 if (ret != 1)
0284 return NULL;
0285
0286 if (jd->needs_bswap) {
0287 prefix->id = bswap_32(prefix->id);
0288 prefix->total_size = bswap_32(prefix->total_size);
0289 prefix->timestamp = bswap_64(prefix->timestamp);
0290 }
0291 id = prefix->id;
0292 size = prefix->total_size;
0293
0294 bs = (size_t)size;
0295 if (bs < sizeof(*prefix))
0296 return NULL;
0297
0298 if (id >= JIT_CODE_MAX) {
0299 pr_warning("next_entry: unknown record type %d, skipping\n", id);
0300 }
0301 if (bs > jd->bufsize) {
0302 void *n;
0303 n = realloc(jd->buf, bs);
0304 if (!n)
0305 return NULL;
0306 jd->buf = n;
0307 jd->bufsize = bs;
0308 }
0309
0310 addr = ((void *)jd->buf) + sizeof(*prefix);
0311
0312 ret = fread(addr, bs - sizeof(*prefix), 1, jd->in);
0313 if (ret != 1)
0314 return NULL;
0315
0316 jr = (union jr_entry *)jd->buf;
0317
0318 switch(id) {
0319 case JIT_CODE_DEBUG_INFO:
0320 if (jd->needs_bswap) {
0321 uint64_t n;
0322 jr->info.code_addr = bswap_64(jr->info.code_addr);
0323 jr->info.nr_entry = bswap_64(jr->info.nr_entry);
0324 for (n = 0 ; n < jr->info.nr_entry; n++) {
0325 jr->info.entries[n].addr = bswap_64(jr->info.entries[n].addr);
0326 jr->info.entries[n].lineno = bswap_32(jr->info.entries[n].lineno);
0327 jr->info.entries[n].discrim = bswap_32(jr->info.entries[n].discrim);
0328 }
0329 }
0330 break;
0331 case JIT_CODE_UNWINDING_INFO:
0332 if (jd->needs_bswap) {
0333 jr->unwinding.unwinding_size = bswap_64(jr->unwinding.unwinding_size);
0334 jr->unwinding.eh_frame_hdr_size = bswap_64(jr->unwinding.eh_frame_hdr_size);
0335 jr->unwinding.mapped_size = bswap_64(jr->unwinding.mapped_size);
0336 }
0337 break;
0338 case JIT_CODE_CLOSE:
0339 break;
0340 case JIT_CODE_LOAD:
0341 if (jd->needs_bswap) {
0342 jr->load.pid = bswap_32(jr->load.pid);
0343 jr->load.tid = bswap_32(jr->load.tid);
0344 jr->load.vma = bswap_64(jr->load.vma);
0345 jr->load.code_addr = bswap_64(jr->load.code_addr);
0346 jr->load.code_size = bswap_64(jr->load.code_size);
0347 jr->load.code_index= bswap_64(jr->load.code_index);
0348 }
0349 jd->code_load_count++;
0350 break;
0351 case JIT_CODE_MOVE:
0352 if (jd->needs_bswap) {
0353 jr->move.pid = bswap_32(jr->move.pid);
0354 jr->move.tid = bswap_32(jr->move.tid);
0355 jr->move.vma = bswap_64(jr->move.vma);
0356 jr->move.old_code_addr = bswap_64(jr->move.old_code_addr);
0357 jr->move.new_code_addr = bswap_64(jr->move.new_code_addr);
0358 jr->move.code_size = bswap_64(jr->move.code_size);
0359 jr->move.code_index = bswap_64(jr->move.code_index);
0360 }
0361 break;
0362 case JIT_CODE_MAX:
0363 default:
0364
0365 break;
0366 }
0367 return jr;
0368 }
0369
0370 static int
0371 jit_inject_event(struct jit_buf_desc *jd, union perf_event *event)
0372 {
0373 ssize_t size;
0374
0375 size = perf_data__write(jd->output, event, event->header.size);
0376 if (size < 0)
0377 return -1;
0378
0379 jd->bytes_written += size;
0380 return 0;
0381 }
0382
0383 static pid_t jr_entry_pid(struct jit_buf_desc *jd, union jr_entry *jr)
0384 {
0385 if (jd->nsi && nsinfo__in_pidns(jd->nsi))
0386 return nsinfo__tgid(jd->nsi);
0387 return jr->load.pid;
0388 }
0389
0390 static pid_t jr_entry_tid(struct jit_buf_desc *jd, union jr_entry *jr)
0391 {
0392 if (jd->nsi && nsinfo__in_pidns(jd->nsi))
0393 return nsinfo__pid(jd->nsi);
0394 return jr->load.tid;
0395 }
0396
0397 static uint64_t convert_timestamp(struct jit_buf_desc *jd, uint64_t timestamp)
0398 {
0399 struct perf_tsc_conversion tc = { .time_shift = 0, };
0400 struct perf_record_time_conv *time_conv = &jd->session->time_conv;
0401
0402 if (!jd->use_arch_timestamp)
0403 return timestamp;
0404
0405 tc.time_shift = time_conv->time_shift;
0406 tc.time_mult = time_conv->time_mult;
0407 tc.time_zero = time_conv->time_zero;
0408
0409
0410
0411
0412
0413
0414
0415 if (event_contains(*time_conv, time_cycles)) {
0416 tc.time_cycles = time_conv->time_cycles;
0417 tc.time_mask = time_conv->time_mask;
0418 tc.cap_user_time_zero = time_conv->cap_user_time_zero;
0419 tc.cap_user_time_short = time_conv->cap_user_time_short;
0420
0421 if (!tc.cap_user_time_zero)
0422 return 0;
0423 }
0424
0425 return tsc_to_perf_time(timestamp, &tc);
0426 }
0427
0428 static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
0429 {
0430 struct perf_sample sample;
0431 union perf_event *event;
0432 struct perf_tool *tool = jd->session->tool;
0433 uint64_t code, addr;
0434 uintptr_t uaddr;
0435 char *filename;
0436 struct stat st;
0437 size_t size;
0438 u16 idr_size;
0439 const char *sym;
0440 uint64_t count;
0441 int ret, csize, usize;
0442 pid_t nspid, pid, tid;
0443 struct {
0444 u32 pid, tid;
0445 u64 time;
0446 } *id;
0447
0448 nspid = jr->load.pid;
0449 pid = jr_entry_pid(jd, jr);
0450 tid = jr_entry_tid(jd, jr);
0451 csize = jr->load.code_size;
0452 usize = jd->unwinding_mapped_size;
0453 addr = jr->load.code_addr;
0454 sym = (void *)((unsigned long)jr + sizeof(jr->load));
0455 code = (unsigned long)jr + jr->load.p.total_size - csize;
0456 count = jr->load.code_index;
0457 idr_size = jd->machine->id_hdr_size;
0458
0459 event = calloc(1, sizeof(*event) + idr_size);
0460 if (!event)
0461 return -1;
0462
0463 filename = event->mmap2.filename;
0464 size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%" PRIu64 ".so",
0465 jd->dir,
0466 nspid,
0467 count);
0468
0469 size++;
0470
0471 size = PERF_ALIGN(size, sizeof(u64));
0472 uaddr = (uintptr_t)code;
0473 ret = jit_emit_elf(jd, filename, sym, addr, (const void *)uaddr, csize, jd->debug_data, jd->nr_debug_entries,
0474 jd->unwinding_data, jd->eh_frame_hdr_size, jd->unwinding_size);
0475
0476 if (jd->debug_data && jd->nr_debug_entries) {
0477 zfree(&jd->debug_data);
0478 jd->nr_debug_entries = 0;
0479 }
0480
0481 if (jd->unwinding_data && jd->eh_frame_hdr_size) {
0482 zfree(&jd->unwinding_data);
0483 jd->eh_frame_hdr_size = 0;
0484 jd->unwinding_mapped_size = 0;
0485 jd->unwinding_size = 0;
0486 }
0487
0488 if (ret) {
0489 free(event);
0490 return -1;
0491 }
0492 if (nsinfo__stat(filename, &st, jd->nsi))
0493 memset(&st, 0, sizeof(st));
0494
0495 event->mmap2.header.type = PERF_RECORD_MMAP2;
0496 event->mmap2.header.misc = PERF_RECORD_MISC_USER;
0497 event->mmap2.header.size = (sizeof(event->mmap2) -
0498 (sizeof(event->mmap2.filename) - size) + idr_size);
0499
0500 event->mmap2.pgoff = GEN_ELF_TEXT_OFFSET;
0501 event->mmap2.start = addr;
0502 event->mmap2.len = usize ? ALIGN_8(csize) + usize : csize;
0503 event->mmap2.pid = pid;
0504 event->mmap2.tid = tid;
0505 event->mmap2.ino = st.st_ino;
0506 event->mmap2.maj = major(st.st_dev);
0507 event->mmap2.min = minor(st.st_dev);
0508 event->mmap2.prot = st.st_mode;
0509 event->mmap2.flags = MAP_SHARED;
0510 event->mmap2.ino_generation = 1;
0511
0512 id = (void *)((unsigned long)event + event->mmap.header.size - idr_size);
0513 if (jd->sample_type & PERF_SAMPLE_TID) {
0514 id->pid = pid;
0515 id->tid = tid;
0516 }
0517 if (jd->sample_type & PERF_SAMPLE_TIME)
0518 id->time = convert_timestamp(jd, jr->load.p.timestamp);
0519
0520
0521
0522
0523
0524 memset(&sample, 0, sizeof(sample));
0525 sample.cpumode = PERF_RECORD_MISC_USER;
0526 sample.pid = pid;
0527 sample.tid = tid;
0528 sample.time = id->time;
0529 sample.ip = addr;
0530
0531 ret = perf_event__process_mmap2(tool, event, &sample, jd->machine);
0532 if (ret)
0533 return ret;
0534
0535 ret = jit_inject_event(jd, event);
0536
0537
0538
0539 if (!ret)
0540 build_id__mark_dso_hit(tool, event, &sample, NULL, jd->machine);
0541
0542 return ret;
0543 }
0544
0545 static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr)
0546 {
0547 struct perf_sample sample;
0548 union perf_event *event;
0549 struct perf_tool *tool = jd->session->tool;
0550 char *filename;
0551 size_t size;
0552 struct stat st;
0553 int usize;
0554 u16 idr_size;
0555 int ret;
0556 pid_t nspid, pid, tid;
0557 struct {
0558 u32 pid, tid;
0559 u64 time;
0560 } *id;
0561
0562 nspid = jr->load.pid;
0563 pid = jr_entry_pid(jd, jr);
0564 tid = jr_entry_tid(jd, jr);
0565 usize = jd->unwinding_mapped_size;
0566 idr_size = jd->machine->id_hdr_size;
0567
0568
0569
0570
0571 event = calloc(1, sizeof(*event) + 16);
0572 if (!event)
0573 return -1;
0574
0575 filename = event->mmap2.filename;
0576 size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%" PRIu64 ".so",
0577 jd->dir,
0578 nspid,
0579 jr->move.code_index);
0580
0581 size++;
0582
0583 if (nsinfo__stat(filename, &st, jd->nsi))
0584 memset(&st, 0, sizeof(st));
0585
0586 size = PERF_ALIGN(size, sizeof(u64));
0587
0588 event->mmap2.header.type = PERF_RECORD_MMAP2;
0589 event->mmap2.header.misc = PERF_RECORD_MISC_USER;
0590 event->mmap2.header.size = (sizeof(event->mmap2) -
0591 (sizeof(event->mmap2.filename) - size) + idr_size);
0592 event->mmap2.pgoff = GEN_ELF_TEXT_OFFSET;
0593 event->mmap2.start = jr->move.new_code_addr;
0594 event->mmap2.len = usize ? ALIGN_8(jr->move.code_size) + usize
0595 : jr->move.code_size;
0596 event->mmap2.pid = pid;
0597 event->mmap2.tid = tid;
0598 event->mmap2.ino = st.st_ino;
0599 event->mmap2.maj = major(st.st_dev);
0600 event->mmap2.min = minor(st.st_dev);
0601 event->mmap2.prot = st.st_mode;
0602 event->mmap2.flags = MAP_SHARED;
0603 event->mmap2.ino_generation = 1;
0604
0605 id = (void *)((unsigned long)event + event->mmap.header.size - idr_size);
0606 if (jd->sample_type & PERF_SAMPLE_TID) {
0607 id->pid = pid;
0608 id->tid = tid;
0609 }
0610 if (jd->sample_type & PERF_SAMPLE_TIME)
0611 id->time = convert_timestamp(jd, jr->load.p.timestamp);
0612
0613
0614
0615
0616
0617 memset(&sample, 0, sizeof(sample));
0618 sample.cpumode = PERF_RECORD_MISC_USER;
0619 sample.pid = pid;
0620 sample.tid = tid;
0621 sample.time = id->time;
0622 sample.ip = jr->move.new_code_addr;
0623
0624 ret = perf_event__process_mmap2(tool, event, &sample, jd->machine);
0625 if (ret)
0626 return ret;
0627
0628 ret = jit_inject_event(jd, event);
0629 if (!ret)
0630 build_id__mark_dso_hit(tool, event, &sample, NULL, jd->machine);
0631
0632 return ret;
0633 }
0634
0635 static int jit_repipe_debug_info(struct jit_buf_desc *jd, union jr_entry *jr)
0636 {
0637 void *data;
0638 size_t sz;
0639
0640 if (!(jd && jr))
0641 return -1;
0642
0643 sz = jr->prefix.total_size - sizeof(jr->info);
0644 data = malloc(sz);
0645 if (!data)
0646 return -1;
0647
0648 memcpy(data, &jr->info.entries, sz);
0649
0650 jd->debug_data = data;
0651
0652
0653
0654
0655
0656 jd->nr_debug_entries = jr->info.nr_entry;
0657
0658 return 0;
0659 }
0660
0661 static int
0662 jit_repipe_unwinding_info(struct jit_buf_desc *jd, union jr_entry *jr)
0663 {
0664 void *unwinding_data;
0665 uint32_t unwinding_data_size;
0666
0667 if (!(jd && jr))
0668 return -1;
0669
0670 unwinding_data_size = jr->prefix.total_size - sizeof(jr->unwinding);
0671 unwinding_data = malloc(unwinding_data_size);
0672 if (!unwinding_data)
0673 return -1;
0674
0675 memcpy(unwinding_data, &jr->unwinding.unwinding_data,
0676 unwinding_data_size);
0677
0678 jd->eh_frame_hdr_size = jr->unwinding.eh_frame_hdr_size;
0679 jd->unwinding_size = jr->unwinding.unwinding_size;
0680 jd->unwinding_mapped_size = jr->unwinding.mapped_size;
0681 jd->unwinding_data = unwinding_data;
0682
0683 return 0;
0684 }
0685
0686 static int
0687 jit_process_dump(struct jit_buf_desc *jd)
0688 {
0689 union jr_entry *jr;
0690 int ret = 0;
0691
0692 while ((jr = jit_get_next_entry(jd))) {
0693 switch(jr->prefix.id) {
0694 case JIT_CODE_LOAD:
0695 ret = jit_repipe_code_load(jd, jr);
0696 break;
0697 case JIT_CODE_MOVE:
0698 ret = jit_repipe_code_move(jd, jr);
0699 break;
0700 case JIT_CODE_DEBUG_INFO:
0701 ret = jit_repipe_debug_info(jd, jr);
0702 break;
0703 case JIT_CODE_UNWINDING_INFO:
0704 ret = jit_repipe_unwinding_info(jd, jr);
0705 break;
0706 default:
0707 ret = 0;
0708 continue;
0709 }
0710 }
0711 return ret;
0712 }
0713
0714 static int
0715 jit_inject(struct jit_buf_desc *jd, char *path)
0716 {
0717 int ret;
0718
0719 if (verbose > 0)
0720 fprintf(stderr, "injecting: %s\n", path);
0721
0722 ret = jit_open(jd, path);
0723 if (ret)
0724 return -1;
0725
0726 ret = jit_process_dump(jd);
0727
0728 jit_close(jd);
0729
0730 if (verbose > 0)
0731 fprintf(stderr, "injected: %s (%d)\n", path, ret);
0732
0733 return 0;
0734 }
0735
0736
0737
0738
0739
0740
0741 static int
0742 jit_detect(char *mmap_name, pid_t pid, struct nsinfo *nsi)
0743 {
0744 char *p;
0745 char *end = NULL;
0746 pid_t pid2;
0747
0748 if (verbose > 2)
0749 fprintf(stderr, "jit marker trying : %s\n", mmap_name);
0750
0751
0752
0753 p = strrchr(mmap_name, '/');
0754 if (!p)
0755 return -1;
0756
0757
0758
0759
0760 if (strncmp(p, "/jit-", 5))
0761 return -1;
0762
0763
0764
0765
0766 p += 5;
0767
0768
0769
0770
0771 if (!isdigit(*p))
0772 return -1;
0773
0774 pid2 = (int)strtol(p, &end, 10);
0775 if (!end)
0776 return -1;
0777
0778
0779
0780
0781
0782 if (pid && pid2 != nsinfo__nstgid(nsi))
0783 return -1;
0784
0785
0786
0787 if (strcmp(end, ".dump"))
0788 return -1;
0789
0790 if (verbose > 0)
0791 fprintf(stderr, "jit marker found: %s\n", mmap_name);
0792
0793 return 0;
0794 }
0795
0796 static void jit_add_pid(struct machine *machine, pid_t pid)
0797 {
0798 struct thread *thread = machine__findnew_thread(machine, pid, pid);
0799
0800 if (!thread) {
0801 pr_err("%s: thread %d not found or created\n", __func__, pid);
0802 return;
0803 }
0804
0805 thread->priv = (void *)1;
0806 }
0807
0808 static bool jit_has_pid(struct machine *machine, pid_t pid)
0809 {
0810 struct thread *thread = machine__find_thread(machine, pid, pid);
0811
0812 if (!thread)
0813 return 0;
0814
0815 return (bool)thread->priv;
0816 }
0817
0818 int
0819 jit_process(struct perf_session *session,
0820 struct perf_data *output,
0821 struct machine *machine,
0822 char *filename,
0823 pid_t pid,
0824 pid_t tid,
0825 u64 *nbytes)
0826 {
0827 struct thread *thread;
0828 struct nsinfo *nsi;
0829 struct evsel *first;
0830 struct jit_buf_desc jd;
0831 int ret;
0832
0833 thread = machine__findnew_thread(machine, pid, tid);
0834 if (thread == NULL) {
0835 pr_err("problem processing JIT mmap event, skipping it.\n");
0836 return 0;
0837 }
0838
0839 nsi = nsinfo__get(thread->nsinfo);
0840 thread__put(thread);
0841
0842
0843
0844
0845 if (jit_detect(filename, pid, nsi)) {
0846 nsinfo__put(nsi);
0847
0848
0849
0850
0851 if (jit_has_pid(machine, pid) &&
0852 ((strncmp(filename, "//anon", 6) == 0) ||
0853 (strncmp(filename, "[anon:", 6) == 0) ||
0854 (strncmp(filename, "/memfd:", 7) == 0)))
0855 return 1;
0856
0857 return 0;
0858 }
0859
0860 memset(&jd, 0, sizeof(jd));
0861
0862 jd.session = session;
0863 jd.output = output;
0864 jd.machine = machine;
0865 jd.nsi = nsi;
0866
0867
0868
0869
0870
0871 first = evlist__first(session->evlist);
0872 jd.sample_type = first->core.attr.sample_type;
0873
0874 *nbytes = 0;
0875
0876 ret = jit_inject(&jd, filename);
0877 if (!ret) {
0878 jit_add_pid(machine, pid);
0879 *nbytes = jd.bytes_written;
0880 ret = 1;
0881 }
0882
0883 nsinfo__put(jd.nsi);
0884
0885 return ret;
0886 }