blob: 5997b78fb872f5c054a1e9a2e7048565f0be096b [file] [log] [blame]
Yabin Cui9759e1b2015-04-28 15:54:13 -07001/*
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
Dan Albert918e4b72015-08-11 15:59:43 -070020#include <sys/types.h>
21
Yabin Cui9759e1b2015-04-28 15:54:13 -070022#include <string>
23#include <vector>
24
Yabin Cui8f622512015-05-05 19:58:07 -070025#include "build_id.h"
Yabin Cui9759e1b2015-04-28 15:54:13 -070026#include "perf_event.h"
27
28struct KernelMmap;
29struct ModuleMmap;
30struct ThreadComm;
31struct ThreadMmap;
32
33enum user_record_type {
34 PERF_RECORD_ATTR = 64,
35 PERF_RECORD_EVENT_TYPE,
36 PERF_RECORD_TRACING_DATA,
37 PERF_RECORD_BUILD_ID,
38 PERF_RECORD_FINISHED_ROUND,
39};
40
41struct PerfSampleIpType {
42 uint64_t ip;
43};
44
45struct PerfSampleTidType {
46 uint32_t pid, tid;
47};
48
49struct PerfSampleTimeType {
50 uint64_t time;
51};
52
53struct PerfSampleAddrType {
54 uint64_t addr;
55};
56
57struct PerfSampleIdType {
58 uint64_t id;
59};
60
61struct PerfSampleStreamIdType {
62 uint64_t stream_id;
63};
64
65struct PerfSampleCpuType {
66 uint32_t cpu, res;
67};
68
69struct PerfSamplePeriodType {
70 uint64_t period;
71};
72
Yabin Cui6e8a9a42015-06-15 14:36:43 -070073struct PerfSampleCallChainType {
74 std::vector<uint64_t> ips;
75};
76
Yabin Cuibfc11b62015-08-19 10:12:51 -070077struct PerfSampleRawType {
78 std::vector<char> data;
79};
80
Yabin Cuiddddc062015-06-02 17:54:52 -070081struct PerfSampleBranchStackType {
82 struct BranchStackItemType {
83 uint64_t from;
84 uint64_t to;
85 uint64_t flags;
86 };
87 std::vector<BranchStackItemType> stack;
88};
89
Yabin Cui76769e52015-07-13 12:23:54 -070090struct PerfSampleRegsUserType {
91 uint64_t abi;
92 uint64_t reg_mask;
93 std::vector<uint64_t> regs;
94};
95
96struct PerfSampleStackUserType {
97 std::vector<char> data;
98 uint64_t dyn_size;
99};
100
Yabin Cui9759e1b2015-04-28 15:54:13 -0700101// SampleId is optional at the end of a record in binary format. Its content is determined by
102// sample_id_all and sample_type in perf_event_attr. To avoid the complexity of referring to
103// perf_event_attr each time, we copy sample_id_all and sample_type inside the SampleId structure.
104struct SampleId {
105 bool sample_id_all;
106 uint64_t sample_type;
107
108 PerfSampleTidType tid_data; // Valid if sample_id_all && PERF_SAMPLE_TID.
109 PerfSampleTimeType time_data; // Valid if sample_id_all && PERF_SAMPLE_TIME.
110 PerfSampleIdType id_data; // Valid if sample_id_all && PERF_SAMPLE_ID.
111 PerfSampleStreamIdType stream_id_data; // Valid if sample_id_all && PERF_SAMPLE_STREAM_ID.
112 PerfSampleCpuType cpu_data; // Valid if sample_id_all && PERF_SAMPLE_CPU.
113
114 SampleId();
115
116 // Create the content of sample_id. It depends on the attr we use.
117 size_t CreateContent(const perf_event_attr& attr);
118
119 // Parse sample_id from binary format in the buffer pointed by p.
120 void ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, const char* end);
121
122 // Write the binary format of sample_id to the buffer pointed by p.
123 void WriteToBinaryFormat(char*& p) const;
124 void Dump(size_t indent) const;
125};
126
127// Usually one record contains the following three parts in order in binary format:
128// perf_event_header (at the head of a record, containing type and size information)
129// data depends on the record type
130// sample_id (optional part at the end of a record)
131// We hold the common parts (perf_event_header and sample_id) in the base class Record, and
132// hold the type specific data part in classes derived from Record.
133struct Record {
134 perf_event_header header;
135 SampleId sample_id;
136
137 Record();
138 Record(const perf_event_header* pheader);
139
140 virtual ~Record() {
141 }
142
143 void Dump(size_t indent = 0) const;
144
145 protected:
146 virtual void DumpData(size_t) const {
147 }
148};
149
150struct MmapRecord : public Record {
151 struct MmapRecordDataType {
152 uint32_t pid, tid;
153 uint64_t addr;
154 uint64_t len;
155 uint64_t pgoff;
156 } data;
157 std::string filename;
158
159 MmapRecord() { // For storage in std::vector.
160 }
161
162 MmapRecord(const perf_event_attr& attr, const perf_event_header* pheader);
Yabin Cui9759e1b2015-04-28 15:54:13 -0700163 std::vector<char> BinaryFormat() const;
Yabin Cui8f622512015-05-05 19:58:07 -0700164
165 protected:
166 void DumpData(size_t indent) const override;
Yabin Cui9759e1b2015-04-28 15:54:13 -0700167};
168
Yabin Cui41d4ba92015-06-22 12:27:58 -0700169struct Mmap2Record : public Record {
170 struct Mmap2RecordDataType {
171 uint32_t pid, tid;
172 uint64_t addr;
173 uint64_t len;
174 uint64_t pgoff;
175 uint32_t maj;
176 uint32_t min;
177 uint64_t ino;
178 uint64_t ino_generation;
179 uint32_t prot, flags;
180 } data;
181 std::string filename;
182
183 Mmap2Record() {
184 }
185
186 Mmap2Record(const perf_event_attr& attr, const perf_event_header* pheader);
187
188 protected:
189 void DumpData(size_t indent) const override;
190};
191
Yabin Cui9759e1b2015-04-28 15:54:13 -0700192struct CommRecord : public Record {
193 struct CommRecordDataType {
194 uint32_t pid, tid;
195 } data;
196 std::string comm;
197
198 CommRecord() {
199 }
200
201 CommRecord(const perf_event_attr& attr, const perf_event_header* pheader);
Yabin Cui9759e1b2015-04-28 15:54:13 -0700202 std::vector<char> BinaryFormat() const;
Yabin Cui8f622512015-05-05 19:58:07 -0700203
204 protected:
205 void DumpData(size_t indent) const override;
Yabin Cui9759e1b2015-04-28 15:54:13 -0700206};
207
Yabin Cui41d4ba92015-06-22 12:27:58 -0700208struct ExitOrForkRecord : public Record {
209 struct ExitOrForkRecordDataType {
Yabin Cui9759e1b2015-04-28 15:54:13 -0700210 uint32_t pid, ppid;
211 uint32_t tid, ptid;
212 uint64_t time;
213 } data;
214
Yabin Cui41d4ba92015-06-22 12:27:58 -0700215 ExitOrForkRecord() {
216 }
217 ExitOrForkRecord(const perf_event_attr& attr, const perf_event_header* pheader);
Yabin Cui8f622512015-05-05 19:58:07 -0700218
219 protected:
Yabin Cui9759e1b2015-04-28 15:54:13 -0700220 void DumpData(size_t indent) const override;
221};
222
Yabin Cui41d4ba92015-06-22 12:27:58 -0700223struct ExitRecord : public ExitOrForkRecord {
224 ExitRecord(const perf_event_attr& attr, const perf_event_header* pheader)
225 : ExitOrForkRecord(attr, pheader) {
226 }
227};
228
229struct ForkRecord : public ExitOrForkRecord {
230 ForkRecord() {
231 }
232 ForkRecord(const perf_event_attr& attr, const perf_event_header* pheader)
233 : ExitOrForkRecord(attr, pheader) {
234 }
235 std::vector<char> BinaryFormat() const;
236};
237
Yabin Cui9759e1b2015-04-28 15:54:13 -0700238struct SampleRecord : public Record {
239 uint64_t sample_type; // sample_type is a bit mask determining which fields below are valid.
240
241 PerfSampleIpType ip_data; // Valid if PERF_SAMPLE_IP.
242 PerfSampleTidType tid_data; // Valid if PERF_SAMPLE_TID.
243 PerfSampleTimeType time_data; // Valid if PERF_SAMPLE_TIME.
244 PerfSampleAddrType addr_data; // Valid if PERF_SAMPLE_ADDR.
245 PerfSampleIdType id_data; // Valid if PERF_SAMPLE_ID.
246 PerfSampleStreamIdType stream_id_data; // Valid if PERF_SAMPLE_STREAM_ID.
247 PerfSampleCpuType cpu_data; // Valid if PERF_SAMPLE_CPU.
248 PerfSamplePeriodType period_data; // Valid if PERF_SAMPLE_PERIOD.
249
Yabin Cui6e8a9a42015-06-15 14:36:43 -0700250 PerfSampleCallChainType callchain_data; // Valid if PERF_SAMPLE_CALLCHAIN.
Yabin Cuibfc11b62015-08-19 10:12:51 -0700251 PerfSampleRawType raw_data; // Valid if PERF_SAMPLE_RAW.
Yabin Cuiddddc062015-06-02 17:54:52 -0700252 PerfSampleBranchStackType branch_stack_data; // Valid if PERF_SAMPLE_BRANCH_STACK.
Yabin Cui76769e52015-07-13 12:23:54 -0700253 PerfSampleRegsUserType regs_user_data; // Valid if PERF_SAMPLE_REGS_USER.
254 PerfSampleStackUserType stack_user_data; // Valid if PERF_SAMPLE_STACK_USER.
Yabin Cuiddddc062015-06-02 17:54:52 -0700255
Yabin Cui9759e1b2015-04-28 15:54:13 -0700256 SampleRecord(const perf_event_attr& attr, const perf_event_header* pheader);
Yabin Cui8f622512015-05-05 19:58:07 -0700257
258 protected:
259 void DumpData(size_t indent) const override;
260};
261
262// BuildIdRecord is defined in user-space, stored in BuildId feature section in record file.
263struct BuildIdRecord : public Record {
264 uint32_t pid;
265 BuildId build_id;
266 std::string filename;
267
268 BuildIdRecord() {
269 }
270
271 BuildIdRecord(const perf_event_header* pheader);
272 std::vector<char> BinaryFormat() const;
273
274 protected:
Yabin Cui9759e1b2015-04-28 15:54:13 -0700275 void DumpData(size_t indent) const override;
276};
277
Yabin Cui73d80782015-07-23 21:39:57 -0700278std::vector<std::unique_ptr<Record>> ReadRecordsFromBuffer(const perf_event_attr& attr,
279 const char* buf, size_t buf_size);
Yabin Cui7d59bb42015-05-04 20:27:57 -0700280MmapRecord CreateMmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid, uint32_t tid,
281 uint64_t addr, uint64_t len, uint64_t pgoff,
282 const std::string& filename);
283CommRecord CreateCommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid,
284 const std::string& comm);
Yabin Cui41d4ba92015-06-22 12:27:58 -0700285ForkRecord CreateForkRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, uint32_t ppid,
286 uint32_t ptid);
Yabin Cui8f622512015-05-05 19:58:07 -0700287BuildIdRecord CreateBuildIdRecord(bool in_kernel, pid_t pid, const BuildId& build_id,
288 const std::string& filename);
Yabin Cui73d80782015-07-23 21:39:57 -0700289
Yabin Cui9759e1b2015-04-28 15:54:13 -0700290#endif // SIMPLE_PERF_RECORD_H_