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