ACPI video: introduce module parameter video.use_bios_initial_backlight
[firefly-linux-kernel-4.4.55.git] / tools / perf / util / header.c
1 #define _FILE_OFFSET_BITS 64
2
3 #include <sys/types.h>
4 #include <byteswap.h>
5 #include <unistd.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <linux/list.h>
9 #include <linux/kernel.h>
10
11 #include "util.h"
12 #include "header.h"
13 #include "../perf.h"
14 #include "trace-event.h"
15 #include "session.h"
16 #include "symbol.h"
17 #include "debug.h"
18
19 static bool no_buildid_cache = false;
20
21 /*
22  * Create new perf.data header attribute:
23  */
24 struct perf_header_attr *perf_header_attr__new(struct perf_event_attr *attr)
25 {
26         struct perf_header_attr *self = malloc(sizeof(*self));
27
28         if (self != NULL) {
29                 self->attr = *attr;
30                 self->ids  = 0;
31                 self->size = 1;
32                 self->id   = malloc(sizeof(u64));
33                 if (self->id == NULL) {
34                         free(self);
35                         self = NULL;
36                 }
37         }
38
39         return self;
40 }
41
42 void perf_header_attr__delete(struct perf_header_attr *self)
43 {
44         free(self->id);
45         free(self);
46 }
47
48 int perf_header_attr__add_id(struct perf_header_attr *self, u64 id)
49 {
50         int pos = self->ids;
51
52         self->ids++;
53         if (self->ids > self->size) {
54                 int nsize = self->size * 2;
55                 u64 *nid = realloc(self->id, nsize * sizeof(u64));
56
57                 if (nid == NULL)
58                         return -1;
59
60                 self->size = nsize;
61                 self->id = nid;
62         }
63         self->id[pos] = id;
64         return 0;
65 }
66
67 int perf_header__init(struct perf_header *self)
68 {
69         self->size = 1;
70         self->attr = malloc(sizeof(void *));
71         return self->attr == NULL ? -ENOMEM : 0;
72 }
73
74 void perf_header__exit(struct perf_header *self)
75 {
76         int i;
77         for (i = 0; i < self->attrs; ++i)
78                 perf_header_attr__delete(self->attr[i]);
79         free(self->attr);
80 }
81
82 int perf_header__add_attr(struct perf_header *self,
83                           struct perf_header_attr *attr)
84 {
85         if (self->frozen)
86                 return -1;
87
88         if (self->attrs == self->size) {
89                 int nsize = self->size * 2;
90                 struct perf_header_attr **nattr;
91
92                 nattr = realloc(self->attr, nsize * sizeof(void *));
93                 if (nattr == NULL)
94                         return -1;
95
96                 self->size = nsize;
97                 self->attr = nattr;
98         }
99
100         self->attr[self->attrs++] = attr;
101         return 0;
102 }
103
104 static int event_count;
105 static struct perf_trace_event_type *events;
106
107 int perf_header__push_event(u64 id, const char *name)
108 {
109         if (strlen(name) > MAX_EVENT_NAME)
110                 pr_warning("Event %s will be truncated\n", name);
111
112         if (!events) {
113                 events = malloc(sizeof(struct perf_trace_event_type));
114                 if (events == NULL)
115                         return -ENOMEM;
116         } else {
117                 struct perf_trace_event_type *nevents;
118
119                 nevents = realloc(events, (event_count + 1) * sizeof(*events));
120                 if (nevents == NULL)
121                         return -ENOMEM;
122                 events = nevents;
123         }
124         memset(&events[event_count], 0, sizeof(struct perf_trace_event_type));
125         events[event_count].event_id = id;
126         strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1);
127         event_count++;
128         return 0;
129 }
130
131 char *perf_header__find_event(u64 id)
132 {
133         int i;
134         for (i = 0 ; i < event_count; i++) {
135                 if (events[i].event_id == id)
136                         return events[i].name;
137         }
138         return NULL;
139 }
140
141 static const char *__perf_magic = "PERFFILE";
142
143 #define PERF_MAGIC      (*(u64 *)__perf_magic)
144
145 struct perf_file_attr {
146         struct perf_event_attr  attr;
147         struct perf_file_section        ids;
148 };
149
150 void perf_header__set_feat(struct perf_header *self, int feat)
151 {
152         set_bit(feat, self->adds_features);
153 }
154
155 bool perf_header__has_feat(const struct perf_header *self, int feat)
156 {
157         return test_bit(feat, self->adds_features);
158 }
159
160 static int do_write(int fd, const void *buf, size_t size)
161 {
162         while (size) {
163                 int ret = write(fd, buf, size);
164
165                 if (ret < 0)
166                         return -errno;
167
168                 size -= ret;
169                 buf += ret;
170         }
171
172         return 0;
173 }
174
175 #define NAME_ALIGN 64
176
177 static int write_padded(int fd, const void *bf, size_t count,
178                         size_t count_aligned)
179 {
180         static const char zero_buf[NAME_ALIGN];
181         int err = do_write(fd, bf, count);
182
183         if (!err)
184                 err = do_write(fd, zero_buf, count_aligned - count);
185
186         return err;
187 }
188
189 #define dsos__for_each_with_build_id(pos, head) \
190         list_for_each_entry(pos, head, node)    \
191                 if (!pos->has_build_id)         \
192                         continue;               \
193                 else
194
195 static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
196                                 u16 misc, int fd)
197 {
198         struct dso *pos;
199
200         dsos__for_each_with_build_id(pos, head) {
201                 int err;
202                 struct build_id_event b;
203                 size_t len;
204
205                 if (!pos->hit)
206                         continue;
207                 len = pos->long_name_len + 1;
208                 len = ALIGN(len, NAME_ALIGN);
209                 memset(&b, 0, sizeof(b));
210                 memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
211                 b.pid = pid;
212                 b.header.misc = misc;
213                 b.header.size = sizeof(b) + len;
214                 err = do_write(fd, &b, sizeof(b));
215                 if (err < 0)
216                         return err;
217                 err = write_padded(fd, pos->long_name,
218                                    pos->long_name_len + 1, len);
219                 if (err < 0)
220                         return err;
221         }
222
223         return 0;
224 }
225
226 static int machine__write_buildid_table(struct machine *self, int fd)
227 {
228         int err;
229         u16 kmisc = PERF_RECORD_MISC_KERNEL,
230             umisc = PERF_RECORD_MISC_USER;
231
232         if (!machine__is_host(self)) {
233                 kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
234                 umisc = PERF_RECORD_MISC_GUEST_USER;
235         }
236
237         err = __dsos__write_buildid_table(&self->kernel_dsos, self->pid,
238                                           kmisc, fd);
239         if (err == 0)
240                 err = __dsos__write_buildid_table(&self->user_dsos,
241                                                   self->pid, umisc, fd);
242         return err;
243 }
244
245 static int dsos__write_buildid_table(struct perf_header *header, int fd)
246 {
247         struct perf_session *session = container_of(header,
248                         struct perf_session, header);
249         struct rb_node *nd;
250         int err = machine__write_buildid_table(&session->host_machine, fd);
251
252         if (err)
253                 return err;
254
255         for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
256                 struct machine *pos = rb_entry(nd, struct machine, rb_node);
257                 err = machine__write_buildid_table(pos, fd);
258                 if (err)
259                         break;
260         }
261         return err;
262 }
263
264 int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
265                           const char *name, bool is_kallsyms)
266 {
267         const size_t size = PATH_MAX;
268         char *filename = malloc(size),
269              *linkname = malloc(size), *targetname;
270         int len, err = -1;
271
272         if (filename == NULL || linkname == NULL)
273                 goto out_free;
274
275         len = snprintf(filename, size, "%s%s%s",
276                        debugdir, is_kallsyms ? "/" : "", name);
277         if (mkdir_p(filename, 0755))
278                 goto out_free;
279
280         snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id);
281
282         if (access(filename, F_OK)) {
283                 if (is_kallsyms) {
284                          if (copyfile("/proc/kallsyms", filename))
285                                 goto out_free;
286                 } else if (link(name, filename) && copyfile(name, filename))
287                         goto out_free;
288         }
289
290         len = snprintf(linkname, size, "%s/.build-id/%.2s",
291                        debugdir, sbuild_id);
292
293         if (access(linkname, X_OK) && mkdir_p(linkname, 0755))
294                 goto out_free;
295
296         snprintf(linkname + len, size - len, "/%s", sbuild_id + 2);
297         targetname = filename + strlen(debugdir) - 5;
298         memcpy(targetname, "../..", 5);
299
300         if (symlink(targetname, linkname) == 0)
301                 err = 0;
302 out_free:
303         free(filename);
304         free(linkname);
305         return err;
306 }
307
308 static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
309                                  const char *name, const char *debugdir,
310                                  bool is_kallsyms)
311 {
312         char sbuild_id[BUILD_ID_SIZE * 2 + 1];
313
314         build_id__sprintf(build_id, build_id_size, sbuild_id);
315
316         return build_id_cache__add_s(sbuild_id, debugdir, name, is_kallsyms);
317 }
318
319 int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir)
320 {
321         const size_t size = PATH_MAX;
322         char *filename = malloc(size),
323              *linkname = malloc(size);
324         int err = -1;
325
326         if (filename == NULL || linkname == NULL)
327                 goto out_free;
328
329         snprintf(linkname, size, "%s/.build-id/%.2s/%s",
330                  debugdir, sbuild_id, sbuild_id + 2);
331
332         if (access(linkname, F_OK))
333                 goto out_free;
334
335         if (readlink(linkname, filename, size) < 0)
336                 goto out_free;
337
338         if (unlink(linkname))
339                 goto out_free;
340
341         /*
342          * Since the link is relative, we must make it absolute:
343          */
344         snprintf(linkname, size, "%s/.build-id/%.2s/%s",
345                  debugdir, sbuild_id, filename);
346
347         if (unlink(linkname))
348                 goto out_free;
349
350         err = 0;
351 out_free:
352         free(filename);
353         free(linkname);
354         return err;
355 }
356
357 static int dso__cache_build_id(struct dso *self, const char *debugdir)
358 {
359         bool is_kallsyms = self->kernel && self->long_name[0] != '/';
360
361         return build_id_cache__add_b(self->build_id, sizeof(self->build_id),
362                                      self->long_name, debugdir, is_kallsyms);
363 }
364
365 static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
366 {
367         struct dso *pos;
368         int err = 0;
369
370         dsos__for_each_with_build_id(pos, head)
371                 if (dso__cache_build_id(pos, debugdir))
372                         err = -1;
373
374         return err;
375 }
376
377 static int machine__cache_build_ids(struct machine *self, const char *debugdir)
378 {
379         int ret = __dsos__cache_build_ids(&self->kernel_dsos, debugdir);
380         ret |= __dsos__cache_build_ids(&self->user_dsos, debugdir);
381         return ret;
382 }
383
384 static int perf_session__cache_build_ids(struct perf_session *self)
385 {
386         struct rb_node *nd;
387         int ret;
388         char debugdir[PATH_MAX];
389
390         snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
391
392         if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
393                 return -1;
394
395         ret = machine__cache_build_ids(&self->host_machine, debugdir);
396
397         for (nd = rb_first(&self->machines); nd; nd = rb_next(nd)) {
398                 struct machine *pos = rb_entry(nd, struct machine, rb_node);
399                 ret |= machine__cache_build_ids(pos, debugdir);
400         }
401         return ret ? -1 : 0;
402 }
403
404 static bool machine__read_build_ids(struct machine *self, bool with_hits)
405 {
406         bool ret = __dsos__read_build_ids(&self->kernel_dsos, with_hits);
407         ret |= __dsos__read_build_ids(&self->user_dsos, with_hits);
408         return ret;
409 }
410
411 static bool perf_session__read_build_ids(struct perf_session *self, bool with_hits)
412 {
413         struct rb_node *nd;
414         bool ret = machine__read_build_ids(&self->host_machine, with_hits);
415
416         for (nd = rb_first(&self->machines); nd; nd = rb_next(nd)) {
417                 struct machine *pos = rb_entry(nd, struct machine, rb_node);
418                 ret |= machine__read_build_ids(pos, with_hits);
419         }
420
421         return ret;
422 }
423
424 static int perf_header__adds_write(struct perf_header *self, int fd)
425 {
426         int nr_sections;
427         struct perf_session *session;
428         struct perf_file_section *feat_sec;
429         int sec_size;
430         u64 sec_start;
431         int idx = 0, err;
432
433         session = container_of(self, struct perf_session, header);
434         if (perf_session__read_build_ids(session, true))
435                 perf_header__set_feat(self, HEADER_BUILD_ID);
436
437         nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
438         if (!nr_sections)
439                 return 0;
440
441         feat_sec = calloc(sizeof(*feat_sec), nr_sections);
442         if (feat_sec == NULL)
443                 return -ENOMEM;
444
445         sec_size = sizeof(*feat_sec) * nr_sections;
446
447         sec_start = self->data_offset + self->data_size;
448         lseek(fd, sec_start + sec_size, SEEK_SET);
449
450         if (perf_header__has_feat(self, HEADER_TRACE_INFO)) {
451                 struct perf_file_section *trace_sec;
452
453                 trace_sec = &feat_sec[idx++];
454
455                 /* Write trace info */
456                 trace_sec->offset = lseek(fd, 0, SEEK_CUR);
457                 read_tracing_data(fd, attrs, nr_counters);
458                 trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset;
459         }
460
461         if (perf_header__has_feat(self, HEADER_BUILD_ID)) {
462                 struct perf_file_section *buildid_sec;
463
464                 buildid_sec = &feat_sec[idx++];
465
466                 /* Write build-ids */
467                 buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
468                 err = dsos__write_buildid_table(self, fd);
469                 if (err < 0) {
470                         pr_debug("failed to write buildid table\n");
471                         goto out_free;
472                 }
473                 buildid_sec->size = lseek(fd, 0, SEEK_CUR) -
474                                           buildid_sec->offset;
475                 if (!no_buildid_cache)
476                         perf_session__cache_build_ids(session);
477         }
478
479         lseek(fd, sec_start, SEEK_SET);
480         err = do_write(fd, feat_sec, sec_size);
481         if (err < 0)
482                 pr_debug("failed to write feature section\n");
483 out_free:
484         free(feat_sec);
485         return err;
486 }
487
488 int perf_header__write_pipe(int fd)
489 {
490         struct perf_pipe_file_header f_header;
491         int err;
492
493         f_header = (struct perf_pipe_file_header){
494                 .magic     = PERF_MAGIC,
495                 .size      = sizeof(f_header),
496         };
497
498         err = do_write(fd, &f_header, sizeof(f_header));
499         if (err < 0) {
500                 pr_debug("failed to write perf pipe header\n");
501                 return err;
502         }
503
504         return 0;
505 }
506
507 int perf_header__write(struct perf_header *self, int fd, bool at_exit)
508 {
509         struct perf_file_header f_header;
510         struct perf_file_attr   f_attr;
511         struct perf_header_attr *attr;
512         int i, err;
513
514         lseek(fd, sizeof(f_header), SEEK_SET);
515
516         for (i = 0; i < self->attrs; i++) {
517                 attr = self->attr[i];
518
519                 attr->id_offset = lseek(fd, 0, SEEK_CUR);
520                 err = do_write(fd, attr->id, attr->ids * sizeof(u64));
521                 if (err < 0) {
522                         pr_debug("failed to write perf header\n");
523                         return err;
524                 }
525         }
526
527
528         self->attr_offset = lseek(fd, 0, SEEK_CUR);
529
530         for (i = 0; i < self->attrs; i++) {
531                 attr = self->attr[i];
532
533                 f_attr = (struct perf_file_attr){
534                         .attr = attr->attr,
535                         .ids  = {
536                                 .offset = attr->id_offset,
537                                 .size   = attr->ids * sizeof(u64),
538                         }
539                 };
540                 err = do_write(fd, &f_attr, sizeof(f_attr));
541                 if (err < 0) {
542                         pr_debug("failed to write perf header attribute\n");
543                         return err;
544                 }
545         }
546
547         self->event_offset = lseek(fd, 0, SEEK_CUR);
548         self->event_size = event_count * sizeof(struct perf_trace_event_type);
549         if (events) {
550                 err = do_write(fd, events, self->event_size);
551                 if (err < 0) {
552                         pr_debug("failed to write perf header events\n");
553                         return err;
554                 }
555         }
556
557         self->data_offset = lseek(fd, 0, SEEK_CUR);
558
559         if (at_exit) {
560                 err = perf_header__adds_write(self, fd);
561                 if (err < 0)
562                         return err;
563         }
564
565         f_header = (struct perf_file_header){
566                 .magic     = PERF_MAGIC,
567                 .size      = sizeof(f_header),
568                 .attr_size = sizeof(f_attr),
569                 .attrs = {
570                         .offset = self->attr_offset,
571                         .size   = self->attrs * sizeof(f_attr),
572                 },
573                 .data = {
574                         .offset = self->data_offset,
575                         .size   = self->data_size,
576                 },
577                 .event_types = {
578                         .offset = self->event_offset,
579                         .size   = self->event_size,
580                 },
581         };
582
583         memcpy(&f_header.adds_features, &self->adds_features, sizeof(self->adds_features));
584
585         lseek(fd, 0, SEEK_SET);
586         err = do_write(fd, &f_header, sizeof(f_header));
587         if (err < 0) {
588                 pr_debug("failed to write perf header\n");
589                 return err;
590         }
591         lseek(fd, self->data_offset + self->data_size, SEEK_SET);
592
593         self->frozen = 1;
594         return 0;
595 }
596
597 static int perf_header__getbuffer64(struct perf_header *self,
598                                     int fd, void *buf, size_t size)
599 {
600         if (do_read(fd, buf, size) <= 0)
601                 return -1;
602
603         if (self->needs_swap)
604                 mem_bswap_64(buf, size);
605
606         return 0;
607 }
608
609 int perf_header__process_sections(struct perf_header *self, int fd,
610                                   int (*process)(struct perf_file_section *self,
611                                                  struct perf_header *ph,
612                                                  int feat, int fd))
613 {
614         struct perf_file_section *feat_sec;
615         int nr_sections;
616         int sec_size;
617         int idx = 0;
618         int err = -1, feat = 1;
619
620         nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
621         if (!nr_sections)
622                 return 0;
623
624         feat_sec = calloc(sizeof(*feat_sec), nr_sections);
625         if (!feat_sec)
626                 return -1;
627
628         sec_size = sizeof(*feat_sec) * nr_sections;
629
630         lseek(fd, self->data_offset + self->data_size, SEEK_SET);
631
632         if (perf_header__getbuffer64(self, fd, feat_sec, sec_size))
633                 goto out_free;
634
635         err = 0;
636         while (idx < nr_sections && feat < HEADER_LAST_FEATURE) {
637                 if (perf_header__has_feat(self, feat)) {
638                         struct perf_file_section *sec = &feat_sec[idx++];
639
640                         err = process(sec, self, feat, fd);
641                         if (err < 0)
642                                 break;
643                 }
644                 ++feat;
645         }
646 out_free:
647         free(feat_sec);
648         return err;
649 }
650
651 int perf_file_header__read(struct perf_file_header *self,
652                            struct perf_header *ph, int fd)
653 {
654         lseek(fd, 0, SEEK_SET);
655
656         if (do_read(fd, self, sizeof(*self)) <= 0 ||
657             memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
658                 return -1;
659
660         if (self->attr_size != sizeof(struct perf_file_attr)) {
661                 u64 attr_size = bswap_64(self->attr_size);
662
663                 if (attr_size != sizeof(struct perf_file_attr))
664                         return -1;
665
666                 mem_bswap_64(self, offsetof(struct perf_file_header,
667                                             adds_features));
668                 ph->needs_swap = true;
669         }
670
671         if (self->size != sizeof(*self)) {
672                 /* Support the previous format */
673                 if (self->size == offsetof(typeof(*self), adds_features))
674                         bitmap_zero(self->adds_features, HEADER_FEAT_BITS);
675                 else
676                         return -1;
677         }
678
679         memcpy(&ph->adds_features, &self->adds_features,
680                sizeof(ph->adds_features));
681         /*
682          * FIXME: hack that assumes that if we need swap the perf.data file
683          * may be coming from an arch with a different word-size, ergo different
684          * DEFINE_BITMAP format, investigate more later, but for now its mostly
685          * safe to assume that we have a build-id section. Trace files probably
686          * have several other issues in this realm anyway...
687          */
688         if (ph->needs_swap) {
689                 memset(&ph->adds_features, 0, sizeof(ph->adds_features));
690                 perf_header__set_feat(ph, HEADER_BUILD_ID);
691         }
692
693         ph->event_offset = self->event_types.offset;
694         ph->event_size   = self->event_types.size;
695         ph->data_offset  = self->data.offset;
696         ph->data_size    = self->data.size;
697         return 0;
698 }
699
700 static int __event_process_build_id(struct build_id_event *bev,
701                                     char *filename,
702                                     struct perf_session *session)
703 {
704         int err = -1;
705         struct list_head *head;
706         struct machine *machine;
707         u16 misc;
708         struct dso *dso;
709         enum dso_kernel_type dso_type;
710
711         machine = perf_session__findnew_machine(session, bev->pid);
712         if (!machine)
713                 goto out;
714
715         misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
716
717         switch (misc) {
718         case PERF_RECORD_MISC_KERNEL:
719                 dso_type = DSO_TYPE_KERNEL;
720                 head = &machine->kernel_dsos;
721                 break;
722         case PERF_RECORD_MISC_GUEST_KERNEL:
723                 dso_type = DSO_TYPE_GUEST_KERNEL;
724                 head = &machine->kernel_dsos;
725                 break;
726         case PERF_RECORD_MISC_USER:
727         case PERF_RECORD_MISC_GUEST_USER:
728                 dso_type = DSO_TYPE_USER;
729                 head = &machine->user_dsos;
730                 break;
731         default:
732                 goto out;
733         }
734
735         dso = __dsos__findnew(head, filename);
736         if (dso != NULL) {
737                 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
738
739                 dso__set_build_id(dso, &bev->build_id);
740
741                 if (filename[0] == '[')
742                         dso->kernel = dso_type;
743
744                 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
745                                   sbuild_id);
746                 pr_debug("build id event received for %s: %s\n",
747                          dso->long_name, sbuild_id);
748         }
749
750         err = 0;
751 out:
752         return err;
753 }
754
755 static int perf_header__read_build_ids(struct perf_header *self,
756                         int input, u64 offset, u64 size)
757 {
758         struct perf_session *session = container_of(self,
759                         struct perf_session, header);
760         struct build_id_event bev;
761         char filename[PATH_MAX];
762         u64 limit = offset + size;
763         int err = -1;
764
765         while (offset < limit) {
766                 ssize_t len;
767
768                 if (read(input, &bev, sizeof(bev)) != sizeof(bev))
769                         goto out;
770
771                 if (self->needs_swap)
772                         perf_event_header__bswap(&bev.header);
773
774                 len = bev.header.size - sizeof(bev);
775                 if (read(input, filename, len) != len)
776                         goto out;
777
778                 __event_process_build_id(&bev, filename, session);
779
780                 offset += bev.header.size;
781         }
782         err = 0;
783 out:
784         return err;
785 }
786
787 static int perf_file_section__process(struct perf_file_section *self,
788                                       struct perf_header *ph,
789                                       int feat, int fd)
790 {
791         if (lseek(fd, self->offset, SEEK_SET) == (off_t)-1) {
792                 pr_debug("Failed to lseek to %Ld offset for feature %d, "
793                          "continuing...\n", self->offset, feat);
794                 return 0;
795         }
796
797         switch (feat) {
798         case HEADER_TRACE_INFO:
799                 trace_report(fd, false);
800                 break;
801
802         case HEADER_BUILD_ID:
803                 if (perf_header__read_build_ids(ph, fd, self->offset, self->size))
804                         pr_debug("Failed to read buildids, continuing...\n");
805                 break;
806         default:
807                 pr_debug("unknown feature %d, continuing...\n", feat);
808         }
809
810         return 0;
811 }
812
813 static int perf_file_header__read_pipe(struct perf_pipe_file_header *self,
814                                        struct perf_header *ph, int fd,
815                                        bool repipe)
816 {
817         if (do_read(fd, self, sizeof(*self)) <= 0 ||
818             memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
819                 return -1;
820
821         if (repipe && do_write(STDOUT_FILENO, self, sizeof(*self)) < 0)
822                 return -1;
823
824         if (self->size != sizeof(*self)) {
825                 u64 size = bswap_64(self->size);
826
827                 if (size != sizeof(*self))
828                         return -1;
829
830                 ph->needs_swap = true;
831         }
832
833         return 0;
834 }
835
836 static int perf_header__read_pipe(struct perf_session *session, int fd)
837 {
838         struct perf_header *self = &session->header;
839         struct perf_pipe_file_header f_header;
840
841         if (perf_file_header__read_pipe(&f_header, self, fd,
842                                         session->repipe) < 0) {
843                 pr_debug("incompatible file format\n");
844                 return -EINVAL;
845         }
846
847         session->fd = fd;
848
849         return 0;
850 }
851
852 int perf_header__read(struct perf_session *session, int fd)
853 {
854         struct perf_header *self = &session->header;
855         struct perf_file_header f_header;
856         struct perf_file_attr   f_attr;
857         u64                     f_id;
858         int nr_attrs, nr_ids, i, j;
859
860         if (session->fd_pipe)
861                 return perf_header__read_pipe(session, fd);
862
863         if (perf_file_header__read(&f_header, self, fd) < 0) {
864                 pr_debug("incompatible file format\n");
865                 return -EINVAL;
866         }
867
868         nr_attrs = f_header.attrs.size / sizeof(f_attr);
869         lseek(fd, f_header.attrs.offset, SEEK_SET);
870
871         for (i = 0; i < nr_attrs; i++) {
872                 struct perf_header_attr *attr;
873                 off_t tmp;
874
875                 if (perf_header__getbuffer64(self, fd, &f_attr, sizeof(f_attr)))
876                         goto out_errno;
877
878                 tmp = lseek(fd, 0, SEEK_CUR);
879
880                 attr = perf_header_attr__new(&f_attr.attr);
881                 if (attr == NULL)
882                          return -ENOMEM;
883
884                 nr_ids = f_attr.ids.size / sizeof(u64);
885                 lseek(fd, f_attr.ids.offset, SEEK_SET);
886
887                 for (j = 0; j < nr_ids; j++) {
888                         if (perf_header__getbuffer64(self, fd, &f_id, sizeof(f_id)))
889                                 goto out_errno;
890
891                         if (perf_header_attr__add_id(attr, f_id) < 0) {
892                                 perf_header_attr__delete(attr);
893                                 return -ENOMEM;
894                         }
895                 }
896                 if (perf_header__add_attr(self, attr) < 0) {
897                         perf_header_attr__delete(attr);
898                         return -ENOMEM;
899                 }
900
901                 lseek(fd, tmp, SEEK_SET);
902         }
903
904         if (f_header.event_types.size) {
905                 lseek(fd, f_header.event_types.offset, SEEK_SET);
906                 events = malloc(f_header.event_types.size);
907                 if (events == NULL)
908                         return -ENOMEM;
909                 if (perf_header__getbuffer64(self, fd, events,
910                                              f_header.event_types.size))
911                         goto out_errno;
912                 event_count =  f_header.event_types.size / sizeof(struct perf_trace_event_type);
913         }
914
915         perf_header__process_sections(self, fd, perf_file_section__process);
916
917         lseek(fd, self->data_offset, SEEK_SET);
918
919         self->frozen = 1;
920         return 0;
921 out_errno:
922         return -errno;
923 }
924
925 u64 perf_header__sample_type(struct perf_header *header)
926 {
927         u64 type = 0;
928         int i;
929
930         for (i = 0; i < header->attrs; i++) {
931                 struct perf_header_attr *attr = header->attr[i];
932
933                 if (!type)
934                         type = attr->attr.sample_type;
935                 else if (type != attr->attr.sample_type)
936                         die("non matching sample_type");
937         }
938
939         return type;
940 }
941
942 struct perf_event_attr *
943 perf_header__find_attr(u64 id, struct perf_header *header)
944 {
945         int i;
946
947         /*
948          * We set id to -1 if the data file doesn't contain sample
949          * ids. Check for this and avoid walking through the entire
950          * list of ids which may be large.
951          */
952         if (id == -1ULL)
953                 return NULL;
954
955         for (i = 0; i < header->attrs; i++) {
956                 struct perf_header_attr *attr = header->attr[i];
957                 int j;
958
959                 for (j = 0; j < attr->ids; j++) {
960                         if (attr->id[j] == id)
961                                 return &attr->attr;
962                 }
963         }
964
965         return NULL;
966 }
967
968 int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
969                            event__handler_t process,
970                            struct perf_session *session)
971 {
972         event_t *ev;
973         size_t size;
974         int err;
975
976         size = sizeof(struct perf_event_attr);
977         size = ALIGN(size, sizeof(u64));
978         size += sizeof(struct perf_event_header);
979         size += ids * sizeof(u64);
980
981         ev = malloc(size);
982
983         ev->attr.attr = *attr;
984         memcpy(ev->attr.id, id, ids * sizeof(u64));
985
986         ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
987         ev->attr.header.size = size;
988
989         err = process(ev, session);
990
991         free(ev);
992
993         return err;
994 }
995
996 int event__synthesize_attrs(struct perf_header *self,
997                             event__handler_t process,
998                             struct perf_session *session)
999 {
1000         struct perf_header_attr *attr;
1001         int i, err = 0;
1002
1003         for (i = 0; i < self->attrs; i++) {
1004                 attr = self->attr[i];
1005
1006                 err = event__synthesize_attr(&attr->attr, attr->ids, attr->id,
1007                                              process, session);
1008                 if (err) {
1009                         pr_debug("failed to create perf header attribute\n");
1010                         return err;
1011                 }
1012         }
1013
1014         return err;
1015 }
1016
1017 int event__process_attr(event_t *self, struct perf_session *session)
1018 {
1019         struct perf_header_attr *attr;
1020         unsigned int i, ids, n_ids;
1021
1022         attr = perf_header_attr__new(&self->attr.attr);
1023         if (attr == NULL)
1024                 return -ENOMEM;
1025
1026         ids = self->header.size;
1027         ids -= (void *)&self->attr.id - (void *)self;
1028         n_ids = ids / sizeof(u64);
1029
1030         for (i = 0; i < n_ids; i++) {
1031                 if (perf_header_attr__add_id(attr, self->attr.id[i]) < 0) {
1032                         perf_header_attr__delete(attr);
1033                         return -ENOMEM;
1034                 }
1035         }
1036
1037         if (perf_header__add_attr(&session->header, attr) < 0) {
1038                 perf_header_attr__delete(attr);
1039                 return -ENOMEM;
1040         }
1041
1042         perf_session__update_sample_type(session);
1043
1044         return 0;
1045 }
1046
1047 int event__synthesize_event_type(u64 event_id, char *name,
1048                                  event__handler_t process,
1049                                  struct perf_session *session)
1050 {
1051         event_t ev;
1052         size_t size = 0;
1053         int err = 0;
1054
1055         memset(&ev, 0, sizeof(ev));
1056
1057         ev.event_type.event_type.event_id = event_id;
1058         memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME);
1059         strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1);
1060
1061         ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
1062         size = strlen(name);
1063         size = ALIGN(size, sizeof(u64));
1064         ev.event_type.header.size = sizeof(ev.event_type) -
1065                 (sizeof(ev.event_type.event_type.name) - size);
1066
1067         err = process(&ev, session);
1068
1069         return err;
1070 }
1071
1072 int event__synthesize_event_types(event__handler_t process,
1073                                   struct perf_session *session)
1074 {
1075         struct perf_trace_event_type *type;
1076         int i, err = 0;
1077
1078         for (i = 0; i < event_count; i++) {
1079                 type = &events[i];
1080
1081                 err = event__synthesize_event_type(type->event_id, type->name,
1082                                                    process, session);
1083                 if (err) {
1084                         pr_debug("failed to create perf header event type\n");
1085                         return err;
1086                 }
1087         }
1088
1089         return err;
1090 }
1091
1092 int event__process_event_type(event_t *self,
1093                               struct perf_session *session __unused)
1094 {
1095         if (perf_header__push_event(self->event_type.event_type.event_id,
1096                                     self->event_type.event_type.name) < 0)
1097                 return -ENOMEM;
1098
1099         return 0;
1100 }
1101
1102 int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs,
1103                                    int nb_events,
1104                                    event__handler_t process,
1105                                    struct perf_session *session __unused)
1106 {
1107         event_t ev;
1108         ssize_t size = 0, aligned_size = 0, padding;
1109         int err = 0;
1110
1111         memset(&ev, 0, sizeof(ev));
1112
1113         ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
1114         size = read_tracing_data_size(fd, pattrs, nb_events);
1115         if (size <= 0)
1116                 return size;
1117         aligned_size = ALIGN(size, sizeof(u64));
1118         padding = aligned_size - size;
1119         ev.tracing_data.header.size = sizeof(ev.tracing_data);
1120         ev.tracing_data.size = aligned_size;
1121
1122         process(&ev, session);
1123
1124         err = read_tracing_data(fd, pattrs, nb_events);
1125         write_padded(fd, NULL, 0, padding);
1126
1127         return aligned_size;
1128 }
1129
1130 int event__process_tracing_data(event_t *self,
1131                                 struct perf_session *session)
1132 {
1133         ssize_t size_read, padding, size = self->tracing_data.size;
1134         off_t offset = lseek(session->fd, 0, SEEK_CUR);
1135         char buf[BUFSIZ];
1136
1137         /* setup for reading amidst mmap */
1138         lseek(session->fd, offset + sizeof(struct tracing_data_event),
1139               SEEK_SET);
1140
1141         size_read = trace_report(session->fd, session->repipe);
1142
1143         padding = ALIGN(size_read, sizeof(u64)) - size_read;
1144
1145         if (read(session->fd, buf, padding) < 0)
1146                 die("reading input file");
1147         if (session->repipe) {
1148                 int retw = write(STDOUT_FILENO, buf, padding);
1149                 if (retw <= 0 || retw != padding)
1150                         die("repiping tracing data padding");
1151         }
1152
1153         if (size_read + padding != size)
1154                 die("tracing data size mismatch");
1155
1156         return size_read + padding;
1157 }
1158
1159 int event__synthesize_build_id(struct dso *pos, u16 misc,
1160                                event__handler_t process,
1161                                struct machine *machine,
1162                                struct perf_session *session)
1163 {
1164         event_t ev;
1165         size_t len;
1166         int err = 0;
1167
1168         if (!pos->hit)
1169                 return err;
1170
1171         memset(&ev, 0, sizeof(ev));
1172
1173         len = pos->long_name_len + 1;
1174         len = ALIGN(len, NAME_ALIGN);
1175         memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
1176         ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
1177         ev.build_id.header.misc = misc;
1178         ev.build_id.pid = machine->pid;
1179         ev.build_id.header.size = sizeof(ev.build_id) + len;
1180         memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
1181
1182         err = process(&ev, session);
1183
1184         return err;
1185 }
1186
1187 int event__process_build_id(event_t *self,
1188                             struct perf_session *session)
1189 {
1190         __event_process_build_id(&self->build_id,
1191                                  self->build_id.filename,
1192                                  session);
1193         return 0;
1194 }
1195
1196 void disable_buildid_cache(void)
1197 {
1198         no_buildid_cache = true;
1199 }