jitdump.c (1809de7e7d37c585e01a1bcc583ea92b78fc759d) | jitdump.c (2a28e23049af99e1c810111ef5e56455cafeda45) |
---|---|
1#include <sys/types.h> 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5#include <fcntl.h> 6#include <unistd.h> 7#include <inttypes.h> 8#include <byteswap.h> 9#include <sys/stat.h> 10#include <sys/mman.h> 11 12#include "util.h" 13#include "event.h" 14#include "debug.h" 15#include "evlist.h" 16#include "symbol.h" 17#include "strlist.h" 18#include <elf.h> 19 | 1#include <sys/types.h> 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5#include <fcntl.h> 6#include <unistd.h> 7#include <inttypes.h> 8#include <byteswap.h> 9#include <sys/stat.h> 10#include <sys/mman.h> 11 12#include "util.h" 13#include "event.h" 14#include "debug.h" 15#include "evlist.h" 16#include "symbol.h" 17#include "strlist.h" 18#include <elf.h> 19 |
20#include "tsc.h" |
|
20#include "session.h" 21#include "jit.h" 22#include "jitdump.h" 23#include "genelf.h" 24#include "../builtin.h" 25 26struct jit_buf_desc { 27 struct perf_data_file *output; 28 struct perf_session *session; 29 struct machine *machine; 30 union jr_entry *entry; 31 void *buf; 32 uint64_t sample_type; 33 size_t bufsize; 34 FILE *in; 35 bool needs_bswap; /* handles cross-endianess */ | 21#include "session.h" 22#include "jit.h" 23#include "jitdump.h" 24#include "genelf.h" 25#include "../builtin.h" 26 27struct jit_buf_desc { 28 struct perf_data_file *output; 29 struct perf_session *session; 30 struct machine *machine; 31 union jr_entry *entry; 32 void *buf; 33 uint64_t sample_type; 34 size_t bufsize; 35 FILE *in; 36 bool needs_bswap; /* handles cross-endianess */ |
37 bool use_arch_timestamp; |
|
36 void *debug_data; 37 size_t nr_debug_entries; 38 uint32_t code_load_count; 39 u64 bytes_written; 40 struct rb_root code_root; 41 char dir[PATH_MAX]; 42}; 43 --- 109 unchanged lines hidden (view full) --- 153 header.version = bswap_32(header.version); 154 header.total_size = bswap_32(header.total_size); 155 header.pid = bswap_32(header.pid); 156 header.elf_mach = bswap_32(header.elf_mach); 157 header.timestamp = bswap_64(header.timestamp); 158 header.flags = bswap_64(header.flags); 159 } 160 | 38 void *debug_data; 39 size_t nr_debug_entries; 40 uint32_t code_load_count; 41 u64 bytes_written; 42 struct rb_root code_root; 43 char dir[PATH_MAX]; 44}; 45 --- 109 unchanged lines hidden (view full) --- 155 header.version = bswap_32(header.version); 156 header.total_size = bswap_32(header.total_size); 157 header.pid = bswap_32(header.pid); 158 header.elf_mach = bswap_32(header.elf_mach); 159 header.timestamp = bswap_64(header.timestamp); 160 header.flags = bswap_64(header.flags); 161 } 162 |
163 jd->use_arch_timestamp = header.flags & JITDUMP_FLAGS_ARCH_TIMESTAMP; 164 |
|
161 if (verbose > 2) | 165 if (verbose > 2) |
162 pr_debug("version=%u\nhdr.size=%u\nts=0x%llx\npid=%d\nelf_mach=%d\n", | 166 pr_debug("version=%u\nhdr.size=%u\nts=0x%llx\npid=%d\nelf_mach=%d\nuse_arch_timestamp=%d\n", |
163 header.version, 164 header.total_size, 165 (unsigned long long)header.timestamp, 166 header.pid, | 167 header.version, 168 header.total_size, 169 (unsigned long long)header.timestamp, 170 header.pid, |
167 header.elf_mach); | 171 header.elf_mach, 172 jd->use_arch_timestamp); |
168 169 if (header.flags & JITDUMP_FLAGS_RESERVED) { 170 pr_err("jitdump file contains invalid or unsupported flags 0x%llx\n", 171 (unsigned long long)header.flags & JITDUMP_FLAGS_RESERVED); 172 goto error; 173 } 174 | 173 174 if (header.flags & JITDUMP_FLAGS_RESERVED) { 175 pr_err("jitdump file contains invalid or unsupported flags 0x%llx\n", 176 (unsigned long long)header.flags & JITDUMP_FLAGS_RESERVED); 177 goto error; 178 } 179 |
180 if (jd->use_arch_timestamp && !jd->session->time_conv.time_mult) { 181 pr_err("jitdump file uses arch timestamps but there is no timestamp conversion\n"); 182 goto error; 183 } 184 |
|
175 /* 176 * validate event is using the correct clockid 177 */ | 185 /* 186 * validate event is using the correct clockid 187 */ |
178 if (jit_validate_events(jd->session)) { | 188 if (!jd->use_arch_timestamp && jit_validate_events(jd->session)) { |
179 pr_err("error, jitted code must be sampled with perf record -k 1\n"); 180 goto error; 181 } 182 183 bs = header.total_size - sizeof(header); 184 185 if (bs > bsz) { 186 n = realloc(buf, bs); --- 137 unchanged lines hidden (view full) --- 324 size = perf_data_file__write(jd->output, event, event->header.size); 325 if (size < 0) 326 return -1; 327 328 jd->bytes_written += size; 329 return 0; 330} 331 | 189 pr_err("error, jitted code must be sampled with perf record -k 1\n"); 190 goto error; 191 } 192 193 bs = header.total_size - sizeof(header); 194 195 if (bs > bsz) { 196 n = realloc(buf, bs); --- 137 unchanged lines hidden (view full) --- 334 size = perf_data_file__write(jd->output, event, event->header.size); 335 if (size < 0) 336 return -1; 337 338 jd->bytes_written += size; 339 return 0; 340} 341 |
342static uint64_t convert_timestamp(struct jit_buf_desc *jd, uint64_t timestamp) 343{ 344 struct perf_tsc_conversion tc; 345 346 if (!jd->use_arch_timestamp) 347 return timestamp; 348 349 tc.time_shift = jd->session->time_conv.time_shift; 350 tc.time_mult = jd->session->time_conv.time_mult; 351 tc.time_zero = jd->session->time_conv.time_zero; 352 353 if (!tc.time_mult) 354 return 0; 355 356 return tsc_to_perf_time(timestamp, &tc); 357} 358 |
|
332static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr) 333{ 334 struct perf_sample sample; 335 union perf_event *event; 336 struct perf_tool *tool = jd->session->tool; 337 uint64_t code, addr; 338 uintptr_t uaddr; 339 char *filename; --- 65 unchanged lines hidden (view full) --- 405 event->mmap2.ino_generation = 1; 406 407 id = (void *)((unsigned long)event + event->mmap.header.size - idr_size); 408 if (jd->sample_type & PERF_SAMPLE_TID) { 409 id->pid = pid; 410 id->tid = tid; 411 } 412 if (jd->sample_type & PERF_SAMPLE_TIME) | 359static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr) 360{ 361 struct perf_sample sample; 362 union perf_event *event; 363 struct perf_tool *tool = jd->session->tool; 364 uint64_t code, addr; 365 uintptr_t uaddr; 366 char *filename; --- 65 unchanged lines hidden (view full) --- 432 event->mmap2.ino_generation = 1; 433 434 id = (void *)((unsigned long)event + event->mmap.header.size - idr_size); 435 if (jd->sample_type & PERF_SAMPLE_TID) { 436 id->pid = pid; 437 id->tid = tid; 438 } 439 if (jd->sample_type & PERF_SAMPLE_TIME) |
413 id->time = jr->load.p.timestamp; | 440 id->time = convert_timestamp(jd, jr->load.p.timestamp); |
414 415 /* 416 * create pseudo sample to induce dso hit increment 417 * use first address as sample address 418 */ 419 memset(&sample, 0, sizeof(sample)); | 441 442 /* 443 * create pseudo sample to induce dso hit increment 444 * use first address as sample address 445 */ 446 memset(&sample, 0, sizeof(sample)); |
447 sample.cpumode = PERF_RECORD_MISC_USER; |
|
420 sample.pid = pid; 421 sample.tid = tid; 422 sample.time = id->time; 423 sample.ip = addr; 424 425 ret = perf_event__process_mmap2(tool, event, &sample, jd->machine); 426 if (ret) 427 return ret; --- 65 unchanged lines hidden (view full) --- 493 event->mmap2.ino_generation = 1; 494 495 id = (void *)((unsigned long)event + event->mmap.header.size - idr_size); 496 if (jd->sample_type & PERF_SAMPLE_TID) { 497 id->pid = pid; 498 id->tid = tid; 499 } 500 if (jd->sample_type & PERF_SAMPLE_TIME) | 448 sample.pid = pid; 449 sample.tid = tid; 450 sample.time = id->time; 451 sample.ip = addr; 452 453 ret = perf_event__process_mmap2(tool, event, &sample, jd->machine); 454 if (ret) 455 return ret; --- 65 unchanged lines hidden (view full) --- 521 event->mmap2.ino_generation = 1; 522 523 id = (void *)((unsigned long)event + event->mmap.header.size - idr_size); 524 if (jd->sample_type & PERF_SAMPLE_TID) { 525 id->pid = pid; 526 id->tid = tid; 527 } 528 if (jd->sample_type & PERF_SAMPLE_TIME) |
501 id->time = jr->load.p.timestamp; | 529 id->time = convert_timestamp(jd, jr->load.p.timestamp); |
502 503 /* 504 * create pseudo sample to induce dso hit increment 505 * use first address as sample address 506 */ 507 memset(&sample, 0, sizeof(sample)); | 530 531 /* 532 * create pseudo sample to induce dso hit increment 533 * use first address as sample address 534 */ 535 memset(&sample, 0, sizeof(sample)); |
536 sample.cpumode = PERF_RECORD_MISC_USER; |
|
508 sample.pid = pid; 509 sample.tid = tid; 510 sample.time = id->time; 511 sample.ip = jr->move.new_code_addr; 512 513 ret = perf_event__process_mmap2(tool, event, &sample, jd->machine); 514 if (ret) 515 return ret; --- 182 unchanged lines hidden --- | 537 sample.pid = pid; 538 sample.tid = tid; 539 sample.time = id->time; 540 sample.ip = jr->move.new_code_addr; 541 542 ret = perf_event__process_mmap2(tool, event, &sample, jd->machine); 543 if (ret) 544 return ret; --- 182 unchanged lines hidden --- |