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