1 #include "util.h"
2 #include <sys/types.h>
3 #include <byteswap.h>
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <linux/list.h>
8 #include <linux/kernel.h>
9 #include <linux/bitops.h>
10 #include <sys/utsname.h>
11
12 #include "evlist.h"
13 #include "evsel.h"
14 #include "header.h"
15 #include "../perf.h"
16 #include "trace-event.h"
17 #include "session.h"
18 #include "symbol.h"
19 #include "debug.h"
20 #include "cpumap.h"
21 #include "pmu.h"
22 #include "vdso.h"
23 #include "strbuf.h"
24 #include "build-id.h"
25 #include "data.h"
26
27 static bool no_buildid_cache = false;
28
29 static u32 header_argc;
30 static const char **header_argv;
31
32 /*
33 * magic2 = "PERFILE2"
34 * must be a numerical value to let the endianness
35 * determine the memory layout. That way we are able
36 * to detect endianness when reading the perf.data file
37 * back.
38 *
39 * we check for legacy (PERFFILE) format.
40 */
41 static const char *__perf_magic1 = "PERFFILE";
42 static const u64 __perf_magic2 = 0x32454c4946524550ULL;
43 static const u64 __perf_magic2_sw = 0x50455246494c4532ULL;
44
45 #define PERF_MAGIC __perf_magic2
46
47 struct perf_file_attr {
48 struct perf_event_attr attr;
49 struct perf_file_section ids;
50 };
51
perf_header__set_feat(struct perf_header * header,int feat)52 void perf_header__set_feat(struct perf_header *header, int feat)
53 {
54 set_bit(feat, header->adds_features);
55 }
56
perf_header__clear_feat(struct perf_header * header,int feat)57 void perf_header__clear_feat(struct perf_header *header, int feat)
58 {
59 clear_bit(feat, header->adds_features);
60 }
61
perf_header__has_feat(const struct perf_header * header,int feat)62 bool perf_header__has_feat(const struct perf_header *header, int feat)
63 {
64 return test_bit(feat, header->adds_features);
65 }
66
do_write(int fd,const void * buf,size_t size)67 static int do_write(int fd, const void *buf, size_t size)
68 {
69 while (size) {
70 int ret = write(fd, buf, size);
71
72 if (ret < 0)
73 return -errno;
74
75 size -= ret;
76 buf += ret;
77 }
78
79 return 0;
80 }
81
82 #define NAME_ALIGN 64
83
write_padded(int fd,const void * bf,size_t count,size_t count_aligned)84 static int write_padded(int fd, const void *bf, size_t count,
85 size_t count_aligned)
86 {
87 static const char zero_buf[NAME_ALIGN];
88 int err = do_write(fd, bf, count);
89
90 if (!err)
91 err = do_write(fd, zero_buf, count_aligned - count);
92
93 return err;
94 }
95
do_write_string(int fd,const char * str)96 static int do_write_string(int fd, const char *str)
97 {
98 u32 len, olen;
99 int ret;
100
101 olen = strlen(str) + 1;
102 len = PERF_ALIGN(olen, NAME_ALIGN);
103
104 /* write len, incl. \0 */
105 ret = do_write(fd, &len, sizeof(len));
106 if (ret < 0)
107 return ret;
108
109 return write_padded(fd, str, olen, len);
110 }
111
do_read_string(int fd,struct perf_header * ph)112 static char *do_read_string(int fd, struct perf_header *ph)
113 {
114 ssize_t sz, ret;
115 u32 len;
116 char *buf;
117
118 sz = readn(fd, &len, sizeof(len));
119 if (sz < (ssize_t)sizeof(len))
120 return NULL;
121
122 if (ph->needs_swap)
123 len = bswap_32(len);
124
125 buf = malloc(len);
126 if (!buf)
127 return NULL;
128
129 ret = readn(fd, buf, len);
130 if (ret == (ssize_t)len) {
131 /*
132 * strings are padded by zeroes
133 * thus the actual strlen of buf
134 * may be less than len
135 */
136 return buf;
137 }
138
139 free(buf);
140 return NULL;
141 }
142
143 int
perf_header__set_cmdline(int argc,const char ** argv)144 perf_header__set_cmdline(int argc, const char **argv)
145 {
146 int i;
147
148 /*
149 * If header_argv has already been set, do not override it.
150 * This allows a command to set the cmdline, parse args and
151 * then call another builtin function that implements a
152 * command -- e.g, cmd_kvm calling cmd_record.
153 */
154 if (header_argv)
155 return 0;
156
157 header_argc = (u32)argc;
158
159 /* do not include NULL termination */
160 header_argv = calloc(argc, sizeof(char *));
161 if (!header_argv)
162 return -ENOMEM;
163
164 /*
165 * must copy argv contents because it gets moved
166 * around during option parsing
167 */
168 for (i = 0; i < argc ; i++)
169 header_argv[i] = argv[i];
170
171 return 0;
172 }
173
174 #define dsos__for_each_with_build_id(pos, head) \
175 list_for_each_entry(pos, head, node) \
176 if (!pos->has_build_id) \
177 continue; \
178 else
179
write_buildid(const char * name,size_t name_len,u8 * build_id,pid_t pid,u16 misc,int fd)180 static int write_buildid(const char *name, size_t name_len, u8 *build_id,
181 pid_t pid, u16 misc, int fd)
182 {
183 int err;
184 struct build_id_event b;
185 size_t len;
186
187 len = name_len + 1;
188 len = PERF_ALIGN(len, NAME_ALIGN);
189
190 memset(&b, 0, sizeof(b));
191 memcpy(&b.build_id, build_id, BUILD_ID_SIZE);
192 b.pid = pid;
193 b.header.misc = misc;
194 b.header.size = sizeof(b) + len;
195
196 err = do_write(fd, &b, sizeof(b));
197 if (err < 0)
198 return err;
199
200 return write_padded(fd, name, name_len + 1, len);
201 }
202
__dsos__hit_all(struct list_head * head)203 static int __dsos__hit_all(struct list_head *head)
204 {
205 struct dso *pos;
206
207 list_for_each_entry(pos, head, node)
208 pos->hit = true;
209
210 return 0;
211 }
212
machine__hit_all_dsos(struct machine * machine)213 static int machine__hit_all_dsos(struct machine *machine)
214 {
215 int err;
216
217 err = __dsos__hit_all(&machine->kernel_dsos.head);
218 if (err)
219 return err;
220
221 return __dsos__hit_all(&machine->user_dsos.head);
222 }
223
dsos__hit_all(struct perf_session * session)224 int dsos__hit_all(struct perf_session *session)
225 {
226 struct rb_node *nd;
227 int err;
228
229 err = machine__hit_all_dsos(&session->machines.host);
230 if (err)
231 return err;
232
233 for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
234 struct machine *pos = rb_entry(nd, struct machine, rb_node);
235
236 err = machine__hit_all_dsos(pos);
237 if (err)
238 return err;
239 }
240
241 return 0;
242 }
243
__dsos__write_buildid_table(struct list_head * head,struct machine * machine,pid_t pid,u16 misc,int fd)244 static int __dsos__write_buildid_table(struct list_head *head,
245 struct machine *machine,
246 pid_t pid, u16 misc, int fd)
247 {
248 char nm[PATH_MAX];
249 struct dso *pos;
250
251 dsos__for_each_with_build_id(pos, head) {
252 int err;
253 const char *name;
254 size_t name_len;
255
256 if (!pos->hit)
257 continue;
258
259 if (dso__is_vdso(pos)) {
260 name = pos->short_name;
261 name_len = pos->short_name_len + 1;
262 } else if (dso__is_kcore(pos)) {
263 machine__mmap_name(machine, nm, sizeof(nm));
264 name = nm;
265 name_len = strlen(nm) + 1;
266 } else {
267 name = pos->long_name;
268 name_len = pos->long_name_len + 1;
269 }
270
271 err = write_buildid(name, name_len, pos->build_id,
272 pid, misc, fd);
273 if (err)
274 return err;
275 }
276
277 return 0;
278 }
279
machine__write_buildid_table(struct machine * machine,int fd)280 static int machine__write_buildid_table(struct machine *machine, int fd)
281 {
282 int err;
283 u16 kmisc = PERF_RECORD_MISC_KERNEL,
284 umisc = PERF_RECORD_MISC_USER;
285
286 if (!machine__is_host(machine)) {
287 kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
288 umisc = PERF_RECORD_MISC_GUEST_USER;
289 }
290
291 err = __dsos__write_buildid_table(&machine->kernel_dsos.head, machine,
292 machine->pid, kmisc, fd);
293 if (err == 0)
294 err = __dsos__write_buildid_table(&machine->user_dsos.head,
295 machine, machine->pid, umisc,
296 fd);
297 return err;
298 }
299
dsos__write_buildid_table(struct perf_header * header,int fd)300 static int dsos__write_buildid_table(struct perf_header *header, int fd)
301 {
302 struct perf_session *session = container_of(header,
303 struct perf_session, header);
304 struct rb_node *nd;
305 int err = machine__write_buildid_table(&session->machines.host, fd);
306
307 if (err)
308 return err;
309
310 for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
311 struct machine *pos = rb_entry(nd, struct machine, rb_node);
312 err = machine__write_buildid_table(pos, fd);
313 if (err)
314 break;
315 }
316 return err;
317 }
318
build_id_cache__add_s(const char * sbuild_id,const char * debugdir,const char * name,bool is_kallsyms,bool is_vdso)319 int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
320 const char *name, bool is_kallsyms, bool is_vdso)
321 {
322 const size_t size = PATH_MAX;
323 char *realname, *filename = zalloc(size),
324 *linkname = zalloc(size), *targetname;
325 int len, err = -1;
326 bool slash = is_kallsyms || is_vdso;
327
328 if (is_kallsyms) {
329 if (symbol_conf.kptr_restrict) {
330 pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n");
331 err = 0;
332 goto out_free;
333 }
334 realname = (char *) name;
335 } else
336 realname = realpath(name, NULL);
337
338 if (realname == NULL || filename == NULL || linkname == NULL)
339 goto out_free;
340
341 len = scnprintf(filename, size, "%s%s%s",
342 debugdir, slash ? "/" : "",
343 is_vdso ? DSO__NAME_VDSO : realname);
344 if (mkdir_p(filename, 0755))
345 goto out_free;
346
347 snprintf(filename + len, size - len, "/%s", sbuild_id);
348
349 if (access(filename, F_OK)) {
350 if (is_kallsyms) {
351 if (copyfile("/proc/kallsyms", filename))
352 goto out_free;
353 } else if (link(realname, filename) && copyfile(name, filename))
354 goto out_free;
355 }
356
357 len = scnprintf(linkname, size, "%s/.build-id/%.2s",
358 debugdir, sbuild_id);
359
360 if (access(linkname, X_OK) && mkdir_p(linkname, 0755))
361 goto out_free;
362
363 snprintf(linkname + len, size - len, "/%s", sbuild_id + 2);
364 targetname = filename + strlen(debugdir) - 5;
365 memcpy(targetname, "../..", 5);
366
367 if (symlink(targetname, linkname) == 0)
368 err = 0;
369 out_free:
370 if (!is_kallsyms)
371 free(realname);
372 free(filename);
373 free(linkname);
374 return err;
375 }
376
build_id_cache__add_b(const u8 * build_id,size_t build_id_size,const char * name,const char * debugdir,bool is_kallsyms,bool is_vdso)377 static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
378 const char *name, const char *debugdir,
379 bool is_kallsyms, bool is_vdso)
380 {
381 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
382
383 build_id__sprintf(build_id, build_id_size, sbuild_id);
384
385 return build_id_cache__add_s(sbuild_id, debugdir, name,
386 is_kallsyms, is_vdso);
387 }
388
build_id_cache__remove_s(const char * sbuild_id,const char * debugdir)389 int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir)
390 {
391 const size_t size = PATH_MAX;
392 char *filename = zalloc(size),
393 *linkname = zalloc(size);
394 int err = -1;
395
396 if (filename == NULL || linkname == NULL)
397 goto out_free;
398
399 snprintf(linkname, size, "%s/.build-id/%.2s/%s",
400 debugdir, sbuild_id, sbuild_id + 2);
401
402 if (access(linkname, F_OK))
403 goto out_free;
404
405 if (readlink(linkname, filename, size - 1) < 0)
406 goto out_free;
407
408 if (unlink(linkname))
409 goto out_free;
410
411 /*
412 * Since the link is relative, we must make it absolute:
413 */
414 snprintf(linkname, size, "%s/.build-id/%.2s/%s",
415 debugdir, sbuild_id, filename);
416
417 if (unlink(linkname))
418 goto out_free;
419
420 err = 0;
421 out_free:
422 free(filename);
423 free(linkname);
424 return err;
425 }
426
dso__cache_build_id(struct dso * dso,struct machine * machine,const char * debugdir)427 static int dso__cache_build_id(struct dso *dso, struct machine *machine,
428 const char *debugdir)
429 {
430 bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
431 bool is_vdso = dso__is_vdso(dso);
432 const char *name = dso->long_name;
433 char nm[PATH_MAX];
434
435 if (dso__is_kcore(dso)) {
436 is_kallsyms = true;
437 machine__mmap_name(machine, nm, sizeof(nm));
438 name = nm;
439 }
440 return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name,
441 debugdir, is_kallsyms, is_vdso);
442 }
443
__dsos__cache_build_ids(struct list_head * head,struct machine * machine,const char * debugdir)444 static int __dsos__cache_build_ids(struct list_head *head,
445 struct machine *machine, const char *debugdir)
446 {
447 struct dso *pos;
448 int err = 0;
449
450 dsos__for_each_with_build_id(pos, head)
451 if (dso__cache_build_id(pos, machine, debugdir))
452 err = -1;
453
454 return err;
455 }
456
machine__cache_build_ids(struct machine * machine,const char * debugdir)457 static int machine__cache_build_ids(struct machine *machine, const char *debugdir)
458 {
459 int ret = __dsos__cache_build_ids(&machine->kernel_dsos.head, machine,
460 debugdir);
461 ret |= __dsos__cache_build_ids(&machine->user_dsos.head, machine,
462 debugdir);
463 return ret;
464 }
465
perf_session__cache_build_ids(struct perf_session * session)466 static int perf_session__cache_build_ids(struct perf_session *session)
467 {
468 struct rb_node *nd;
469 int ret;
470 char debugdir[PATH_MAX];
471
472 snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
473
474 if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
475 return -1;
476
477 ret = machine__cache_build_ids(&session->machines.host, debugdir);
478
479 for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
480 struct machine *pos = rb_entry(nd, struct machine, rb_node);
481 ret |= machine__cache_build_ids(pos, debugdir);
482 }
483 return ret ? -1 : 0;
484 }
485
machine__read_build_ids(struct machine * machine,bool with_hits)486 static bool machine__read_build_ids(struct machine *machine, bool with_hits)
487 {
488 bool ret;
489
490 ret = __dsos__read_build_ids(&machine->kernel_dsos.head, with_hits);
491 ret |= __dsos__read_build_ids(&machine->user_dsos.head, with_hits);
492 return ret;
493 }
494
perf_session__read_build_ids(struct perf_session * session,bool with_hits)495 static bool perf_session__read_build_ids(struct perf_session *session, bool with_hits)
496 {
497 struct rb_node *nd;
498 bool ret = machine__read_build_ids(&session->machines.host, with_hits);
499
500 for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
501 struct machine *pos = rb_entry(nd, struct machine, rb_node);
502 ret |= machine__read_build_ids(pos, with_hits);
503 }
504
505 return ret;
506 }
507
write_tracing_data(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist)508 static int write_tracing_data(int fd, struct perf_header *h __maybe_unused,
509 struct perf_evlist *evlist)
510 {
511 return read_tracing_data(fd, &evlist->entries);
512 }
513
514
write_build_id(int fd,struct perf_header * h,struct perf_evlist * evlist __maybe_unused)515 static int write_build_id(int fd, struct perf_header *h,
516 struct perf_evlist *evlist __maybe_unused)
517 {
518 struct perf_session *session;
519 int err;
520
521 session = container_of(h, struct perf_session, header);
522
523 if (!perf_session__read_build_ids(session, true))
524 return -1;
525
526 err = dsos__write_buildid_table(h, fd);
527 if (err < 0) {
528 pr_debug("failed to write buildid table\n");
529 return err;
530 }
531 if (!no_buildid_cache)
532 perf_session__cache_build_ids(session);
533
534 return 0;
535 }
536
write_hostname(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)537 static int write_hostname(int fd, struct perf_header *h __maybe_unused,
538 struct perf_evlist *evlist __maybe_unused)
539 {
540 struct utsname uts;
541 int ret;
542
543 ret = uname(&uts);
544 if (ret < 0)
545 return -1;
546
547 return do_write_string(fd, uts.nodename);
548 }
549
write_osrelease(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)550 static int write_osrelease(int fd, struct perf_header *h __maybe_unused,
551 struct perf_evlist *evlist __maybe_unused)
552 {
553 struct utsname uts;
554 int ret;
555
556 ret = uname(&uts);
557 if (ret < 0)
558 return -1;
559
560 return do_write_string(fd, uts.release);
561 }
562
write_arch(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)563 static int write_arch(int fd, struct perf_header *h __maybe_unused,
564 struct perf_evlist *evlist __maybe_unused)
565 {
566 struct utsname uts;
567 int ret;
568
569 ret = uname(&uts);
570 if (ret < 0)
571 return -1;
572
573 return do_write_string(fd, uts.machine);
574 }
575
write_version(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)576 static int write_version(int fd, struct perf_header *h __maybe_unused,
577 struct perf_evlist *evlist __maybe_unused)
578 {
579 return do_write_string(fd, perf_version_string);
580 }
581
__write_cpudesc(int fd,const char * cpuinfo_proc)582 static int __write_cpudesc(int fd, const char *cpuinfo_proc)
583 {
584 FILE *file;
585 char *buf = NULL;
586 char *s, *p;
587 const char *search = cpuinfo_proc;
588 size_t len = 0;
589 int ret = -1;
590
591 if (!search)
592 return -1;
593
594 file = fopen("/proc/cpuinfo", "r");
595 if (!file)
596 return -1;
597
598 while (getline(&buf, &len, file) > 0) {
599 ret = strncmp(buf, search, strlen(search));
600 if (!ret)
601 break;
602 }
603
604 if (ret)
605 goto done;
606
607 s = buf;
608
609 p = strchr(buf, ':');
610 if (p && *(p+1) == ' ' && *(p+2))
611 s = p + 2;
612 p = strchr(s, '\n');
613 if (p)
614 *p = '\0';
615
616 /* squash extra space characters (branding string) */
617 p = s;
618 while (*p) {
619 if (isspace(*p)) {
620 char *r = p + 1;
621 char *q = r;
622 *p = ' ';
623 while (*q && isspace(*q))
624 q++;
625 if (q != (p+1))
626 while ((*r++ = *q++));
627 }
628 p++;
629 }
630 ret = do_write_string(fd, s);
631 done:
632 free(buf);
633 fclose(file);
634 return ret;
635 }
636
write_cpudesc(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)637 static int write_cpudesc(int fd, struct perf_header *h __maybe_unused,
638 struct perf_evlist *evlist __maybe_unused)
639 {
640 #ifndef CPUINFO_PROC
641 #define CPUINFO_PROC {"model name", }
642 #endif
643 const char *cpuinfo_procs[] = CPUINFO_PROC;
644 unsigned int i;
645
646 for (i = 0; i < ARRAY_SIZE(cpuinfo_procs); i++) {
647 int ret;
648 ret = __write_cpudesc(fd, cpuinfo_procs[i]);
649 if (ret >= 0)
650 return ret;
651 }
652 return -1;
653 }
654
655
write_nrcpus(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)656 static int write_nrcpus(int fd, struct perf_header *h __maybe_unused,
657 struct perf_evlist *evlist __maybe_unused)
658 {
659 long nr;
660 u32 nrc, nra;
661 int ret;
662
663 nr = sysconf(_SC_NPROCESSORS_CONF);
664 if (nr < 0)
665 return -1;
666
667 nrc = (u32)(nr & UINT_MAX);
668
669 nr = sysconf(_SC_NPROCESSORS_ONLN);
670 if (nr < 0)
671 return -1;
672
673 nra = (u32)(nr & UINT_MAX);
674
675 ret = do_write(fd, &nrc, sizeof(nrc));
676 if (ret < 0)
677 return ret;
678
679 return do_write(fd, &nra, sizeof(nra));
680 }
681
write_event_desc(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist)682 static int write_event_desc(int fd, struct perf_header *h __maybe_unused,
683 struct perf_evlist *evlist)
684 {
685 struct perf_evsel *evsel;
686 u32 nre, nri, sz;
687 int ret;
688
689 nre = evlist->nr_entries;
690
691 /*
692 * write number of events
693 */
694 ret = do_write(fd, &nre, sizeof(nre));
695 if (ret < 0)
696 return ret;
697
698 /*
699 * size of perf_event_attr struct
700 */
701 sz = (u32)sizeof(evsel->attr);
702 ret = do_write(fd, &sz, sizeof(sz));
703 if (ret < 0)
704 return ret;
705
706 evlist__for_each(evlist, evsel) {
707 ret = do_write(fd, &evsel->attr, sz);
708 if (ret < 0)
709 return ret;
710 /*
711 * write number of unique id per event
712 * there is one id per instance of an event
713 *
714 * copy into an nri to be independent of the
715 * type of ids,
716 */
717 nri = evsel->ids;
718 ret = do_write(fd, &nri, sizeof(nri));
719 if (ret < 0)
720 return ret;
721
722 /*
723 * write event string as passed on cmdline
724 */
725 ret = do_write_string(fd, perf_evsel__name(evsel));
726 if (ret < 0)
727 return ret;
728 /*
729 * write unique ids for this event
730 */
731 ret = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
732 if (ret < 0)
733 return ret;
734 }
735 return 0;
736 }
737
write_cmdline(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)738 static int write_cmdline(int fd, struct perf_header *h __maybe_unused,
739 struct perf_evlist *evlist __maybe_unused)
740 {
741 char buf[MAXPATHLEN];
742 char proc[32];
743 u32 i, n;
744 int ret;
745
746 /*
747 * actual atual path to perf binary
748 */
749 sprintf(proc, "/proc/%d/exe", getpid());
750 ret = readlink(proc, buf, sizeof(buf));
751 if (ret <= 0)
752 return -1;
753
754 /* readlink() does not add null termination */
755 buf[ret] = '\0';
756
757 /* account for binary path */
758 n = header_argc + 1;
759
760 ret = do_write(fd, &n, sizeof(n));
761 if (ret < 0)
762 return ret;
763
764 ret = do_write_string(fd, buf);
765 if (ret < 0)
766 return ret;
767
768 for (i = 0 ; i < header_argc; i++) {
769 ret = do_write_string(fd, header_argv[i]);
770 if (ret < 0)
771 return ret;
772 }
773 return 0;
774 }
775
776 #define CORE_SIB_FMT \
777 "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list"
778 #define THRD_SIB_FMT \
779 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
780
781 struct cpu_topo {
782 u32 core_sib;
783 u32 thread_sib;
784 char **core_siblings;
785 char **thread_siblings;
786 };
787
build_cpu_topo(struct cpu_topo * tp,int cpu)788 static int build_cpu_topo(struct cpu_topo *tp, int cpu)
789 {
790 FILE *fp;
791 char filename[MAXPATHLEN];
792 char *buf = NULL, *p;
793 size_t len = 0;
794 ssize_t sret;
795 u32 i = 0;
796 int ret = -1;
797
798 sprintf(filename, CORE_SIB_FMT, cpu);
799 fp = fopen(filename, "r");
800 if (!fp)
801 goto try_threads;
802
803 sret = getline(&buf, &len, fp);
804 fclose(fp);
805 if (sret <= 0)
806 goto try_threads;
807
808 p = strchr(buf, '\n');
809 if (p)
810 *p = '\0';
811
812 for (i = 0; i < tp->core_sib; i++) {
813 if (!strcmp(buf, tp->core_siblings[i]))
814 break;
815 }
816 if (i == tp->core_sib) {
817 tp->core_siblings[i] = buf;
818 tp->core_sib++;
819 buf = NULL;
820 len = 0;
821 }
822 ret = 0;
823
824 try_threads:
825 sprintf(filename, THRD_SIB_FMT, cpu);
826 fp = fopen(filename, "r");
827 if (!fp)
828 goto done;
829
830 if (getline(&buf, &len, fp) <= 0)
831 goto done;
832
833 p = strchr(buf, '\n');
834 if (p)
835 *p = '\0';
836
837 for (i = 0; i < tp->thread_sib; i++) {
838 if (!strcmp(buf, tp->thread_siblings[i]))
839 break;
840 }
841 if (i == tp->thread_sib) {
842 tp->thread_siblings[i] = buf;
843 tp->thread_sib++;
844 buf = NULL;
845 }
846 ret = 0;
847 done:
848 if(fp)
849 fclose(fp);
850 free(buf);
851 return ret;
852 }
853
free_cpu_topo(struct cpu_topo * tp)854 static void free_cpu_topo(struct cpu_topo *tp)
855 {
856 u32 i;
857
858 if (!tp)
859 return;
860
861 for (i = 0 ; i < tp->core_sib; i++)
862 zfree(&tp->core_siblings[i]);
863
864 for (i = 0 ; i < tp->thread_sib; i++)
865 zfree(&tp->thread_siblings[i]);
866
867 free(tp);
868 }
869
build_cpu_topology(void)870 static struct cpu_topo *build_cpu_topology(void)
871 {
872 struct cpu_topo *tp;
873 void *addr;
874 u32 nr, i;
875 size_t sz;
876 long ncpus;
877 int ret = -1;
878
879 ncpus = sysconf(_SC_NPROCESSORS_CONF);
880 if (ncpus < 0)
881 return NULL;
882
883 nr = (u32)(ncpus & UINT_MAX);
884
885 sz = nr * sizeof(char *);
886
887 addr = calloc(1, sizeof(*tp) + 2 * sz);
888 if (!addr)
889 return NULL;
890
891 tp = addr;
892
893 addr += sizeof(*tp);
894 tp->core_siblings = addr;
895 addr += sz;
896 tp->thread_siblings = addr;
897
898 for (i = 0; i < nr; i++) {
899 ret = build_cpu_topo(tp, i);
900 if (ret < 0)
901 break;
902 }
903 if (ret) {
904 free_cpu_topo(tp);
905 tp = NULL;
906 }
907 return tp;
908 }
909
write_cpu_topology(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)910 static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused,
911 struct perf_evlist *evlist __maybe_unused)
912 {
913 struct cpu_topo *tp;
914 u32 i;
915 int ret;
916
917 tp = build_cpu_topology();
918 if (!tp)
919 return -1;
920
921 ret = do_write(fd, &tp->core_sib, sizeof(tp->core_sib));
922 if (ret < 0)
923 goto done;
924
925 for (i = 0; i < tp->core_sib; i++) {
926 ret = do_write_string(fd, tp->core_siblings[i]);
927 if (ret < 0)
928 goto done;
929 }
930 ret = do_write(fd, &tp->thread_sib, sizeof(tp->thread_sib));
931 if (ret < 0)
932 goto done;
933
934 for (i = 0; i < tp->thread_sib; i++) {
935 ret = do_write_string(fd, tp->thread_siblings[i]);
936 if (ret < 0)
937 break;
938 }
939 done:
940 free_cpu_topo(tp);
941 return ret;
942 }
943
944
945
write_total_mem(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)946 static int write_total_mem(int fd, struct perf_header *h __maybe_unused,
947 struct perf_evlist *evlist __maybe_unused)
948 {
949 char *buf = NULL;
950 FILE *fp;
951 size_t len = 0;
952 int ret = -1, n;
953 uint64_t mem;
954
955 fp = fopen("/proc/meminfo", "r");
956 if (!fp)
957 return -1;
958
959 while (getline(&buf, &len, fp) > 0) {
960 ret = strncmp(buf, "MemTotal:", 9);
961 if (!ret)
962 break;
963 }
964 if (!ret) {
965 n = sscanf(buf, "%*s %"PRIu64, &mem);
966 if (n == 1)
967 ret = do_write(fd, &mem, sizeof(mem));
968 }
969 free(buf);
970 fclose(fp);
971 return ret;
972 }
973
write_topo_node(int fd,int node)974 static int write_topo_node(int fd, int node)
975 {
976 char str[MAXPATHLEN];
977 char field[32];
978 char *buf = NULL, *p;
979 size_t len = 0;
980 FILE *fp;
981 u64 mem_total, mem_free, mem;
982 int ret = -1;
983
984 sprintf(str, "/sys/devices/system/node/node%d/meminfo", node);
985 fp = fopen(str, "r");
986 if (!fp)
987 return -1;
988
989 while (getline(&buf, &len, fp) > 0) {
990 /* skip over invalid lines */
991 if (!strchr(buf, ':'))
992 continue;
993 if (sscanf(buf, "%*s %*d %31s %"PRIu64, field, &mem) != 2)
994 goto done;
995 if (!strcmp(field, "MemTotal:"))
996 mem_total = mem;
997 if (!strcmp(field, "MemFree:"))
998 mem_free = mem;
999 }
1000
1001 fclose(fp);
1002 fp = NULL;
1003
1004 ret = do_write(fd, &mem_total, sizeof(u64));
1005 if (ret)
1006 goto done;
1007
1008 ret = do_write(fd, &mem_free, sizeof(u64));
1009 if (ret)
1010 goto done;
1011
1012 ret = -1;
1013 sprintf(str, "/sys/devices/system/node/node%d/cpulist", node);
1014
1015 fp = fopen(str, "r");
1016 if (!fp)
1017 goto done;
1018
1019 if (getline(&buf, &len, fp) <= 0)
1020 goto done;
1021
1022 p = strchr(buf, '\n');
1023 if (p)
1024 *p = '\0';
1025
1026 ret = do_write_string(fd, buf);
1027 done:
1028 free(buf);
1029 if (fp)
1030 fclose(fp);
1031 return ret;
1032 }
1033
write_numa_topology(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)1034 static int write_numa_topology(int fd, struct perf_header *h __maybe_unused,
1035 struct perf_evlist *evlist __maybe_unused)
1036 {
1037 char *buf = NULL;
1038 size_t len = 0;
1039 FILE *fp;
1040 struct cpu_map *node_map = NULL;
1041 char *c;
1042 u32 nr, i, j;
1043 int ret = -1;
1044
1045 fp = fopen("/sys/devices/system/node/online", "r");
1046 if (!fp)
1047 return -1;
1048
1049 if (getline(&buf, &len, fp) <= 0)
1050 goto done;
1051
1052 c = strchr(buf, '\n');
1053 if (c)
1054 *c = '\0';
1055
1056 node_map = cpu_map__new(buf);
1057 if (!node_map)
1058 goto done;
1059
1060 nr = (u32)node_map->nr;
1061
1062 ret = do_write(fd, &nr, sizeof(nr));
1063 if (ret < 0)
1064 goto done;
1065
1066 for (i = 0; i < nr; i++) {
1067 j = (u32)node_map->map[i];
1068 ret = do_write(fd, &j, sizeof(j));
1069 if (ret < 0)
1070 break;
1071
1072 ret = write_topo_node(fd, i);
1073 if (ret < 0)
1074 break;
1075 }
1076 done:
1077 free(buf);
1078 fclose(fp);
1079 free(node_map);
1080 return ret;
1081 }
1082
1083 /*
1084 * File format:
1085 *
1086 * struct pmu_mappings {
1087 * u32 pmu_num;
1088 * struct pmu_map {
1089 * u32 type;
1090 * char name[];
1091 * }[pmu_num];
1092 * };
1093 */
1094
write_pmu_mappings(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)1095 static int write_pmu_mappings(int fd, struct perf_header *h __maybe_unused,
1096 struct perf_evlist *evlist __maybe_unused)
1097 {
1098 struct perf_pmu *pmu = NULL;
1099 off_t offset = lseek(fd, 0, SEEK_CUR);
1100 __u32 pmu_num = 0;
1101 int ret;
1102
1103 /* write real pmu_num later */
1104 ret = do_write(fd, &pmu_num, sizeof(pmu_num));
1105 if (ret < 0)
1106 return ret;
1107
1108 while ((pmu = perf_pmu__scan(pmu))) {
1109 if (!pmu->name)
1110 continue;
1111 pmu_num++;
1112
1113 ret = do_write(fd, &pmu->type, sizeof(pmu->type));
1114 if (ret < 0)
1115 return ret;
1116
1117 ret = do_write_string(fd, pmu->name);
1118 if (ret < 0)
1119 return ret;
1120 }
1121
1122 if (pwrite(fd, &pmu_num, sizeof(pmu_num), offset) != sizeof(pmu_num)) {
1123 /* discard all */
1124 lseek(fd, offset, SEEK_SET);
1125 return -1;
1126 }
1127
1128 return 0;
1129 }
1130
1131 /*
1132 * File format:
1133 *
1134 * struct group_descs {
1135 * u32 nr_groups;
1136 * struct group_desc {
1137 * char name[];
1138 * u32 leader_idx;
1139 * u32 nr_members;
1140 * }[nr_groups];
1141 * };
1142 */
write_group_desc(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist)1143 static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
1144 struct perf_evlist *evlist)
1145 {
1146 u32 nr_groups = evlist->nr_groups;
1147 struct perf_evsel *evsel;
1148 int ret;
1149
1150 ret = do_write(fd, &nr_groups, sizeof(nr_groups));
1151 if (ret < 0)
1152 return ret;
1153
1154 evlist__for_each(evlist, evsel) {
1155 if (perf_evsel__is_group_leader(evsel) &&
1156 evsel->nr_members > 1) {
1157 const char *name = evsel->group_name ?: "{anon_group}";
1158 u32 leader_idx = evsel->idx;
1159 u32 nr_members = evsel->nr_members;
1160
1161 ret = do_write_string(fd, name);
1162 if (ret < 0)
1163 return ret;
1164
1165 ret = do_write(fd, &leader_idx, sizeof(leader_idx));
1166 if (ret < 0)
1167 return ret;
1168
1169 ret = do_write(fd, &nr_members, sizeof(nr_members));
1170 if (ret < 0)
1171 return ret;
1172 }
1173 }
1174 return 0;
1175 }
1176
1177 /*
1178 * default get_cpuid(): nothing gets recorded
1179 * actual implementation must be in arch/$(ARCH)/util/header.c
1180 */
get_cpuid(char * buffer __maybe_unused,size_t sz __maybe_unused)1181 int __attribute__ ((weak)) get_cpuid(char *buffer __maybe_unused,
1182 size_t sz __maybe_unused)
1183 {
1184 return -1;
1185 }
1186
write_cpuid(int fd,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)1187 static int write_cpuid(int fd, struct perf_header *h __maybe_unused,
1188 struct perf_evlist *evlist __maybe_unused)
1189 {
1190 char buffer[64];
1191 int ret;
1192
1193 ret = get_cpuid(buffer, sizeof(buffer));
1194 if (!ret)
1195 goto write_it;
1196
1197 return -1;
1198 write_it:
1199 return do_write_string(fd, buffer);
1200 }
1201
write_branch_stack(int fd __maybe_unused,struct perf_header * h __maybe_unused,struct perf_evlist * evlist __maybe_unused)1202 static int write_branch_stack(int fd __maybe_unused,
1203 struct perf_header *h __maybe_unused,
1204 struct perf_evlist *evlist __maybe_unused)
1205 {
1206 return 0;
1207 }
1208
print_hostname(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1209 static void print_hostname(struct perf_header *ph, int fd __maybe_unused,
1210 FILE *fp)
1211 {
1212 fprintf(fp, "# hostname : %s\n", ph->env.hostname);
1213 }
1214
print_osrelease(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1215 static void print_osrelease(struct perf_header *ph, int fd __maybe_unused,
1216 FILE *fp)
1217 {
1218 fprintf(fp, "# os release : %s\n", ph->env.os_release);
1219 }
1220
print_arch(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1221 static void print_arch(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
1222 {
1223 fprintf(fp, "# arch : %s\n", ph->env.arch);
1224 }
1225
print_cpudesc(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1226 static void print_cpudesc(struct perf_header *ph, int fd __maybe_unused,
1227 FILE *fp)
1228 {
1229 fprintf(fp, "# cpudesc : %s\n", ph->env.cpu_desc);
1230 }
1231
print_nrcpus(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1232 static void print_nrcpus(struct perf_header *ph, int fd __maybe_unused,
1233 FILE *fp)
1234 {
1235 fprintf(fp, "# nrcpus online : %u\n", ph->env.nr_cpus_online);
1236 fprintf(fp, "# nrcpus avail : %u\n", ph->env.nr_cpus_avail);
1237 }
1238
print_version(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1239 static void print_version(struct perf_header *ph, int fd __maybe_unused,
1240 FILE *fp)
1241 {
1242 fprintf(fp, "# perf version : %s\n", ph->env.version);
1243 }
1244
print_cmdline(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1245 static void print_cmdline(struct perf_header *ph, int fd __maybe_unused,
1246 FILE *fp)
1247 {
1248 int nr, i;
1249 char *str;
1250
1251 nr = ph->env.nr_cmdline;
1252 str = ph->env.cmdline;
1253
1254 fprintf(fp, "# cmdline : ");
1255
1256 for (i = 0; i < nr; i++) {
1257 fprintf(fp, "%s ", str);
1258 str += strlen(str) + 1;
1259 }
1260 fputc('\n', fp);
1261 }
1262
print_cpu_topology(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1263 static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
1264 FILE *fp)
1265 {
1266 int nr, i;
1267 char *str;
1268
1269 nr = ph->env.nr_sibling_cores;
1270 str = ph->env.sibling_cores;
1271
1272 for (i = 0; i < nr; i++) {
1273 fprintf(fp, "# sibling cores : %s\n", str);
1274 str += strlen(str) + 1;
1275 }
1276
1277 nr = ph->env.nr_sibling_threads;
1278 str = ph->env.sibling_threads;
1279
1280 for (i = 0; i < nr; i++) {
1281 fprintf(fp, "# sibling threads : %s\n", str);
1282 str += strlen(str) + 1;
1283 }
1284 }
1285
free_event_desc(struct perf_evsel * events)1286 static void free_event_desc(struct perf_evsel *events)
1287 {
1288 struct perf_evsel *evsel;
1289
1290 if (!events)
1291 return;
1292
1293 for (evsel = events; evsel->attr.size; evsel++) {
1294 zfree(&evsel->name);
1295 zfree(&evsel->id);
1296 }
1297
1298 free(events);
1299 }
1300
1301 static struct perf_evsel *
read_event_desc(struct perf_header * ph,int fd)1302 read_event_desc(struct perf_header *ph, int fd)
1303 {
1304 struct perf_evsel *evsel, *events = NULL;
1305 u64 *id;
1306 void *buf = NULL;
1307 u32 nre, sz, nr, i, j;
1308 ssize_t ret;
1309 size_t msz;
1310
1311 /* number of events */
1312 ret = readn(fd, &nre, sizeof(nre));
1313 if (ret != (ssize_t)sizeof(nre))
1314 goto error;
1315
1316 if (ph->needs_swap)
1317 nre = bswap_32(nre);
1318
1319 ret = readn(fd, &sz, sizeof(sz));
1320 if (ret != (ssize_t)sizeof(sz))
1321 goto error;
1322
1323 if (ph->needs_swap)
1324 sz = bswap_32(sz);
1325
1326 /* buffer to hold on file attr struct */
1327 buf = malloc(sz);
1328 if (!buf)
1329 goto error;
1330
1331 /* the last event terminates with evsel->attr.size == 0: */
1332 events = calloc(nre + 1, sizeof(*events));
1333 if (!events)
1334 goto error;
1335
1336 msz = sizeof(evsel->attr);
1337 if (sz < msz)
1338 msz = sz;
1339
1340 for (i = 0, evsel = events; i < nre; evsel++, i++) {
1341 evsel->idx = i;
1342
1343 /*
1344 * must read entire on-file attr struct to
1345 * sync up with layout.
1346 */
1347 ret = readn(fd, buf, sz);
1348 if (ret != (ssize_t)sz)
1349 goto error;
1350
1351 if (ph->needs_swap)
1352 perf_event__attr_swap(buf);
1353
1354 memcpy(&evsel->attr, buf, msz);
1355
1356 ret = readn(fd, &nr, sizeof(nr));
1357 if (ret != (ssize_t)sizeof(nr))
1358 goto error;
1359
1360 if (ph->needs_swap) {
1361 nr = bswap_32(nr);
1362 evsel->needs_swap = true;
1363 }
1364
1365 evsel->name = do_read_string(fd, ph);
1366
1367 if (!nr)
1368 continue;
1369
1370 id = calloc(nr, sizeof(*id));
1371 if (!id)
1372 goto error;
1373 evsel->ids = nr;
1374 evsel->id = id;
1375
1376 for (j = 0 ; j < nr; j++) {
1377 ret = readn(fd, id, sizeof(*id));
1378 if (ret != (ssize_t)sizeof(*id))
1379 goto error;
1380 if (ph->needs_swap)
1381 *id = bswap_64(*id);
1382 id++;
1383 }
1384 }
1385 out:
1386 free(buf);
1387 return events;
1388 error:
1389 if (events)
1390 free_event_desc(events);
1391 events = NULL;
1392 goto out;
1393 }
1394
print_event_desc(struct perf_header * ph,int fd,FILE * fp)1395 static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
1396 {
1397 struct perf_evsel *evsel, *events = read_event_desc(ph, fd);
1398 u32 j;
1399 u64 *id;
1400
1401 if (!events) {
1402 fprintf(fp, "# event desc: not available or unable to read\n");
1403 return;
1404 }
1405
1406 for (evsel = events; evsel->attr.size; evsel++) {
1407 fprintf(fp, "# event : name = %s, ", evsel->name);
1408
1409 fprintf(fp, "type = %d, config = 0x%"PRIx64
1410 ", config1 = 0x%"PRIx64", config2 = 0x%"PRIx64,
1411 evsel->attr.type,
1412 (u64)evsel->attr.config,
1413 (u64)evsel->attr.config1,
1414 (u64)evsel->attr.config2);
1415
1416 fprintf(fp, ", excl_usr = %d, excl_kern = %d",
1417 evsel->attr.exclude_user,
1418 evsel->attr.exclude_kernel);
1419
1420 fprintf(fp, ", excl_host = %d, excl_guest = %d",
1421 evsel->attr.exclude_host,
1422 evsel->attr.exclude_guest);
1423
1424 fprintf(fp, ", precise_ip = %d", evsel->attr.precise_ip);
1425
1426 fprintf(fp, ", attr_mmap2 = %d", evsel->attr.mmap2);
1427 fprintf(fp, ", attr_mmap = %d", evsel->attr.mmap);
1428 fprintf(fp, ", attr_mmap_data = %d", evsel->attr.mmap_data);
1429 if (evsel->ids) {
1430 fprintf(fp, ", id = {");
1431 for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) {
1432 if (j)
1433 fputc(',', fp);
1434 fprintf(fp, " %"PRIu64, *id);
1435 }
1436 fprintf(fp, " }");
1437 }
1438
1439 fputc('\n', fp);
1440 }
1441
1442 free_event_desc(events);
1443 }
1444
print_total_mem(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1445 static void print_total_mem(struct perf_header *ph, int fd __maybe_unused,
1446 FILE *fp)
1447 {
1448 fprintf(fp, "# total memory : %Lu kB\n", ph->env.total_mem);
1449 }
1450
print_numa_topology(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1451 static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused,
1452 FILE *fp)
1453 {
1454 u32 nr, c, i;
1455 char *str, *tmp;
1456 uint64_t mem_total, mem_free;
1457
1458 /* nr nodes */
1459 nr = ph->env.nr_numa_nodes;
1460 str = ph->env.numa_nodes;
1461
1462 for (i = 0; i < nr; i++) {
1463 /* node number */
1464 c = strtoul(str, &tmp, 0);
1465 if (*tmp != ':')
1466 goto error;
1467
1468 str = tmp + 1;
1469 mem_total = strtoull(str, &tmp, 0);
1470 if (*tmp != ':')
1471 goto error;
1472
1473 str = tmp + 1;
1474 mem_free = strtoull(str, &tmp, 0);
1475 if (*tmp != ':')
1476 goto error;
1477
1478 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB,"
1479 " free = %"PRIu64" kB\n",
1480 c, mem_total, mem_free);
1481
1482 str = tmp + 1;
1483 fprintf(fp, "# node%u cpu list : %s\n", c, str);
1484
1485 str += strlen(str) + 1;
1486 }
1487 return;
1488 error:
1489 fprintf(fp, "# numa topology : not available\n");
1490 }
1491
print_cpuid(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1492 static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
1493 {
1494 fprintf(fp, "# cpuid : %s\n", ph->env.cpuid);
1495 }
1496
print_branch_stack(struct perf_header * ph __maybe_unused,int fd __maybe_unused,FILE * fp)1497 static void print_branch_stack(struct perf_header *ph __maybe_unused,
1498 int fd __maybe_unused, FILE *fp)
1499 {
1500 fprintf(fp, "# contains samples with branch stack\n");
1501 }
1502
print_pmu_mappings(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1503 static void print_pmu_mappings(struct perf_header *ph, int fd __maybe_unused,
1504 FILE *fp)
1505 {
1506 const char *delimiter = "# pmu mappings: ";
1507 char *str, *tmp;
1508 u32 pmu_num;
1509 u32 type;
1510
1511 pmu_num = ph->env.nr_pmu_mappings;
1512 if (!pmu_num) {
1513 fprintf(fp, "# pmu mappings: not available\n");
1514 return;
1515 }
1516
1517 str = ph->env.pmu_mappings;
1518
1519 while (pmu_num) {
1520 type = strtoul(str, &tmp, 0);
1521 if (*tmp != ':')
1522 goto error;
1523
1524 str = tmp + 1;
1525 fprintf(fp, "%s%s = %" PRIu32, delimiter, str, type);
1526
1527 delimiter = ", ";
1528 str += strlen(str) + 1;
1529 pmu_num--;
1530 }
1531
1532 fprintf(fp, "\n");
1533
1534 if (!pmu_num)
1535 return;
1536 error:
1537 fprintf(fp, "# pmu mappings: unable to read\n");
1538 }
1539
print_group_desc(struct perf_header * ph,int fd __maybe_unused,FILE * fp)1540 static void print_group_desc(struct perf_header *ph, int fd __maybe_unused,
1541 FILE *fp)
1542 {
1543 struct perf_session *session;
1544 struct perf_evsel *evsel;
1545 u32 nr = 0;
1546
1547 session = container_of(ph, struct perf_session, header);
1548
1549 evlist__for_each(session->evlist, evsel) {
1550 if (perf_evsel__is_group_leader(evsel) &&
1551 evsel->nr_members > 1) {
1552 fprintf(fp, "# group: %s{%s", evsel->group_name ?: "",
1553 perf_evsel__name(evsel));
1554
1555 nr = evsel->nr_members - 1;
1556 } else if (nr) {
1557 fprintf(fp, ",%s", perf_evsel__name(evsel));
1558
1559 if (--nr == 0)
1560 fprintf(fp, "}\n");
1561 }
1562 }
1563 }
1564
__event_process_build_id(struct build_id_event * bev,char * filename,struct perf_session * session)1565 static int __event_process_build_id(struct build_id_event *bev,
1566 char *filename,
1567 struct perf_session *session)
1568 {
1569 int err = -1;
1570 struct dsos *dsos;
1571 struct machine *machine;
1572 u16 misc;
1573 struct dso *dso;
1574 enum dso_kernel_type dso_type;
1575
1576 machine = perf_session__findnew_machine(session, bev->pid);
1577 if (!machine)
1578 goto out;
1579
1580 misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
1581
1582 switch (misc) {
1583 case PERF_RECORD_MISC_KERNEL:
1584 dso_type = DSO_TYPE_KERNEL;
1585 dsos = &machine->kernel_dsos;
1586 break;
1587 case PERF_RECORD_MISC_GUEST_KERNEL:
1588 dso_type = DSO_TYPE_GUEST_KERNEL;
1589 dsos = &machine->kernel_dsos;
1590 break;
1591 case PERF_RECORD_MISC_USER:
1592 case PERF_RECORD_MISC_GUEST_USER:
1593 dso_type = DSO_TYPE_USER;
1594 dsos = &machine->user_dsos;
1595 break;
1596 default:
1597 goto out;
1598 }
1599
1600 dso = __dsos__findnew(dsos, filename);
1601 if (dso != NULL) {
1602 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1603
1604 dso__set_build_id(dso, &bev->build_id);
1605
1606 if (filename[0] == '[')
1607 dso->kernel = dso_type;
1608
1609 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1610 sbuild_id);
1611 pr_debug("build id event received for %s: %s\n",
1612 dso->long_name, sbuild_id);
1613 }
1614
1615 err = 0;
1616 out:
1617 return err;
1618 }
1619
perf_header__read_build_ids_abi_quirk(struct perf_header * header,int input,u64 offset,u64 size)1620 static int perf_header__read_build_ids_abi_quirk(struct perf_header *header,
1621 int input, u64 offset, u64 size)
1622 {
1623 struct perf_session *session = container_of(header, struct perf_session, header);
1624 struct {
1625 struct perf_event_header header;
1626 u8 build_id[PERF_ALIGN(BUILD_ID_SIZE, sizeof(u64))];
1627 char filename[0];
1628 } old_bev;
1629 struct build_id_event bev;
1630 char filename[PATH_MAX];
1631 u64 limit = offset + size;
1632
1633 while (offset < limit) {
1634 ssize_t len;
1635
1636 if (readn(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev))
1637 return -1;
1638
1639 if (header->needs_swap)
1640 perf_event_header__bswap(&old_bev.header);
1641
1642 len = old_bev.header.size - sizeof(old_bev);
1643 if (readn(input, filename, len) != len)
1644 return -1;
1645
1646 bev.header = old_bev.header;
1647
1648 /*
1649 * As the pid is the missing value, we need to fill
1650 * it properly. The header.misc value give us nice hint.
1651 */
1652 bev.pid = HOST_KERNEL_ID;
1653 if (bev.header.misc == PERF_RECORD_MISC_GUEST_USER ||
1654 bev.header.misc == PERF_RECORD_MISC_GUEST_KERNEL)
1655 bev.pid = DEFAULT_GUEST_KERNEL_ID;
1656
1657 memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id));
1658 __event_process_build_id(&bev, filename, session);
1659
1660 offset += bev.header.size;
1661 }
1662
1663 return 0;
1664 }
1665
perf_header__read_build_ids(struct perf_header * header,int input,u64 offset,u64 size)1666 static int perf_header__read_build_ids(struct perf_header *header,
1667 int input, u64 offset, u64 size)
1668 {
1669 struct perf_session *session = container_of(header, struct perf_session, header);
1670 struct build_id_event bev;
1671 char filename[PATH_MAX];
1672 u64 limit = offset + size, orig_offset = offset;
1673 int err = -1;
1674
1675 while (offset < limit) {
1676 ssize_t len;
1677
1678 if (readn(input, &bev, sizeof(bev)) != sizeof(bev))
1679 goto out;
1680
1681 if (header->needs_swap)
1682 perf_event_header__bswap(&bev.header);
1683
1684 len = bev.header.size - sizeof(bev);
1685 if (readn(input, filename, len) != len)
1686 goto out;
1687 /*
1688 * The a1645ce1 changeset:
1689 *
1690 * "perf: 'perf kvm' tool for monitoring guest performance from host"
1691 *
1692 * Added a field to struct build_id_event that broke the file
1693 * format.
1694 *
1695 * Since the kernel build-id is the first entry, process the
1696 * table using the old format if the well known
1697 * '[kernel.kallsyms]' string for the kernel build-id has the
1698 * first 4 characters chopped off (where the pid_t sits).
1699 */
1700 if (memcmp(filename, "nel.kallsyms]", 13) == 0) {
1701 if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1)
1702 return -1;
1703 return perf_header__read_build_ids_abi_quirk(header, input, offset, size);
1704 }
1705
1706 __event_process_build_id(&bev, filename, session);
1707
1708 offset += bev.header.size;
1709 }
1710 err = 0;
1711 out:
1712 return err;
1713 }
1714
process_tracing_data(struct perf_file_section * section __maybe_unused,struct perf_header * ph __maybe_unused,int fd,void * data)1715 static int process_tracing_data(struct perf_file_section *section __maybe_unused,
1716 struct perf_header *ph __maybe_unused,
1717 int fd, void *data)
1718 {
1719 ssize_t ret = trace_report(fd, data, false);
1720 return ret < 0 ? -1 : 0;
1721 }
1722
process_build_id(struct perf_file_section * section,struct perf_header * ph,int fd,void * data __maybe_unused)1723 static int process_build_id(struct perf_file_section *section,
1724 struct perf_header *ph, int fd,
1725 void *data __maybe_unused)
1726 {
1727 if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
1728 pr_debug("Failed to read buildids, continuing...\n");
1729 return 0;
1730 }
1731
process_hostname(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1732 static int process_hostname(struct perf_file_section *section __maybe_unused,
1733 struct perf_header *ph, int fd,
1734 void *data __maybe_unused)
1735 {
1736 ph->env.hostname = do_read_string(fd, ph);
1737 return ph->env.hostname ? 0 : -ENOMEM;
1738 }
1739
process_osrelease(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1740 static int process_osrelease(struct perf_file_section *section __maybe_unused,
1741 struct perf_header *ph, int fd,
1742 void *data __maybe_unused)
1743 {
1744 ph->env.os_release = do_read_string(fd, ph);
1745 return ph->env.os_release ? 0 : -ENOMEM;
1746 }
1747
process_version(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1748 static int process_version(struct perf_file_section *section __maybe_unused,
1749 struct perf_header *ph, int fd,
1750 void *data __maybe_unused)
1751 {
1752 ph->env.version = do_read_string(fd, ph);
1753 return ph->env.version ? 0 : -ENOMEM;
1754 }
1755
process_arch(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1756 static int process_arch(struct perf_file_section *section __maybe_unused,
1757 struct perf_header *ph, int fd,
1758 void *data __maybe_unused)
1759 {
1760 ph->env.arch = do_read_string(fd, ph);
1761 return ph->env.arch ? 0 : -ENOMEM;
1762 }
1763
process_nrcpus(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1764 static int process_nrcpus(struct perf_file_section *section __maybe_unused,
1765 struct perf_header *ph, int fd,
1766 void *data __maybe_unused)
1767 {
1768 ssize_t ret;
1769 u32 nr;
1770
1771 ret = readn(fd, &nr, sizeof(nr));
1772 if (ret != sizeof(nr))
1773 return -1;
1774
1775 if (ph->needs_swap)
1776 nr = bswap_32(nr);
1777
1778 ph->env.nr_cpus_avail = nr;
1779
1780 ret = readn(fd, &nr, sizeof(nr));
1781 if (ret != sizeof(nr))
1782 return -1;
1783
1784 if (ph->needs_swap)
1785 nr = bswap_32(nr);
1786
1787 ph->env.nr_cpus_online = nr;
1788 return 0;
1789 }
1790
process_cpudesc(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1791 static int process_cpudesc(struct perf_file_section *section __maybe_unused,
1792 struct perf_header *ph, int fd,
1793 void *data __maybe_unused)
1794 {
1795 ph->env.cpu_desc = do_read_string(fd, ph);
1796 return ph->env.cpu_desc ? 0 : -ENOMEM;
1797 }
1798
process_cpuid(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1799 static int process_cpuid(struct perf_file_section *section __maybe_unused,
1800 struct perf_header *ph, int fd,
1801 void *data __maybe_unused)
1802 {
1803 ph->env.cpuid = do_read_string(fd, ph);
1804 return ph->env.cpuid ? 0 : -ENOMEM;
1805 }
1806
process_total_mem(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1807 static int process_total_mem(struct perf_file_section *section __maybe_unused,
1808 struct perf_header *ph, int fd,
1809 void *data __maybe_unused)
1810 {
1811 uint64_t mem;
1812 ssize_t ret;
1813
1814 ret = readn(fd, &mem, sizeof(mem));
1815 if (ret != sizeof(mem))
1816 return -1;
1817
1818 if (ph->needs_swap)
1819 mem = bswap_64(mem);
1820
1821 ph->env.total_mem = mem;
1822 return 0;
1823 }
1824
1825 static struct perf_evsel *
perf_evlist__find_by_index(struct perf_evlist * evlist,int idx)1826 perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
1827 {
1828 struct perf_evsel *evsel;
1829
1830 evlist__for_each(evlist, evsel) {
1831 if (evsel->idx == idx)
1832 return evsel;
1833 }
1834
1835 return NULL;
1836 }
1837
1838 static void
perf_evlist__set_event_name(struct perf_evlist * evlist,struct perf_evsel * event)1839 perf_evlist__set_event_name(struct perf_evlist *evlist,
1840 struct perf_evsel *event)
1841 {
1842 struct perf_evsel *evsel;
1843
1844 if (!event->name)
1845 return;
1846
1847 evsel = perf_evlist__find_by_index(evlist, event->idx);
1848 if (!evsel)
1849 return;
1850
1851 if (evsel->name)
1852 return;
1853
1854 evsel->name = strdup(event->name);
1855 }
1856
1857 static int
process_event_desc(struct perf_file_section * section __maybe_unused,struct perf_header * header,int fd,void * data __maybe_unused)1858 process_event_desc(struct perf_file_section *section __maybe_unused,
1859 struct perf_header *header, int fd,
1860 void *data __maybe_unused)
1861 {
1862 struct perf_session *session;
1863 struct perf_evsel *evsel, *events = read_event_desc(header, fd);
1864
1865 if (!events)
1866 return 0;
1867
1868 session = container_of(header, struct perf_session, header);
1869 for (evsel = events; evsel->attr.size; evsel++)
1870 perf_evlist__set_event_name(session->evlist, evsel);
1871
1872 free_event_desc(events);
1873
1874 return 0;
1875 }
1876
process_cmdline(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1877 static int process_cmdline(struct perf_file_section *section __maybe_unused,
1878 struct perf_header *ph, int fd,
1879 void *data __maybe_unused)
1880 {
1881 ssize_t ret;
1882 char *str;
1883 u32 nr, i;
1884 struct strbuf sb;
1885
1886 ret = readn(fd, &nr, sizeof(nr));
1887 if (ret != sizeof(nr))
1888 return -1;
1889
1890 if (ph->needs_swap)
1891 nr = bswap_32(nr);
1892
1893 ph->env.nr_cmdline = nr;
1894 strbuf_init(&sb, 128);
1895
1896 for (i = 0; i < nr; i++) {
1897 str = do_read_string(fd, ph);
1898 if (!str)
1899 goto error;
1900
1901 /* include a NULL character at the end */
1902 strbuf_add(&sb, str, strlen(str) + 1);
1903 free(str);
1904 }
1905 ph->env.cmdline = strbuf_detach(&sb, NULL);
1906 return 0;
1907
1908 error:
1909 strbuf_release(&sb);
1910 return -1;
1911 }
1912
process_cpu_topology(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1913 static int process_cpu_topology(struct perf_file_section *section __maybe_unused,
1914 struct perf_header *ph, int fd,
1915 void *data __maybe_unused)
1916 {
1917 ssize_t ret;
1918 u32 nr, i;
1919 char *str;
1920 struct strbuf sb;
1921
1922 ret = readn(fd, &nr, sizeof(nr));
1923 if (ret != sizeof(nr))
1924 return -1;
1925
1926 if (ph->needs_swap)
1927 nr = bswap_32(nr);
1928
1929 ph->env.nr_sibling_cores = nr;
1930 strbuf_init(&sb, 128);
1931
1932 for (i = 0; i < nr; i++) {
1933 str = do_read_string(fd, ph);
1934 if (!str)
1935 goto error;
1936
1937 /* include a NULL character at the end */
1938 strbuf_add(&sb, str, strlen(str) + 1);
1939 free(str);
1940 }
1941 ph->env.sibling_cores = strbuf_detach(&sb, NULL);
1942
1943 ret = readn(fd, &nr, sizeof(nr));
1944 if (ret != sizeof(nr))
1945 return -1;
1946
1947 if (ph->needs_swap)
1948 nr = bswap_32(nr);
1949
1950 ph->env.nr_sibling_threads = nr;
1951
1952 for (i = 0; i < nr; i++) {
1953 str = do_read_string(fd, ph);
1954 if (!str)
1955 goto error;
1956
1957 /* include a NULL character at the end */
1958 strbuf_add(&sb, str, strlen(str) + 1);
1959 free(str);
1960 }
1961 ph->env.sibling_threads = strbuf_detach(&sb, NULL);
1962 return 0;
1963
1964 error:
1965 strbuf_release(&sb);
1966 return -1;
1967 }
1968
process_numa_topology(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)1969 static int process_numa_topology(struct perf_file_section *section __maybe_unused,
1970 struct perf_header *ph, int fd,
1971 void *data __maybe_unused)
1972 {
1973 ssize_t ret;
1974 u32 nr, node, i;
1975 char *str;
1976 uint64_t mem_total, mem_free;
1977 struct strbuf sb;
1978
1979 /* nr nodes */
1980 ret = readn(fd, &nr, sizeof(nr));
1981 if (ret != sizeof(nr))
1982 goto error;
1983
1984 if (ph->needs_swap)
1985 nr = bswap_32(nr);
1986
1987 ph->env.nr_numa_nodes = nr;
1988 strbuf_init(&sb, 256);
1989
1990 for (i = 0; i < nr; i++) {
1991 /* node number */
1992 ret = readn(fd, &node, sizeof(node));
1993 if (ret != sizeof(node))
1994 goto error;
1995
1996 ret = readn(fd, &mem_total, sizeof(u64));
1997 if (ret != sizeof(u64))
1998 goto error;
1999
2000 ret = readn(fd, &mem_free, sizeof(u64));
2001 if (ret != sizeof(u64))
2002 goto error;
2003
2004 if (ph->needs_swap) {
2005 node = bswap_32(node);
2006 mem_total = bswap_64(mem_total);
2007 mem_free = bswap_64(mem_free);
2008 }
2009
2010 strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":",
2011 node, mem_total, mem_free);
2012
2013 str = do_read_string(fd, ph);
2014 if (!str)
2015 goto error;
2016
2017 /* include a NULL character at the end */
2018 strbuf_add(&sb, str, strlen(str) + 1);
2019 free(str);
2020 }
2021 ph->env.numa_nodes = strbuf_detach(&sb, NULL);
2022 return 0;
2023
2024 error:
2025 strbuf_release(&sb);
2026 return -1;
2027 }
2028
process_pmu_mappings(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)2029 static int process_pmu_mappings(struct perf_file_section *section __maybe_unused,
2030 struct perf_header *ph, int fd,
2031 void *data __maybe_unused)
2032 {
2033 ssize_t ret;
2034 char *name;
2035 u32 pmu_num;
2036 u32 type;
2037 struct strbuf sb;
2038
2039 ret = readn(fd, &pmu_num, sizeof(pmu_num));
2040 if (ret != sizeof(pmu_num))
2041 return -1;
2042
2043 if (ph->needs_swap)
2044 pmu_num = bswap_32(pmu_num);
2045
2046 if (!pmu_num) {
2047 pr_debug("pmu mappings not available\n");
2048 return 0;
2049 }
2050
2051 ph->env.nr_pmu_mappings = pmu_num;
2052 strbuf_init(&sb, 128);
2053
2054 while (pmu_num) {
2055 if (readn(fd, &type, sizeof(type)) != sizeof(type))
2056 goto error;
2057 if (ph->needs_swap)
2058 type = bswap_32(type);
2059
2060 name = do_read_string(fd, ph);
2061 if (!name)
2062 goto error;
2063
2064 strbuf_addf(&sb, "%u:%s", type, name);
2065 /* include a NULL character at the end */
2066 strbuf_add(&sb, "", 1);
2067
2068 free(name);
2069 pmu_num--;
2070 }
2071 ph->env.pmu_mappings = strbuf_detach(&sb, NULL);
2072 return 0;
2073
2074 error:
2075 strbuf_release(&sb);
2076 return -1;
2077 }
2078
process_group_desc(struct perf_file_section * section __maybe_unused,struct perf_header * ph,int fd,void * data __maybe_unused)2079 static int process_group_desc(struct perf_file_section *section __maybe_unused,
2080 struct perf_header *ph, int fd,
2081 void *data __maybe_unused)
2082 {
2083 size_t ret = -1;
2084 u32 i, nr, nr_groups;
2085 struct perf_session *session;
2086 struct perf_evsel *evsel, *leader = NULL;
2087 struct group_desc {
2088 char *name;
2089 u32 leader_idx;
2090 u32 nr_members;
2091 } *desc;
2092
2093 if (readn(fd, &nr_groups, sizeof(nr_groups)) != sizeof(nr_groups))
2094 return -1;
2095
2096 if (ph->needs_swap)
2097 nr_groups = bswap_32(nr_groups);
2098
2099 ph->env.nr_groups = nr_groups;
2100 if (!nr_groups) {
2101 pr_debug("group desc not available\n");
2102 return 0;
2103 }
2104
2105 desc = calloc(nr_groups, sizeof(*desc));
2106 if (!desc)
2107 return -1;
2108
2109 for (i = 0; i < nr_groups; i++) {
2110 desc[i].name = do_read_string(fd, ph);
2111 if (!desc[i].name)
2112 goto out_free;
2113
2114 if (readn(fd, &desc[i].leader_idx, sizeof(u32)) != sizeof(u32))
2115 goto out_free;
2116
2117 if (readn(fd, &desc[i].nr_members, sizeof(u32)) != sizeof(u32))
2118 goto out_free;
2119
2120 if (ph->needs_swap) {
2121 desc[i].leader_idx = bswap_32(desc[i].leader_idx);
2122 desc[i].nr_members = bswap_32(desc[i].nr_members);
2123 }
2124 }
2125
2126 /*
2127 * Rebuild group relationship based on the group_desc
2128 */
2129 session = container_of(ph, struct perf_session, header);
2130 session->evlist->nr_groups = nr_groups;
2131
2132 i = nr = 0;
2133 evlist__for_each(session->evlist, evsel) {
2134 if (evsel->idx == (int) desc[i].leader_idx) {
2135 evsel->leader = evsel;
2136 /* {anon_group} is a dummy name */
2137 if (strcmp(desc[i].name, "{anon_group}")) {
2138 evsel->group_name = desc[i].name;
2139 desc[i].name = NULL;
2140 }
2141 evsel->nr_members = desc[i].nr_members;
2142
2143 if (i >= nr_groups || nr > 0) {
2144 pr_debug("invalid group desc\n");
2145 goto out_free;
2146 }
2147
2148 leader = evsel;
2149 nr = evsel->nr_members - 1;
2150 i++;
2151 } else if (nr) {
2152 /* This is a group member */
2153 evsel->leader = leader;
2154
2155 nr--;
2156 }
2157 }
2158
2159 if (i != nr_groups || nr != 0) {
2160 pr_debug("invalid group desc\n");
2161 goto out_free;
2162 }
2163
2164 ret = 0;
2165 out_free:
2166 for (i = 0; i < nr_groups; i++)
2167 zfree(&desc[i].name);
2168 free(desc);
2169
2170 return ret;
2171 }
2172
2173 struct feature_ops {
2174 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
2175 void (*print)(struct perf_header *h, int fd, FILE *fp);
2176 int (*process)(struct perf_file_section *section,
2177 struct perf_header *h, int fd, void *data);
2178 const char *name;
2179 bool full_only;
2180 };
2181
2182 #define FEAT_OPA(n, func) \
2183 [n] = { .name = #n, .write = write_##func, .print = print_##func }
2184 #define FEAT_OPP(n, func) \
2185 [n] = { .name = #n, .write = write_##func, .print = print_##func, \
2186 .process = process_##func }
2187 #define FEAT_OPF(n, func) \
2188 [n] = { .name = #n, .write = write_##func, .print = print_##func, \
2189 .process = process_##func, .full_only = true }
2190
2191 /* feature_ops not implemented: */
2192 #define print_tracing_data NULL
2193 #define print_build_id NULL
2194
2195 static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
2196 FEAT_OPP(HEADER_TRACING_DATA, tracing_data),
2197 FEAT_OPP(HEADER_BUILD_ID, build_id),
2198 FEAT_OPP(HEADER_HOSTNAME, hostname),
2199 FEAT_OPP(HEADER_OSRELEASE, osrelease),
2200 FEAT_OPP(HEADER_VERSION, version),
2201 FEAT_OPP(HEADER_ARCH, arch),
2202 FEAT_OPP(HEADER_NRCPUS, nrcpus),
2203 FEAT_OPP(HEADER_CPUDESC, cpudesc),
2204 FEAT_OPP(HEADER_CPUID, cpuid),
2205 FEAT_OPP(HEADER_TOTAL_MEM, total_mem),
2206 FEAT_OPP(HEADER_EVENT_DESC, event_desc),
2207 FEAT_OPP(HEADER_CMDLINE, cmdline),
2208 FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology),
2209 FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology),
2210 FEAT_OPA(HEADER_BRANCH_STACK, branch_stack),
2211 FEAT_OPP(HEADER_PMU_MAPPINGS, pmu_mappings),
2212 FEAT_OPP(HEADER_GROUP_DESC, group_desc),
2213 };
2214
2215 struct header_print_data {
2216 FILE *fp;
2217 bool full; /* extended list of headers */
2218 };
2219
perf_file_section__fprintf_info(struct perf_file_section * section,struct perf_header * ph,int feat,int fd,void * data)2220 static int perf_file_section__fprintf_info(struct perf_file_section *section,
2221 struct perf_header *ph,
2222 int feat, int fd, void *data)
2223 {
2224 struct header_print_data *hd = data;
2225
2226 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) {
2227 pr_debug("Failed to lseek to %" PRIu64 " offset for feature "
2228 "%d, continuing...\n", section->offset, feat);
2229 return 0;
2230 }
2231 if (feat >= HEADER_LAST_FEATURE) {
2232 pr_warning("unknown feature %d\n", feat);
2233 return 0;
2234 }
2235 if (!feat_ops[feat].print)
2236 return 0;
2237
2238 if (!feat_ops[feat].full_only || hd->full)
2239 feat_ops[feat].print(ph, fd, hd->fp);
2240 else
2241 fprintf(hd->fp, "# %s info available, use -I to display\n",
2242 feat_ops[feat].name);
2243
2244 return 0;
2245 }
2246
perf_header__fprintf_info(struct perf_session * session,FILE * fp,bool full)2247 int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full)
2248 {
2249 struct header_print_data hd;
2250 struct perf_header *header = &session->header;
2251 int fd = perf_data_file__fd(session->file);
2252 hd.fp = fp;
2253 hd.full = full;
2254
2255 perf_header__process_sections(header, fd, &hd,
2256 perf_file_section__fprintf_info);
2257 return 0;
2258 }
2259
do_write_feat(int fd,struct perf_header * h,int type,struct perf_file_section ** p,struct perf_evlist * evlist)2260 static int do_write_feat(int fd, struct perf_header *h, int type,
2261 struct perf_file_section **p,
2262 struct perf_evlist *evlist)
2263 {
2264 int err;
2265 int ret = 0;
2266
2267 if (perf_header__has_feat(h, type)) {
2268 if (!feat_ops[type].write)
2269 return -1;
2270
2271 (*p)->offset = lseek(fd, 0, SEEK_CUR);
2272
2273 err = feat_ops[type].write(fd, h, evlist);
2274 if (err < 0) {
2275 pr_debug("failed to write feature %d\n", type);
2276
2277 /* undo anything written */
2278 lseek(fd, (*p)->offset, SEEK_SET);
2279
2280 return -1;
2281 }
2282 (*p)->size = lseek(fd, 0, SEEK_CUR) - (*p)->offset;
2283 (*p)++;
2284 }
2285 return ret;
2286 }
2287
perf_header__adds_write(struct perf_header * header,struct perf_evlist * evlist,int fd)2288 static int perf_header__adds_write(struct perf_header *header,
2289 struct perf_evlist *evlist, int fd)
2290 {
2291 int nr_sections;
2292 struct perf_file_section *feat_sec, *p;
2293 int sec_size;
2294 u64 sec_start;
2295 int feat;
2296 int err;
2297
2298 nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS);
2299 if (!nr_sections)
2300 return 0;
2301
2302 feat_sec = p = calloc(nr_sections, sizeof(*feat_sec));
2303 if (feat_sec == NULL)
2304 return -ENOMEM;
2305
2306 sec_size = sizeof(*feat_sec) * nr_sections;
2307
2308 sec_start = header->feat_offset;
2309 lseek(fd, sec_start + sec_size, SEEK_SET);
2310
2311 for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) {
2312 if (do_write_feat(fd, header, feat, &p, evlist))
2313 perf_header__clear_feat(header, feat);
2314 }
2315
2316 lseek(fd, sec_start, SEEK_SET);
2317 /*
2318 * may write more than needed due to dropped feature, but
2319 * this is okay, reader will skip the mising entries
2320 */
2321 err = do_write(fd, feat_sec, sec_size);
2322 if (err < 0)
2323 pr_debug("failed to write feature section\n");
2324 free(feat_sec);
2325 return err;
2326 }
2327
perf_header__write_pipe(int fd)2328 int perf_header__write_pipe(int fd)
2329 {
2330 struct perf_pipe_file_header f_header;
2331 int err;
2332
2333 f_header = (struct perf_pipe_file_header){
2334 .magic = PERF_MAGIC,
2335 .size = sizeof(f_header),
2336 };
2337
2338 err = do_write(fd, &f_header, sizeof(f_header));
2339 if (err < 0) {
2340 pr_debug("failed to write perf pipe header\n");
2341 return err;
2342 }
2343
2344 return 0;
2345 }
2346
perf_session__write_header(struct perf_session * session,struct perf_evlist * evlist,int fd,bool at_exit)2347 int perf_session__write_header(struct perf_session *session,
2348 struct perf_evlist *evlist,
2349 int fd, bool at_exit)
2350 {
2351 struct perf_file_header f_header;
2352 struct perf_file_attr f_attr;
2353 struct perf_header *header = &session->header;
2354 struct perf_evsel *evsel;
2355 u64 attr_offset;
2356 int err;
2357
2358 lseek(fd, sizeof(f_header), SEEK_SET);
2359
2360 evlist__for_each(session->evlist, evsel) {
2361 evsel->id_offset = lseek(fd, 0, SEEK_CUR);
2362 err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
2363 if (err < 0) {
2364 pr_debug("failed to write perf header\n");
2365 return err;
2366 }
2367 }
2368
2369 attr_offset = lseek(fd, 0, SEEK_CUR);
2370
2371 evlist__for_each(evlist, evsel) {
2372 f_attr = (struct perf_file_attr){
2373 .attr = evsel->attr,
2374 .ids = {
2375 .offset = evsel->id_offset,
2376 .size = evsel->ids * sizeof(u64),
2377 }
2378 };
2379 err = do_write(fd, &f_attr, sizeof(f_attr));
2380 if (err < 0) {
2381 pr_debug("failed to write perf header attribute\n");
2382 return err;
2383 }
2384 }
2385
2386 if (!header->data_offset)
2387 header->data_offset = lseek(fd, 0, SEEK_CUR);
2388 header->feat_offset = header->data_offset + header->data_size;
2389
2390 if (at_exit) {
2391 err = perf_header__adds_write(header, evlist, fd);
2392 if (err < 0)
2393 return err;
2394 }
2395
2396 f_header = (struct perf_file_header){
2397 .magic = PERF_MAGIC,
2398 .size = sizeof(f_header),
2399 .attr_size = sizeof(f_attr),
2400 .attrs = {
2401 .offset = attr_offset,
2402 .size = evlist->nr_entries * sizeof(f_attr),
2403 },
2404 .data = {
2405 .offset = header->data_offset,
2406 .size = header->data_size,
2407 },
2408 /* event_types is ignored, store zeros */
2409 };
2410
2411 memcpy(&f_header.adds_features, &header->adds_features, sizeof(header->adds_features));
2412
2413 lseek(fd, 0, SEEK_SET);
2414 err = do_write(fd, &f_header, sizeof(f_header));
2415 if (err < 0) {
2416 pr_debug("failed to write perf header\n");
2417 return err;
2418 }
2419 lseek(fd, header->data_offset + header->data_size, SEEK_SET);
2420
2421 return 0;
2422 }
2423
perf_header__getbuffer64(struct perf_header * header,int fd,void * buf,size_t size)2424 static int perf_header__getbuffer64(struct perf_header *header,
2425 int fd, void *buf, size_t size)
2426 {
2427 if (readn(fd, buf, size) <= 0)
2428 return -1;
2429
2430 if (header->needs_swap)
2431 mem_bswap_64(buf, size);
2432
2433 return 0;
2434 }
2435
perf_header__process_sections(struct perf_header * header,int fd,void * data,int (* process)(struct perf_file_section * section,struct perf_header * ph,int feat,int fd,void * data))2436 int perf_header__process_sections(struct perf_header *header, int fd,
2437 void *data,
2438 int (*process)(struct perf_file_section *section,
2439 struct perf_header *ph,
2440 int feat, int fd, void *data))
2441 {
2442 struct perf_file_section *feat_sec, *sec;
2443 int nr_sections;
2444 int sec_size;
2445 int feat;
2446 int err;
2447
2448 nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS);
2449 if (!nr_sections)
2450 return 0;
2451
2452 feat_sec = sec = calloc(nr_sections, sizeof(*feat_sec));
2453 if (!feat_sec)
2454 return -1;
2455
2456 sec_size = sizeof(*feat_sec) * nr_sections;
2457
2458 lseek(fd, header->feat_offset, SEEK_SET);
2459
2460 err = perf_header__getbuffer64(header, fd, feat_sec, sec_size);
2461 if (err < 0)
2462 goto out_free;
2463
2464 for_each_set_bit(feat, header->adds_features, HEADER_LAST_FEATURE) {
2465 err = process(sec++, header, feat, fd, data);
2466 if (err < 0)
2467 goto out_free;
2468 }
2469 err = 0;
2470 out_free:
2471 free(feat_sec);
2472 return err;
2473 }
2474
2475 static const int attr_file_abi_sizes[] = {
2476 [0] = PERF_ATTR_SIZE_VER0,
2477 [1] = PERF_ATTR_SIZE_VER1,
2478 [2] = PERF_ATTR_SIZE_VER2,
2479 [3] = PERF_ATTR_SIZE_VER3,
2480 0,
2481 };
2482
2483 /*
2484 * In the legacy file format, the magic number is not used to encode endianness.
2485 * hdr_sz was used to encode endianness. But given that hdr_sz can vary based
2486 * on ABI revisions, we need to try all combinations for all endianness to
2487 * detect the endianness.
2488 */
try_all_file_abis(uint64_t hdr_sz,struct perf_header * ph)2489 static int try_all_file_abis(uint64_t hdr_sz, struct perf_header *ph)
2490 {
2491 uint64_t ref_size, attr_size;
2492 int i;
2493
2494 for (i = 0 ; attr_file_abi_sizes[i]; i++) {
2495 ref_size = attr_file_abi_sizes[i]
2496 + sizeof(struct perf_file_section);
2497 if (hdr_sz != ref_size) {
2498 attr_size = bswap_64(hdr_sz);
2499 if (attr_size != ref_size)
2500 continue;
2501
2502 ph->needs_swap = true;
2503 }
2504 pr_debug("ABI%d perf.data file detected, need_swap=%d\n",
2505 i,
2506 ph->needs_swap);
2507 return 0;
2508 }
2509 /* could not determine endianness */
2510 return -1;
2511 }
2512
2513 #define PERF_PIPE_HDR_VER0 16
2514
2515 static const size_t attr_pipe_abi_sizes[] = {
2516 [0] = PERF_PIPE_HDR_VER0,
2517 0,
2518 };
2519
2520 /*
2521 * In the legacy pipe format, there is an implicit assumption that endiannesss
2522 * between host recording the samples, and host parsing the samples is the
2523 * same. This is not always the case given that the pipe output may always be
2524 * redirected into a file and analyzed on a different machine with possibly a
2525 * different endianness and perf_event ABI revsions in the perf tool itself.
2526 */
try_all_pipe_abis(uint64_t hdr_sz,struct perf_header * ph)2527 static int try_all_pipe_abis(uint64_t hdr_sz, struct perf_header *ph)
2528 {
2529 u64 attr_size;
2530 int i;
2531
2532 for (i = 0 ; attr_pipe_abi_sizes[i]; i++) {
2533 if (hdr_sz != attr_pipe_abi_sizes[i]) {
2534 attr_size = bswap_64(hdr_sz);
2535 if (attr_size != hdr_sz)
2536 continue;
2537
2538 ph->needs_swap = true;
2539 }
2540 pr_debug("Pipe ABI%d perf.data file detected\n", i);
2541 return 0;
2542 }
2543 return -1;
2544 }
2545
is_perf_magic(u64 magic)2546 bool is_perf_magic(u64 magic)
2547 {
2548 if (!memcmp(&magic, __perf_magic1, sizeof(magic))
2549 || magic == __perf_magic2
2550 || magic == __perf_magic2_sw)
2551 return true;
2552
2553 return false;
2554 }
2555
check_magic_endian(u64 magic,uint64_t hdr_sz,bool is_pipe,struct perf_header * ph)2556 static int check_magic_endian(u64 magic, uint64_t hdr_sz,
2557 bool is_pipe, struct perf_header *ph)
2558 {
2559 int ret;
2560
2561 /* check for legacy format */
2562 ret = memcmp(&magic, __perf_magic1, sizeof(magic));
2563 if (ret == 0) {
2564 ph->version = PERF_HEADER_VERSION_1;
2565 pr_debug("legacy perf.data format\n");
2566 if (is_pipe)
2567 return try_all_pipe_abis(hdr_sz, ph);
2568
2569 return try_all_file_abis(hdr_sz, ph);
2570 }
2571 /*
2572 * the new magic number serves two purposes:
2573 * - unique number to identify actual perf.data files
2574 * - encode endianness of file
2575 */
2576
2577 /* check magic number with one endianness */
2578 if (magic == __perf_magic2)
2579 return 0;
2580
2581 /* check magic number with opposite endianness */
2582 if (magic != __perf_magic2_sw)
2583 return -1;
2584
2585 ph->needs_swap = true;
2586 ph->version = PERF_HEADER_VERSION_2;
2587
2588 return 0;
2589 }
2590
perf_file_header__read(struct perf_file_header * header,struct perf_header * ph,int fd)2591 int perf_file_header__read(struct perf_file_header *header,
2592 struct perf_header *ph, int fd)
2593 {
2594 ssize_t ret;
2595
2596 lseek(fd, 0, SEEK_SET);
2597
2598 ret = readn(fd, header, sizeof(*header));
2599 if (ret <= 0)
2600 return -1;
2601
2602 if (check_magic_endian(header->magic,
2603 header->attr_size, false, ph) < 0) {
2604 pr_debug("magic/endian check failed\n");
2605 return -1;
2606 }
2607
2608 if (ph->needs_swap) {
2609 mem_bswap_64(header, offsetof(struct perf_file_header,
2610 adds_features));
2611 }
2612
2613 if (header->size != sizeof(*header)) {
2614 /* Support the previous format */
2615 if (header->size == offsetof(typeof(*header), adds_features))
2616 bitmap_zero(header->adds_features, HEADER_FEAT_BITS);
2617 else
2618 return -1;
2619 } else if (ph->needs_swap) {
2620 /*
2621 * feature bitmap is declared as an array of unsigned longs --
2622 * not good since its size can differ between the host that
2623 * generated the data file and the host analyzing the file.
2624 *
2625 * We need to handle endianness, but we don't know the size of
2626 * the unsigned long where the file was generated. Take a best
2627 * guess at determining it: try 64-bit swap first (ie., file
2628 * created on a 64-bit host), and check if the hostname feature
2629 * bit is set (this feature bit is forced on as of fbe96f2).
2630 * If the bit is not, undo the 64-bit swap and try a 32-bit
2631 * swap. If the hostname bit is still not set (e.g., older data
2632 * file), punt and fallback to the original behavior --
2633 * clearing all feature bits and setting buildid.
2634 */
2635 mem_bswap_64(&header->adds_features,
2636 BITS_TO_U64(HEADER_FEAT_BITS));
2637
2638 if (!test_bit(HEADER_HOSTNAME, header->adds_features)) {
2639 /* unswap as u64 */
2640 mem_bswap_64(&header->adds_features,
2641 BITS_TO_U64(HEADER_FEAT_BITS));
2642
2643 /* unswap as u32 */
2644 mem_bswap_32(&header->adds_features,
2645 BITS_TO_U32(HEADER_FEAT_BITS));
2646 }
2647
2648 if (!test_bit(HEADER_HOSTNAME, header->adds_features)) {
2649 bitmap_zero(header->adds_features, HEADER_FEAT_BITS);
2650 set_bit(HEADER_BUILD_ID, header->adds_features);
2651 }
2652 }
2653
2654 memcpy(&ph->adds_features, &header->adds_features,
2655 sizeof(ph->adds_features));
2656
2657 ph->data_offset = header->data.offset;
2658 ph->data_size = header->data.size;
2659 ph->feat_offset = header->data.offset + header->data.size;
2660 return 0;
2661 }
2662
perf_file_section__process(struct perf_file_section * section,struct perf_header * ph,int feat,int fd,void * data)2663 static int perf_file_section__process(struct perf_file_section *section,
2664 struct perf_header *ph,
2665 int feat, int fd, void *data)
2666 {
2667 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) {
2668 pr_debug("Failed to lseek to %" PRIu64 " offset for feature "
2669 "%d, continuing...\n", section->offset, feat);
2670 return 0;
2671 }
2672
2673 if (feat >= HEADER_LAST_FEATURE) {
2674 pr_debug("unknown feature %d, continuing...\n", feat);
2675 return 0;
2676 }
2677
2678 if (!feat_ops[feat].process)
2679 return 0;
2680
2681 return feat_ops[feat].process(section, ph, fd, data);
2682 }
2683
perf_file_header__read_pipe(struct perf_pipe_file_header * header,struct perf_header * ph,int fd,bool repipe)2684 static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
2685 struct perf_header *ph, int fd,
2686 bool repipe)
2687 {
2688 ssize_t ret;
2689
2690 ret = readn(fd, header, sizeof(*header));
2691 if (ret <= 0)
2692 return -1;
2693
2694 if (check_magic_endian(header->magic, header->size, true, ph) < 0) {
2695 pr_debug("endian/magic failed\n");
2696 return -1;
2697 }
2698
2699 if (ph->needs_swap)
2700 header->size = bswap_64(header->size);
2701
2702 if (repipe && do_write(STDOUT_FILENO, header, sizeof(*header)) < 0)
2703 return -1;
2704
2705 return 0;
2706 }
2707
perf_header__read_pipe(struct perf_session * session)2708 static int perf_header__read_pipe(struct perf_session *session)
2709 {
2710 struct perf_header *header = &session->header;
2711 struct perf_pipe_file_header f_header;
2712
2713 if (perf_file_header__read_pipe(&f_header, header,
2714 perf_data_file__fd(session->file),
2715 session->repipe) < 0) {
2716 pr_debug("incompatible file format\n");
2717 return -EINVAL;
2718 }
2719
2720 return 0;
2721 }
2722
read_attr(int fd,struct perf_header * ph,struct perf_file_attr * f_attr)2723 static int read_attr(int fd, struct perf_header *ph,
2724 struct perf_file_attr *f_attr)
2725 {
2726 struct perf_event_attr *attr = &f_attr->attr;
2727 size_t sz, left;
2728 size_t our_sz = sizeof(f_attr->attr);
2729 ssize_t ret;
2730
2731 memset(f_attr, 0, sizeof(*f_attr));
2732
2733 /* read minimal guaranteed structure */
2734 ret = readn(fd, attr, PERF_ATTR_SIZE_VER0);
2735 if (ret <= 0) {
2736 pr_debug("cannot read %d bytes of header attr\n",
2737 PERF_ATTR_SIZE_VER0);
2738 return -1;
2739 }
2740
2741 /* on file perf_event_attr size */
2742 sz = attr->size;
2743
2744 if (ph->needs_swap)
2745 sz = bswap_32(sz);
2746
2747 if (sz == 0) {
2748 /* assume ABI0 */
2749 sz = PERF_ATTR_SIZE_VER0;
2750 } else if (sz > our_sz) {
2751 pr_debug("file uses a more recent and unsupported ABI"
2752 " (%zu bytes extra)\n", sz - our_sz);
2753 return -1;
2754 }
2755 /* what we have not yet read and that we know about */
2756 left = sz - PERF_ATTR_SIZE_VER0;
2757 if (left) {
2758 void *ptr = attr;
2759 ptr += PERF_ATTR_SIZE_VER0;
2760
2761 ret = readn(fd, ptr, left);
2762 }
2763 /* read perf_file_section, ids are read in caller */
2764 ret = readn(fd, &f_attr->ids, sizeof(f_attr->ids));
2765
2766 return ret <= 0 ? -1 : 0;
2767 }
2768
perf_evsel__prepare_tracepoint_event(struct perf_evsel * evsel,struct pevent * pevent)2769 static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
2770 struct pevent *pevent)
2771 {
2772 struct event_format *event;
2773 char bf[128];
2774
2775 /* already prepared */
2776 if (evsel->tp_format)
2777 return 0;
2778
2779 if (pevent == NULL) {
2780 pr_debug("broken or missing trace data\n");
2781 return -1;
2782 }
2783
2784 event = pevent_find_event(pevent, evsel->attr.config);
2785 if (event == NULL)
2786 return -1;
2787
2788 if (!evsel->name) {
2789 snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name);
2790 evsel->name = strdup(bf);
2791 if (evsel->name == NULL)
2792 return -1;
2793 }
2794
2795 evsel->tp_format = event;
2796 return 0;
2797 }
2798
perf_evlist__prepare_tracepoint_events(struct perf_evlist * evlist,struct pevent * pevent)2799 static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
2800 struct pevent *pevent)
2801 {
2802 struct perf_evsel *pos;
2803
2804 evlist__for_each(evlist, pos) {
2805 if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
2806 perf_evsel__prepare_tracepoint_event(pos, pevent))
2807 return -1;
2808 }
2809
2810 return 0;
2811 }
2812
perf_session__read_header(struct perf_session * session)2813 int perf_session__read_header(struct perf_session *session)
2814 {
2815 struct perf_data_file *file = session->file;
2816 struct perf_header *header = &session->header;
2817 struct perf_file_header f_header;
2818 struct perf_file_attr f_attr;
2819 u64 f_id;
2820 int nr_attrs, nr_ids, i, j;
2821 int fd = perf_data_file__fd(file);
2822
2823 session->evlist = perf_evlist__new();
2824 if (session->evlist == NULL)
2825 return -ENOMEM;
2826
2827 if (perf_data_file__is_pipe(file))
2828 return perf_header__read_pipe(session);
2829
2830 if (perf_file_header__read(&f_header, header, fd) < 0)
2831 return -EINVAL;
2832
2833 /*
2834 * Sanity check that perf.data was written cleanly; data size is
2835 * initialized to 0 and updated only if the on_exit function is run.
2836 * If data size is still 0 then the file contains only partial
2837 * information. Just warn user and process it as much as it can.
2838 */
2839 if (f_header.data.size == 0) {
2840 pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n"
2841 "Was the 'perf record' command properly terminated?\n",
2842 file->path);
2843 }
2844
2845 nr_attrs = f_header.attrs.size / f_header.attr_size;
2846 lseek(fd, f_header.attrs.offset, SEEK_SET);
2847
2848 for (i = 0; i < nr_attrs; i++) {
2849 struct perf_evsel *evsel;
2850 off_t tmp;
2851
2852 if (read_attr(fd, header, &f_attr) < 0)
2853 goto out_errno;
2854
2855 if (header->needs_swap)
2856 perf_event__attr_swap(&f_attr.attr);
2857
2858 tmp = lseek(fd, 0, SEEK_CUR);
2859 evsel = perf_evsel__new(&f_attr.attr);
2860
2861 if (evsel == NULL)
2862 goto out_delete_evlist;
2863
2864 evsel->needs_swap = header->needs_swap;
2865 /*
2866 * Do it before so that if perf_evsel__alloc_id fails, this
2867 * entry gets purged too at perf_evlist__delete().
2868 */
2869 perf_evlist__add(session->evlist, evsel);
2870
2871 nr_ids = f_attr.ids.size / sizeof(u64);
2872 /*
2873 * We don't have the cpu and thread maps on the header, so
2874 * for allocating the perf_sample_id table we fake 1 cpu and
2875 * hattr->ids threads.
2876 */
2877 if (perf_evsel__alloc_id(evsel, 1, nr_ids))
2878 goto out_delete_evlist;
2879
2880 lseek(fd, f_attr.ids.offset, SEEK_SET);
2881
2882 for (j = 0; j < nr_ids; j++) {
2883 if (perf_header__getbuffer64(header, fd, &f_id, sizeof(f_id)))
2884 goto out_errno;
2885
2886 perf_evlist__id_add(session->evlist, evsel, 0, j, f_id);
2887 }
2888
2889 lseek(fd, tmp, SEEK_SET);
2890 }
2891
2892 symbol_conf.nr_events = nr_attrs;
2893
2894 perf_header__process_sections(header, fd, &session->tevent,
2895 perf_file_section__process);
2896
2897 if (perf_evlist__prepare_tracepoint_events(session->evlist,
2898 session->tevent.pevent))
2899 goto out_delete_evlist;
2900
2901 return 0;
2902 out_errno:
2903 return -errno;
2904
2905 out_delete_evlist:
2906 perf_evlist__delete(session->evlist);
2907 session->evlist = NULL;
2908 return -ENOMEM;
2909 }
2910
perf_event__synthesize_attr(struct perf_tool * tool,struct perf_event_attr * attr,u32 ids,u64 * id,perf_event__handler_t process)2911 int perf_event__synthesize_attr(struct perf_tool *tool,
2912 struct perf_event_attr *attr, u32 ids, u64 *id,
2913 perf_event__handler_t process)
2914 {
2915 union perf_event *ev;
2916 size_t size;
2917 int err;
2918
2919 size = sizeof(struct perf_event_attr);
2920 size = PERF_ALIGN(size, sizeof(u64));
2921 size += sizeof(struct perf_event_header);
2922 size += ids * sizeof(u64);
2923
2924 ev = malloc(size);
2925
2926 if (ev == NULL)
2927 return -ENOMEM;
2928
2929 ev->attr.attr = *attr;
2930 memcpy(ev->attr.id, id, ids * sizeof(u64));
2931
2932 ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
2933 ev->attr.header.size = (u16)size;
2934
2935 if (ev->attr.header.size == size)
2936 err = process(tool, ev, NULL, NULL);
2937 else
2938 err = -E2BIG;
2939
2940 free(ev);
2941
2942 return err;
2943 }
2944
perf_event__synthesize_attrs(struct perf_tool * tool,struct perf_session * session,perf_event__handler_t process)2945 int perf_event__synthesize_attrs(struct perf_tool *tool,
2946 struct perf_session *session,
2947 perf_event__handler_t process)
2948 {
2949 struct perf_evsel *evsel;
2950 int err = 0;
2951
2952 evlist__for_each(session->evlist, evsel) {
2953 err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids,
2954 evsel->id, process);
2955 if (err) {
2956 pr_debug("failed to create perf header attribute\n");
2957 return err;
2958 }
2959 }
2960
2961 return err;
2962 }
2963
perf_event__process_attr(struct perf_tool * tool __maybe_unused,union perf_event * event,struct perf_evlist ** pevlist)2964 int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
2965 union perf_event *event,
2966 struct perf_evlist **pevlist)
2967 {
2968 u32 i, ids, n_ids;
2969 struct perf_evsel *evsel;
2970 struct perf_evlist *evlist = *pevlist;
2971
2972 if (evlist == NULL) {
2973 *pevlist = evlist = perf_evlist__new();
2974 if (evlist == NULL)
2975 return -ENOMEM;
2976 }
2977
2978 evsel = perf_evsel__new(&event->attr.attr);
2979 if (evsel == NULL)
2980 return -ENOMEM;
2981
2982 perf_evlist__add(evlist, evsel);
2983
2984 ids = event->header.size;
2985 ids -= (void *)&event->attr.id - (void *)event;
2986 n_ids = ids / sizeof(u64);
2987 /*
2988 * We don't have the cpu and thread maps on the header, so
2989 * for allocating the perf_sample_id table we fake 1 cpu and
2990 * hattr->ids threads.
2991 */
2992 if (perf_evsel__alloc_id(evsel, 1, n_ids))
2993 return -ENOMEM;
2994
2995 for (i = 0; i < n_ids; i++) {
2996 perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]);
2997 }
2998
2999 symbol_conf.nr_events = evlist->nr_entries;
3000
3001 return 0;
3002 }
3003
perf_event__synthesize_tracing_data(struct perf_tool * tool,int fd,struct perf_evlist * evlist,perf_event__handler_t process)3004 int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd,
3005 struct perf_evlist *evlist,
3006 perf_event__handler_t process)
3007 {
3008 union perf_event ev;
3009 struct tracing_data *tdata;
3010 ssize_t size = 0, aligned_size = 0, padding;
3011 int err __maybe_unused = 0;
3012
3013 /*
3014 * We are going to store the size of the data followed
3015 * by the data contents. Since the fd descriptor is a pipe,
3016 * we cannot seek back to store the size of the data once
3017 * we know it. Instead we:
3018 *
3019 * - write the tracing data to the temp file
3020 * - get/write the data size to pipe
3021 * - write the tracing data from the temp file
3022 * to the pipe
3023 */
3024 tdata = tracing_data_get(&evlist->entries, fd, true);
3025 if (!tdata)
3026 return -1;
3027
3028 memset(&ev, 0, sizeof(ev));
3029
3030 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
3031 size = tdata->size;
3032 aligned_size = PERF_ALIGN(size, sizeof(u64));
3033 padding = aligned_size - size;
3034 ev.tracing_data.header.size = sizeof(ev.tracing_data);
3035 ev.tracing_data.size = aligned_size;
3036
3037 process(tool, &ev, NULL, NULL);
3038
3039 /*
3040 * The put function will copy all the tracing data
3041 * stored in temp file to the pipe.
3042 */
3043 tracing_data_put(tdata);
3044
3045 write_padded(fd, NULL, 0, padding);
3046
3047 return aligned_size;
3048 }
3049
perf_event__process_tracing_data(struct perf_tool * tool __maybe_unused,union perf_event * event,struct perf_session * session)3050 int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused,
3051 union perf_event *event,
3052 struct perf_session *session)
3053 {
3054 ssize_t size_read, padding, size = event->tracing_data.size;
3055 int fd = perf_data_file__fd(session->file);
3056 off_t offset = lseek(fd, 0, SEEK_CUR);
3057 char buf[BUFSIZ];
3058
3059 /* setup for reading amidst mmap */
3060 lseek(fd, offset + sizeof(struct tracing_data_event),
3061 SEEK_SET);
3062
3063 size_read = trace_report(fd, &session->tevent,
3064 session->repipe);
3065 padding = PERF_ALIGN(size_read, sizeof(u64)) - size_read;
3066
3067 if (readn(fd, buf, padding) < 0) {
3068 pr_err("%s: reading input file", __func__);
3069 return -1;
3070 }
3071 if (session->repipe) {
3072 int retw = write(STDOUT_FILENO, buf, padding);
3073 if (retw <= 0 || retw != padding) {
3074 pr_err("%s: repiping tracing data padding", __func__);
3075 return -1;
3076 }
3077 }
3078
3079 if (size_read + padding != size) {
3080 pr_err("%s: tracing data size mismatch", __func__);
3081 return -1;
3082 }
3083
3084 perf_evlist__prepare_tracepoint_events(session->evlist,
3085 session->tevent.pevent);
3086
3087 return size_read + padding;
3088 }
3089
perf_event__synthesize_build_id(struct perf_tool * tool,struct dso * pos,u16 misc,perf_event__handler_t process,struct machine * machine)3090 int perf_event__synthesize_build_id(struct perf_tool *tool,
3091 struct dso *pos, u16 misc,
3092 perf_event__handler_t process,
3093 struct machine *machine)
3094 {
3095 union perf_event ev;
3096 size_t len;
3097 int err = 0;
3098
3099 if (!pos->hit)
3100 return err;
3101
3102 memset(&ev, 0, sizeof(ev));
3103
3104 len = pos->long_name_len + 1;
3105 len = PERF_ALIGN(len, NAME_ALIGN);
3106 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
3107 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
3108 ev.build_id.header.misc = misc;
3109 ev.build_id.pid = machine->pid;
3110 ev.build_id.header.size = sizeof(ev.build_id) + len;
3111 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
3112
3113 err = process(tool, &ev, NULL, machine);
3114
3115 return err;
3116 }
3117
perf_event__process_build_id(struct perf_tool * tool __maybe_unused,union perf_event * event,struct perf_session * session)3118 int perf_event__process_build_id(struct perf_tool *tool __maybe_unused,
3119 union perf_event *event,
3120 struct perf_session *session)
3121 {
3122 __event_process_build_id(&event->build_id,
3123 event->build_id.filename,
3124 session);
3125 return 0;
3126 }
3127
disable_buildid_cache(void)3128 void disable_buildid_cache(void)
3129 {
3130 no_buildid_cache = true;
3131 }
3132