1 #define _FILE_OFFSET_BITS 64
8 #include <linux/list.h>
9 #include <linux/kernel.h>
10 #include <sys/utsname.h>
17 #include "trace-event.h"
23 static bool no_buildid_cache
= false;
25 static int event_count
;
26 static struct perf_trace_event_type
*events
;
28 static u32 header_argc
;
29 static const char **header_argv
;
31 static int dsos__write_buildid_table(struct perf_header
*header
, int fd
);
32 static int perf_session__cache_build_ids(struct perf_session
*session
);
34 int perf_header__push_event(u64 id
, const char *name
)
36 if (strlen(name
) > MAX_EVENT_NAME
)
37 pr_warning("Event %s will be truncated\n", name
);
40 events
= malloc(sizeof(struct perf_trace_event_type
));
44 struct perf_trace_event_type
*nevents
;
46 nevents
= realloc(events
, (event_count
+ 1) * sizeof(*events
));
51 memset(&events
[event_count
], 0, sizeof(struct perf_trace_event_type
));
52 events
[event_count
].event_id
= id
;
53 strncpy(events
[event_count
].name
, name
, MAX_EVENT_NAME
- 1);
58 char *perf_header__find_event(u64 id
)
61 for (i
= 0 ; i
< event_count
; i
++) {
62 if (events
[i
].event_id
== id
)
63 return events
[i
].name
;
68 static const char *__perf_magic
= "PERFFILE";
70 #define PERF_MAGIC (*(u64 *)__perf_magic)
72 struct perf_file_attr
{
73 struct perf_event_attr attr
;
74 struct perf_file_section ids
;
77 void perf_header__set_feat(struct perf_header
*header
, int feat
)
79 set_bit(feat
, header
->adds_features
);
82 void perf_header__clear_feat(struct perf_header
*header
, int feat
)
84 clear_bit(feat
, header
->adds_features
);
87 bool perf_header__has_feat(const struct perf_header
*header
, int feat
)
89 return test_bit(feat
, header
->adds_features
);
92 static int do_write(int fd
, const void *buf
, size_t size
)
95 int ret
= write(fd
, buf
, size
);
107 #define NAME_ALIGN 64
109 static int write_padded(int fd
, const void *bf
, size_t count
,
110 size_t count_aligned
)
112 static const char zero_buf
[NAME_ALIGN
];
113 int err
= do_write(fd
, bf
, count
);
116 err
= do_write(fd
, zero_buf
, count_aligned
- count
);
121 static int do_write_string(int fd
, const char *str
)
126 olen
= strlen(str
) + 1;
127 len
= ALIGN(olen
, NAME_ALIGN
);
129 /* write len, incl. \0 */
130 ret
= do_write(fd
, &len
, sizeof(len
));
134 return write_padded(fd
, str
, olen
, len
);
137 static char *do_read_string(int fd
, struct perf_header
*ph
)
143 sz
= read(fd
, &len
, sizeof(len
));
144 if (sz
< (ssize_t
)sizeof(len
))
154 ret
= read(fd
, buf
, len
);
155 if (ret
== (ssize_t
)len
) {
157 * strings are padded by zeroes
158 * thus the actual strlen of buf
159 * may be less than len
169 perf_header__set_cmdline(int argc
, const char **argv
)
173 header_argc
= (u32
)argc
;
175 /* do not include NULL termination */
176 header_argv
= calloc(argc
, sizeof(char *));
181 * must copy argv contents because it gets moved
182 * around during option parsing
184 for (i
= 0; i
< argc
; i
++)
185 header_argv
[i
] = argv
[i
];
190 static int write_trace_info(int fd
, struct perf_header
*h __used
,
191 struct perf_evlist
*evlist
)
193 return read_tracing_data(fd
, &evlist
->entries
);
197 static int write_build_id(int fd
, struct perf_header
*h
,
198 struct perf_evlist
*evlist __used
)
200 struct perf_session
*session
;
203 session
= container_of(h
, struct perf_session
, header
);
205 err
= dsos__write_buildid_table(h
, fd
);
207 pr_debug("failed to write buildid table\n");
210 if (!no_buildid_cache
)
211 perf_session__cache_build_ids(session
);
216 static int write_hostname(int fd
, struct perf_header
*h __used
,
217 struct perf_evlist
*evlist __used
)
226 return do_write_string(fd
, uts
.nodename
);
229 static int write_osrelease(int fd
, struct perf_header
*h __used
,
230 struct perf_evlist
*evlist __used
)
239 return do_write_string(fd
, uts
.release
);
242 static int write_arch(int fd
, struct perf_header
*h __used
,
243 struct perf_evlist
*evlist __used
)
252 return do_write_string(fd
, uts
.machine
);
255 static int write_version(int fd
, struct perf_header
*h __used
,
256 struct perf_evlist
*evlist __used
)
258 return do_write_string(fd
, perf_version_string
);
261 static int write_cpudesc(int fd
, struct perf_header
*h __used
,
262 struct perf_evlist
*evlist __used
)
265 #define CPUINFO_PROC NULL
270 const char *search
= CPUINFO_PROC
;
277 file
= fopen("/proc/cpuinfo", "r");
281 while (getline(&buf
, &len
, file
) > 0) {
282 ret
= strncmp(buf
, search
, strlen(search
));
292 p
= strchr(buf
, ':');
293 if (p
&& *(p
+1) == ' ' && *(p
+2))
299 /* squash extra space characters (branding string) */
306 while (*q
&& isspace(*q
))
309 while ((*r
++ = *q
++));
313 ret
= do_write_string(fd
, s
);
320 static int write_nrcpus(int fd
, struct perf_header
*h __used
,
321 struct perf_evlist
*evlist __used
)
327 nr
= sysconf(_SC_NPROCESSORS_CONF
);
331 nrc
= (u32
)(nr
& UINT_MAX
);
333 nr
= sysconf(_SC_NPROCESSORS_ONLN
);
337 nra
= (u32
)(nr
& UINT_MAX
);
339 ret
= do_write(fd
, &nrc
, sizeof(nrc
));
343 return do_write(fd
, &nra
, sizeof(nra
));
346 static int write_event_desc(int fd
, struct perf_header
*h __used
,
347 struct perf_evlist
*evlist
)
349 struct perf_evsel
*attr
;
350 u32 nre
= 0, nri
, sz
;
353 list_for_each_entry(attr
, &evlist
->entries
, node
)
357 * write number of events
359 ret
= do_write(fd
, &nre
, sizeof(nre
));
364 * size of perf_event_attr struct
366 sz
= (u32
)sizeof(attr
->attr
);
367 ret
= do_write(fd
, &sz
, sizeof(sz
));
371 list_for_each_entry(attr
, &evlist
->entries
, node
) {
373 ret
= do_write(fd
, &attr
->attr
, sz
);
377 * write number of unique id per event
378 * there is one id per instance of an event
380 * copy into an nri to be independent of the
384 ret
= do_write(fd
, &nri
, sizeof(nri
));
389 * write event string as passed on cmdline
391 ret
= do_write_string(fd
, attr
->name
);
395 * write unique ids for this event
397 ret
= do_write(fd
, attr
->id
, attr
->ids
* sizeof(u64
));
404 static int write_cmdline(int fd
, struct perf_header
*h __used
,
405 struct perf_evlist
*evlist __used
)
407 char buf
[MAXPATHLEN
];
413 * actual atual path to perf binary
415 sprintf(proc
, "/proc/%d/exe", getpid());
416 ret
= readlink(proc
, buf
, sizeof(buf
));
420 /* readlink() does not add null termination */
423 /* account for binary path */
426 ret
= do_write(fd
, &n
, sizeof(n
));
430 ret
= do_write_string(fd
, buf
);
434 for (i
= 0 ; i
< header_argc
; i
++) {
435 ret
= do_write_string(fd
, header_argv
[i
]);
442 #define CORE_SIB_FMT \
443 "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list"
444 #define THRD_SIB_FMT \
445 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
450 char **core_siblings
;
451 char **thread_siblings
;
454 static int build_cpu_topo(struct cpu_topo
*tp
, int cpu
)
457 char filename
[MAXPATHLEN
];
458 char *buf
= NULL
, *p
;
463 sprintf(filename
, CORE_SIB_FMT
, cpu
);
464 fp
= fopen(filename
, "r");
468 if (getline(&buf
, &len
, fp
) <= 0)
473 p
= strchr(buf
, '\n');
477 for (i
= 0; i
< tp
->core_sib
; i
++) {
478 if (!strcmp(buf
, tp
->core_siblings
[i
]))
481 if (i
== tp
->core_sib
) {
482 tp
->core_siblings
[i
] = buf
;
488 sprintf(filename
, THRD_SIB_FMT
, cpu
);
489 fp
= fopen(filename
, "r");
493 if (getline(&buf
, &len
, fp
) <= 0)
496 p
= strchr(buf
, '\n');
500 for (i
= 0; i
< tp
->thread_sib
; i
++) {
501 if (!strcmp(buf
, tp
->thread_siblings
[i
]))
504 if (i
== tp
->thread_sib
) {
505 tp
->thread_siblings
[i
] = buf
;
517 static void free_cpu_topo(struct cpu_topo
*tp
)
524 for (i
= 0 ; i
< tp
->core_sib
; i
++)
525 free(tp
->core_siblings
[i
]);
527 for (i
= 0 ; i
< tp
->thread_sib
; i
++)
528 free(tp
->thread_siblings
[i
]);
533 static struct cpu_topo
*build_cpu_topology(void)
542 ncpus
= sysconf(_SC_NPROCESSORS_CONF
);
546 nr
= (u32
)(ncpus
& UINT_MAX
);
548 sz
= nr
* sizeof(char *);
550 addr
= calloc(1, sizeof(*tp
) + 2 * sz
);
557 tp
->core_siblings
= addr
;
559 tp
->thread_siblings
= addr
;
561 for (i
= 0; i
< nr
; i
++) {
562 ret
= build_cpu_topo(tp
, i
);
573 static int write_cpu_topology(int fd
, struct perf_header
*h __used
,
574 struct perf_evlist
*evlist __used
)
580 tp
= build_cpu_topology();
584 ret
= do_write(fd
, &tp
->core_sib
, sizeof(tp
->core_sib
));
588 for (i
= 0; i
< tp
->core_sib
; i
++) {
589 ret
= do_write_string(fd
, tp
->core_siblings
[i
]);
593 ret
= do_write(fd
, &tp
->thread_sib
, sizeof(tp
->thread_sib
));
597 for (i
= 0; i
< tp
->thread_sib
; i
++) {
598 ret
= do_write_string(fd
, tp
->thread_siblings
[i
]);
609 static int write_total_mem(int fd
, struct perf_header
*h __used
,
610 struct perf_evlist
*evlist __used
)
618 fp
= fopen("/proc/meminfo", "r");
622 while (getline(&buf
, &len
, fp
) > 0) {
623 ret
= strncmp(buf
, "MemTotal:", 9);
628 n
= sscanf(buf
, "%*s %"PRIu64
, &mem
);
630 ret
= do_write(fd
, &mem
, sizeof(mem
));
637 static int write_topo_node(int fd
, int node
)
639 char str
[MAXPATHLEN
];
641 char *buf
= NULL
, *p
;
644 u64 mem_total
, mem_free
, mem
;
647 sprintf(str
, "/sys/devices/system/node/node%d/meminfo", node
);
648 fp
= fopen(str
, "r");
652 while (getline(&buf
, &len
, fp
) > 0) {
653 /* skip over invalid lines */
654 if (!strchr(buf
, ':'))
656 if (sscanf(buf
, "%*s %*d %s %"PRIu64
, field
, &mem
) != 2)
658 if (!strcmp(field
, "MemTotal:"))
660 if (!strcmp(field
, "MemFree:"))
666 ret
= do_write(fd
, &mem_total
, sizeof(u64
));
670 ret
= do_write(fd
, &mem_free
, sizeof(u64
));
675 sprintf(str
, "/sys/devices/system/node/node%d/cpulist", node
);
677 fp
= fopen(str
, "r");
681 if (getline(&buf
, &len
, fp
) <= 0)
684 p
= strchr(buf
, '\n');
688 ret
= do_write_string(fd
, buf
);
695 static int write_numa_topology(int fd
, struct perf_header
*h __used
,
696 struct perf_evlist
*evlist __used
)
701 struct cpu_map
*node_map
= NULL
;
706 fp
= fopen("/sys/devices/system/node/online", "r");
710 if (getline(&buf
, &len
, fp
) <= 0)
713 c
= strchr(buf
, '\n');
717 node_map
= cpu_map__new(buf
);
721 nr
= (u32
)node_map
->nr
;
723 ret
= do_write(fd
, &nr
, sizeof(nr
));
727 for (i
= 0; i
< nr
; i
++) {
728 j
= (u32
)node_map
->map
[i
];
729 ret
= do_write(fd
, &j
, sizeof(j
));
733 ret
= write_topo_node(fd
, i
);
745 * default get_cpuid(): nothing gets recorded
746 * actual implementation must be in arch/$(ARCH)/util/header.c
748 int __attribute__((weak
)) get_cpuid(char *buffer __used
, size_t sz __used
)
753 static int write_cpuid(int fd
, struct perf_header
*h __used
,
754 struct perf_evlist
*evlist __used
)
759 ret
= get_cpuid(buffer
, sizeof(buffer
));
765 return do_write_string(fd
, buffer
);
768 static void print_hostname(struct perf_header
*ph
, int fd
, FILE *fp
)
770 char *str
= do_read_string(fd
, ph
);
771 fprintf(fp
, "# hostname : %s\n", str
);
775 static void print_osrelease(struct perf_header
*ph
, int fd
, FILE *fp
)
777 char *str
= do_read_string(fd
, ph
);
778 fprintf(fp
, "# os release : %s\n", str
);
782 static void print_arch(struct perf_header
*ph
, int fd
, FILE *fp
)
784 char *str
= do_read_string(fd
, ph
);
785 fprintf(fp
, "# arch : %s\n", str
);
789 static void print_cpudesc(struct perf_header
*ph
, int fd
, FILE *fp
)
791 char *str
= do_read_string(fd
, ph
);
792 fprintf(fp
, "# cpudesc : %s\n", str
);
796 static void print_nrcpus(struct perf_header
*ph
, int fd
, FILE *fp
)
801 ret
= read(fd
, &nr
, sizeof(nr
));
802 if (ret
!= (ssize_t
)sizeof(nr
))
803 nr
= -1; /* interpreted as error */
808 fprintf(fp
, "# nrcpus online : %u\n", nr
);
810 ret
= read(fd
, &nr
, sizeof(nr
));
811 if (ret
!= (ssize_t
)sizeof(nr
))
812 nr
= -1; /* interpreted as error */
817 fprintf(fp
, "# nrcpus avail : %u\n", nr
);
820 static void print_version(struct perf_header
*ph
, int fd
, FILE *fp
)
822 char *str
= do_read_string(fd
, ph
);
823 fprintf(fp
, "# perf version : %s\n", str
);
827 static void print_cmdline(struct perf_header
*ph
, int fd
, FILE *fp
)
833 ret
= read(fd
, &nr
, sizeof(nr
));
834 if (ret
!= (ssize_t
)sizeof(nr
))
840 fprintf(fp
, "# cmdline : ");
842 for (i
= 0; i
< nr
; i
++) {
843 str
= do_read_string(fd
, ph
);
844 fprintf(fp
, "%s ", str
);
850 static void print_cpu_topology(struct perf_header
*ph
, int fd
, FILE *fp
)
856 ret
= read(fd
, &nr
, sizeof(nr
));
857 if (ret
!= (ssize_t
)sizeof(nr
))
863 for (i
= 0; i
< nr
; i
++) {
864 str
= do_read_string(fd
, ph
);
865 fprintf(fp
, "# sibling cores : %s\n", str
);
869 ret
= read(fd
, &nr
, sizeof(nr
));
870 if (ret
!= (ssize_t
)sizeof(nr
))
876 for (i
= 0; i
< nr
; i
++) {
877 str
= do_read_string(fd
, ph
);
878 fprintf(fp
, "# sibling threads : %s\n", str
);
883 static void print_event_desc(struct perf_header
*ph
, int fd
, FILE *fp
)
885 struct perf_event_attr attr
;
889 u32 nre
, sz
, nr
, i
, j
, msz
;
892 /* number of events */
893 ret
= read(fd
, &nre
, sizeof(nre
));
894 if (ret
!= (ssize_t
)sizeof(nre
))
900 ret
= read(fd
, &sz
, sizeof(sz
));
901 if (ret
!= (ssize_t
)sizeof(sz
))
908 * ensure it is at least to our ABI rev
910 if (sz
< (u32
)sizeof(attr
))
913 memset(&attr
, 0, sizeof(attr
));
915 /* read entire region to sync up to next field */
924 for (i
= 0 ; i
< nre
; i
++) {
926 ret
= read(fd
, buf
, sz
);
927 if (ret
!= (ssize_t
)sz
)
931 perf_event__attr_swap(buf
);
933 memcpy(&attr
, buf
, msz
);
935 ret
= read(fd
, &nr
, sizeof(nr
));
936 if (ret
!= (ssize_t
)sizeof(nr
))
942 str
= do_read_string(fd
, ph
);
943 fprintf(fp
, "# event : name = %s, ", str
);
946 fprintf(fp
, "type = %d, config = 0x%"PRIx64
947 ", config1 = 0x%"PRIx64
", config2 = 0x%"PRIx64
,
953 fprintf(fp
, ", excl_usr = %d, excl_kern = %d",
955 attr
.exclude_kernel
);
958 fprintf(fp
, ", id = {");
960 for (j
= 0 ; j
< nr
; j
++) {
961 ret
= read(fd
, &id
, sizeof(id
));
962 if (ret
!= (ssize_t
)sizeof(id
))
971 fprintf(fp
, " %"PRIu64
, id
);
980 fprintf(fp
, "# event desc: not available or unable to read\n");
983 static void print_total_mem(struct perf_header
*h __used
, int fd
, FILE *fp
)
988 ret
= read(fd
, &mem
, sizeof(mem
));
989 if (ret
!= sizeof(mem
))
995 fprintf(fp
, "# total memory : %"PRIu64
" kB\n", mem
);
998 fprintf(fp
, "# total memory : unknown\n");
1001 static void print_numa_topology(struct perf_header
*h __used
, int fd
, FILE *fp
)
1006 uint64_t mem_total
, mem_free
;
1009 ret
= read(fd
, &nr
, sizeof(nr
));
1010 if (ret
!= (ssize_t
)sizeof(nr
))
1016 for (i
= 0; i
< nr
; i
++) {
1019 ret
= read(fd
, &c
, sizeof(c
));
1020 if (ret
!= (ssize_t
)sizeof(c
))
1026 ret
= read(fd
, &mem_total
, sizeof(u64
));
1027 if (ret
!= sizeof(u64
))
1030 ret
= read(fd
, &mem_free
, sizeof(u64
));
1031 if (ret
!= sizeof(u64
))
1034 if (h
->needs_swap
) {
1035 mem_total
= bswap_64(mem_total
);
1036 mem_free
= bswap_64(mem_free
);
1039 fprintf(fp
, "# node%u meminfo : total = %"PRIu64
" kB,"
1040 " free = %"PRIu64
" kB\n",
1045 str
= do_read_string(fd
, h
);
1046 fprintf(fp
, "# node%u cpu list : %s\n", c
, str
);
1051 fprintf(fp
, "# numa topology : not available\n");
1054 static void print_cpuid(struct perf_header
*ph
, int fd
, FILE *fp
)
1056 char *str
= do_read_string(fd
, ph
);
1057 fprintf(fp
, "# cpuid : %s\n", str
);
1061 struct feature_ops
{
1062 int (*write
)(int fd
, struct perf_header
*h
, struct perf_evlist
*evlist
);
1063 void (*print
)(struct perf_header
*h
, int fd
, FILE *fp
);
1068 #define FEAT_OPA(n, w, p) \
1069 [n] = { .name = #n, .write = w, .print = p }
1070 #define FEAT_OPF(n, w, p) \
1071 [n] = { .name = #n, .write = w, .print = p, .full_only = true }
1073 static const struct feature_ops feat_ops
[HEADER_LAST_FEATURE
] = {
1074 FEAT_OPA(HEADER_TRACE_INFO
, write_trace_info
, NULL
),
1075 FEAT_OPA(HEADER_BUILD_ID
, write_build_id
, NULL
),
1076 FEAT_OPA(HEADER_HOSTNAME
, write_hostname
, print_hostname
),
1077 FEAT_OPA(HEADER_OSRELEASE
, write_osrelease
, print_osrelease
),
1078 FEAT_OPA(HEADER_VERSION
, write_version
, print_version
),
1079 FEAT_OPA(HEADER_ARCH
, write_arch
, print_arch
),
1080 FEAT_OPA(HEADER_NRCPUS
, write_nrcpus
, print_nrcpus
),
1081 FEAT_OPA(HEADER_CPUDESC
, write_cpudesc
, print_cpudesc
),
1082 FEAT_OPA(HEADER_CPUID
, write_cpuid
, print_cpuid
),
1083 FEAT_OPA(HEADER_TOTAL_MEM
, write_total_mem
, print_total_mem
),
1084 FEAT_OPA(HEADER_EVENT_DESC
, write_event_desc
, print_event_desc
),
1085 FEAT_OPA(HEADER_CMDLINE
, write_cmdline
, print_cmdline
),
1086 FEAT_OPF(HEADER_CPU_TOPOLOGY
, write_cpu_topology
, print_cpu_topology
),
1087 FEAT_OPF(HEADER_NUMA_TOPOLOGY
, write_numa_topology
, print_numa_topology
),
1090 struct header_print_data
{
1092 bool full
; /* extended list of headers */
1095 static int perf_file_section__fprintf_info(struct perf_file_section
*section
,
1096 struct perf_header
*ph
,
1097 int feat
, int fd
, void *data
)
1099 struct header_print_data
*hd
= data
;
1101 if (lseek(fd
, section
->offset
, SEEK_SET
) == (off_t
)-1) {
1102 pr_debug("Failed to lseek to %" PRIu64
" offset for feature "
1103 "%d, continuing...\n", section
->offset
, feat
);
1106 if (feat
< HEADER_TRACE_INFO
|| feat
>= HEADER_LAST_FEATURE
) {
1107 pr_warning("unknown feature %d\n", feat
);
1110 if (!feat_ops
[feat
].print
)
1113 if (!feat_ops
[feat
].full_only
|| hd
->full
)
1114 feat_ops
[feat
].print(ph
, fd
, hd
->fp
);
1116 fprintf(hd
->fp
, "# %s info available, use -I to display\n",
1117 feat_ops
[feat
].name
);
1122 int perf_header__fprintf_info(struct perf_session
*session
, FILE *fp
, bool full
)
1124 struct header_print_data hd
;
1125 struct perf_header
*header
= &session
->header
;
1126 int fd
= session
->fd
;
1130 perf_header__process_sections(header
, fd
, &hd
,
1131 perf_file_section__fprintf_info
);
1135 #define dsos__for_each_with_build_id(pos, head) \
1136 list_for_each_entry(pos, head, node) \
1137 if (!pos->has_build_id) \
1141 static int __dsos__write_buildid_table(struct list_head
*head
, pid_t pid
,
1146 dsos__for_each_with_build_id(pos
, head
) {
1148 struct build_id_event b
;
1153 len
= pos
->long_name_len
+ 1;
1154 len
= ALIGN(len
, NAME_ALIGN
);
1155 memset(&b
, 0, sizeof(b
));
1156 memcpy(&b
.build_id
, pos
->build_id
, sizeof(pos
->build_id
));
1158 b
.header
.misc
= misc
;
1159 b
.header
.size
= sizeof(b
) + len
;
1160 err
= do_write(fd
, &b
, sizeof(b
));
1163 err
= write_padded(fd
, pos
->long_name
,
1164 pos
->long_name_len
+ 1, len
);
1172 static int machine__write_buildid_table(struct machine
*machine
, int fd
)
1175 u16 kmisc
= PERF_RECORD_MISC_KERNEL
,
1176 umisc
= PERF_RECORD_MISC_USER
;
1178 if (!machine__is_host(machine
)) {
1179 kmisc
= PERF_RECORD_MISC_GUEST_KERNEL
;
1180 umisc
= PERF_RECORD_MISC_GUEST_USER
;
1183 err
= __dsos__write_buildid_table(&machine
->kernel_dsos
, machine
->pid
,
1186 err
= __dsos__write_buildid_table(&machine
->user_dsos
,
1187 machine
->pid
, umisc
, fd
);
1191 static int dsos__write_buildid_table(struct perf_header
*header
, int fd
)
1193 struct perf_session
*session
= container_of(header
,
1194 struct perf_session
, header
);
1196 int err
= machine__write_buildid_table(&session
->host_machine
, fd
);
1201 for (nd
= rb_first(&session
->machines
); nd
; nd
= rb_next(nd
)) {
1202 struct machine
*pos
= rb_entry(nd
, struct machine
, rb_node
);
1203 err
= machine__write_buildid_table(pos
, fd
);
1210 int build_id_cache__add_s(const char *sbuild_id
, const char *debugdir
,
1211 const char *name
, bool is_kallsyms
)
1213 const size_t size
= PATH_MAX
;
1214 char *realname
, *filename
= zalloc(size
),
1215 *linkname
= zalloc(size
), *targetname
;
1219 if (symbol_conf
.kptr_restrict
) {
1220 pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n");
1223 realname
= (char *)name
;
1225 realname
= realpath(name
, NULL
);
1227 if (realname
== NULL
|| filename
== NULL
|| linkname
== NULL
)
1230 len
= snprintf(filename
, size
, "%s%s%s",
1231 debugdir
, is_kallsyms
? "/" : "", realname
);
1232 if (mkdir_p(filename
, 0755))
1235 snprintf(filename
+ len
, sizeof(filename
) - len
, "/%s", sbuild_id
);
1237 if (access(filename
, F_OK
)) {
1239 if (copyfile("/proc/kallsyms", filename
))
1241 } else if (link(realname
, filename
) && copyfile(name
, filename
))
1245 len
= snprintf(linkname
, size
, "%s/.build-id/%.2s",
1246 debugdir
, sbuild_id
);
1248 if (access(linkname
, X_OK
) && mkdir_p(linkname
, 0755))
1251 snprintf(linkname
+ len
, size
- len
, "/%s", sbuild_id
+ 2);
1252 targetname
= filename
+ strlen(debugdir
) - 5;
1253 memcpy(targetname
, "../..", 5);
1255 if (symlink(targetname
, linkname
) == 0)
1265 static int build_id_cache__add_b(const u8
*build_id
, size_t build_id_size
,
1266 const char *name
, const char *debugdir
,
1269 char sbuild_id
[BUILD_ID_SIZE
* 2 + 1];
1271 build_id__sprintf(build_id
, build_id_size
, sbuild_id
);
1273 return build_id_cache__add_s(sbuild_id
, debugdir
, name
, is_kallsyms
);
1276 int build_id_cache__remove_s(const char *sbuild_id
, const char *debugdir
)
1278 const size_t size
= PATH_MAX
;
1279 char *filename
= zalloc(size
),
1280 *linkname
= zalloc(size
);
1283 if (filename
== NULL
|| linkname
== NULL
)
1286 snprintf(linkname
, size
, "%s/.build-id/%.2s/%s",
1287 debugdir
, sbuild_id
, sbuild_id
+ 2);
1289 if (access(linkname
, F_OK
))
1292 if (readlink(linkname
, filename
, size
- 1) < 0)
1295 if (unlink(linkname
))
1299 * Since the link is relative, we must make it absolute:
1301 snprintf(linkname
, size
, "%s/.build-id/%.2s/%s",
1302 debugdir
, sbuild_id
, filename
);
1304 if (unlink(linkname
))
1314 static int dso__cache_build_id(struct dso
*dso
, const char *debugdir
)
1316 bool is_kallsyms
= dso
->kernel
&& dso
->long_name
[0] != '/';
1318 return build_id_cache__add_b(dso
->build_id
, sizeof(dso
->build_id
),
1319 dso
->long_name
, debugdir
, is_kallsyms
);
1322 static int __dsos__cache_build_ids(struct list_head
*head
, const char *debugdir
)
1327 dsos__for_each_with_build_id(pos
, head
)
1328 if (dso__cache_build_id(pos
, debugdir
))
1334 static int machine__cache_build_ids(struct machine
*machine
, const char *debugdir
)
1336 int ret
= __dsos__cache_build_ids(&machine
->kernel_dsos
, debugdir
);
1337 ret
|= __dsos__cache_build_ids(&machine
->user_dsos
, debugdir
);
1341 static int perf_session__cache_build_ids(struct perf_session
*session
)
1345 char debugdir
[PATH_MAX
];
1347 snprintf(debugdir
, sizeof(debugdir
), "%s", buildid_dir
);
1349 if (mkdir(debugdir
, 0755) != 0 && errno
!= EEXIST
)
1352 ret
= machine__cache_build_ids(&session
->host_machine
, debugdir
);
1354 for (nd
= rb_first(&session
->machines
); nd
; nd
= rb_next(nd
)) {
1355 struct machine
*pos
= rb_entry(nd
, struct machine
, rb_node
);
1356 ret
|= machine__cache_build_ids(pos
, debugdir
);
1358 return ret
? -1 : 0;
1361 static bool machine__read_build_ids(struct machine
*machine
, bool with_hits
)
1363 bool ret
= __dsos__read_build_ids(&machine
->kernel_dsos
, with_hits
);
1364 ret
|= __dsos__read_build_ids(&machine
->user_dsos
, with_hits
);
1368 static bool perf_session__read_build_ids(struct perf_session
*session
, bool with_hits
)
1371 bool ret
= machine__read_build_ids(&session
->host_machine
, with_hits
);
1373 for (nd
= rb_first(&session
->machines
); nd
; nd
= rb_next(nd
)) {
1374 struct machine
*pos
= rb_entry(nd
, struct machine
, rb_node
);
1375 ret
|= machine__read_build_ids(pos
, with_hits
);
1381 static int do_write_feat(int fd
, struct perf_header
*h
, int type
,
1382 struct perf_file_section
**p
,
1383 struct perf_evlist
*evlist
)
1388 if (perf_header__has_feat(h
, type
)) {
1390 (*p
)->offset
= lseek(fd
, 0, SEEK_CUR
);
1392 err
= feat_ops
[type
].write(fd
, h
, evlist
);
1394 pr_debug("failed to write feature %d\n", type
);
1396 /* undo anything written */
1397 lseek(fd
, (*p
)->offset
, SEEK_SET
);
1401 (*p
)->size
= lseek(fd
, 0, SEEK_CUR
) - (*p
)->offset
;
1407 static int perf_header__adds_write(struct perf_header
*header
,
1408 struct perf_evlist
*evlist
, int fd
)
1411 struct perf_session
*session
;
1412 struct perf_file_section
*feat_sec
, *p
;
1417 session
= container_of(header
, struct perf_session
, header
);
1419 if (perf_header__has_feat(header
, HEADER_BUILD_ID
&&
1420 !perf_session__read_build_ids(session
, true)))
1421 perf_header__clear_feat(header
, HEADER_BUILD_ID
);
1423 nr_sections
= bitmap_weight(header
->adds_features
, HEADER_FEAT_BITS
);
1427 feat_sec
= p
= calloc(sizeof(*feat_sec
), nr_sections
);
1428 if (feat_sec
== NULL
)
1431 sec_size
= sizeof(*feat_sec
) * nr_sections
;
1433 sec_start
= header
->data_offset
+ header
->data_size
;
1434 lseek(fd
, sec_start
+ sec_size
, SEEK_SET
);
1436 err
= do_write_feat(fd
, header
, HEADER_TRACE_INFO
, &p
, evlist
);
1440 err
= do_write_feat(fd
, header
, HEADER_BUILD_ID
, &p
, evlist
);
1442 perf_header__clear_feat(header
, HEADER_BUILD_ID
);
1446 err
= do_write_feat(fd
, header
, HEADER_HOSTNAME
, &p
, evlist
);
1448 perf_header__clear_feat(header
, HEADER_HOSTNAME
);
1450 err
= do_write_feat(fd
, header
, HEADER_OSRELEASE
, &p
, evlist
);
1452 perf_header__clear_feat(header
, HEADER_OSRELEASE
);
1454 err
= do_write_feat(fd
, header
, HEADER_VERSION
, &p
, evlist
);
1456 perf_header__clear_feat(header
, HEADER_VERSION
);
1458 err
= do_write_feat(fd
, header
, HEADER_ARCH
, &p
, evlist
);
1460 perf_header__clear_feat(header
, HEADER_ARCH
);
1462 err
= do_write_feat(fd
, header
, HEADER_NRCPUS
, &p
, evlist
);
1464 perf_header__clear_feat(header
, HEADER_NRCPUS
);
1466 err
= do_write_feat(fd
, header
, HEADER_CPUDESC
, &p
, evlist
);
1468 perf_header__clear_feat(header
, HEADER_CPUDESC
);
1470 err
= do_write_feat(fd
, header
, HEADER_CPUID
, &p
, evlist
);
1472 perf_header__clear_feat(header
, HEADER_CPUID
);
1474 err
= do_write_feat(fd
, header
, HEADER_TOTAL_MEM
, &p
, evlist
);
1476 perf_header__clear_feat(header
, HEADER_TOTAL_MEM
);
1478 err
= do_write_feat(fd
, header
, HEADER_CMDLINE
, &p
, evlist
);
1480 perf_header__clear_feat(header
, HEADER_CMDLINE
);
1482 err
= do_write_feat(fd
, header
, HEADER_EVENT_DESC
, &p
, evlist
);
1484 perf_header__clear_feat(header
, HEADER_EVENT_DESC
);
1486 err
= do_write_feat(fd
, header
, HEADER_CPU_TOPOLOGY
, &p
, evlist
);
1488 perf_header__clear_feat(header
, HEADER_CPU_TOPOLOGY
);
1490 err
= do_write_feat(fd
, header
, HEADER_NUMA_TOPOLOGY
, &p
, evlist
);
1492 perf_header__clear_feat(header
, HEADER_NUMA_TOPOLOGY
);
1494 lseek(fd
, sec_start
, SEEK_SET
);
1496 * may write more than needed due to dropped feature, but
1497 * this is okay, reader will skip the mising entries
1499 err
= do_write(fd
, feat_sec
, sec_size
);
1501 pr_debug("failed to write feature section\n");
1507 int perf_header__write_pipe(int fd
)
1509 struct perf_pipe_file_header f_header
;
1512 f_header
= (struct perf_pipe_file_header
){
1513 .magic
= PERF_MAGIC
,
1514 .size
= sizeof(f_header
),
1517 err
= do_write(fd
, &f_header
, sizeof(f_header
));
1519 pr_debug("failed to write perf pipe header\n");
1526 int perf_session__write_header(struct perf_session
*session
,
1527 struct perf_evlist
*evlist
,
1528 int fd
, bool at_exit
)
1530 struct perf_file_header f_header
;
1531 struct perf_file_attr f_attr
;
1532 struct perf_header
*header
= &session
->header
;
1533 struct perf_evsel
*attr
, *pair
= NULL
;
1536 lseek(fd
, sizeof(f_header
), SEEK_SET
);
1538 if (session
->evlist
!= evlist
)
1539 pair
= list_entry(session
->evlist
->entries
.next
, struct perf_evsel
, node
);
1541 list_for_each_entry(attr
, &evlist
->entries
, node
) {
1542 attr
->id_offset
= lseek(fd
, 0, SEEK_CUR
);
1543 err
= do_write(fd
, attr
->id
, attr
->ids
* sizeof(u64
));
1546 pr_debug("failed to write perf header\n");
1549 if (session
->evlist
!= evlist
) {
1550 err
= do_write(fd
, pair
->id
, pair
->ids
* sizeof(u64
));
1553 attr
->ids
+= pair
->ids
;
1554 pair
= list_entry(pair
->node
.next
, struct perf_evsel
, node
);
1558 header
->attr_offset
= lseek(fd
, 0, SEEK_CUR
);
1560 list_for_each_entry(attr
, &evlist
->entries
, node
) {
1561 f_attr
= (struct perf_file_attr
){
1564 .offset
= attr
->id_offset
,
1565 .size
= attr
->ids
* sizeof(u64
),
1568 err
= do_write(fd
, &f_attr
, sizeof(f_attr
));
1570 pr_debug("failed to write perf header attribute\n");
1575 header
->event_offset
= lseek(fd
, 0, SEEK_CUR
);
1576 header
->event_size
= event_count
* sizeof(struct perf_trace_event_type
);
1578 err
= do_write(fd
, events
, header
->event_size
);
1580 pr_debug("failed to write perf header events\n");
1585 header
->data_offset
= lseek(fd
, 0, SEEK_CUR
);
1588 err
= perf_header__adds_write(header
, evlist
, fd
);
1593 f_header
= (struct perf_file_header
){
1594 .magic
= PERF_MAGIC
,
1595 .size
= sizeof(f_header
),
1596 .attr_size
= sizeof(f_attr
),
1598 .offset
= header
->attr_offset
,
1599 .size
= evlist
->nr_entries
* sizeof(f_attr
),
1602 .offset
= header
->data_offset
,
1603 .size
= header
->data_size
,
1606 .offset
= header
->event_offset
,
1607 .size
= header
->event_size
,
1611 memcpy(&f_header
.adds_features
, &header
->adds_features
, sizeof(header
->adds_features
));
1613 lseek(fd
, 0, SEEK_SET
);
1614 err
= do_write(fd
, &f_header
, sizeof(f_header
));
1616 pr_debug("failed to write perf header\n");
1619 lseek(fd
, header
->data_offset
+ header
->data_size
, SEEK_SET
);
1625 static int perf_header__getbuffer64(struct perf_header
*header
,
1626 int fd
, void *buf
, size_t size
)
1628 if (readn(fd
, buf
, size
) <= 0)
1631 if (header
->needs_swap
)
1632 mem_bswap_64(buf
, size
);
1637 int perf_header__process_sections(struct perf_header
*header
, int fd
,
1639 int (*process
)(struct perf_file_section
*section
,
1640 struct perf_header
*ph
,
1641 int feat
, int fd
, void *data
))
1643 struct perf_file_section
*feat_sec
;
1647 int err
= -1, feat
= 1;
1649 nr_sections
= bitmap_weight(header
->adds_features
, HEADER_FEAT_BITS
);
1653 feat_sec
= calloc(sizeof(*feat_sec
), nr_sections
);
1657 sec_size
= sizeof(*feat_sec
) * nr_sections
;
1659 lseek(fd
, header
->data_offset
+ header
->data_size
, SEEK_SET
);
1661 if (perf_header__getbuffer64(header
, fd
, feat_sec
, sec_size
))
1665 while (idx
< nr_sections
&& feat
< HEADER_LAST_FEATURE
) {
1666 if (perf_header__has_feat(header
, feat
)) {
1667 struct perf_file_section
*sec
= &feat_sec
[idx
++];
1669 err
= process(sec
, header
, feat
, fd
, data
);
1680 int perf_file_header__read(struct perf_file_header
*header
,
1681 struct perf_header
*ph
, int fd
)
1683 lseek(fd
, 0, SEEK_SET
);
1685 if (readn(fd
, header
, sizeof(*header
)) <= 0 ||
1686 memcmp(&header
->magic
, __perf_magic
, sizeof(header
->magic
)))
1689 if (header
->attr_size
!= sizeof(struct perf_file_attr
)) {
1690 u64 attr_size
= bswap_64(header
->attr_size
);
1692 if (attr_size
!= sizeof(struct perf_file_attr
))
1695 mem_bswap_64(header
, offsetof(struct perf_file_header
,
1697 ph
->needs_swap
= true;
1700 if (header
->size
!= sizeof(*header
)) {
1701 /* Support the previous format */
1702 if (header
->size
== offsetof(typeof(*header
), adds_features
))
1703 bitmap_zero(header
->adds_features
, HEADER_FEAT_BITS
);
1708 memcpy(&ph
->adds_features
, &header
->adds_features
,
1709 sizeof(ph
->adds_features
));
1711 * FIXME: hack that assumes that if we need swap the perf.data file
1712 * may be coming from an arch with a different word-size, ergo different
1713 * DEFINE_BITMAP format, investigate more later, but for now its mostly
1714 * safe to assume that we have a build-id section. Trace files probably
1715 * have several other issues in this realm anyway...
1717 if (ph
->needs_swap
) {
1718 memset(&ph
->adds_features
, 0, sizeof(ph
->adds_features
));
1719 perf_header__set_feat(ph
, HEADER_BUILD_ID
);
1722 ph
->event_offset
= header
->event_types
.offset
;
1723 ph
->event_size
= header
->event_types
.size
;
1724 ph
->data_offset
= header
->data
.offset
;
1725 ph
->data_size
= header
->data
.size
;
1729 static int __event_process_build_id(struct build_id_event
*bev
,
1731 struct perf_session
*session
)
1734 struct list_head
*head
;
1735 struct machine
*machine
;
1738 enum dso_kernel_type dso_type
;
1740 machine
= perf_session__findnew_machine(session
, bev
->pid
);
1744 misc
= bev
->header
.misc
& PERF_RECORD_MISC_CPUMODE_MASK
;
1747 case PERF_RECORD_MISC_KERNEL
:
1748 dso_type
= DSO_TYPE_KERNEL
;
1749 head
= &machine
->kernel_dsos
;
1751 case PERF_RECORD_MISC_GUEST_KERNEL
:
1752 dso_type
= DSO_TYPE_GUEST_KERNEL
;
1753 head
= &machine
->kernel_dsos
;
1755 case PERF_RECORD_MISC_USER
:
1756 case PERF_RECORD_MISC_GUEST_USER
:
1757 dso_type
= DSO_TYPE_USER
;
1758 head
= &machine
->user_dsos
;
1764 dso
= __dsos__findnew(head
, filename
);
1766 char sbuild_id
[BUILD_ID_SIZE
* 2 + 1];
1768 dso__set_build_id(dso
, &bev
->build_id
);
1770 if (filename
[0] == '[')
1771 dso
->kernel
= dso_type
;
1773 build_id__sprintf(dso
->build_id
, sizeof(dso
->build_id
),
1775 pr_debug("build id event received for %s: %s\n",
1776 dso
->long_name
, sbuild_id
);
1784 static int perf_header__read_build_ids_abi_quirk(struct perf_header
*header
,
1785 int input
, u64 offset
, u64 size
)
1787 struct perf_session
*session
= container_of(header
, struct perf_session
, header
);
1789 struct perf_event_header header
;
1790 u8 build_id
[ALIGN(BUILD_ID_SIZE
, sizeof(u64
))];
1793 struct build_id_event bev
;
1794 char filename
[PATH_MAX
];
1795 u64 limit
= offset
+ size
;
1797 while (offset
< limit
) {
1800 if (read(input
, &old_bev
, sizeof(old_bev
)) != sizeof(old_bev
))
1803 if (header
->needs_swap
)
1804 perf_event_header__bswap(&old_bev
.header
);
1806 len
= old_bev
.header
.size
- sizeof(old_bev
);
1807 if (read(input
, filename
, len
) != len
)
1810 bev
.header
= old_bev
.header
;
1813 * As the pid is the missing value, we need to fill
1814 * it properly. The header.misc value give us nice hint.
1816 bev
.pid
= HOST_KERNEL_ID
;
1817 if (bev
.header
.misc
== PERF_RECORD_MISC_GUEST_USER
||
1818 bev
.header
.misc
== PERF_RECORD_MISC_GUEST_KERNEL
)
1819 bev
.pid
= DEFAULT_GUEST_KERNEL_ID
;
1821 memcpy(bev
.build_id
, old_bev
.build_id
, sizeof(bev
.build_id
));
1822 __event_process_build_id(&bev
, filename
, session
);
1824 offset
+= bev
.header
.size
;
1830 static int perf_header__read_build_ids(struct perf_header
*header
,
1831 int input
, u64 offset
, u64 size
)
1833 struct perf_session
*session
= container_of(header
, struct perf_session
, header
);
1834 struct build_id_event bev
;
1835 char filename
[PATH_MAX
];
1836 u64 limit
= offset
+ size
, orig_offset
= offset
;
1839 while (offset
< limit
) {
1842 if (read(input
, &bev
, sizeof(bev
)) != sizeof(bev
))
1845 if (header
->needs_swap
)
1846 perf_event_header__bswap(&bev
.header
);
1848 len
= bev
.header
.size
- sizeof(bev
);
1849 if (read(input
, filename
, len
) != len
)
1852 * The a1645ce1 changeset:
1854 * "perf: 'perf kvm' tool for monitoring guest performance from host"
1856 * Added a field to struct build_id_event that broke the file
1859 * Since the kernel build-id is the first entry, process the
1860 * table using the old format if the well known
1861 * '[kernel.kallsyms]' string for the kernel build-id has the
1862 * first 4 characters chopped off (where the pid_t sits).
1864 if (memcmp(filename
, "nel.kallsyms]", 13) == 0) {
1865 if (lseek(input
, orig_offset
, SEEK_SET
) == (off_t
)-1)
1867 return perf_header__read_build_ids_abi_quirk(header
, input
, offset
, size
);
1870 __event_process_build_id(&bev
, filename
, session
);
1872 offset
+= bev
.header
.size
;
1879 static int perf_file_section__process(struct perf_file_section
*section
,
1880 struct perf_header
*ph
,
1881 int feat
, int fd
, void *data __used
)
1883 if (lseek(fd
, section
->offset
, SEEK_SET
) == (off_t
)-1) {
1884 pr_debug("Failed to lseek to %" PRIu64
" offset for feature "
1885 "%d, continuing...\n", section
->offset
, feat
);
1890 case HEADER_TRACE_INFO
:
1891 trace_report(fd
, false);
1894 case HEADER_BUILD_ID
:
1895 if (perf_header__read_build_ids(ph
, fd
, section
->offset
, section
->size
))
1896 pr_debug("Failed to read buildids, continuing...\n");
1899 pr_debug("unknown feature %d, continuing...\n", feat
);
1905 static int perf_file_header__read_pipe(struct perf_pipe_file_header
*header
,
1906 struct perf_header
*ph
, int fd
,
1909 if (readn(fd
, header
, sizeof(*header
)) <= 0 ||
1910 memcmp(&header
->magic
, __perf_magic
, sizeof(header
->magic
)))
1913 if (repipe
&& do_write(STDOUT_FILENO
, header
, sizeof(*header
)) < 0)
1916 if (header
->size
!= sizeof(*header
)) {
1917 u64 size
= bswap_64(header
->size
);
1919 if (size
!= sizeof(*header
))
1922 ph
->needs_swap
= true;
1928 static int perf_header__read_pipe(struct perf_session
*session
, int fd
)
1930 struct perf_header
*header
= &session
->header
;
1931 struct perf_pipe_file_header f_header
;
1933 if (perf_file_header__read_pipe(&f_header
, header
, fd
,
1934 session
->repipe
) < 0) {
1935 pr_debug("incompatible file format\n");
1944 int perf_session__read_header(struct perf_session
*session
, int fd
)
1946 struct perf_header
*header
= &session
->header
;
1947 struct perf_file_header f_header
;
1948 struct perf_file_attr f_attr
;
1950 int nr_attrs
, nr_ids
, i
, j
;
1952 session
->evlist
= perf_evlist__new(NULL
, NULL
);
1953 if (session
->evlist
== NULL
)
1956 if (session
->fd_pipe
)
1957 return perf_header__read_pipe(session
, fd
);
1959 if (perf_file_header__read(&f_header
, header
, fd
) < 0) {
1960 pr_debug("incompatible file format\n");
1964 nr_attrs
= f_header
.attrs
.size
/ sizeof(f_attr
);
1965 lseek(fd
, f_header
.attrs
.offset
, SEEK_SET
);
1967 for (i
= 0; i
< nr_attrs
; i
++) {
1968 struct perf_evsel
*evsel
;
1971 if (readn(fd
, &f_attr
, sizeof(f_attr
)) <= 0)
1974 if (header
->needs_swap
)
1975 perf_event__attr_swap(&f_attr
.attr
);
1977 tmp
= lseek(fd
, 0, SEEK_CUR
);
1978 evsel
= perf_evsel__new(&f_attr
.attr
, i
);
1981 goto out_delete_evlist
;
1983 * Do it before so that if perf_evsel__alloc_id fails, this
1984 * entry gets purged too at perf_evlist__delete().
1986 perf_evlist__add(session
->evlist
, evsel
);
1988 nr_ids
= f_attr
.ids
.size
/ sizeof(u64
);
1990 * We don't have the cpu and thread maps on the header, so
1991 * for allocating the perf_sample_id table we fake 1 cpu and
1992 * hattr->ids threads.
1994 if (perf_evsel__alloc_id(evsel
, 1, nr_ids
))
1995 goto out_delete_evlist
;
1997 lseek(fd
, f_attr
.ids
.offset
, SEEK_SET
);
1999 for (j
= 0; j
< nr_ids
; j
++) {
2000 if (perf_header__getbuffer64(header
, fd
, &f_id
, sizeof(f_id
)))
2003 perf_evlist__id_add(session
->evlist
, evsel
, 0, j
, f_id
);
2006 lseek(fd
, tmp
, SEEK_SET
);
2009 if (f_header
.event_types
.size
) {
2010 lseek(fd
, f_header
.event_types
.offset
, SEEK_SET
);
2011 events
= malloc(f_header
.event_types
.size
);
2014 if (perf_header__getbuffer64(header
, fd
, events
,
2015 f_header
.event_types
.size
))
2017 event_count
= f_header
.event_types
.size
/ sizeof(struct perf_trace_event_type
);
2020 perf_header__process_sections(header
, fd
, NULL
,
2021 perf_file_section__process
);
2023 lseek(fd
, header
->data_offset
, SEEK_SET
);
2031 perf_evlist__delete(session
->evlist
);
2032 session
->evlist
= NULL
;
2036 int perf_event__synthesize_attr(struct perf_event_attr
*attr
, u16 ids
, u64
*id
,
2037 perf_event__handler_t process
,
2038 struct perf_session
*session
)
2040 union perf_event
*ev
;
2044 size
= sizeof(struct perf_event_attr
);
2045 size
= ALIGN(size
, sizeof(u64
));
2046 size
+= sizeof(struct perf_event_header
);
2047 size
+= ids
* sizeof(u64
);
2054 ev
->attr
.attr
= *attr
;
2055 memcpy(ev
->attr
.id
, id
, ids
* sizeof(u64
));
2057 ev
->attr
.header
.type
= PERF_RECORD_HEADER_ATTR
;
2058 ev
->attr
.header
.size
= size
;
2060 err
= process(ev
, NULL
, session
);
2067 int perf_session__synthesize_attrs(struct perf_session
*session
,
2068 perf_event__handler_t process
)
2070 struct perf_evsel
*attr
;
2073 list_for_each_entry(attr
, &session
->evlist
->entries
, node
) {
2074 err
= perf_event__synthesize_attr(&attr
->attr
, attr
->ids
,
2075 attr
->id
, process
, session
);
2077 pr_debug("failed to create perf header attribute\n");
2085 int perf_event__process_attr(union perf_event
*event
,
2086 struct perf_session
*session
)
2088 unsigned int i
, ids
, n_ids
;
2089 struct perf_evsel
*evsel
;
2091 if (session
->evlist
== NULL
) {
2092 session
->evlist
= perf_evlist__new(NULL
, NULL
);
2093 if (session
->evlist
== NULL
)
2097 evsel
= perf_evsel__new(&event
->attr
.attr
,
2098 session
->evlist
->nr_entries
);
2102 perf_evlist__add(session
->evlist
, evsel
);
2104 ids
= event
->header
.size
;
2105 ids
-= (void *)&event
->attr
.id
- (void *)event
;
2106 n_ids
= ids
/ sizeof(u64
);
2108 * We don't have the cpu and thread maps on the header, so
2109 * for allocating the perf_sample_id table we fake 1 cpu and
2110 * hattr->ids threads.
2112 if (perf_evsel__alloc_id(evsel
, 1, n_ids
))
2115 for (i
= 0; i
< n_ids
; i
++) {
2116 perf_evlist__id_add(session
->evlist
, evsel
, 0, i
,
2120 perf_session__update_sample_type(session
);
2125 int perf_event__synthesize_event_type(u64 event_id
, char *name
,
2126 perf_event__handler_t process
,
2127 struct perf_session
*session
)
2129 union perf_event ev
;
2133 memset(&ev
, 0, sizeof(ev
));
2135 ev
.event_type
.event_type
.event_id
= event_id
;
2136 memset(ev
.event_type
.event_type
.name
, 0, MAX_EVENT_NAME
);
2137 strncpy(ev
.event_type
.event_type
.name
, name
, MAX_EVENT_NAME
- 1);
2139 ev
.event_type
.header
.type
= PERF_RECORD_HEADER_EVENT_TYPE
;
2140 size
= strlen(name
);
2141 size
= ALIGN(size
, sizeof(u64
));
2142 ev
.event_type
.header
.size
= sizeof(ev
.event_type
) -
2143 (sizeof(ev
.event_type
.event_type
.name
) - size
);
2145 err
= process(&ev
, NULL
, session
);
2150 int perf_event__synthesize_event_types(perf_event__handler_t process
,
2151 struct perf_session
*session
)
2153 struct perf_trace_event_type
*type
;
2156 for (i
= 0; i
< event_count
; i
++) {
2159 err
= perf_event__synthesize_event_type(type
->event_id
,
2160 type
->name
, process
,
2163 pr_debug("failed to create perf header event type\n");
2171 int perf_event__process_event_type(union perf_event
*event
,
2172 struct perf_session
*session __unused
)
2174 if (perf_header__push_event(event
->event_type
.event_type
.event_id
,
2175 event
->event_type
.event_type
.name
) < 0)
2181 int perf_event__synthesize_tracing_data(int fd
, struct perf_evlist
*evlist
,
2182 perf_event__handler_t process
,
2183 struct perf_session
*session __unused
)
2185 union perf_event ev
;
2186 ssize_t size
= 0, aligned_size
= 0, padding
;
2189 memset(&ev
, 0, sizeof(ev
));
2191 ev
.tracing_data
.header
.type
= PERF_RECORD_HEADER_TRACING_DATA
;
2192 size
= read_tracing_data_size(fd
, &evlist
->entries
);
2195 aligned_size
= ALIGN(size
, sizeof(u64
));
2196 padding
= aligned_size
- size
;
2197 ev
.tracing_data
.header
.size
= sizeof(ev
.tracing_data
);
2198 ev
.tracing_data
.size
= aligned_size
;
2200 process(&ev
, NULL
, session
);
2202 err
= read_tracing_data(fd
, &evlist
->entries
);
2203 write_padded(fd
, NULL
, 0, padding
);
2205 return aligned_size
;
2208 int perf_event__process_tracing_data(union perf_event
*event
,
2209 struct perf_session
*session
)
2211 ssize_t size_read
, padding
, size
= event
->tracing_data
.size
;
2212 off_t offset
= lseek(session
->fd
, 0, SEEK_CUR
);
2215 /* setup for reading amidst mmap */
2216 lseek(session
->fd
, offset
+ sizeof(struct tracing_data_event
),
2219 size_read
= trace_report(session
->fd
, session
->repipe
);
2221 padding
= ALIGN(size_read
, sizeof(u64
)) - size_read
;
2223 if (read(session
->fd
, buf
, padding
) < 0)
2224 die("reading input file");
2225 if (session
->repipe
) {
2226 int retw
= write(STDOUT_FILENO
, buf
, padding
);
2227 if (retw
<= 0 || retw
!= padding
)
2228 die("repiping tracing data padding");
2231 if (size_read
+ padding
!= size
)
2232 die("tracing data size mismatch");
2234 return size_read
+ padding
;
2237 int perf_event__synthesize_build_id(struct dso
*pos
, u16 misc
,
2238 perf_event__handler_t process
,
2239 struct machine
*machine
,
2240 struct perf_session
*session
)
2242 union perf_event ev
;
2249 memset(&ev
, 0, sizeof(ev
));
2251 len
= pos
->long_name_len
+ 1;
2252 len
= ALIGN(len
, NAME_ALIGN
);
2253 memcpy(&ev
.build_id
.build_id
, pos
->build_id
, sizeof(pos
->build_id
));
2254 ev
.build_id
.header
.type
= PERF_RECORD_HEADER_BUILD_ID
;
2255 ev
.build_id
.header
.misc
= misc
;
2256 ev
.build_id
.pid
= machine
->pid
;
2257 ev
.build_id
.header
.size
= sizeof(ev
.build_id
) + len
;
2258 memcpy(&ev
.build_id
.filename
, pos
->long_name
, pos
->long_name_len
);
2260 err
= process(&ev
, NULL
, session
);
2265 int perf_event__process_build_id(union perf_event
*event
,
2266 struct perf_session
*session
)
2268 __event_process_build_id(&event
->build_id
,
2269 event
->build_id
.filename
,
2274 void disable_buildid_cache(void)
2276 no_buildid_cache
= true;