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 ---