aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 13:28:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 13:28:49 -0400
commit7e92daaefa68e5ef1e1732e45231e73adbb724e7 (patch)
tree8e7f8ac9d82654df4c65939c6682f95510e22977 /tools/perf/util/header.c
parent7a68294278ae714ce2632a54f0f46916dca64f56 (diff)
parent1d787d37c8ff6612b8151c6dff15bfa7347bcbdf (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf update from Ingo Molnar: "Lots of changes in this cycle as well, with hundreds of commits from over 30 contributors. Most of the activity was on the tooling side. Higher level changes: - New 'perf kvm' analysis tool, from Xiao Guangrong. - New 'perf trace' system-wide tracing tool - uprobes fixes + cleanups from Oleg Nesterov. - Lots of patches to make perf build on Android out of box, from Irina Tirdea - Extend ftrace function tracing utility to be more dynamic for its users. It allows for data passing to the callback functions, as well as reading regs as if a breakpoint were to trigger at function entry. The main goal of this patch series was to allow kprobes to use ftrace as an optimized probe point when a probe is placed on an ftrace nop. With lots of help from Masami Hiramatsu, and going through lots of iterations, we finally came up with a good solution. - Add cpumask for uncore pmu, use it in 'stat', from Yan, Zheng. - Various tracing updates from Steve Rostedt - Clean up and improve 'perf sched' performance by elliminating lots of needless calls to libtraceevent. - Event group parsing support, from Jiri Olsa - UI/gtk refactorings and improvements from Namhyung Kim - Add support for non-tracepoint events in perf script python, from Feng Tang - Add --symbols to 'script', similar to the one in 'report', from Feng Tang. Infrastructure enhancements and fixes: - Convert the trace builtins to use the growing evsel/evlist tracepoint infrastructure, removing several open coded constructs like switch like series of strcmp to dispatch events, etc. Basically what had already been showcased in 'perf sched'. - Add evsel constructor for tracepoints, that uses libtraceevent just to parse the /format events file, use it in a new 'perf test' to make sure the libtraceevent format parsing regressions can be more readily caught. - Some strange errors were happening in some builds, but not on the next, reported by several people, problem was some parser related files, generated during the build, didn't had proper make deps, fix from Eric Sandeen. - Introduce struct and cache information about the environment where a perf.data file was captured, from Namhyung Kim. - Fix handling of unresolved samples when --symbols is used in 'report', from Feng Tang. - Add union member access support to 'probe', from Hyeoncheol Lee. - Fixups to die() removal, from Namhyung Kim. - Render fixes for the TUI, from Namhyung Kim. - Don't enable annotation in non symbolic view, from Namhyung Kim. - Fix pipe mode in 'report', from Namhyung Kim. - Move related stats code from stat to util/, will be used by the 'stat' kvm tool, from Xiao Guangrong. - Remove die()/exit() calls from several tools. - Resolve vdso callchains, from Jiri Olsa - Don't pass const char pointers to basename, so that we can unconditionally use libgen.h and thus avoid ifdef BIONIC lines, from David Ahern - Refactor hist formatting so that it can be reused with the GTK browser, From Namhyung Kim - Fix build for another rbtree.c change, from Adrian Hunter. - Make 'perf diff' command work with evsel hists, from Jiri Olsa. - Use the only field_sep var that is set up: symbol_conf.field_sep, fix from Jiri Olsa. - .gitignore compiled python binaries, from Namhyung Kim. - Get rid of die() in more libtraceevent places, from Namhyung Kim. - Rename libtraceevent 'private' struct member to 'priv' so that it works in C++, from Steven Rostedt - Remove lots of exit()/die() calls from tools so that the main perf exit routine can take place, from David Ahern - Fix x86 build on x86-64, from David Ahern. - {int,str,rb}list fixes from Suzuki K Poulose - perf.data header fixes from Namhyung Kim - Allow user to indicate objdump path, needed in cross environments, from Maciek Borzecki - Fix hardware cache event name generation, fix from Jiri Olsa - Add round trip test for sw, hw and cache event names, catching the problem Jiri fixed, after Jiri's patch, the test passes successfully. - Clean target should do clean for lib/traceevent too, fix from David Ahern - Check the right variable for allocation failure, fix from Namhyung Kim - Set up evsel->tp_format regardless of evsel->name being set already, fix from Namhyung Kim - Oprofile fixes from Robert Richter. - Remove perf_event_attr needless version inflation, from Jiri Olsa - Introduce libtraceevent strerror like error reporting facility, from Namhyung Kim - Add pmu mappings to perf.data header and use event names from cmd line, from Robert Richter - Fix include order for bison/flex-generated C files, from Ben Hutchings - Build fixes and documentation corrections from David Ahern - Assorted cleanups from Robert Richter - Let O= makes handle relative paths, from Steven Rostedt - perf script python fixes, from Feng Tang. - Initial bash completion support, from Frederic Weisbecker - Allow building without libelf, from Namhyung Kim. - Support DWARF CFI based unwind to have callchains when %bp based unwinding is not possible, from Jiri Olsa. - Symbol resolution fixes, while fixing support PPC64 files with an .opt ELF section was the end goal, several fixes for code that handles all architectures and cleanups are included, from Cody Schafer. - Assorted fixes for Documentation and build in 32 bit, from Robert Richter - Cache the libtraceevent event_format associated to each evsel early, so that we avoid relookups, i.e. calling pevent_find_event repeatedly when processing tracepoint events. [ This is to reduce the surface contact with libtraceevents and make clear what is that the perf tools needs from that lib: so far parsing the common and per event fields. ] - Don't stop the build if the audit libraries are not installed, fix from Namhyung Kim. - Fix bfd.h/libbfd detection with recent binutils, from Markus Trippelsdorf. - Improve warning message when libunwind devel packages not present, from Jiri Olsa" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (282 commits) perf trace: Add aliases for some syscalls perf probe: Print an enum type variable in "enum variable-name" format when showing accessible variables perf tools: Check libaudit availability for perf-trace builtin perf hists: Add missing period_* fields when collapsing a hist entry perf trace: New tool perf evsel: Export the event_format constructor perf evsel: Introduce rawptr() method perf tools: Use perf_evsel__newtp in the event parser perf evsel: The tracepoint constructor should store sys:name perf evlist: Introduce set_filter() method perf evlist: Renane set_filters method to apply_filters perf test: Add test to check we correctly parse and match syscall open parms perf evsel: Handle endianity in intval method perf evsel: Know if byte swap is needed perf tools: Allow handling a NULL cpu_map as meaning "all cpus" perf evsel: Improve tracepoint constructor setup tools lib traceevent: Fix error path on pevent_parse_event perf test: Fix build failure trace: Move trace event enable from fs_initcall to core_initcall tracing: Add an option for disabling markers ...
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r--tools/perf/util/header.c1063
1 files changed, 762 insertions, 301 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 74ea3c2f8138..7daad237dea5 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -20,11 +20,14 @@
20#include "symbol.h" 20#include "symbol.h"
21#include "debug.h" 21#include "debug.h"
22#include "cpumap.h" 22#include "cpumap.h"
23#include "pmu.h"
24#include "vdso.h"
25#include "strbuf.h"
23 26
24static bool no_buildid_cache = false; 27static bool no_buildid_cache = false;
25 28
26static int event_count; 29static int trace_event_count;
27static struct perf_trace_event_type *events; 30static struct perf_trace_event_type *trace_events;
28 31
29static u32 header_argc; 32static u32 header_argc;
30static const char **header_argv; 33static const char **header_argv;
@@ -36,24 +39,24 @@ int perf_header__push_event(u64 id, const char *name)
36 if (strlen(name) > MAX_EVENT_NAME) 39 if (strlen(name) > MAX_EVENT_NAME)
37 pr_warning("Event %s will be truncated\n", name); 40 pr_warning("Event %s will be truncated\n", name);
38 41
39 nevents = realloc(events, (event_count + 1) * sizeof(*events)); 42 nevents = realloc(trace_events, (trace_event_count + 1) * sizeof(*trace_events));
40 if (nevents == NULL) 43 if (nevents == NULL)
41 return -ENOMEM; 44 return -ENOMEM;
42 events = nevents; 45 trace_events = nevents;
43 46
44 memset(&events[event_count], 0, sizeof(struct perf_trace_event_type)); 47 memset(&trace_events[trace_event_count], 0, sizeof(struct perf_trace_event_type));
45 events[event_count].event_id = id; 48 trace_events[trace_event_count].event_id = id;
46 strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1); 49 strncpy(trace_events[trace_event_count].name, name, MAX_EVENT_NAME - 1);
47 event_count++; 50 trace_event_count++;
48 return 0; 51 return 0;
49} 52}
50 53
51char *perf_header__find_event(u64 id) 54char *perf_header__find_event(u64 id)
52{ 55{
53 int i; 56 int i;
54 for (i = 0 ; i < event_count; i++) { 57 for (i = 0 ; i < trace_event_count; i++) {
55 if (events[i].event_id == id) 58 if (trace_events[i].event_id == id)
56 return events[i].name; 59 return trace_events[i].name;
57 } 60 }
58 return NULL; 61 return NULL;
59} 62}
@@ -128,7 +131,7 @@ static int do_write_string(int fd, const char *str)
128 int ret; 131 int ret;
129 132
130 olen = strlen(str) + 1; 133 olen = strlen(str) + 1;
131 len = ALIGN(olen, NAME_ALIGN); 134 len = PERF_ALIGN(olen, NAME_ALIGN);
132 135
133 /* write len, incl. \0 */ 136 /* write len, incl. \0 */
134 ret = do_write(fd, &len, sizeof(len)); 137 ret = do_write(fd, &len, sizeof(len));
@@ -206,6 +209,29 @@ perf_header__set_cmdline(int argc, const char **argv)
206 continue; \ 209 continue; \
207 else 210 else
208 211
212static int write_buildid(char *name, size_t name_len, u8 *build_id,
213 pid_t pid, u16 misc, int fd)
214{
215 int err;
216 struct build_id_event b;
217 size_t len;
218
219 len = name_len + 1;
220 len = PERF_ALIGN(len, NAME_ALIGN);
221
222 memset(&b, 0, sizeof(b));
223 memcpy(&b.build_id, build_id, BUILD_ID_SIZE);
224 b.pid = pid;
225 b.header.misc = misc;
226 b.header.size = sizeof(b) + len;
227
228 err = do_write(fd, &b, sizeof(b));
229 if (err < 0)
230 return err;
231
232 return write_padded(fd, name, name_len + 1, len);
233}
234
209static int __dsos__write_buildid_table(struct list_head *head, pid_t pid, 235static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
210 u16 misc, int fd) 236 u16 misc, int fd)
211{ 237{
@@ -213,24 +239,23 @@ static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
213 239
214 dsos__for_each_with_build_id(pos, head) { 240 dsos__for_each_with_build_id(pos, head) {
215 int err; 241 int err;
216 struct build_id_event b; 242 char *name;
217 size_t len; 243 size_t name_len;
218 244
219 if (!pos->hit) 245 if (!pos->hit)
220 continue; 246 continue;
221 len = pos->long_name_len + 1; 247
222 len = ALIGN(len, NAME_ALIGN); 248 if (is_vdso_map(pos->short_name)) {
223 memset(&b, 0, sizeof(b)); 249 name = (char *) VDSO__MAP_NAME;
224 memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id)); 250 name_len = sizeof(VDSO__MAP_NAME) + 1;
225 b.pid = pid; 251 } else {
226 b.header.misc = misc; 252 name = pos->long_name;
227 b.header.size = sizeof(b) + len; 253 name_len = pos->long_name_len + 1;
228 err = do_write(fd, &b, sizeof(b)); 254 }
229 if (err < 0) 255
230 return err; 256 err = write_buildid(name, name_len, pos->build_id,
231 err = write_padded(fd, pos->long_name, 257 pid, misc, fd);
232 pos->long_name_len + 1, len); 258 if (err)
233 if (err < 0)
234 return err; 259 return err;
235 } 260 }
236 261
@@ -276,19 +301,20 @@ static int dsos__write_buildid_table(struct perf_header *header, int fd)
276} 301}
277 302
278int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, 303int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
279 const char *name, bool is_kallsyms) 304 const char *name, bool is_kallsyms, bool is_vdso)
280{ 305{
281 const size_t size = PATH_MAX; 306 const size_t size = PATH_MAX;
282 char *realname, *filename = zalloc(size), 307 char *realname, *filename = zalloc(size),
283 *linkname = zalloc(size), *targetname; 308 *linkname = zalloc(size), *targetname;
284 int len, err = -1; 309 int len, err = -1;
310 bool slash = is_kallsyms || is_vdso;
285 311
286 if (is_kallsyms) { 312 if (is_kallsyms) {
287 if (symbol_conf.kptr_restrict) { 313 if (symbol_conf.kptr_restrict) {
288 pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); 314 pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n");
289 return 0; 315 return 0;
290 } 316 }
291 realname = (char *)name; 317 realname = (char *) name;
292 } else 318 } else
293 realname = realpath(name, NULL); 319 realname = realpath(name, NULL);
294 320
@@ -296,7 +322,8 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
296 goto out_free; 322 goto out_free;
297 323
298 len = scnprintf(filename, size, "%s%s%s", 324 len = scnprintf(filename, size, "%s%s%s",
299 debugdir, is_kallsyms ? "/" : "", realname); 325 debugdir, slash ? "/" : "",
326 is_vdso ? VDSO__MAP_NAME : realname);
300 if (mkdir_p(filename, 0755)) 327 if (mkdir_p(filename, 0755))
301 goto out_free; 328 goto out_free;
302 329
@@ -332,13 +359,14 @@ out_free:
332 359
333static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, 360static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
334 const char *name, const char *debugdir, 361 const char *name, const char *debugdir,
335 bool is_kallsyms) 362 bool is_kallsyms, bool is_vdso)
336{ 363{
337 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 364 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
338 365
339 build_id__sprintf(build_id, build_id_size, sbuild_id); 366 build_id__sprintf(build_id, build_id_size, sbuild_id);
340 367
341 return build_id_cache__add_s(sbuild_id, debugdir, name, is_kallsyms); 368 return build_id_cache__add_s(sbuild_id, debugdir, name,
369 is_kallsyms, is_vdso);
342} 370}
343 371
344int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) 372int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir)
@@ -382,9 +410,11 @@ out_free:
382static int dso__cache_build_id(struct dso *dso, const char *debugdir) 410static int dso__cache_build_id(struct dso *dso, const char *debugdir)
383{ 411{
384 bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; 412 bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
413 bool is_vdso = is_vdso_map(dso->short_name);
385 414
386 return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), 415 return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id),
387 dso->long_name, debugdir, is_kallsyms); 416 dso->long_name, debugdir,
417 is_kallsyms, is_vdso);
388} 418}
389 419
390static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) 420static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
@@ -446,7 +476,7 @@ static bool perf_session__read_build_ids(struct perf_session *session, bool with
446 return ret; 476 return ret;
447} 477}
448 478
449static int write_tracing_data(int fd, struct perf_header *h __used, 479static int write_tracing_data(int fd, struct perf_header *h __maybe_unused,
450 struct perf_evlist *evlist) 480 struct perf_evlist *evlist)
451{ 481{
452 return read_tracing_data(fd, &evlist->entries); 482 return read_tracing_data(fd, &evlist->entries);
@@ -454,7 +484,7 @@ static int write_tracing_data(int fd, struct perf_header *h __used,
454 484
455 485
456static int write_build_id(int fd, struct perf_header *h, 486static int write_build_id(int fd, struct perf_header *h,
457 struct perf_evlist *evlist __used) 487 struct perf_evlist *evlist __maybe_unused)
458{ 488{
459 struct perf_session *session; 489 struct perf_session *session;
460 int err; 490 int err;
@@ -475,8 +505,8 @@ static int write_build_id(int fd, struct perf_header *h,
475 return 0; 505 return 0;
476} 506}
477 507
478static int write_hostname(int fd, struct perf_header *h __used, 508static int write_hostname(int fd, struct perf_header *h __maybe_unused,
479 struct perf_evlist *evlist __used) 509 struct perf_evlist *evlist __maybe_unused)
480{ 510{
481 struct utsname uts; 511 struct utsname uts;
482 int ret; 512 int ret;
@@ -488,8 +518,8 @@ static int write_hostname(int fd, struct perf_header *h __used,
488 return do_write_string(fd, uts.nodename); 518 return do_write_string(fd, uts.nodename);
489} 519}
490 520
491static int write_osrelease(int fd, struct perf_header *h __used, 521static int write_osrelease(int fd, struct perf_header *h __maybe_unused,
492 struct perf_evlist *evlist __used) 522 struct perf_evlist *evlist __maybe_unused)
493{ 523{
494 struct utsname uts; 524 struct utsname uts;
495 int ret; 525 int ret;
@@ -501,8 +531,8 @@ static int write_osrelease(int fd, struct perf_header *h __used,
501 return do_write_string(fd, uts.release); 531 return do_write_string(fd, uts.release);
502} 532}
503 533
504static int write_arch(int fd, struct perf_header *h __used, 534static int write_arch(int fd, struct perf_header *h __maybe_unused,
505 struct perf_evlist *evlist __used) 535 struct perf_evlist *evlist __maybe_unused)
506{ 536{
507 struct utsname uts; 537 struct utsname uts;
508 int ret; 538 int ret;
@@ -514,14 +544,14 @@ static int write_arch(int fd, struct perf_header *h __used,
514 return do_write_string(fd, uts.machine); 544 return do_write_string(fd, uts.machine);
515} 545}
516 546
517static int write_version(int fd, struct perf_header *h __used, 547static int write_version(int fd, struct perf_header *h __maybe_unused,
518 struct perf_evlist *evlist __used) 548 struct perf_evlist *evlist __maybe_unused)
519{ 549{
520 return do_write_string(fd, perf_version_string); 550 return do_write_string(fd, perf_version_string);
521} 551}
522 552
523static int write_cpudesc(int fd, struct perf_header *h __used, 553static int write_cpudesc(int fd, struct perf_header *h __maybe_unused,
524 struct perf_evlist *evlist __used) 554 struct perf_evlist *evlist __maybe_unused)
525{ 555{
526#ifndef CPUINFO_PROC 556#ifndef CPUINFO_PROC
527#define CPUINFO_PROC NULL 557#define CPUINFO_PROC NULL
@@ -579,8 +609,8 @@ done:
579 return ret; 609 return ret;
580} 610}
581 611
582static int write_nrcpus(int fd, struct perf_header *h __used, 612static int write_nrcpus(int fd, struct perf_header *h __maybe_unused,
583 struct perf_evlist *evlist __used) 613 struct perf_evlist *evlist __maybe_unused)
584{ 614{
585 long nr; 615 long nr;
586 u32 nrc, nra; 616 u32 nrc, nra;
@@ -605,15 +635,14 @@ static int write_nrcpus(int fd, struct perf_header *h __used,
605 return do_write(fd, &nra, sizeof(nra)); 635 return do_write(fd, &nra, sizeof(nra));
606} 636}
607 637
608static int write_event_desc(int fd, struct perf_header *h __used, 638static int write_event_desc(int fd, struct perf_header *h __maybe_unused,
609 struct perf_evlist *evlist) 639 struct perf_evlist *evlist)
610{ 640{
611 struct perf_evsel *attr; 641 struct perf_evsel *evsel;
612 u32 nre = 0, nri, sz; 642 u32 nre, nri, sz;
613 int ret; 643 int ret;
614 644
615 list_for_each_entry(attr, &evlist->entries, node) 645 nre = evlist->nr_entries;
616 nre++;
617 646
618 /* 647 /*
619 * write number of events 648 * write number of events
@@ -625,14 +654,14 @@ static int write_event_desc(int fd, struct perf_header *h __used,
625 /* 654 /*
626 * size of perf_event_attr struct 655 * size of perf_event_attr struct
627 */ 656 */
628 sz = (u32)sizeof(attr->attr); 657 sz = (u32)sizeof(evsel->attr);
629 ret = do_write(fd, &sz, sizeof(sz)); 658 ret = do_write(fd, &sz, sizeof(sz));
630 if (ret < 0) 659 if (ret < 0)
631 return ret; 660 return ret;
632 661
633 list_for_each_entry(attr, &evlist->entries, node) { 662 list_for_each_entry(evsel, &evlist->entries, node) {
634 663
635 ret = do_write(fd, &attr->attr, sz); 664 ret = do_write(fd, &evsel->attr, sz);
636 if (ret < 0) 665 if (ret < 0)
637 return ret; 666 return ret;
638 /* 667 /*
@@ -642,7 +671,7 @@ static int write_event_desc(int fd, struct perf_header *h __used,
642 * copy into an nri to be independent of the 671 * copy into an nri to be independent of the
643 * type of ids, 672 * type of ids,
644 */ 673 */
645 nri = attr->ids; 674 nri = evsel->ids;
646 ret = do_write(fd, &nri, sizeof(nri)); 675 ret = do_write(fd, &nri, sizeof(nri));
647 if (ret < 0) 676 if (ret < 0)
648 return ret; 677 return ret;
@@ -650,21 +679,21 @@ static int write_event_desc(int fd, struct perf_header *h __used,
650 /* 679 /*
651 * write event string as passed on cmdline 680 * write event string as passed on cmdline
652 */ 681 */
653 ret = do_write_string(fd, perf_evsel__name(attr)); 682 ret = do_write_string(fd, perf_evsel__name(evsel));
654 if (ret < 0) 683 if (ret < 0)
655 return ret; 684 return ret;
656 /* 685 /*
657 * write unique ids for this event 686 * write unique ids for this event
658 */ 687 */
659 ret = do_write(fd, attr->id, attr->ids * sizeof(u64)); 688 ret = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
660 if (ret < 0) 689 if (ret < 0)
661 return ret; 690 return ret;
662 } 691 }
663 return 0; 692 return 0;
664} 693}
665 694
666static int write_cmdline(int fd, struct perf_header *h __used, 695static int write_cmdline(int fd, struct perf_header *h __maybe_unused,
667 struct perf_evlist *evlist __used) 696 struct perf_evlist *evlist __maybe_unused)
668{ 697{
669 char buf[MAXPATHLEN]; 698 char buf[MAXPATHLEN];
670 char proc[32]; 699 char proc[32];
@@ -832,8 +861,8 @@ static struct cpu_topo *build_cpu_topology(void)
832 return tp; 861 return tp;
833} 862}
834 863
835static int write_cpu_topology(int fd, struct perf_header *h __used, 864static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused,
836 struct perf_evlist *evlist __used) 865 struct perf_evlist *evlist __maybe_unused)
837{ 866{
838 struct cpu_topo *tp; 867 struct cpu_topo *tp;
839 u32 i; 868 u32 i;
@@ -868,8 +897,8 @@ done:
868 897
869 898
870 899
871static int write_total_mem(int fd, struct perf_header *h __used, 900static int write_total_mem(int fd, struct perf_header *h __maybe_unused,
872 struct perf_evlist *evlist __used) 901 struct perf_evlist *evlist __maybe_unused)
873{ 902{
874 char *buf = NULL; 903 char *buf = NULL;
875 FILE *fp; 904 FILE *fp;
@@ -954,8 +983,8 @@ done:
954 return ret; 983 return ret;
955} 984}
956 985
957static int write_numa_topology(int fd, struct perf_header *h __used, 986static int write_numa_topology(int fd, struct perf_header *h __maybe_unused,
958 struct perf_evlist *evlist __used) 987 struct perf_evlist *evlist __maybe_unused)
959{ 988{
960 char *buf = NULL; 989 char *buf = NULL;
961 size_t len = 0; 990 size_t len = 0;
@@ -1004,16 +1033,56 @@ done:
1004} 1033}
1005 1034
1006/* 1035/*
1036 * File format:
1037 *
1038 * struct pmu_mappings {
1039 * u32 pmu_num;
1040 * struct pmu_map {
1041 * u32 type;
1042 * char name[];
1043 * }[pmu_num];
1044 * };
1045 */
1046
1047static int write_pmu_mappings(int fd, struct perf_header *h __maybe_unused,
1048 struct perf_evlist *evlist __maybe_unused)
1049{
1050 struct perf_pmu *pmu = NULL;
1051 off_t offset = lseek(fd, 0, SEEK_CUR);
1052 __u32 pmu_num = 0;
1053
1054 /* write real pmu_num later */
1055 do_write(fd, &pmu_num, sizeof(pmu_num));
1056
1057 while ((pmu = perf_pmu__scan(pmu))) {
1058 if (!pmu->name)
1059 continue;
1060 pmu_num++;
1061 do_write(fd, &pmu->type, sizeof(pmu->type));
1062 do_write_string(fd, pmu->name);
1063 }
1064
1065 if (pwrite(fd, &pmu_num, sizeof(pmu_num), offset) != sizeof(pmu_num)) {
1066 /* discard all */
1067 lseek(fd, offset, SEEK_SET);
1068 return -1;
1069 }
1070
1071 return 0;
1072}
1073
1074/*
1007 * default get_cpuid(): nothing gets recorded 1075 * default get_cpuid(): nothing gets recorded
1008 * actual implementation must be in arch/$(ARCH)/util/header.c 1076 * actual implementation must be in arch/$(ARCH)/util/header.c
1009 */ 1077 */
1010int __attribute__((weak)) get_cpuid(char *buffer __used, size_t sz __used) 1078int __attribute__ ((weak)) get_cpuid(char *buffer __maybe_unused,
1079 size_t sz __maybe_unused)
1011{ 1080{
1012 return -1; 1081 return -1;
1013} 1082}
1014 1083
1015static int write_cpuid(int fd, struct perf_header *h __used, 1084static int write_cpuid(int fd, struct perf_header *h __maybe_unused,
1016 struct perf_evlist *evlist __used) 1085 struct perf_evlist *evlist __maybe_unused)
1017{ 1086{
1018 char buffer[64]; 1087 char buffer[64];
1019 int ret; 1088 int ret;
@@ -1027,133 +1096,113 @@ write_it:
1027 return do_write_string(fd, buffer); 1096 return do_write_string(fd, buffer);
1028} 1097}
1029 1098
1030static int write_branch_stack(int fd __used, struct perf_header *h __used, 1099static int write_branch_stack(int fd __maybe_unused,
1031 struct perf_evlist *evlist __used) 1100 struct perf_header *h __maybe_unused,
1101 struct perf_evlist *evlist __maybe_unused)
1032{ 1102{
1033 return 0; 1103 return 0;
1034} 1104}
1035 1105
1036static void print_hostname(struct perf_header *ph, int fd, FILE *fp) 1106static void print_hostname(struct perf_header *ph, int fd __maybe_unused,
1107 FILE *fp)
1037{ 1108{
1038 char *str = do_read_string(fd, ph); 1109 fprintf(fp, "# hostname : %s\n", ph->env.hostname);
1039 fprintf(fp, "# hostname : %s\n", str);
1040 free(str);
1041} 1110}
1042 1111
1043static void print_osrelease(struct perf_header *ph, int fd, FILE *fp) 1112static void print_osrelease(struct perf_header *ph, int fd __maybe_unused,
1113 FILE *fp)
1044{ 1114{
1045 char *str = do_read_string(fd, ph); 1115 fprintf(fp, "# os release : %s\n", ph->env.os_release);
1046 fprintf(fp, "# os release : %s\n", str);
1047 free(str);
1048} 1116}
1049 1117
1050static void print_arch(struct perf_header *ph, int fd, FILE *fp) 1118static void print_arch(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
1051{ 1119{
1052 char *str = do_read_string(fd, ph); 1120 fprintf(fp, "# arch : %s\n", ph->env.arch);
1053 fprintf(fp, "# arch : %s\n", str);
1054 free(str);
1055} 1121}
1056 1122
1057static void print_cpudesc(struct perf_header *ph, int fd, FILE *fp) 1123static void print_cpudesc(struct perf_header *ph, int fd __maybe_unused,
1124 FILE *fp)
1058{ 1125{
1059 char *str = do_read_string(fd, ph); 1126 fprintf(fp, "# cpudesc : %s\n", ph->env.cpu_desc);
1060 fprintf(fp, "# cpudesc : %s\n", str);
1061 free(str);
1062} 1127}
1063 1128
1064static void print_nrcpus(struct perf_header *ph, int fd, FILE *fp) 1129static void print_nrcpus(struct perf_header *ph, int fd __maybe_unused,
1130 FILE *fp)
1065{ 1131{
1066 ssize_t ret; 1132 fprintf(fp, "# nrcpus online : %u\n", ph->env.nr_cpus_online);
1067 u32 nr; 1133 fprintf(fp, "# nrcpus avail : %u\n", ph->env.nr_cpus_avail);
1068
1069 ret = read(fd, &nr, sizeof(nr));
1070 if (ret != (ssize_t)sizeof(nr))
1071 nr = -1; /* interpreted as error */
1072
1073 if (ph->needs_swap)
1074 nr = bswap_32(nr);
1075
1076 fprintf(fp, "# nrcpus online : %u\n", nr);
1077
1078 ret = read(fd, &nr, sizeof(nr));
1079 if (ret != (ssize_t)sizeof(nr))
1080 nr = -1; /* interpreted as error */
1081
1082 if (ph->needs_swap)
1083 nr = bswap_32(nr);
1084
1085 fprintf(fp, "# nrcpus avail : %u\n", nr);
1086} 1134}
1087 1135
1088static void print_version(struct perf_header *ph, int fd, FILE *fp) 1136static void print_version(struct perf_header *ph, int fd __maybe_unused,
1137 FILE *fp)
1089{ 1138{
1090 char *str = do_read_string(fd, ph); 1139 fprintf(fp, "# perf version : %s\n", ph->env.version);
1091 fprintf(fp, "# perf version : %s\n", str);
1092 free(str);
1093} 1140}
1094 1141
1095static void print_cmdline(struct perf_header *ph, int fd, FILE *fp) 1142static void print_cmdline(struct perf_header *ph, int fd __maybe_unused,
1143 FILE *fp)
1096{ 1144{
1097 ssize_t ret; 1145 int nr, i;
1098 char *str; 1146 char *str;
1099 u32 nr, i;
1100
1101 ret = read(fd, &nr, sizeof(nr));
1102 if (ret != (ssize_t)sizeof(nr))
1103 return;
1104 1147
1105 if (ph->needs_swap) 1148 nr = ph->env.nr_cmdline;
1106 nr = bswap_32(nr); 1149 str = ph->env.cmdline;
1107 1150
1108 fprintf(fp, "# cmdline : "); 1151 fprintf(fp, "# cmdline : ");
1109 1152
1110 for (i = 0; i < nr; i++) { 1153 for (i = 0; i < nr; i++) {
1111 str = do_read_string(fd, ph);
1112 fprintf(fp, "%s ", str); 1154 fprintf(fp, "%s ", str);
1113 free(str); 1155 str += strlen(str) + 1;
1114 } 1156 }
1115 fputc('\n', fp); 1157 fputc('\n', fp);
1116} 1158}
1117 1159
1118static void print_cpu_topology(struct perf_header *ph, int fd, FILE *fp) 1160static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
1161 FILE *fp)
1119{ 1162{
1120 ssize_t ret; 1163 int nr, i;
1121 u32 nr, i;
1122 char *str; 1164 char *str;
1123 1165
1124 ret = read(fd, &nr, sizeof(nr)); 1166 nr = ph->env.nr_sibling_cores;
1125 if (ret != (ssize_t)sizeof(nr)) 1167 str = ph->env.sibling_cores;
1126 return;
1127
1128 if (ph->needs_swap)
1129 nr = bswap_32(nr);
1130 1168
1131 for (i = 0; i < nr; i++) { 1169 for (i = 0; i < nr; i++) {
1132 str = do_read_string(fd, ph);
1133 fprintf(fp, "# sibling cores : %s\n", str); 1170 fprintf(fp, "# sibling cores : %s\n", str);
1134 free(str); 1171 str += strlen(str) + 1;
1135 } 1172 }
1136 1173
1137 ret = read(fd, &nr, sizeof(nr)); 1174 nr = ph->env.nr_sibling_threads;
1138 if (ret != (ssize_t)sizeof(nr)) 1175 str = ph->env.sibling_threads;
1139 return;
1140
1141 if (ph->needs_swap)
1142 nr = bswap_32(nr);
1143 1176
1144 for (i = 0; i < nr; i++) { 1177 for (i = 0; i < nr; i++) {
1145 str = do_read_string(fd, ph);
1146 fprintf(fp, "# sibling threads : %s\n", str); 1178 fprintf(fp, "# sibling threads : %s\n", str);
1147 free(str); 1179 str += strlen(str) + 1;
1148 } 1180 }
1149} 1181}
1150 1182
1151static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) 1183static void free_event_desc(struct perf_evsel *events)
1184{
1185 struct perf_evsel *evsel;
1186
1187 if (!events)
1188 return;
1189
1190 for (evsel = events; evsel->attr.size; evsel++) {
1191 if (evsel->name)
1192 free(evsel->name);
1193 if (evsel->id)
1194 free(evsel->id);
1195 }
1196
1197 free(events);
1198}
1199
1200static struct perf_evsel *
1201read_event_desc(struct perf_header *ph, int fd)
1152{ 1202{
1153 struct perf_event_attr attr; 1203 struct perf_evsel *evsel, *events = NULL;
1154 uint64_t id; 1204 u64 *id;
1155 void *buf = NULL; 1205 void *buf = NULL;
1156 char *str;
1157 u32 nre, sz, nr, i, j; 1206 u32 nre, sz, nr, i, j;
1158 ssize_t ret; 1207 ssize_t ret;
1159 size_t msz; 1208 size_t msz;
@@ -1173,18 +1222,22 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
1173 if (ph->needs_swap) 1222 if (ph->needs_swap)
1174 sz = bswap_32(sz); 1223 sz = bswap_32(sz);
1175 1224
1176 memset(&attr, 0, sizeof(attr));
1177
1178 /* buffer to hold on file attr struct */ 1225 /* buffer to hold on file attr struct */
1179 buf = malloc(sz); 1226 buf = malloc(sz);
1180 if (!buf) 1227 if (!buf)
1181 goto error; 1228 goto error;
1182 1229
1183 msz = sizeof(attr); 1230 /* the last event terminates with evsel->attr.size == 0: */
1231 events = calloc(nre + 1, sizeof(*events));
1232 if (!events)
1233 goto error;
1234
1235 msz = sizeof(evsel->attr);
1184 if (sz < msz) 1236 if (sz < msz)
1185 msz = sz; 1237 msz = sz;
1186 1238
1187 for (i = 0 ; i < nre; i++) { 1239 for (i = 0, evsel = events; i < nre; evsel++, i++) {
1240 evsel->idx = i;
1188 1241
1189 /* 1242 /*
1190 * must read entire on-file attr struct to 1243 * must read entire on-file attr struct to
@@ -1197,146 +1250,188 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
1197 if (ph->needs_swap) 1250 if (ph->needs_swap)
1198 perf_event__attr_swap(buf); 1251 perf_event__attr_swap(buf);
1199 1252
1200 memcpy(&attr, buf, msz); 1253 memcpy(&evsel->attr, buf, msz);
1201 1254
1202 ret = read(fd, &nr, sizeof(nr)); 1255 ret = read(fd, &nr, sizeof(nr));
1203 if (ret != (ssize_t)sizeof(nr)) 1256 if (ret != (ssize_t)sizeof(nr))
1204 goto error; 1257 goto error;
1205 1258
1206 if (ph->needs_swap) 1259 if (ph->needs_swap) {
1207 nr = bswap_32(nr); 1260 nr = bswap_32(nr);
1261 evsel->needs_swap = true;
1262 }
1208 1263
1209 str = do_read_string(fd, ph); 1264 evsel->name = do_read_string(fd, ph);
1210 fprintf(fp, "# event : name = %s, ", str); 1265
1211 free(str); 1266 if (!nr)
1267 continue;
1268
1269 id = calloc(nr, sizeof(*id));
1270 if (!id)
1271 goto error;
1272 evsel->ids = nr;
1273 evsel->id = id;
1274
1275 for (j = 0 ; j < nr; j++) {
1276 ret = read(fd, id, sizeof(*id));
1277 if (ret != (ssize_t)sizeof(*id))
1278 goto error;
1279 if (ph->needs_swap)
1280 *id = bswap_64(*id);
1281 id++;
1282 }
1283 }
1284out:
1285 if (buf)
1286 free(buf);
1287 return events;
1288error:
1289 if (events)
1290 free_event_desc(events);
1291 events = NULL;
1292 goto out;
1293}
1294
1295static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
1296{
1297 struct perf_evsel *evsel, *events = read_event_desc(ph, fd);
1298 u32 j;
1299 u64 *id;
1300
1301 if (!events) {
1302 fprintf(fp, "# event desc: not available or unable to read\n");
1303 return;
1304 }
1305
1306 for (evsel = events; evsel->attr.size; evsel++) {
1307 fprintf(fp, "# event : name = %s, ", evsel->name);
1212 1308
1213 fprintf(fp, "type = %d, config = 0x%"PRIx64 1309 fprintf(fp, "type = %d, config = 0x%"PRIx64
1214 ", config1 = 0x%"PRIx64", config2 = 0x%"PRIx64, 1310 ", config1 = 0x%"PRIx64", config2 = 0x%"PRIx64,
1215 attr.type, 1311 evsel->attr.type,
1216 (u64)attr.config, 1312 (u64)evsel->attr.config,
1217 (u64)attr.config1, 1313 (u64)evsel->attr.config1,
1218 (u64)attr.config2); 1314 (u64)evsel->attr.config2);
1219 1315
1220 fprintf(fp, ", excl_usr = %d, excl_kern = %d", 1316 fprintf(fp, ", excl_usr = %d, excl_kern = %d",
1221 attr.exclude_user, 1317 evsel->attr.exclude_user,
1222 attr.exclude_kernel); 1318 evsel->attr.exclude_kernel);
1223 1319
1224 fprintf(fp, ", excl_host = %d, excl_guest = %d", 1320 fprintf(fp, ", excl_host = %d, excl_guest = %d",
1225 attr.exclude_host, 1321 evsel->attr.exclude_host,
1226 attr.exclude_guest); 1322 evsel->attr.exclude_guest);
1227 1323
1228 fprintf(fp, ", precise_ip = %d", attr.precise_ip); 1324 fprintf(fp, ", precise_ip = %d", evsel->attr.precise_ip);
1229 1325
1230 if (nr) 1326 if (evsel->ids) {
1231 fprintf(fp, ", id = {"); 1327 fprintf(fp, ", id = {");
1232 1328 for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) {
1233 for (j = 0 ; j < nr; j++) { 1329 if (j)
1234 ret = read(fd, &id, sizeof(id)); 1330 fputc(',', fp);
1235 if (ret != (ssize_t)sizeof(id)) 1331 fprintf(fp, " %"PRIu64, *id);
1236 goto error; 1332 }
1237
1238 if (ph->needs_swap)
1239 id = bswap_64(id);
1240
1241 if (j)
1242 fputc(',', fp);
1243
1244 fprintf(fp, " %"PRIu64, id);
1245 }
1246 if (nr && j == nr)
1247 fprintf(fp, " }"); 1333 fprintf(fp, " }");
1334 }
1335
1248 fputc('\n', fp); 1336 fputc('\n', fp);
1249 } 1337 }
1250 free(buf); 1338
1251 return; 1339 free_event_desc(events);
1252error:
1253 fprintf(fp, "# event desc: not available or unable to read\n");
1254} 1340}
1255 1341
1256static void print_total_mem(struct perf_header *h __used, int fd, FILE *fp) 1342static void print_total_mem(struct perf_header *ph, int fd __maybe_unused,
1343 FILE *fp)
1257{ 1344{
1258 uint64_t mem; 1345 fprintf(fp, "# total memory : %Lu kB\n", ph->env.total_mem);
1259 ssize_t ret;
1260
1261 ret = read(fd, &mem, sizeof(mem));
1262 if (ret != sizeof(mem))
1263 goto error;
1264
1265 if (h->needs_swap)
1266 mem = bswap_64(mem);
1267
1268 fprintf(fp, "# total memory : %"PRIu64" kB\n", mem);
1269 return;
1270error:
1271 fprintf(fp, "# total memory : unknown\n");
1272} 1346}
1273 1347
1274static void print_numa_topology(struct perf_header *h __used, int fd, FILE *fp) 1348static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused,
1349 FILE *fp)
1275{ 1350{
1276 ssize_t ret;
1277 u32 nr, c, i; 1351 u32 nr, c, i;
1278 char *str; 1352 char *str, *tmp;
1279 uint64_t mem_total, mem_free; 1353 uint64_t mem_total, mem_free;
1280 1354
1281 /* nr nodes */ 1355 /* nr nodes */
1282 ret = read(fd, &nr, sizeof(nr)); 1356 nr = ph->env.nr_numa_nodes;
1283 if (ret != (ssize_t)sizeof(nr)) 1357 str = ph->env.numa_nodes;
1284 goto error;
1285
1286 if (h->needs_swap)
1287 nr = bswap_32(nr);
1288 1358
1289 for (i = 0; i < nr; i++) { 1359 for (i = 0; i < nr; i++) {
1290
1291 /* node number */ 1360 /* node number */
1292 ret = read(fd, &c, sizeof(c)); 1361 c = strtoul(str, &tmp, 0);
1293 if (ret != (ssize_t)sizeof(c)) 1362 if (*tmp != ':')
1294 goto error; 1363 goto error;
1295 1364
1296 if (h->needs_swap) 1365 str = tmp + 1;
1297 c = bswap_32(c); 1366 mem_total = strtoull(str, &tmp, 0);
1298 1367 if (*tmp != ':')
1299 ret = read(fd, &mem_total, sizeof(u64));
1300 if (ret != sizeof(u64))
1301 goto error; 1368 goto error;
1302 1369
1303 ret = read(fd, &mem_free, sizeof(u64)); 1370 str = tmp + 1;
1304 if (ret != sizeof(u64)) 1371 mem_free = strtoull(str, &tmp, 0);
1372 if (*tmp != ':')
1305 goto error; 1373 goto error;
1306 1374
1307 if (h->needs_swap) {
1308 mem_total = bswap_64(mem_total);
1309 mem_free = bswap_64(mem_free);
1310 }
1311
1312 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB," 1375 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB,"
1313 " free = %"PRIu64" kB\n", 1376 " free = %"PRIu64" kB\n",
1314 c, 1377 c, mem_total, mem_free);
1315 mem_total,
1316 mem_free);
1317 1378
1318 str = do_read_string(fd, h); 1379 str = tmp + 1;
1319 fprintf(fp, "# node%u cpu list : %s\n", c, str); 1380 fprintf(fp, "# node%u cpu list : %s\n", c, str);
1320 free(str);
1321 } 1381 }
1322 return; 1382 return;
1323error: 1383error:
1324 fprintf(fp, "# numa topology : not available\n"); 1384 fprintf(fp, "# numa topology : not available\n");
1325} 1385}
1326 1386
1327static void print_cpuid(struct perf_header *ph, int fd, FILE *fp) 1387static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
1328{ 1388{
1329 char *str = do_read_string(fd, ph); 1389 fprintf(fp, "# cpuid : %s\n", ph->env.cpuid);
1330 fprintf(fp, "# cpuid : %s\n", str);
1331 free(str);
1332} 1390}
1333 1391
1334static void print_branch_stack(struct perf_header *ph __used, int fd __used, 1392static void print_branch_stack(struct perf_header *ph __maybe_unused,
1335 FILE *fp) 1393 int fd __maybe_unused, FILE *fp)
1336{ 1394{
1337 fprintf(fp, "# contains samples with branch stack\n"); 1395 fprintf(fp, "# contains samples with branch stack\n");
1338} 1396}
1339 1397
1398static void print_pmu_mappings(struct perf_header *ph, int fd __maybe_unused,
1399 FILE *fp)
1400{
1401 const char *delimiter = "# pmu mappings: ";
1402 char *str, *tmp;
1403 u32 pmu_num;
1404 u32 type;
1405
1406 pmu_num = ph->env.nr_pmu_mappings;
1407 if (!pmu_num) {
1408 fprintf(fp, "# pmu mappings: not available\n");
1409 return;
1410 }
1411
1412 str = ph->env.pmu_mappings;
1413
1414 while (pmu_num) {
1415 type = strtoul(str, &tmp, 0);
1416 if (*tmp != ':')
1417 goto error;
1418
1419 str = tmp + 1;
1420 fprintf(fp, "%s%s = %" PRIu32, delimiter, str, type);
1421
1422 delimiter = ", ";
1423 str += strlen(str) + 1;
1424 pmu_num--;
1425 }
1426
1427 fprintf(fp, "\n");
1428
1429 if (!pmu_num)
1430 return;
1431error:
1432 fprintf(fp, "# pmu mappings: unable to read\n");
1433}
1434
1340static int __event_process_build_id(struct build_id_event *bev, 1435static int __event_process_build_id(struct build_id_event *bev,
1341 char *filename, 1436 char *filename,
1342 struct perf_session *session) 1437 struct perf_session *session)
@@ -1398,7 +1493,7 @@ static int perf_header__read_build_ids_abi_quirk(struct perf_header *header,
1398 struct perf_session *session = container_of(header, struct perf_session, header); 1493 struct perf_session *session = container_of(header, struct perf_session, header);
1399 struct { 1494 struct {
1400 struct perf_event_header header; 1495 struct perf_event_header header;
1401 u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))]; 1496 u8 build_id[PERF_ALIGN(BUILD_ID_SIZE, sizeof(u64))];
1402 char filename[0]; 1497 char filename[0];
1403 } old_bev; 1498 } old_bev;
1404 struct build_id_event bev; 1499 struct build_id_event bev;
@@ -1487,28 +1582,375 @@ out:
1487 return err; 1582 return err;
1488} 1583}
1489 1584
1490static int process_tracing_data(struct perf_file_section *section __unused, 1585static int process_tracing_data(struct perf_file_section *section __maybe_unused,
1491 struct perf_header *ph __unused, 1586 struct perf_header *ph __maybe_unused,
1492 int feat __unused, int fd, void *data) 1587 int fd, void *data)
1493{ 1588{
1494 trace_report(fd, data, false); 1589 trace_report(fd, data, false);
1495 return 0; 1590 return 0;
1496} 1591}
1497 1592
1498static int process_build_id(struct perf_file_section *section, 1593static int process_build_id(struct perf_file_section *section,
1499 struct perf_header *ph, 1594 struct perf_header *ph, int fd,
1500 int feat __unused, int fd, void *data __used) 1595 void *data __maybe_unused)
1501{ 1596{
1502 if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) 1597 if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
1503 pr_debug("Failed to read buildids, continuing...\n"); 1598 pr_debug("Failed to read buildids, continuing...\n");
1504 return 0; 1599 return 0;
1505} 1600}
1506 1601
1602static int process_hostname(struct perf_file_section *section __maybe_unused,
1603 struct perf_header *ph, int fd,
1604 void *data __maybe_unused)
1605{
1606 ph->env.hostname = do_read_string(fd, ph);
1607 return ph->env.hostname ? 0 : -ENOMEM;
1608}
1609
1610static int process_osrelease(struct perf_file_section *section __maybe_unused,
1611 struct perf_header *ph, int fd,
1612 void *data __maybe_unused)
1613{
1614 ph->env.os_release = do_read_string(fd, ph);
1615 return ph->env.os_release ? 0 : -ENOMEM;
1616}
1617
1618static int process_version(struct perf_file_section *section __maybe_unused,
1619 struct perf_header *ph, int fd,
1620 void *data __maybe_unused)
1621{
1622 ph->env.version = do_read_string(fd, ph);
1623 return ph->env.version ? 0 : -ENOMEM;
1624}
1625
1626static int process_arch(struct perf_file_section *section __maybe_unused,
1627 struct perf_header *ph, int fd,
1628 void *data __maybe_unused)
1629{
1630 ph->env.arch = do_read_string(fd, ph);
1631 return ph->env.arch ? 0 : -ENOMEM;
1632}
1633
1634static int process_nrcpus(struct perf_file_section *section __maybe_unused,
1635 struct perf_header *ph, int fd,
1636 void *data __maybe_unused)
1637{
1638 size_t ret;
1639 u32 nr;
1640
1641 ret = read(fd, &nr, sizeof(nr));
1642 if (ret != sizeof(nr))
1643 return -1;
1644
1645 if (ph->needs_swap)
1646 nr = bswap_32(nr);
1647
1648 ph->env.nr_cpus_online = nr;
1649
1650 ret = read(fd, &nr, sizeof(nr));
1651 if (ret != sizeof(nr))
1652 return -1;
1653
1654 if (ph->needs_swap)
1655 nr = bswap_32(nr);
1656
1657 ph->env.nr_cpus_avail = nr;
1658 return 0;
1659}
1660
1661static int process_cpudesc(struct perf_file_section *section __maybe_unused,
1662 struct perf_header *ph, int fd,
1663 void *data __maybe_unused)
1664{
1665 ph->env.cpu_desc = do_read_string(fd, ph);
1666 return ph->env.cpu_desc ? 0 : -ENOMEM;
1667}
1668
1669static int process_cpuid(struct perf_file_section *section __maybe_unused,
1670 struct perf_header *ph, int fd,
1671 void *data __maybe_unused)
1672{
1673 ph->env.cpuid = do_read_string(fd, ph);
1674 return ph->env.cpuid ? 0 : -ENOMEM;
1675}
1676
1677static int process_total_mem(struct perf_file_section *section __maybe_unused,
1678 struct perf_header *ph, int fd,
1679 void *data __maybe_unused)
1680{
1681 uint64_t mem;
1682 size_t ret;
1683
1684 ret = read(fd, &mem, sizeof(mem));
1685 if (ret != sizeof(mem))
1686 return -1;
1687
1688 if (ph->needs_swap)
1689 mem = bswap_64(mem);
1690
1691 ph->env.total_mem = mem;
1692 return 0;
1693}
1694
1695static struct perf_evsel *
1696perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
1697{
1698 struct perf_evsel *evsel;
1699
1700 list_for_each_entry(evsel, &evlist->entries, node) {
1701 if (evsel->idx == idx)
1702 return evsel;
1703 }
1704
1705 return NULL;
1706}
1707
1708static void
1709perf_evlist__set_event_name(struct perf_evlist *evlist,
1710 struct perf_evsel *event)
1711{
1712 struct perf_evsel *evsel;
1713
1714 if (!event->name)
1715 return;
1716
1717 evsel = perf_evlist__find_by_index(evlist, event->idx);
1718 if (!evsel)
1719 return;
1720
1721 if (evsel->name)
1722 return;
1723
1724 evsel->name = strdup(event->name);
1725}
1726
1727static int
1728process_event_desc(struct perf_file_section *section __maybe_unused,
1729 struct perf_header *header, int fd,
1730 void *data __maybe_unused)
1731{
1732 struct perf_session *session;
1733 struct perf_evsel *evsel, *events = read_event_desc(header, fd);
1734
1735 if (!events)
1736 return 0;
1737
1738 session = container_of(header, struct perf_session, header);
1739 for (evsel = events; evsel->attr.size; evsel++)
1740 perf_evlist__set_event_name(session->evlist, evsel);
1741
1742 free_event_desc(events);
1743
1744 return 0;
1745}
1746
1747static int process_cmdline(struct perf_file_section *section __maybe_unused,
1748 struct perf_header *ph, int fd,
1749 void *data __maybe_unused)
1750{
1751 size_t ret;
1752 char *str;
1753 u32 nr, i;
1754 struct strbuf sb;
1755
1756 ret = read(fd, &nr, sizeof(nr));
1757 if (ret != sizeof(nr))
1758 return -1;
1759
1760 if (ph->needs_swap)
1761 nr = bswap_32(nr);
1762
1763 ph->env.nr_cmdline = nr;
1764 strbuf_init(&sb, 128);
1765
1766 for (i = 0; i < nr; i++) {
1767 str = do_read_string(fd, ph);
1768 if (!str)
1769 goto error;
1770
1771 /* include a NULL character at the end */
1772 strbuf_add(&sb, str, strlen(str) + 1);
1773 free(str);
1774 }
1775 ph->env.cmdline = strbuf_detach(&sb, NULL);
1776 return 0;
1777
1778error:
1779 strbuf_release(&sb);
1780 return -1;
1781}
1782
1783static int process_cpu_topology(struct perf_file_section *section __maybe_unused,
1784 struct perf_header *ph, int fd,
1785 void *data __maybe_unused)
1786{
1787 size_t ret;
1788 u32 nr, i;
1789 char *str;
1790 struct strbuf sb;
1791
1792 ret = read(fd, &nr, sizeof(nr));
1793 if (ret != sizeof(nr))
1794 return -1;
1795
1796 if (ph->needs_swap)
1797 nr = bswap_32(nr);
1798
1799 ph->env.nr_sibling_cores = nr;
1800 strbuf_init(&sb, 128);
1801
1802 for (i = 0; i < nr; i++) {
1803 str = do_read_string(fd, ph);
1804 if (!str)
1805 goto error;
1806
1807 /* include a NULL character at the end */
1808 strbuf_add(&sb, str, strlen(str) + 1);
1809 free(str);
1810 }
1811 ph->env.sibling_cores = strbuf_detach(&sb, NULL);
1812
1813 ret = read(fd, &nr, sizeof(nr));
1814 if (ret != sizeof(nr))
1815 return -1;
1816
1817 if (ph->needs_swap)
1818 nr = bswap_32(nr);
1819
1820 ph->env.nr_sibling_threads = nr;
1821
1822 for (i = 0; i < nr; i++) {
1823 str = do_read_string(fd, ph);
1824 if (!str)
1825 goto error;
1826
1827 /* include a NULL character at the end */
1828 strbuf_add(&sb, str, strlen(str) + 1);
1829 free(str);
1830 }
1831 ph->env.sibling_threads = strbuf_detach(&sb, NULL);
1832 return 0;
1833
1834error:
1835 strbuf_release(&sb);
1836 return -1;
1837}
1838
1839static int process_numa_topology(struct perf_file_section *section __maybe_unused,
1840 struct perf_header *ph, int fd,
1841 void *data __maybe_unused)
1842{
1843 size_t ret;
1844 u32 nr, node, i;
1845 char *str;
1846 uint64_t mem_total, mem_free;
1847 struct strbuf sb;
1848
1849 /* nr nodes */
1850 ret = read(fd, &nr, sizeof(nr));
1851 if (ret != sizeof(nr))
1852 goto error;
1853
1854 if (ph->needs_swap)
1855 nr = bswap_32(nr);
1856
1857 ph->env.nr_numa_nodes = nr;
1858 strbuf_init(&sb, 256);
1859
1860 for (i = 0; i < nr; i++) {
1861 /* node number */
1862 ret = read(fd, &node, sizeof(node));
1863 if (ret != sizeof(node))
1864 goto error;
1865
1866 ret = read(fd, &mem_total, sizeof(u64));
1867 if (ret != sizeof(u64))
1868 goto error;
1869
1870 ret = read(fd, &mem_free, sizeof(u64));
1871 if (ret != sizeof(u64))
1872 goto error;
1873
1874 if (ph->needs_swap) {
1875 node = bswap_32(node);
1876 mem_total = bswap_64(mem_total);
1877 mem_free = bswap_64(mem_free);
1878 }
1879
1880 strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":",
1881 node, mem_total, mem_free);
1882
1883 str = do_read_string(fd, ph);
1884 if (!str)
1885 goto error;
1886
1887 /* include a NULL character at the end */
1888 strbuf_add(&sb, str, strlen(str) + 1);
1889 free(str);
1890 }
1891 ph->env.numa_nodes = strbuf_detach(&sb, NULL);
1892 return 0;
1893
1894error:
1895 strbuf_release(&sb);
1896 return -1;
1897}
1898
1899static int process_pmu_mappings(struct perf_file_section *section __maybe_unused,
1900 struct perf_header *ph, int fd,
1901 void *data __maybe_unused)
1902{
1903 size_t ret;
1904 char *name;
1905 u32 pmu_num;
1906 u32 type;
1907 struct strbuf sb;
1908
1909 ret = read(fd, &pmu_num, sizeof(pmu_num));
1910 if (ret != sizeof(pmu_num))
1911 return -1;
1912
1913 if (ph->needs_swap)
1914 pmu_num = bswap_32(pmu_num);
1915
1916 if (!pmu_num) {
1917 pr_debug("pmu mappings not available\n");
1918 return 0;
1919 }
1920
1921 ph->env.nr_pmu_mappings = pmu_num;
1922 strbuf_init(&sb, 128);
1923
1924 while (pmu_num) {
1925 if (read(fd, &type, sizeof(type)) != sizeof(type))
1926 goto error;
1927 if (ph->needs_swap)
1928 type = bswap_32(type);
1929
1930 name = do_read_string(fd, ph);
1931 if (!name)
1932 goto error;
1933
1934 strbuf_addf(&sb, "%u:%s", type, name);
1935 /* include a NULL character at the end */
1936 strbuf_add(&sb, "", 1);
1937
1938 free(name);
1939 pmu_num--;
1940 }
1941 ph->env.pmu_mappings = strbuf_detach(&sb, NULL);
1942 return 0;
1943
1944error:
1945 strbuf_release(&sb);
1946 return -1;
1947}
1948
1507struct feature_ops { 1949struct feature_ops {
1508 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); 1950 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
1509 void (*print)(struct perf_header *h, int fd, FILE *fp); 1951 void (*print)(struct perf_header *h, int fd, FILE *fp);
1510 int (*process)(struct perf_file_section *section, 1952 int (*process)(struct perf_file_section *section,
1511 struct perf_header *h, int feat, int fd, void *data); 1953 struct perf_header *h, int fd, void *data);
1512 const char *name; 1954 const char *name;
1513 bool full_only; 1955 bool full_only;
1514}; 1956};
@@ -1520,7 +1962,7 @@ struct feature_ops {
1520 .process = process_##func } 1962 .process = process_##func }
1521#define FEAT_OPF(n, func) \ 1963#define FEAT_OPF(n, func) \
1522 [n] = { .name = #n, .write = write_##func, .print = print_##func, \ 1964 [n] = { .name = #n, .write = write_##func, .print = print_##func, \
1523 .full_only = true } 1965 .process = process_##func, .full_only = true }
1524 1966
1525/* feature_ops not implemented: */ 1967/* feature_ops not implemented: */
1526#define print_tracing_data NULL 1968#define print_tracing_data NULL
@@ -1529,19 +1971,20 @@ struct feature_ops {
1529static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { 1971static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
1530 FEAT_OPP(HEADER_TRACING_DATA, tracing_data), 1972 FEAT_OPP(HEADER_TRACING_DATA, tracing_data),
1531 FEAT_OPP(HEADER_BUILD_ID, build_id), 1973 FEAT_OPP(HEADER_BUILD_ID, build_id),
1532 FEAT_OPA(HEADER_HOSTNAME, hostname), 1974 FEAT_OPP(HEADER_HOSTNAME, hostname),
1533 FEAT_OPA(HEADER_OSRELEASE, osrelease), 1975 FEAT_OPP(HEADER_OSRELEASE, osrelease),
1534 FEAT_OPA(HEADER_VERSION, version), 1976 FEAT_OPP(HEADER_VERSION, version),
1535 FEAT_OPA(HEADER_ARCH, arch), 1977 FEAT_OPP(HEADER_ARCH, arch),
1536 FEAT_OPA(HEADER_NRCPUS, nrcpus), 1978 FEAT_OPP(HEADER_NRCPUS, nrcpus),
1537 FEAT_OPA(HEADER_CPUDESC, cpudesc), 1979 FEAT_OPP(HEADER_CPUDESC, cpudesc),
1538 FEAT_OPA(HEADER_CPUID, cpuid), 1980 FEAT_OPP(HEADER_CPUID, cpuid),
1539 FEAT_OPA(HEADER_TOTAL_MEM, total_mem), 1981 FEAT_OPP(HEADER_TOTAL_MEM, total_mem),
1540 FEAT_OPA(HEADER_EVENT_DESC, event_desc), 1982 FEAT_OPP(HEADER_EVENT_DESC, event_desc),
1541 FEAT_OPA(HEADER_CMDLINE, cmdline), 1983 FEAT_OPP(HEADER_CMDLINE, cmdline),
1542 FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology), 1984 FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology),
1543 FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology), 1985 FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology),
1544 FEAT_OPA(HEADER_BRANCH_STACK, branch_stack), 1986 FEAT_OPA(HEADER_BRANCH_STACK, branch_stack),
1987 FEAT_OPP(HEADER_PMU_MAPPINGS, pmu_mappings),
1545}; 1988};
1546 1989
1547struct header_print_data { 1990struct header_print_data {
@@ -1683,17 +2126,17 @@ int perf_session__write_header(struct perf_session *session,
1683 struct perf_file_header f_header; 2126 struct perf_file_header f_header;
1684 struct perf_file_attr f_attr; 2127 struct perf_file_attr f_attr;
1685 struct perf_header *header = &session->header; 2128 struct perf_header *header = &session->header;
1686 struct perf_evsel *attr, *pair = NULL; 2129 struct perf_evsel *evsel, *pair = NULL;
1687 int err; 2130 int err;
1688 2131
1689 lseek(fd, sizeof(f_header), SEEK_SET); 2132 lseek(fd, sizeof(f_header), SEEK_SET);
1690 2133
1691 if (session->evlist != evlist) 2134 if (session->evlist != evlist)
1692 pair = list_entry(session->evlist->entries.next, struct perf_evsel, node); 2135 pair = perf_evlist__first(session->evlist);
1693 2136
1694 list_for_each_entry(attr, &evlist->entries, node) { 2137 list_for_each_entry(evsel, &evlist->entries, node) {
1695 attr->id_offset = lseek(fd, 0, SEEK_CUR); 2138 evsel->id_offset = lseek(fd, 0, SEEK_CUR);
1696 err = do_write(fd, attr->id, attr->ids * sizeof(u64)); 2139 err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
1697 if (err < 0) { 2140 if (err < 0) {
1698out_err_write: 2141out_err_write:
1699 pr_debug("failed to write perf header\n"); 2142 pr_debug("failed to write perf header\n");
@@ -1703,19 +2146,19 @@ out_err_write:
1703 err = do_write(fd, pair->id, pair->ids * sizeof(u64)); 2146 err = do_write(fd, pair->id, pair->ids * sizeof(u64));
1704 if (err < 0) 2147 if (err < 0)
1705 goto out_err_write; 2148 goto out_err_write;
1706 attr->ids += pair->ids; 2149 evsel->ids += pair->ids;
1707 pair = list_entry(pair->node.next, struct perf_evsel, node); 2150 pair = perf_evsel__next(pair);
1708 } 2151 }
1709 } 2152 }
1710 2153
1711 header->attr_offset = lseek(fd, 0, SEEK_CUR); 2154 header->attr_offset = lseek(fd, 0, SEEK_CUR);
1712 2155
1713 list_for_each_entry(attr, &evlist->entries, node) { 2156 list_for_each_entry(evsel, &evlist->entries, node) {
1714 f_attr = (struct perf_file_attr){ 2157 f_attr = (struct perf_file_attr){
1715 .attr = attr->attr, 2158 .attr = evsel->attr,
1716 .ids = { 2159 .ids = {
1717 .offset = attr->id_offset, 2160 .offset = evsel->id_offset,
1718 .size = attr->ids * sizeof(u64), 2161 .size = evsel->ids * sizeof(u64),
1719 } 2162 }
1720 }; 2163 };
1721 err = do_write(fd, &f_attr, sizeof(f_attr)); 2164 err = do_write(fd, &f_attr, sizeof(f_attr));
@@ -1726,9 +2169,9 @@ out_err_write:
1726 } 2169 }
1727 2170
1728 header->event_offset = lseek(fd, 0, SEEK_CUR); 2171 header->event_offset = lseek(fd, 0, SEEK_CUR);
1729 header->event_size = event_count * sizeof(struct perf_trace_event_type); 2172 header->event_size = trace_event_count * sizeof(struct perf_trace_event_type);
1730 if (events) { 2173 if (trace_events) {
1731 err = do_write(fd, events, header->event_size); 2174 err = do_write(fd, trace_events, header->event_size);
1732 if (err < 0) { 2175 if (err < 0) {
1733 pr_debug("failed to write perf header events\n"); 2176 pr_debug("failed to write perf header events\n");
1734 return err; 2177 return err;
@@ -1829,6 +2272,8 @@ out_free:
1829static const int attr_file_abi_sizes[] = { 2272static const int attr_file_abi_sizes[] = {
1830 [0] = PERF_ATTR_SIZE_VER0, 2273 [0] = PERF_ATTR_SIZE_VER0,
1831 [1] = PERF_ATTR_SIZE_VER1, 2274 [1] = PERF_ATTR_SIZE_VER1,
2275 [2] = PERF_ATTR_SIZE_VER2,
2276 [3] = PERF_ATTR_SIZE_VER3,
1832 0, 2277 0,
1833}; 2278};
1834 2279
@@ -2019,7 +2464,7 @@ static int perf_file_section__process(struct perf_file_section *section,
2019 if (!feat_ops[feat].process) 2464 if (!feat_ops[feat].process)
2020 return 0; 2465 return 0;
2021 2466
2022 return feat_ops[feat].process(section, ph, feat, fd, data); 2467 return feat_ops[feat].process(section, ph, fd, data);
2023} 2468}
2024 2469
2025static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, 2470static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
@@ -2108,32 +2553,39 @@ static int read_attr(int fd, struct perf_header *ph,
2108 return ret <= 0 ? -1 : 0; 2553 return ret <= 0 ? -1 : 0;
2109} 2554}
2110 2555
2111static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel, 2556static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
2112 struct pevent *pevent) 2557 struct pevent *pevent)
2113{ 2558{
2114 struct event_format *event = pevent_find_event(pevent, 2559 struct event_format *event;
2115 evsel->attr.config);
2116 char bf[128]; 2560 char bf[128];
2117 2561
2562 /* already prepared */
2563 if (evsel->tp_format)
2564 return 0;
2565
2566 event = pevent_find_event(pevent, evsel->attr.config);
2118 if (event == NULL) 2567 if (event == NULL)
2119 return -1; 2568 return -1;
2120 2569
2121 snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name); 2570 if (!evsel->name) {
2122 evsel->name = strdup(bf); 2571 snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name);
2123 if (event->name == NULL) 2572 evsel->name = strdup(bf);
2124 return -1; 2573 if (evsel->name == NULL)
2574 return -1;
2575 }
2125 2576
2577 evsel->tp_format = event;
2126 return 0; 2578 return 0;
2127} 2579}
2128 2580
2129static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist, 2581static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
2130 struct pevent *pevent) 2582 struct pevent *pevent)
2131{ 2583{
2132 struct perf_evsel *pos; 2584 struct perf_evsel *pos;
2133 2585
2134 list_for_each_entry(pos, &evlist->entries, node) { 2586 list_for_each_entry(pos, &evlist->entries, node) {
2135 if (pos->attr.type == PERF_TYPE_TRACEPOINT && 2587 if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
2136 perf_evsel__set_tracepoint_name(pos, pevent)) 2588 perf_evsel__prepare_tracepoint_event(pos, pevent))
2137 return -1; 2589 return -1;
2138 } 2590 }
2139 2591
@@ -2176,6 +2628,8 @@ int perf_session__read_header(struct perf_session *session, int fd)
2176 2628
2177 if (evsel == NULL) 2629 if (evsel == NULL)
2178 goto out_delete_evlist; 2630 goto out_delete_evlist;
2631
2632 evsel->needs_swap = header->needs_swap;
2179 /* 2633 /*
2180 * Do it before so that if perf_evsel__alloc_id fails, this 2634 * Do it before so that if perf_evsel__alloc_id fails, this
2181 * entry gets purged too at perf_evlist__delete(). 2635 * entry gets purged too at perf_evlist__delete().
@@ -2207,13 +2661,13 @@ int perf_session__read_header(struct perf_session *session, int fd)
2207 2661
2208 if (f_header.event_types.size) { 2662 if (f_header.event_types.size) {
2209 lseek(fd, f_header.event_types.offset, SEEK_SET); 2663 lseek(fd, f_header.event_types.offset, SEEK_SET);
2210 events = malloc(f_header.event_types.size); 2664 trace_events = malloc(f_header.event_types.size);
2211 if (events == NULL) 2665 if (trace_events == NULL)
2212 return -ENOMEM; 2666 return -ENOMEM;
2213 if (perf_header__getbuffer64(header, fd, events, 2667 if (perf_header__getbuffer64(header, fd, trace_events,
2214 f_header.event_types.size)) 2668 f_header.event_types.size))
2215 goto out_errno; 2669 goto out_errno;
2216 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); 2670 trace_event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
2217 } 2671 }
2218 2672
2219 perf_header__process_sections(header, fd, &session->pevent, 2673 perf_header__process_sections(header, fd, &session->pevent,
@@ -2221,7 +2675,8 @@ int perf_session__read_header(struct perf_session *session, int fd)
2221 2675
2222 lseek(fd, header->data_offset, SEEK_SET); 2676 lseek(fd, header->data_offset, SEEK_SET);
2223 2677
2224 if (perf_evlist__set_tracepoint_names(session->evlist, session->pevent)) 2678 if (perf_evlist__prepare_tracepoint_events(session->evlist,
2679 session->pevent))
2225 goto out_delete_evlist; 2680 goto out_delete_evlist;
2226 2681
2227 header->frozen = 1; 2682 header->frozen = 1;
@@ -2236,7 +2691,7 @@ out_delete_evlist:
2236} 2691}
2237 2692
2238int perf_event__synthesize_attr(struct perf_tool *tool, 2693int perf_event__synthesize_attr(struct perf_tool *tool,
2239 struct perf_event_attr *attr, u16 ids, u64 *id, 2694 struct perf_event_attr *attr, u32 ids, u64 *id,
2240 perf_event__handler_t process) 2695 perf_event__handler_t process)
2241{ 2696{
2242 union perf_event *ev; 2697 union perf_event *ev;
@@ -2244,7 +2699,7 @@ int perf_event__synthesize_attr(struct perf_tool *tool,
2244 int err; 2699 int err;
2245 2700
2246 size = sizeof(struct perf_event_attr); 2701 size = sizeof(struct perf_event_attr);
2247 size = ALIGN(size, sizeof(u64)); 2702 size = PERF_ALIGN(size, sizeof(u64));
2248 size += sizeof(struct perf_event_header); 2703 size += sizeof(struct perf_event_header);
2249 size += ids * sizeof(u64); 2704 size += ids * sizeof(u64);
2250 2705
@@ -2257,9 +2712,12 @@ int perf_event__synthesize_attr(struct perf_tool *tool,
2257 memcpy(ev->attr.id, id, ids * sizeof(u64)); 2712 memcpy(ev->attr.id, id, ids * sizeof(u64));
2258 2713
2259 ev->attr.header.type = PERF_RECORD_HEADER_ATTR; 2714 ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
2260 ev->attr.header.size = size; 2715 ev->attr.header.size = (u16)size;
2261 2716
2262 err = process(tool, ev, NULL, NULL); 2717 if (ev->attr.header.size == size)
2718 err = process(tool, ev, NULL, NULL);
2719 else
2720 err = -E2BIG;
2263 2721
2264 free(ev); 2722 free(ev);
2265 2723
@@ -2270,12 +2728,12 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
2270 struct perf_session *session, 2728 struct perf_session *session,
2271 perf_event__handler_t process) 2729 perf_event__handler_t process)
2272{ 2730{
2273 struct perf_evsel *attr; 2731 struct perf_evsel *evsel;
2274 int err = 0; 2732 int err = 0;
2275 2733
2276 list_for_each_entry(attr, &session->evlist->entries, node) { 2734 list_for_each_entry(evsel, &session->evlist->entries, node) {
2277 err = perf_event__synthesize_attr(tool, &attr->attr, attr->ids, 2735 err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids,
2278 attr->id, process); 2736 evsel->id, process);
2279 if (err) { 2737 if (err) {
2280 pr_debug("failed to create perf header attribute\n"); 2738 pr_debug("failed to create perf header attribute\n");
2281 return err; 2739 return err;
@@ -2288,7 +2746,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
2288int perf_event__process_attr(union perf_event *event, 2746int perf_event__process_attr(union perf_event *event,
2289 struct perf_evlist **pevlist) 2747 struct perf_evlist **pevlist)
2290{ 2748{
2291 unsigned int i, ids, n_ids; 2749 u32 i, ids, n_ids;
2292 struct perf_evsel *evsel; 2750 struct perf_evsel *evsel;
2293 struct perf_evlist *evlist = *pevlist; 2751 struct perf_evlist *evlist = *pevlist;
2294 2752
@@ -2339,7 +2797,7 @@ int perf_event__synthesize_event_type(struct perf_tool *tool,
2339 2797
2340 ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE; 2798 ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
2341 size = strlen(ev.event_type.event_type.name); 2799 size = strlen(ev.event_type.event_type.name);
2342 size = ALIGN(size, sizeof(u64)); 2800 size = PERF_ALIGN(size, sizeof(u64));
2343 ev.event_type.header.size = sizeof(ev.event_type) - 2801 ev.event_type.header.size = sizeof(ev.event_type) -
2344 (sizeof(ev.event_type.event_type.name) - size); 2802 (sizeof(ev.event_type.event_type.name) - size);
2345 2803
@@ -2355,8 +2813,8 @@ int perf_event__synthesize_event_types(struct perf_tool *tool,
2355 struct perf_trace_event_type *type; 2813 struct perf_trace_event_type *type;
2356 int i, err = 0; 2814 int i, err = 0;
2357 2815
2358 for (i = 0; i < event_count; i++) { 2816 for (i = 0; i < trace_event_count; i++) {
2359 type = &events[i]; 2817 type = &trace_events[i];
2360 2818
2361 err = perf_event__synthesize_event_type(tool, type->event_id, 2819 err = perf_event__synthesize_event_type(tool, type->event_id,
2362 type->name, process, 2820 type->name, process,
@@ -2370,7 +2828,7 @@ int perf_event__synthesize_event_types(struct perf_tool *tool,
2370 return err; 2828 return err;
2371} 2829}
2372 2830
2373int perf_event__process_event_type(struct perf_tool *tool __unused, 2831int perf_event__process_event_type(struct perf_tool *tool __maybe_unused,
2374 union perf_event *event) 2832 union perf_event *event)
2375{ 2833{
2376 if (perf_header__push_event(event->event_type.event_type.event_id, 2834 if (perf_header__push_event(event->event_type.event_type.event_id,
@@ -2387,7 +2845,7 @@ int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd,
2387 union perf_event ev; 2845 union perf_event ev;
2388 struct tracing_data *tdata; 2846 struct tracing_data *tdata;
2389 ssize_t size = 0, aligned_size = 0, padding; 2847 ssize_t size = 0, aligned_size = 0, padding;
2390 int err __used = 0; 2848 int err __maybe_unused = 0;
2391 2849
2392 /* 2850 /*
2393 * We are going to store the size of the data followed 2851 * We are going to store the size of the data followed
@@ -2408,7 +2866,7 @@ int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd,
2408 2866
2409 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; 2867 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
2410 size = tdata->size; 2868 size = tdata->size;
2411 aligned_size = ALIGN(size, sizeof(u64)); 2869 aligned_size = PERF_ALIGN(size, sizeof(u64));
2412 padding = aligned_size - size; 2870 padding = aligned_size - size;
2413 ev.tracing_data.header.size = sizeof(ev.tracing_data); 2871 ev.tracing_data.header.size = sizeof(ev.tracing_data);
2414 ev.tracing_data.size = aligned_size; 2872 ev.tracing_data.size = aligned_size;
@@ -2439,7 +2897,7 @@ int perf_event__process_tracing_data(union perf_event *event,
2439 2897
2440 size_read = trace_report(session->fd, &session->pevent, 2898 size_read = trace_report(session->fd, &session->pevent,
2441 session->repipe); 2899 session->repipe);
2442 padding = ALIGN(size_read, sizeof(u64)) - size_read; 2900 padding = PERF_ALIGN(size_read, sizeof(u64)) - size_read;
2443 2901
2444 if (read(session->fd, buf, padding) < 0) 2902 if (read(session->fd, buf, padding) < 0)
2445 die("reading input file"); 2903 die("reading input file");
@@ -2452,6 +2910,9 @@ int perf_event__process_tracing_data(union perf_event *event,
2452 if (size_read + padding != size) 2910 if (size_read + padding != size)
2453 die("tracing data size mismatch"); 2911 die("tracing data size mismatch");
2454 2912
2913 perf_evlist__prepare_tracepoint_events(session->evlist,
2914 session->pevent);
2915
2455 return size_read + padding; 2916 return size_read + padding;
2456} 2917}
2457 2918
@@ -2470,7 +2931,7 @@ int perf_event__synthesize_build_id(struct perf_tool *tool,
2470 memset(&ev, 0, sizeof(ev)); 2931 memset(&ev, 0, sizeof(ev));
2471 2932
2472 len = pos->long_name_len + 1; 2933 len = pos->long_name_len + 1;
2473 len = ALIGN(len, NAME_ALIGN); 2934 len = PERF_ALIGN(len, NAME_ALIGN);
2474 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id)); 2935 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
2475 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; 2936 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
2476 ev.build_id.header.misc = misc; 2937 ev.build_id.header.misc = misc;
@@ -2483,7 +2944,7 @@ int perf_event__synthesize_build_id(struct perf_tool *tool,
2483 return err; 2944 return err;
2484} 2945}
2485 2946
2486int perf_event__process_build_id(struct perf_tool *tool __used, 2947int perf_event__process_build_id(struct perf_tool *tool __maybe_unused,
2487 union perf_event *event, 2948 union perf_event *event,
2488 struct perf_session *session) 2949 struct perf_session *session)
2489{ 2950{