1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef SIMPLE_PERF_RECORD_H_ 18#define SIMPLE_PERF_RECORD_H_ 19 20#include <string> 21#include <vector> 22 23#include "build_id.h" 24#include "perf_event.h" 25 26struct KernelMmap; 27struct ModuleMmap; 28struct ThreadComm; 29struct ThreadMmap; 30 31enum user_record_type { 32 PERF_RECORD_ATTR = 64, 33 PERF_RECORD_EVENT_TYPE, 34 PERF_RECORD_TRACING_DATA, 35 PERF_RECORD_BUILD_ID, 36 PERF_RECORD_FINISHED_ROUND, 37}; 38 39struct PerfSampleIpType { 40 uint64_t ip; 41}; 42 43struct PerfSampleTidType { 44 uint32_t pid, tid; 45}; 46 47struct PerfSampleTimeType { 48 uint64_t time; 49}; 50 51struct PerfSampleAddrType { 52 uint64_t addr; 53}; 54 55struct PerfSampleIdType { 56 uint64_t id; 57}; 58 59struct PerfSampleStreamIdType { 60 uint64_t stream_id; 61}; 62 63struct PerfSampleCpuType { 64 uint32_t cpu, res; 65}; 66 67struct PerfSamplePeriodType { 68 uint64_t period; 69}; 70 71// SampleId is optional at the end of a record in binary format. Its content is determined by 72// sample_id_all and sample_type in perf_event_attr. To avoid the complexity of referring to 73// perf_event_attr each time, we copy sample_id_all and sample_type inside the SampleId structure. 74struct SampleId { 75 bool sample_id_all; 76 uint64_t sample_type; 77 78 PerfSampleTidType tid_data; // Valid if sample_id_all && PERF_SAMPLE_TID. 79 PerfSampleTimeType time_data; // Valid if sample_id_all && PERF_SAMPLE_TIME. 80 PerfSampleIdType id_data; // Valid if sample_id_all && PERF_SAMPLE_ID. 81 PerfSampleStreamIdType stream_id_data; // Valid if sample_id_all && PERF_SAMPLE_STREAM_ID. 82 PerfSampleCpuType cpu_data; // Valid if sample_id_all && PERF_SAMPLE_CPU. 83 84 SampleId(); 85 86 // Create the content of sample_id. It depends on the attr we use. 87 size_t CreateContent(const perf_event_attr& attr); 88 89 // Parse sample_id from binary format in the buffer pointed by p. 90 void ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, const char* end); 91 92 // Write the binary format of sample_id to the buffer pointed by p. 93 void WriteToBinaryFormat(char*& p) const; 94 void Dump(size_t indent) const; 95}; 96 97// Usually one record contains the following three parts in order in binary format: 98// perf_event_header (at the head of a record, containing type and size information) 99// data depends on the record type 100// sample_id (optional part at the end of a record) 101// We hold the common parts (perf_event_header and sample_id) in the base class Record, and 102// hold the type specific data part in classes derived from Record. 103struct Record { 104 perf_event_header header; 105 SampleId sample_id; 106 107 Record(); 108 Record(const perf_event_header* pheader); 109 110 virtual ~Record() { 111 } 112 113 void Dump(size_t indent = 0) const; 114 115 protected: 116 virtual void DumpData(size_t) const { 117 } 118}; 119 120struct MmapRecord : public Record { 121 struct MmapRecordDataType { 122 uint32_t pid, tid; 123 uint64_t addr; 124 uint64_t len; 125 uint64_t pgoff; 126 } data; 127 std::string filename; 128 129 MmapRecord() { // For storage in std::vector. 130 } 131 132 MmapRecord(const perf_event_attr& attr, const perf_event_header* pheader); 133 std::vector<char> BinaryFormat() const; 134 135 protected: 136 void DumpData(size_t indent) const override; 137}; 138 139struct CommRecord : public Record { 140 struct CommRecordDataType { 141 uint32_t pid, tid; 142 } data; 143 std::string comm; 144 145 CommRecord() { 146 } 147 148 CommRecord(const perf_event_attr& attr, const perf_event_header* pheader); 149 std::vector<char> BinaryFormat() const; 150 151 protected: 152 void DumpData(size_t indent) const override; 153}; 154 155struct ExitRecord : public Record { 156 struct ExitRecordDataType { 157 uint32_t pid, ppid; 158 uint32_t tid, ptid; 159 uint64_t time; 160 } data; 161 162 ExitRecord(const perf_event_attr& attr, const perf_event_header* pheader); 163 164 protected: 165 void DumpData(size_t indent) const override; 166}; 167 168struct SampleRecord : public Record { 169 uint64_t sample_type; // sample_type is a bit mask determining which fields below are valid. 170 171 PerfSampleIpType ip_data; // Valid if PERF_SAMPLE_IP. 172 PerfSampleTidType tid_data; // Valid if PERF_SAMPLE_TID. 173 PerfSampleTimeType time_data; // Valid if PERF_SAMPLE_TIME. 174 PerfSampleAddrType addr_data; // Valid if PERF_SAMPLE_ADDR. 175 PerfSampleIdType id_data; // Valid if PERF_SAMPLE_ID. 176 PerfSampleStreamIdType stream_id_data; // Valid if PERF_SAMPLE_STREAM_ID. 177 PerfSampleCpuType cpu_data; // Valid if PERF_SAMPLE_CPU. 178 PerfSamplePeriodType period_data; // Valid if PERF_SAMPLE_PERIOD. 179 180 SampleRecord(const perf_event_attr& attr, const perf_event_header* pheader); 181 182 protected: 183 void DumpData(size_t indent) const override; 184}; 185 186// BuildIdRecord is defined in user-space, stored in BuildId feature section in record file. 187struct BuildIdRecord : public Record { 188 uint32_t pid; 189 BuildId build_id; 190 std::string filename; 191 192 BuildIdRecord() { 193 } 194 195 BuildIdRecord(const perf_event_header* pheader); 196 std::vector<char> BinaryFormat() const; 197 198 protected: 199 void DumpData(size_t indent) const override; 200}; 201 202std::unique_ptr<const Record> ReadRecordFromBuffer(const perf_event_attr& attr, 203 const perf_event_header* pheader); 204MmapRecord CreateMmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid, uint32_t tid, 205 uint64_t addr, uint64_t len, uint64_t pgoff, 206 const std::string& filename); 207CommRecord CreateCommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, 208 const std::string& comm); 209BuildIdRecord CreateBuildIdRecord(bool in_kernel, pid_t pid, const BuildId& build_id, 210 const std::string& filename); 211#endif // SIMPLE_PERF_RECORD_H_ 212