1 #define _FILE_OFFSET_BITS 64
9 #include <linux/list.h>
10 #include <linux/kernel.h>
11 #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
);
1706 } else if (ph
->needs_swap
) {
1709 * feature bitmap is declared as an array of unsigned longs --
1710 * not good since its size can differ between the host that
1711 * generated the data file and the host analyzing the file.
1713 * We need to handle endianness, but we don't know the size of
1714 * the unsigned long where the file was generated. Take a best
1715 * guess at determining it: try 64-bit swap first (ie., file
1716 * created on a 64-bit host), and check if the hostname feature
1717 * bit is set (this feature bit is forced on as of fbe96f2).
1718 * If the bit is not, undo the 64-bit swap and try a 32-bit
1719 * swap. If the hostname bit is still not set (e.g., older data
1720 * file), punt and fallback to the original behavior --
1721 * clearing all feature bits and setting buildid.
1723 for (i
= 0; i
< BITS_TO_LONGS(HEADER_FEAT_BITS
); ++i
)
1724 header
->adds_features
[i
] = bswap_64(header
->adds_features
[i
]);
1726 if (!test_bit(HEADER_HOSTNAME
, header
->adds_features
)) {
1727 for (i
= 0; i
< BITS_TO_LONGS(HEADER_FEAT_BITS
); ++i
) {
1728 header
->adds_features
[i
] = bswap_64(header
->adds_features
[i
]);
1729 header
->adds_features
[i
] = bswap_32(header
->adds_features
[i
]);
1733 if (!test_bit(HEADER_HOSTNAME
, header
->adds_features
)) {
1734 bitmap_zero(header
->adds_features
, HEADER_FEAT_BITS
);
1735 set_bit(HEADER_BUILD_ID
, header
->adds_features
);
1739 memcpy(&ph
->adds_features
, &header
->adds_features
,
1740 sizeof(ph
->adds_features
));
1742 ph
->event_offset
= header
->event_types
.offset
;
1743 ph
->event_size
= header
->event_types
.size
;
1744 ph
->data_offset
= header
->data
.offset
;
1745 ph
->data_size
= header
->data
.size
;
1749 static int __event_process_build_id(struct build_id_event
*bev
,
1751 struct perf_session
*session
)
1754 struct list_head
*head
;
1755 struct machine
*machine
;
1758 enum dso_kernel_type dso_type
;
1760 machine
= perf_session__findnew_machine(session
, bev
->pid
);
1764 misc
= bev
->header
.misc
& PERF_RECORD_MISC_CPUMODE_MASK
;
1767 case PERF_RECORD_MISC_KERNEL
:
1768 dso_type
= DSO_TYPE_KERNEL
;
1769 head
= &machine
->kernel_dsos
;
1771 case PERF_RECORD_MISC_GUEST_KERNEL
:
1772 dso_type
= DSO_TYPE_GUEST_KERNEL
;
1773 head
= &machine
->kernel_dsos
;
1775 case PERF_RECORD_MISC_USER
:
1776 case PERF_RECORD_MISC_GUEST_USER
:
1777 dso_type
= DSO_TYPE_USER
;
1778 head
= &machine
->user_dsos
;
1784 dso
= __dsos__findnew(head
, filename
);
1786 char sbuild_id
[BUILD_ID_SIZE
* 2 + 1];
1788 dso__set_build_id(dso
, &bev
->build_id
);
1790 if (filename
[0] == '[')
1791 dso
->kernel
= dso_type
;
1793 build_id__sprintf(dso
->build_id
, sizeof(dso
->build_id
),
1795 pr_debug("build id event received for %s: %s\n",
1796 dso
->long_name
, sbuild_id
);
1804 static int perf_header__read_build_ids_abi_quirk(struct perf_header
*header
,
1805 int input
, u64 offset
, u64 size
)
1807 struct perf_session
*session
= container_of(header
, struct perf_session
, header
);
1809 struct perf_event_header header
;
1810 u8 build_id
[ALIGN(BUILD_ID_SIZE
, sizeof(u64
))];
1813 struct build_id_event bev
;
1814 char filename
[PATH_MAX
];
1815 u64 limit
= offset
+ size
;
1817 while (offset
< limit
) {
1820 if (read(input
, &old_bev
, sizeof(old_bev
)) != sizeof(old_bev
))
1823 if (header
->needs_swap
)
1824 perf_event_header__bswap(&old_bev
.header
);
1826 len
= old_bev
.header
.size
- sizeof(old_bev
);
1827 if (read(input
, filename
, len
) != len
)
1830 bev
.header
= old_bev
.header
;
1833 * As the pid is the missing value, we need to fill
1834 * it properly. The header.misc value give us nice hint.
1836 bev
.pid
= HOST_KERNEL_ID
;
1837 if (bev
.header
.misc
== PERF_RECORD_MISC_GUEST_USER
||
1838 bev
.header
.misc
== PERF_RECORD_MISC_GUEST_KERNEL
)
1839 bev
.pid
= DEFAULT_GUEST_KERNEL_ID
;
1841 memcpy(bev
.build_id
, old_bev
.build_id
, sizeof(bev
.build_id
));
1842 __event_process_build_id(&bev
, filename
, session
);
1844 offset
+= bev
.header
.size
;
1850 static int perf_header__read_build_ids(struct perf_header
*header
,
1851 int input
, u64 offset
, u64 size
)
1853 struct perf_session
*session
= container_of(header
, struct perf_session
, header
);
1854 struct build_id_event bev
;
1855 char filename
[PATH_MAX
];
1856 u64 limit
= offset
+ size
, orig_offset
= offset
;
1859 while (offset
< limit
) {
1862 if (read(input
, &bev
, sizeof(bev
)) != sizeof(bev
))
1865 if (header
->needs_swap
)
1866 perf_event_header__bswap(&bev
.header
);
1868 len
= bev
.header
.size
- sizeof(bev
);
1869 if (read(input
, filename
, len
) != len
)
1872 * The a1645ce1 changeset:
1874 * "perf: 'perf kvm' tool for monitoring guest performance from host"
1876 * Added a field to struct build_id_event that broke the file
1879 * Since the kernel build-id is the first entry, process the
1880 * table using the old format if the well known
1881 * '[kernel.kallsyms]' string for the kernel build-id has the
1882 * first 4 characters chopped off (where the pid_t sits).
1884 if (memcmp(filename
, "nel.kallsyms]", 13) == 0) {
1885 if (lseek(input
, orig_offset
, SEEK_SET
) == (off_t
)-1)
1887 return perf_header__read_build_ids_abi_quirk(header
, input
, offset
, size
);
1890 __event_process_build_id(&bev
, filename
, session
);
1892 offset
+= bev
.header
.size
;
1899 static int perf_file_section__process(struct perf_file_section
*section
,
1900 struct perf_header
*ph
,
1901 int feat
, int fd
, void *data __used
)
1903 if (lseek(fd
, section
->offset
, SEEK_SET
) == (off_t
)-1) {
1904 pr_debug("Failed to lseek to %" PRIu64
" offset for feature "
1905 "%d, continuing...\n", section
->offset
, feat
);
1910 case HEADER_TRACE_INFO
:
1911 trace_report(fd
, false);
1914 case HEADER_BUILD_ID
:
1915 if (perf_header__read_build_ids(ph
, fd
, section
->offset
, section
->size
))
1916 pr_debug("Failed to read buildids, continuing...\n");
1919 case HEADER_HOSTNAME
:
1920 case HEADER_OSRELEASE
:
1921 case HEADER_VERSION
:
1924 case HEADER_CPUDESC
:
1926 case HEADER_TOTAL_MEM
:
1927 case HEADER_CMDLINE
:
1928 case HEADER_EVENT_DESC
:
1929 case HEADER_CPU_TOPOLOGY
:
1930 case HEADER_NUMA_TOPOLOGY
:
1934 pr_debug("unknown feature %d, continuing...\n", feat
);
1940 static int perf_file_header__read_pipe(struct perf_pipe_file_header
*header
,
1941 struct perf_header
*ph
, int fd
,
1944 if (readn(fd
, header
, sizeof(*header
)) <= 0 ||
1945 memcmp(&header
->magic
, __perf_magic
, sizeof(header
->magic
)))
1948 if (repipe
&& do_write(STDOUT_FILENO
, header
, sizeof(*header
)) < 0)
1951 if (header
->size
!= sizeof(*header
)) {
1952 u64 size
= bswap_64(header
->size
);
1954 if (size
!= sizeof(*header
))
1957 ph
->needs_swap
= true;
1963 static int perf_header__read_pipe(struct perf_session
*session
, int fd
)
1965 struct perf_header
*header
= &session
->header
;
1966 struct perf_pipe_file_header f_header
;
1968 if (perf_file_header__read_pipe(&f_header
, header
, fd
,
1969 session
->repipe
) < 0) {
1970 pr_debug("incompatible file format\n");
1979 int perf_session__read_header(struct perf_session
*session
, int fd
)
1981 struct perf_header
*header
= &session
->header
;
1982 struct perf_file_header f_header
;
1983 struct perf_file_attr f_attr
;
1985 int nr_attrs
, nr_ids
, i
, j
;
1987 session
->evlist
= perf_evlist__new(NULL
, NULL
);
1988 if (session
->evlist
== NULL
)
1991 if (session
->fd_pipe
)
1992 return perf_header__read_pipe(session
, fd
);
1994 if (perf_file_header__read(&f_header
, header
, fd
) < 0) {
1995 pr_debug("incompatible file format\n");
1999 nr_attrs
= f_header
.attrs
.size
/ sizeof(f_attr
);
2000 lseek(fd
, f_header
.attrs
.offset
, SEEK_SET
);
2002 for (i
= 0; i
< nr_attrs
; i
++) {
2003 struct perf_evsel
*evsel
;
2006 if (readn(fd
, &f_attr
, sizeof(f_attr
)) <= 0)
2009 if (header
->needs_swap
)
2010 perf_event__attr_swap(&f_attr
.attr
);
2012 tmp
= lseek(fd
, 0, SEEK_CUR
);
2013 evsel
= perf_evsel__new(&f_attr
.attr
, i
);
2016 goto out_delete_evlist
;
2018 * Do it before so that if perf_evsel__alloc_id fails, this
2019 * entry gets purged too at perf_evlist__delete().
2021 perf_evlist__add(session
->evlist
, evsel
);
2023 nr_ids
= f_attr
.ids
.size
/ sizeof(u64
);
2025 * We don't have the cpu and thread maps on the header, so
2026 * for allocating the perf_sample_id table we fake 1 cpu and
2027 * hattr->ids threads.
2029 if (perf_evsel__alloc_id(evsel
, 1, nr_ids
))
2030 goto out_delete_evlist
;
2032 lseek(fd
, f_attr
.ids
.offset
, SEEK_SET
);
2034 for (j
= 0; j
< nr_ids
; j
++) {
2035 if (perf_header__getbuffer64(header
, fd
, &f_id
, sizeof(f_id
)))
2038 perf_evlist__id_add(session
->evlist
, evsel
, 0, j
, f_id
);
2041 lseek(fd
, tmp
, SEEK_SET
);
2044 symbol_conf
.nr_events
= nr_attrs
;
2046 if (f_header
.event_types
.size
) {
2047 lseek(fd
, f_header
.event_types
.offset
, SEEK_SET
);
2048 events
= malloc(f_header
.event_types
.size
);
2051 if (perf_header__getbuffer64(header
, fd
, events
,
2052 f_header
.event_types
.size
))
2054 event_count
= f_header
.event_types
.size
/ sizeof(struct perf_trace_event_type
);
2057 perf_header__process_sections(header
, fd
, NULL
,
2058 perf_file_section__process
);
2060 lseek(fd
, header
->data_offset
, SEEK_SET
);
2068 perf_evlist__delete(session
->evlist
);
2069 session
->evlist
= NULL
;
2073 int perf_event__synthesize_attr(struct perf_tool
*tool
,
2074 struct perf_event_attr
*attr
, u16 ids
, u64
*id
,
2075 perf_event__handler_t process
)
2077 union perf_event
*ev
;
2081 size
= sizeof(struct perf_event_attr
);
2082 size
= ALIGN(size
, sizeof(u64
));
2083 size
+= sizeof(struct perf_event_header
);
2084 size
+= ids
* sizeof(u64
);
2091 ev
->attr
.attr
= *attr
;
2092 memcpy(ev
->attr
.id
, id
, ids
* sizeof(u64
));
2094 ev
->attr
.header
.type
= PERF_RECORD_HEADER_ATTR
;
2095 ev
->attr
.header
.size
= size
;
2097 err
= process(tool
, ev
, NULL
, NULL
);
2104 int perf_event__synthesize_attrs(struct perf_tool
*tool
,
2105 struct perf_session
*session
,
2106 perf_event__handler_t process
)
2108 struct perf_evsel
*attr
;
2111 list_for_each_entry(attr
, &session
->evlist
->entries
, node
) {
2112 err
= perf_event__synthesize_attr(tool
, &attr
->attr
, attr
->ids
,
2115 pr_debug("failed to create perf header attribute\n");
2123 int perf_event__process_attr(union perf_event
*event
,
2124 struct perf_evlist
**pevlist
)
2126 unsigned int i
, ids
, n_ids
;
2127 struct perf_evsel
*evsel
;
2128 struct perf_evlist
*evlist
= *pevlist
;
2130 if (evlist
== NULL
) {
2131 *pevlist
= evlist
= perf_evlist__new(NULL
, NULL
);
2136 evsel
= perf_evsel__new(&event
->attr
.attr
, evlist
->nr_entries
);
2140 perf_evlist__add(evlist
, evsel
);
2142 ids
= event
->header
.size
;
2143 ids
-= (void *)&event
->attr
.id
- (void *)event
;
2144 n_ids
= ids
/ sizeof(u64
);
2146 * We don't have the cpu and thread maps on the header, so
2147 * for allocating the perf_sample_id table we fake 1 cpu and
2148 * hattr->ids threads.
2150 if (perf_evsel__alloc_id(evsel
, 1, n_ids
))
2153 for (i
= 0; i
< n_ids
; i
++) {
2154 perf_evlist__id_add(evlist
, evsel
, 0, i
, event
->attr
.id
[i
]);
2160 int perf_event__synthesize_event_type(struct perf_tool
*tool
,
2161 u64 event_id
, char *name
,
2162 perf_event__handler_t process
,
2163 struct machine
*machine
)
2165 union perf_event ev
;
2169 memset(&ev
, 0, sizeof(ev
));
2171 ev
.event_type
.event_type
.event_id
= event_id
;
2172 memset(ev
.event_type
.event_type
.name
, 0, MAX_EVENT_NAME
);
2173 strncpy(ev
.event_type
.event_type
.name
, name
, MAX_EVENT_NAME
- 1);
2175 ev
.event_type
.header
.type
= PERF_RECORD_HEADER_EVENT_TYPE
;
2176 size
= strlen(name
);
2177 size
= ALIGN(size
, sizeof(u64
));
2178 ev
.event_type
.header
.size
= sizeof(ev
.event_type
) -
2179 (sizeof(ev
.event_type
.event_type
.name
) - size
);
2181 err
= process(tool
, &ev
, NULL
, machine
);
2186 int perf_event__synthesize_event_types(struct perf_tool
*tool
,
2187 perf_event__handler_t process
,
2188 struct machine
*machine
)
2190 struct perf_trace_event_type
*type
;
2193 for (i
= 0; i
< event_count
; i
++) {
2196 err
= perf_event__synthesize_event_type(tool
, type
->event_id
,
2197 type
->name
, process
,
2200 pr_debug("failed to create perf header event type\n");
2208 int perf_event__process_event_type(struct perf_tool
*tool __unused
,
2209 union perf_event
*event
)
2211 if (perf_header__push_event(event
->event_type
.event_type
.event_id
,
2212 event
->event_type
.event_type
.name
) < 0)
2218 int perf_event__synthesize_tracing_data(struct perf_tool
*tool
, int fd
,
2219 struct perf_evlist
*evlist
,
2220 perf_event__handler_t process
)
2222 union perf_event ev
;
2223 struct tracing_data
*tdata
;
2224 ssize_t size
= 0, aligned_size
= 0, padding
;
2228 * We are going to store the size of the data followed
2229 * by the data contents. Since the fd descriptor is a pipe,
2230 * we cannot seek back to store the size of the data once
2231 * we know it. Instead we:
2233 * - write the tracing data to the temp file
2234 * - get/write the data size to pipe
2235 * - write the tracing data from the temp file
2238 tdata
= tracing_data_get(&evlist
->entries
, fd
, true);
2242 memset(&ev
, 0, sizeof(ev
));
2244 ev
.tracing_data
.header
.type
= PERF_RECORD_HEADER_TRACING_DATA
;
2246 aligned_size
= ALIGN(size
, sizeof(u64
));
2247 padding
= aligned_size
- size
;
2248 ev
.tracing_data
.header
.size
= sizeof(ev
.tracing_data
);
2249 ev
.tracing_data
.size
= aligned_size
;
2251 process(tool
, &ev
, NULL
, NULL
);
2254 * The put function will copy all the tracing data
2255 * stored in temp file to the pipe.
2257 tracing_data_put(tdata
);
2259 write_padded(fd
, NULL
, 0, padding
);
2261 return aligned_size
;
2264 int perf_event__process_tracing_data(union perf_event
*event
,
2265 struct perf_session
*session
)
2267 ssize_t size_read
, padding
, size
= event
->tracing_data
.size
;
2268 off_t offset
= lseek(session
->fd
, 0, SEEK_CUR
);
2271 /* setup for reading amidst mmap */
2272 lseek(session
->fd
, offset
+ sizeof(struct tracing_data_event
),
2275 size_read
= trace_report(session
->fd
, session
->repipe
);
2277 padding
= ALIGN(size_read
, sizeof(u64
)) - size_read
;
2279 if (read(session
->fd
, buf
, padding
) < 0)
2280 die("reading input file");
2281 if (session
->repipe
) {
2282 int retw
= write(STDOUT_FILENO
, buf
, padding
);
2283 if (retw
<= 0 || retw
!= padding
)
2284 die("repiping tracing data padding");
2287 if (size_read
+ padding
!= size
)
2288 die("tracing data size mismatch");
2290 return size_read
+ padding
;
2293 int perf_event__synthesize_build_id(struct perf_tool
*tool
,
2294 struct dso
*pos
, u16 misc
,
2295 perf_event__handler_t process
,
2296 struct machine
*machine
)
2298 union perf_event ev
;
2305 memset(&ev
, 0, sizeof(ev
));
2307 len
= pos
->long_name_len
+ 1;
2308 len
= ALIGN(len
, NAME_ALIGN
);
2309 memcpy(&ev
.build_id
.build_id
, pos
->build_id
, sizeof(pos
->build_id
));
2310 ev
.build_id
.header
.type
= PERF_RECORD_HEADER_BUILD_ID
;
2311 ev
.build_id
.header
.misc
= misc
;
2312 ev
.build_id
.pid
= machine
->pid
;
2313 ev
.build_id
.header
.size
= sizeof(ev
.build_id
) + len
;
2314 memcpy(&ev
.build_id
.filename
, pos
->long_name
, pos
->long_name_len
);
2316 err
= process(tool
, &ev
, NULL
, machine
);
2321 int perf_event__process_build_id(struct perf_tool
*tool __used
,
2322 union perf_event
*event
,
2323 struct perf_session
*session
)
2325 __event_process_build_id(&event
->build_id
,
2326 event
->build_id
.filename
,
2331 void disable_buildid_cache(void)
2333 no_buildid_cache
= true;