xref: /aosp_15_r20/system/extras/simpleperf/record.h (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #ifndef SIMPLE_PERF_RECORD_H_
18*288bf522SAndroid Build Coastguard Worker #define SIMPLE_PERF_RECORD_H_
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
21*288bf522SAndroid Build Coastguard Worker #include <sys/types.h>
22*288bf522SAndroid Build Coastguard Worker 
23*288bf522SAndroid Build Coastguard Worker #include <memory>
24*288bf522SAndroid Build Coastguard Worker #include <queue>
25*288bf522SAndroid Build Coastguard Worker #include <string>
26*288bf522SAndroid Build Coastguard Worker #include <vector>
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker #include <android-base/logging.h>
29*288bf522SAndroid Build Coastguard Worker 
30*288bf522SAndroid Build Coastguard Worker #include "CallChainJoiner.h"
31*288bf522SAndroid Build Coastguard Worker #include "OfflineUnwinder.h"
32*288bf522SAndroid Build Coastguard Worker #include "build_id.h"
33*288bf522SAndroid Build Coastguard Worker #include "perf_event.h"
34*288bf522SAndroid Build Coastguard Worker 
35*288bf522SAndroid Build Coastguard Worker namespace simpleperf {
36*288bf522SAndroid Build Coastguard Worker 
37*288bf522SAndroid Build Coastguard Worker enum user_record_type {
38*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_USER_DEFINED_TYPE_START = 64,
39*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_ATTR = 64,
40*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_EVENT_TYPE,
41*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_TRACING_DATA,
42*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_BUILD_ID,
43*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_FINISHED_ROUND,
44*288bf522SAndroid Build Coastguard Worker 
45*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_AUXTRACE_INFO = 70,
46*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_AUXTRACE = 71,
47*288bf522SAndroid Build Coastguard Worker   PERF_RECORD_COMPRESSED = 81,
48*288bf522SAndroid Build Coastguard Worker 
49*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_TYPE_START = 32768,
50*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_KERNEL_SYMBOL,
51*288bf522SAndroid Build Coastguard Worker   // TODO: remove DsoRecord and SymbolRecord.
52*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_DSO,
53*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_SYMBOL,
54*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_SPLIT,
55*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_SPLIT_END,
56*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_EVENT_ID,
57*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_CALLCHAIN,
58*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_UNWINDING_RESULT,
59*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_TRACING_DATA,
60*288bf522SAndroid Build Coastguard Worker   SIMPLE_PERF_RECORD_DEBUG,
61*288bf522SAndroid Build Coastguard Worker };
62*288bf522SAndroid Build Coastguard Worker 
63*288bf522SAndroid Build Coastguard Worker // perf_event_header uses u16 to store record size. However, that is not
64*288bf522SAndroid Build Coastguard Worker // enough for storing records like KERNEL_SYMBOL or TRACING_DATA. So define
65*288bf522SAndroid Build Coastguard Worker // a simpleperf_record_header struct to store record header for simpleperf
66*288bf522SAndroid Build Coastguard Worker // defined records (type > SIMPLE_PERF_RECORD_TYPE_START).
67*288bf522SAndroid Build Coastguard Worker struct simpleperf_record_header {
68*288bf522SAndroid Build Coastguard Worker   uint32_t type;
69*288bf522SAndroid Build Coastguard Worker   uint16_t size1;
70*288bf522SAndroid Build Coastguard Worker   uint16_t size0;
71*288bf522SAndroid Build Coastguard Worker };
72*288bf522SAndroid Build Coastguard Worker 
73*288bf522SAndroid Build Coastguard Worker static_assert(sizeof(simpleperf_record_header) == sizeof(perf_event_header),
74*288bf522SAndroid Build Coastguard Worker               "simpleperf_record_header should have the same size as perf_event_header");
75*288bf522SAndroid Build Coastguard Worker 
76*288bf522SAndroid Build Coastguard Worker struct PerfSampleIpType {
77*288bf522SAndroid Build Coastguard Worker   uint64_t ip;
78*288bf522SAndroid Build Coastguard Worker };
79*288bf522SAndroid Build Coastguard Worker 
80*288bf522SAndroid Build Coastguard Worker struct PerfSampleTidType {
81*288bf522SAndroid Build Coastguard Worker   uint32_t pid, tid;
82*288bf522SAndroid Build Coastguard Worker };
83*288bf522SAndroid Build Coastguard Worker 
84*288bf522SAndroid Build Coastguard Worker struct PerfSampleTimeType {
85*288bf522SAndroid Build Coastguard Worker   uint64_t time;
86*288bf522SAndroid Build Coastguard Worker };
87*288bf522SAndroid Build Coastguard Worker 
88*288bf522SAndroid Build Coastguard Worker struct PerfSampleAddrType {
89*288bf522SAndroid Build Coastguard Worker   uint64_t addr;
90*288bf522SAndroid Build Coastguard Worker };
91*288bf522SAndroid Build Coastguard Worker 
92*288bf522SAndroid Build Coastguard Worker struct PerfSampleIdType {
93*288bf522SAndroid Build Coastguard Worker   uint64_t id;
94*288bf522SAndroid Build Coastguard Worker };
95*288bf522SAndroid Build Coastguard Worker 
96*288bf522SAndroid Build Coastguard Worker struct PerfSampleStreamIdType {
97*288bf522SAndroid Build Coastguard Worker   uint64_t stream_id;
98*288bf522SAndroid Build Coastguard Worker };
99*288bf522SAndroid Build Coastguard Worker 
100*288bf522SAndroid Build Coastguard Worker struct PerfSampleCpuType {
101*288bf522SAndroid Build Coastguard Worker   uint32_t cpu, res;
102*288bf522SAndroid Build Coastguard Worker };
103*288bf522SAndroid Build Coastguard Worker 
104*288bf522SAndroid Build Coastguard Worker struct PerfSamplePeriodType {
105*288bf522SAndroid Build Coastguard Worker   uint64_t period;
106*288bf522SAndroid Build Coastguard Worker };
107*288bf522SAndroid Build Coastguard Worker 
108*288bf522SAndroid Build Coastguard Worker struct PerfSampleReadType {
109*288bf522SAndroid Build Coastguard Worker   uint64_t time_enabled = 0;
110*288bf522SAndroid Build Coastguard Worker   uint64_t time_running = 0;
111*288bf522SAndroid Build Coastguard Worker   std::vector<uint64_t> counts;
112*288bf522SAndroid Build Coastguard Worker   std::vector<uint64_t> ids;
113*288bf522SAndroid Build Coastguard Worker };
114*288bf522SAndroid Build Coastguard Worker 
115*288bf522SAndroid Build Coastguard Worker struct PerfSampleCallChainType {
116*288bf522SAndroid Build Coastguard Worker   uint64_t ip_nr;
117*288bf522SAndroid Build Coastguard Worker   uint64_t* ips;
118*288bf522SAndroid Build Coastguard Worker };
119*288bf522SAndroid Build Coastguard Worker 
120*288bf522SAndroid Build Coastguard Worker struct PerfSampleRawType {
121*288bf522SAndroid Build Coastguard Worker   uint32_t size;
122*288bf522SAndroid Build Coastguard Worker   const char* data;
123*288bf522SAndroid Build Coastguard Worker };
124*288bf522SAndroid Build Coastguard Worker 
125*288bf522SAndroid Build Coastguard Worker struct BranchStackItemType {
126*288bf522SAndroid Build Coastguard Worker   uint64_t from;
127*288bf522SAndroid Build Coastguard Worker   uint64_t to;
128*288bf522SAndroid Build Coastguard Worker   uint64_t flags;
129*288bf522SAndroid Build Coastguard Worker };
130*288bf522SAndroid Build Coastguard Worker 
131*288bf522SAndroid Build Coastguard Worker struct PerfSampleBranchStackType {
132*288bf522SAndroid Build Coastguard Worker   uint64_t stack_nr;
133*288bf522SAndroid Build Coastguard Worker   const BranchStackItemType* stack;
134*288bf522SAndroid Build Coastguard Worker };
135*288bf522SAndroid Build Coastguard Worker 
136*288bf522SAndroid Build Coastguard Worker struct PerfSampleRegsUserType {
137*288bf522SAndroid Build Coastguard Worker   uint64_t abi;
138*288bf522SAndroid Build Coastguard Worker   uint64_t reg_mask;
139*288bf522SAndroid Build Coastguard Worker   uint64_t reg_nr;
140*288bf522SAndroid Build Coastguard Worker   const uint64_t* regs;
141*288bf522SAndroid Build Coastguard Worker };
142*288bf522SAndroid Build Coastguard Worker 
143*288bf522SAndroid Build Coastguard Worker struct PerfSampleStackUserType {
144*288bf522SAndroid Build Coastguard Worker   uint64_t size;
145*288bf522SAndroid Build Coastguard Worker   char* data;
146*288bf522SAndroid Build Coastguard Worker   uint64_t dyn_size;
147*288bf522SAndroid Build Coastguard Worker };
148*288bf522SAndroid Build Coastguard Worker 
149*288bf522SAndroid Build Coastguard Worker struct RecordHeader {
150*288bf522SAndroid Build Coastguard Worker  public:
151*288bf522SAndroid Build Coastguard Worker   uint32_t type;
152*288bf522SAndroid Build Coastguard Worker   uint16_t misc;
153*288bf522SAndroid Build Coastguard Worker   uint32_t size;
154*288bf522SAndroid Build Coastguard Worker 
RecordHeaderRecordHeader155*288bf522SAndroid Build Coastguard Worker   RecordHeader() : type(0), misc(0), size(0) {}
156*288bf522SAndroid Build Coastguard Worker 
ParseRecordHeader157*288bf522SAndroid Build Coastguard Worker   bool Parse(const char* p) {
158*288bf522SAndroid Build Coastguard Worker     auto pheader = reinterpret_cast<const perf_event_header*>(p);
159*288bf522SAndroid Build Coastguard Worker     if (pheader->type < SIMPLE_PERF_RECORD_TYPE_START) {
160*288bf522SAndroid Build Coastguard Worker       type = pheader->type;
161*288bf522SAndroid Build Coastguard Worker       misc = pheader->misc;
162*288bf522SAndroid Build Coastguard Worker       size = pheader->size;
163*288bf522SAndroid Build Coastguard Worker     } else {
164*288bf522SAndroid Build Coastguard Worker       auto sheader = reinterpret_cast<const simpleperf_record_header*>(p);
165*288bf522SAndroid Build Coastguard Worker       type = sheader->type;
166*288bf522SAndroid Build Coastguard Worker       misc = 0;
167*288bf522SAndroid Build Coastguard Worker       size = (sheader->size1 << 16) | sheader->size0;
168*288bf522SAndroid Build Coastguard Worker     }
169*288bf522SAndroid Build Coastguard Worker     if (size < sizeof(perf_event_header)) {
170*288bf522SAndroid Build Coastguard Worker       LOG(ERROR) << "invalid record";
171*288bf522SAndroid Build Coastguard Worker       return false;
172*288bf522SAndroid Build Coastguard Worker     }
173*288bf522SAndroid Build Coastguard Worker     return true;
174*288bf522SAndroid Build Coastguard Worker   }
175*288bf522SAndroid Build Coastguard Worker 
MoveToBinaryFormatRecordHeader176*288bf522SAndroid Build Coastguard Worker   void MoveToBinaryFormat(char*& p) const {
177*288bf522SAndroid Build Coastguard Worker     if (type < SIMPLE_PERF_RECORD_TYPE_START) {
178*288bf522SAndroid Build Coastguard Worker       auto pheader = reinterpret_cast<perf_event_header*>(p);
179*288bf522SAndroid Build Coastguard Worker       pheader->type = type;
180*288bf522SAndroid Build Coastguard Worker       pheader->misc = misc;
181*288bf522SAndroid Build Coastguard Worker       CHECK_LT(size, 1u << 16);
182*288bf522SAndroid Build Coastguard Worker       pheader->size = static_cast<uint16_t>(size);
183*288bf522SAndroid Build Coastguard Worker     } else {
184*288bf522SAndroid Build Coastguard Worker       auto sheader = reinterpret_cast<simpleperf_record_header*>(p);
185*288bf522SAndroid Build Coastguard Worker       sheader->type = type;
186*288bf522SAndroid Build Coastguard Worker       CHECK_EQ(misc, 0u);
187*288bf522SAndroid Build Coastguard Worker       sheader->size1 = size >> 16;
188*288bf522SAndroid Build Coastguard Worker       sheader->size0 = size & 0xffff;
189*288bf522SAndroid Build Coastguard Worker     }
190*288bf522SAndroid Build Coastguard Worker     p += sizeof(perf_event_header);
191*288bf522SAndroid Build Coastguard Worker   }
192*288bf522SAndroid Build Coastguard Worker };
193*288bf522SAndroid Build Coastguard Worker 
194*288bf522SAndroid Build Coastguard Worker // SampleId is optional at the end of a record in binary format. Its content is
195*288bf522SAndroid Build Coastguard Worker // determined by sample_id_all and sample_type in perf_event_attr. To avoid the
196*288bf522SAndroid Build Coastguard Worker // complexity of referring to perf_event_attr each time, we copy sample_id_all
197*288bf522SAndroid Build Coastguard Worker // and sample_type inside the SampleId structure.
198*288bf522SAndroid Build Coastguard Worker struct SampleId {
199*288bf522SAndroid Build Coastguard Worker   bool sample_id_all;
200*288bf522SAndroid Build Coastguard Worker   uint64_t sample_type;
201*288bf522SAndroid Build Coastguard Worker 
202*288bf522SAndroid Build Coastguard Worker   PerfSampleTidType tid_data;             // Valid if sample_id_all && PERF_SAMPLE_TID.
203*288bf522SAndroid Build Coastguard Worker   PerfSampleTimeType time_data;           // Valid if sample_id_all && PERF_SAMPLE_TIME.
204*288bf522SAndroid Build Coastguard Worker   PerfSampleIdType id_data;               // Valid if sample_id_all && PERF_SAMPLE_ID.
205*288bf522SAndroid Build Coastguard Worker   PerfSampleStreamIdType stream_id_data;  // Valid if sample_id_all && PERF_SAMPLE_STREAM_ID.
206*288bf522SAndroid Build Coastguard Worker   PerfSampleCpuType cpu_data;             // Valid if sample_id_all && PERF_SAMPLE_CPU.
207*288bf522SAndroid Build Coastguard Worker 
208*288bf522SAndroid Build Coastguard Worker   SampleId();
209*288bf522SAndroid Build Coastguard Worker 
210*288bf522SAndroid Build Coastguard Worker   // Create the content of sample_id. It depends on the attr we use.
211*288bf522SAndroid Build Coastguard Worker   size_t CreateContent(const perf_event_attr& attr, uint64_t event_id);
212*288bf522SAndroid Build Coastguard Worker 
213*288bf522SAndroid Build Coastguard Worker   // Parse sample_id from binary format in the buffer pointed by p.
214*288bf522SAndroid Build Coastguard Worker   bool ReadFromBinaryFormat(const perf_event_attr& attr, const char* p, const char* end);
215*288bf522SAndroid Build Coastguard Worker 
216*288bf522SAndroid Build Coastguard Worker   // Write the binary format of sample_id to the buffer pointed by p.
217*288bf522SAndroid Build Coastguard Worker   void WriteToBinaryFormat(char*& p) const;
218*288bf522SAndroid Build Coastguard Worker   void Dump(size_t indent) const;
219*288bf522SAndroid Build Coastguard Worker   size_t Size() const;
220*288bf522SAndroid Build Coastguard Worker };
221*288bf522SAndroid Build Coastguard Worker 
222*288bf522SAndroid Build Coastguard Worker // Usually one record contains the following three parts in order in binary
223*288bf522SAndroid Build Coastguard Worker // format:
224*288bf522SAndroid Build Coastguard Worker //   RecordHeader (at the head of a record, containing type and size info)
225*288bf522SAndroid Build Coastguard Worker //   data depends on the record type
226*288bf522SAndroid Build Coastguard Worker //   SampleId (optional part at the end of a record)
227*288bf522SAndroid Build Coastguard Worker // We hold the common parts (RecordHeader and SampleId) in the base class
228*288bf522SAndroid Build Coastguard Worker // Record, and hold the type specific data part in classes derived from Record.
229*288bf522SAndroid Build Coastguard Worker struct Record {
230*288bf522SAndroid Build Coastguard Worker   RecordHeader header;
231*288bf522SAndroid Build Coastguard Worker   SampleId sample_id;
232*288bf522SAndroid Build Coastguard Worker 
RecordRecord233*288bf522SAndroid Build Coastguard Worker   Record() : binary_(nullptr), own_binary_(false) {}
234*288bf522SAndroid Build Coastguard Worker   Record(Record&& other) noexcept;
235*288bf522SAndroid Build Coastguard Worker 
~RecordRecord236*288bf522SAndroid Build Coastguard Worker   virtual ~Record() {
237*288bf522SAndroid Build Coastguard Worker     if (own_binary_) {
238*288bf522SAndroid Build Coastguard Worker       delete[] binary_;
239*288bf522SAndroid Build Coastguard Worker     }
240*288bf522SAndroid Build Coastguard Worker   }
241*288bf522SAndroid Build Coastguard Worker 
242*288bf522SAndroid Build Coastguard Worker   virtual bool Parse(const perf_event_attr& attr, char* p, char* end) = 0;
243*288bf522SAndroid Build Coastguard Worker 
OwnBinaryRecord244*288bf522SAndroid Build Coastguard Worker   void OwnBinary() { own_binary_ = true; }
245*288bf522SAndroid Build Coastguard Worker 
typeRecord246*288bf522SAndroid Build Coastguard Worker   uint32_t type() const { return header.type; }
247*288bf522SAndroid Build Coastguard Worker 
miscRecord248*288bf522SAndroid Build Coastguard Worker   uint16_t misc() const { return header.misc; }
249*288bf522SAndroid Build Coastguard Worker 
sizeRecord250*288bf522SAndroid Build Coastguard Worker   uint32_t size() const { return header.size; }
251*288bf522SAndroid Build Coastguard Worker 
header_sizeRecord252*288bf522SAndroid Build Coastguard Worker   static uint32_t header_size() { return sizeof(perf_event_header); }
253*288bf522SAndroid Build Coastguard Worker 
InKernelRecord254*288bf522SAndroid Build Coastguard Worker   bool InKernel() const {
255*288bf522SAndroid Build Coastguard Worker     uint16_t cpumode = header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
256*288bf522SAndroid Build Coastguard Worker     return cpumode == PERF_RECORD_MISC_KERNEL || cpumode == PERF_RECORD_MISC_GUEST_KERNEL;
257*288bf522SAndroid Build Coastguard Worker   }
258*288bf522SAndroid Build Coastguard Worker 
SetTypeAndMiscRecord259*288bf522SAndroid Build Coastguard Worker   void SetTypeAndMisc(uint32_t type, uint16_t misc) {
260*288bf522SAndroid Build Coastguard Worker     header.type = type;
261*288bf522SAndroid Build Coastguard Worker     header.misc = misc;
262*288bf522SAndroid Build Coastguard Worker   }
263*288bf522SAndroid Build Coastguard Worker 
SetSizeRecord264*288bf522SAndroid Build Coastguard Worker   void SetSize(uint32_t size) { header.size = size; }
265*288bf522SAndroid Build Coastguard Worker 
266*288bf522SAndroid Build Coastguard Worker   void Dump(size_t indent = 0) const;
267*288bf522SAndroid Build Coastguard Worker 
BinaryRecord268*288bf522SAndroid Build Coastguard Worker   const char* Binary() const { return binary_; }
BinaryForTestingOnlyRecord269*288bf522SAndroid Build Coastguard Worker   char* BinaryForTestingOnly() { return binary_; }
270*288bf522SAndroid Build Coastguard Worker 
271*288bf522SAndroid Build Coastguard Worker   virtual uint64_t Timestamp() const;
272*288bf522SAndroid Build Coastguard Worker   virtual uint32_t Cpu() const;
273*288bf522SAndroid Build Coastguard Worker   virtual uint64_t Id() const;
274*288bf522SAndroid Build Coastguard Worker 
275*288bf522SAndroid Build Coastguard Worker  protected:
276*288bf522SAndroid Build Coastguard Worker   bool ParseHeader(char*& p, char*& end);
277*288bf522SAndroid Build Coastguard Worker   void UpdateBinary(char* new_binary);
278*288bf522SAndroid Build Coastguard Worker   virtual void DumpData(size_t) const = 0;
279*288bf522SAndroid Build Coastguard Worker 
280*288bf522SAndroid Build Coastguard Worker   char* binary_;
281*288bf522SAndroid Build Coastguard Worker   bool own_binary_;
282*288bf522SAndroid Build Coastguard Worker 
283*288bf522SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Record);
284*288bf522SAndroid Build Coastguard Worker };
285*288bf522SAndroid Build Coastguard Worker 
286*288bf522SAndroid Build Coastguard Worker struct MmapRecord : public Record {
287*288bf522SAndroid Build Coastguard Worker   struct MmapRecordDataType {
288*288bf522SAndroid Build Coastguard Worker     uint32_t pid, tid;
289*288bf522SAndroid Build Coastguard Worker     uint64_t addr;
290*288bf522SAndroid Build Coastguard Worker     uint64_t len;
291*288bf522SAndroid Build Coastguard Worker     uint64_t pgoff;
292*288bf522SAndroid Build Coastguard Worker   };
293*288bf522SAndroid Build Coastguard Worker   const MmapRecordDataType* data;
294*288bf522SAndroid Build Coastguard Worker   const char* filename;
295*288bf522SAndroid Build Coastguard Worker 
MmapRecordMmapRecord296*288bf522SAndroid Build Coastguard Worker   MmapRecord() {}
297*288bf522SAndroid Build Coastguard Worker   MmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid, uint32_t tid, uint64_t addr,
298*288bf522SAndroid Build Coastguard Worker              uint64_t len, uint64_t pgoff, const std::string& filename, uint64_t event_id,
299*288bf522SAndroid Build Coastguard Worker              uint64_t time = 0);
300*288bf522SAndroid Build Coastguard Worker 
301*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
302*288bf522SAndroid Build Coastguard Worker   void SetDataAndFilename(const MmapRecordDataType& data, const std::string& filename);
303*288bf522SAndroid Build Coastguard Worker 
304*288bf522SAndroid Build Coastguard Worker  protected:
305*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
306*288bf522SAndroid Build Coastguard Worker };
307*288bf522SAndroid Build Coastguard Worker 
308*288bf522SAndroid Build Coastguard Worker struct Mmap2Record : public Record {
309*288bf522SAndroid Build Coastguard Worker   struct Mmap2RecordDataType {
310*288bf522SAndroid Build Coastguard Worker     uint32_t pid, tid;
311*288bf522SAndroid Build Coastguard Worker     uint64_t addr;
312*288bf522SAndroid Build Coastguard Worker     uint64_t len;
313*288bf522SAndroid Build Coastguard Worker     uint64_t pgoff;
314*288bf522SAndroid Build Coastguard Worker     uint32_t maj;
315*288bf522SAndroid Build Coastguard Worker     uint32_t min;
316*288bf522SAndroid Build Coastguard Worker     uint64_t ino;
317*288bf522SAndroid Build Coastguard Worker     uint64_t ino_generation;
318*288bf522SAndroid Build Coastguard Worker     uint32_t prot, flags;
319*288bf522SAndroid Build Coastguard Worker   };
320*288bf522SAndroid Build Coastguard Worker   const Mmap2RecordDataType* data;
321*288bf522SAndroid Build Coastguard Worker   const char* filename;
322*288bf522SAndroid Build Coastguard Worker 
Mmap2RecordMmap2Record323*288bf522SAndroid Build Coastguard Worker   Mmap2Record() {}
324*288bf522SAndroid Build Coastguard Worker   Mmap2Record(const perf_event_attr& attr, bool in_kernel, uint32_t pid, uint32_t tid,
325*288bf522SAndroid Build Coastguard Worker               uint64_t addr, uint64_t len, uint64_t pgoff, uint32_t prot,
326*288bf522SAndroid Build Coastguard Worker               const std::string& filename, uint64_t event_id, uint64_t time = 0);
327*288bf522SAndroid Build Coastguard Worker 
328*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
329*288bf522SAndroid Build Coastguard Worker   void SetDataAndFilename(const Mmap2RecordDataType& data, const std::string& filename);
330*288bf522SAndroid Build Coastguard Worker 
331*288bf522SAndroid Build Coastguard Worker  protected:
332*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
333*288bf522SAndroid Build Coastguard Worker };
334*288bf522SAndroid Build Coastguard Worker 
335*288bf522SAndroid Build Coastguard Worker struct CommRecord : public Record {
336*288bf522SAndroid Build Coastguard Worker   struct CommRecordDataType {
337*288bf522SAndroid Build Coastguard Worker     uint32_t pid, tid;
338*288bf522SAndroid Build Coastguard Worker   };
339*288bf522SAndroid Build Coastguard Worker   const CommRecordDataType* data;
340*288bf522SAndroid Build Coastguard Worker   const char* comm;
341*288bf522SAndroid Build Coastguard Worker 
CommRecordCommRecord342*288bf522SAndroid Build Coastguard Worker   CommRecord() {}
343*288bf522SAndroid Build Coastguard Worker   CommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, const std::string& comm,
344*288bf522SAndroid Build Coastguard Worker              uint64_t event_id, uint64_t time);
345*288bf522SAndroid Build Coastguard Worker 
346*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
347*288bf522SAndroid Build Coastguard Worker   void SetCommandName(const std::string& name);
348*288bf522SAndroid Build Coastguard Worker 
349*288bf522SAndroid Build Coastguard Worker  protected:
350*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
351*288bf522SAndroid Build Coastguard Worker };
352*288bf522SAndroid Build Coastguard Worker 
353*288bf522SAndroid Build Coastguard Worker struct ExitOrForkRecord : public Record {
354*288bf522SAndroid Build Coastguard Worker   struct ExitOrForkRecordDataType {
355*288bf522SAndroid Build Coastguard Worker     uint32_t pid, ppid;
356*288bf522SAndroid Build Coastguard Worker     uint32_t tid, ptid;
357*288bf522SAndroid Build Coastguard Worker     uint64_t time;
358*288bf522SAndroid Build Coastguard Worker   };
359*288bf522SAndroid Build Coastguard Worker   const ExitOrForkRecordDataType* data;
360*288bf522SAndroid Build Coastguard Worker 
ExitOrForkRecordExitOrForkRecord361*288bf522SAndroid Build Coastguard Worker   ExitOrForkRecord() : data(nullptr) {}
362*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
363*288bf522SAndroid Build Coastguard Worker 
364*288bf522SAndroid Build Coastguard Worker  protected:
365*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
366*288bf522SAndroid Build Coastguard Worker };
367*288bf522SAndroid Build Coastguard Worker 
368*288bf522SAndroid Build Coastguard Worker struct ExitRecord : public ExitOrForkRecord {};
369*288bf522SAndroid Build Coastguard Worker 
370*288bf522SAndroid Build Coastguard Worker struct ForkRecord : public ExitOrForkRecord {
ForkRecordForkRecord371*288bf522SAndroid Build Coastguard Worker   ForkRecord() {}
372*288bf522SAndroid Build Coastguard Worker   ForkRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid, uint32_t ppid, uint32_t ptid,
373*288bf522SAndroid Build Coastguard Worker              uint64_t event_id);
374*288bf522SAndroid Build Coastguard Worker };
375*288bf522SAndroid Build Coastguard Worker 
376*288bf522SAndroid Build Coastguard Worker struct LostRecord : public Record {
377*288bf522SAndroid Build Coastguard Worker   uint64_t id;
378*288bf522SAndroid Build Coastguard Worker   uint64_t lost;
379*288bf522SAndroid Build Coastguard Worker 
380*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
381*288bf522SAndroid Build Coastguard Worker 
382*288bf522SAndroid Build Coastguard Worker  protected:
383*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
384*288bf522SAndroid Build Coastguard Worker };
385*288bf522SAndroid Build Coastguard Worker 
386*288bf522SAndroid Build Coastguard Worker struct SampleRecord : public Record {
387*288bf522SAndroid Build Coastguard Worker   uint64_t sample_type;  // sample_type is a bit mask determining which fields
388*288bf522SAndroid Build Coastguard Worker                          // below are valid.
389*288bf522SAndroid Build Coastguard Worker   uint64_t read_format;
390*288bf522SAndroid Build Coastguard Worker 
391*288bf522SAndroid Build Coastguard Worker   PerfSampleIpType ip_data;               // Valid if PERF_SAMPLE_IP.
392*288bf522SAndroid Build Coastguard Worker   PerfSampleTidType tid_data;             // Valid if PERF_SAMPLE_TID.
393*288bf522SAndroid Build Coastguard Worker   PerfSampleTimeType time_data;           // Valid if PERF_SAMPLE_TIME.
394*288bf522SAndroid Build Coastguard Worker   PerfSampleAddrType addr_data;           // Valid if PERF_SAMPLE_ADDR.
395*288bf522SAndroid Build Coastguard Worker   PerfSampleIdType id_data;               // Valid if PERF_SAMPLE_ID.
396*288bf522SAndroid Build Coastguard Worker   PerfSampleStreamIdType stream_id_data;  // Valid if PERF_SAMPLE_STREAM_ID.
397*288bf522SAndroid Build Coastguard Worker   PerfSampleCpuType cpu_data;             // Valid if PERF_SAMPLE_CPU.
398*288bf522SAndroid Build Coastguard Worker   PerfSamplePeriodType period_data;       // Valid if PERF_SAMPLE_PERIOD.
399*288bf522SAndroid Build Coastguard Worker   PerfSampleReadType read_data;           // Valid if PERF_SAMPLE_READ.
400*288bf522SAndroid Build Coastguard Worker 
401*288bf522SAndroid Build Coastguard Worker   PerfSampleCallChainType callchain_data;       // Valid if PERF_SAMPLE_CALLCHAIN.
402*288bf522SAndroid Build Coastguard Worker   PerfSampleRawType raw_data;                   // Valid if PERF_SAMPLE_RAW.
403*288bf522SAndroid Build Coastguard Worker   PerfSampleBranchStackType branch_stack_data;  // Valid if PERF_SAMPLE_BRANCH_STACK.
404*288bf522SAndroid Build Coastguard Worker   PerfSampleRegsUserType regs_user_data;        // Valid if PERF_SAMPLE_REGS_USER.
405*288bf522SAndroid Build Coastguard Worker   PerfSampleStackUserType stack_user_data;      // Valid if PERF_SAMPLE_STACK_USER.
406*288bf522SAndroid Build Coastguard Worker 
SampleRecordSampleRecord407*288bf522SAndroid Build Coastguard Worker   SampleRecord() {}
408*288bf522SAndroid Build Coastguard Worker   SampleRecord(const perf_event_attr& attr, uint64_t id, uint64_t ip, uint32_t pid, uint32_t tid,
409*288bf522SAndroid Build Coastguard Worker                uint64_t time, uint32_t cpu, uint64_t period, const PerfSampleReadType& read_data,
410*288bf522SAndroid Build Coastguard Worker                const std::vector<uint64_t>& ips, const std::vector<char>& stack,
411*288bf522SAndroid Build Coastguard Worker                uint64_t dyn_stack_size);
412*288bf522SAndroid Build Coastguard Worker 
413*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
414*288bf522SAndroid Build Coastguard Worker   void ReplaceRegAndStackWithCallChain(const std::vector<uint64_t>& ips);
415*288bf522SAndroid Build Coastguard Worker   // Remove kernel callchain, return true if there is a user space callchain left, otherwise
416*288bf522SAndroid Build Coastguard Worker   // return false.
417*288bf522SAndroid Build Coastguard Worker   bool ExcludeKernelCallChain();
418*288bf522SAndroid Build Coastguard Worker   bool HasUserCallChain() const;
419*288bf522SAndroid Build Coastguard Worker   void UpdateUserCallChain(const std::vector<uint64_t>& user_ips);
420*288bf522SAndroid Build Coastguard Worker 
421*288bf522SAndroid Build Coastguard Worker   uint64_t Timestamp() const override;
422*288bf522SAndroid Build Coastguard Worker   uint32_t Cpu() const override;
423*288bf522SAndroid Build Coastguard Worker   uint64_t Id() const override;
424*288bf522SAndroid Build Coastguard Worker 
GetValidStackSizeSampleRecord425*288bf522SAndroid Build Coastguard Worker   uint64_t GetValidStackSize() const {
426*288bf522SAndroid Build Coastguard Worker     // Invaid stack data has been removed by RecordReadThread::PushRecordToRecordBuffer().
427*288bf522SAndroid Build Coastguard Worker     return stack_user_data.size;
428*288bf522SAndroid Build Coastguard Worker   }
429*288bf522SAndroid Build Coastguard Worker 
430*288bf522SAndroid Build Coastguard Worker   void AdjustCallChainGeneratedByKernel();
431*288bf522SAndroid Build Coastguard Worker   std::vector<uint64_t> GetCallChain(size_t* kernel_ip_count) const;
432*288bf522SAndroid Build Coastguard Worker 
433*288bf522SAndroid Build Coastguard Worker  protected:
434*288bf522SAndroid Build Coastguard Worker   void BuildBinaryWithNewCallChain(uint32_t new_size, const std::vector<uint64_t>& ips);
435*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
436*288bf522SAndroid Build Coastguard Worker };
437*288bf522SAndroid Build Coastguard Worker 
438*288bf522SAndroid Build Coastguard Worker struct AuxRecord : public Record {
439*288bf522SAndroid Build Coastguard Worker   struct DataType {
440*288bf522SAndroid Build Coastguard Worker     uint64_t aux_offset;
441*288bf522SAndroid Build Coastguard Worker     uint64_t aux_size;
442*288bf522SAndroid Build Coastguard Worker     uint64_t flags;
443*288bf522SAndroid Build Coastguard Worker   }* data;
444*288bf522SAndroid Build Coastguard Worker 
445*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
UnformattedAuxRecord446*288bf522SAndroid Build Coastguard Worker   bool Unformatted() const { return data->flags & PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW; }
447*288bf522SAndroid Build Coastguard Worker 
448*288bf522SAndroid Build Coastguard Worker  protected:
449*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
450*288bf522SAndroid Build Coastguard Worker };
451*288bf522SAndroid Build Coastguard Worker 
452*288bf522SAndroid Build Coastguard Worker struct SwitchRecord : public Record {
453*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
454*288bf522SAndroid Build Coastguard Worker 
455*288bf522SAndroid Build Coastguard Worker  protected:
DumpDataSwitchRecord456*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t) const override {}
457*288bf522SAndroid Build Coastguard Worker };
458*288bf522SAndroid Build Coastguard Worker 
459*288bf522SAndroid Build Coastguard Worker struct SwitchCpuWideRecord : public Record {
460*288bf522SAndroid Build Coastguard Worker   PerfSampleTidType tid_data;
461*288bf522SAndroid Build Coastguard Worker 
462*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
463*288bf522SAndroid Build Coastguard Worker 
464*288bf522SAndroid Build Coastguard Worker  protected:
465*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
466*288bf522SAndroid Build Coastguard Worker };
467*288bf522SAndroid Build Coastguard Worker 
468*288bf522SAndroid Build Coastguard Worker // BuildIdRecord is defined in user-space, stored in BuildId feature section in
469*288bf522SAndroid Build Coastguard Worker // record file.
470*288bf522SAndroid Build Coastguard Worker struct BuildIdRecord : public Record {
471*288bf522SAndroid Build Coastguard Worker   uint32_t pid;
472*288bf522SAndroid Build Coastguard Worker   BuildId build_id;
473*288bf522SAndroid Build Coastguard Worker   const char* filename;
474*288bf522SAndroid Build Coastguard Worker 
BuildIdRecordBuildIdRecord475*288bf522SAndroid Build Coastguard Worker   BuildIdRecord() {}
476*288bf522SAndroid Build Coastguard Worker   BuildIdRecord(bool in_kernel, uint32_t pid, const BuildId& build_id, const std::string& filename);
477*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
478*288bf522SAndroid Build Coastguard Worker 
479*288bf522SAndroid Build Coastguard Worker  protected:
480*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
481*288bf522SAndroid Build Coastguard Worker };
482*288bf522SAndroid Build Coastguard Worker 
483*288bf522SAndroid Build Coastguard Worker struct AuxTraceInfoRecord : public Record {
484*288bf522SAndroid Build Coastguard Worker   // magic values to be compatible with linux perf
485*288bf522SAndroid Build Coastguard Worker   static constexpr uint32_t AUX_TYPE_ETM = 3;
486*288bf522SAndroid Build Coastguard Worker   static constexpr uint64_t MAGIC_ETM4 = 0x4040404040404040ULL;
487*288bf522SAndroid Build Coastguard Worker   static constexpr uint64_t MAGIC_ETE = 0x5050505050505050ULL;
488*288bf522SAndroid Build Coastguard Worker 
489*288bf522SAndroid Build Coastguard Worker   struct ETM4Info {
490*288bf522SAndroid Build Coastguard Worker     uint64_t magic;
491*288bf522SAndroid Build Coastguard Worker     uint64_t cpu;
492*288bf522SAndroid Build Coastguard Worker     uint64_t nrtrcparams;
493*288bf522SAndroid Build Coastguard Worker     uint64_t trcconfigr;
494*288bf522SAndroid Build Coastguard Worker     uint64_t trctraceidr;
495*288bf522SAndroid Build Coastguard Worker     uint64_t trcidr0;
496*288bf522SAndroid Build Coastguard Worker     uint64_t trcidr1;
497*288bf522SAndroid Build Coastguard Worker     uint64_t trcidr2;
498*288bf522SAndroid Build Coastguard Worker     uint64_t trcidr8;
499*288bf522SAndroid Build Coastguard Worker     uint64_t trcauthstatus;
500*288bf522SAndroid Build Coastguard Worker   };
501*288bf522SAndroid Build Coastguard Worker 
502*288bf522SAndroid Build Coastguard Worker   struct ETEInfo {
503*288bf522SAndroid Build Coastguard Worker     uint64_t magic;
504*288bf522SAndroid Build Coastguard Worker     uint64_t cpu;
505*288bf522SAndroid Build Coastguard Worker     uint64_t nrtrcparams;
506*288bf522SAndroid Build Coastguard Worker     uint64_t trcconfigr;
507*288bf522SAndroid Build Coastguard Worker     uint64_t trctraceidr;
508*288bf522SAndroid Build Coastguard Worker     uint64_t trcidr0;
509*288bf522SAndroid Build Coastguard Worker     uint64_t trcidr1;
510*288bf522SAndroid Build Coastguard Worker     uint64_t trcidr2;
511*288bf522SAndroid Build Coastguard Worker     uint64_t trcidr8;
512*288bf522SAndroid Build Coastguard Worker     uint64_t trcauthstatus;
513*288bf522SAndroid Build Coastguard Worker     uint64_t trcdevarch;
514*288bf522SAndroid Build Coastguard Worker   };
515*288bf522SAndroid Build Coastguard Worker 
516*288bf522SAndroid Build Coastguard Worker   struct DataType {
517*288bf522SAndroid Build Coastguard Worker     uint32_t aux_type;
518*288bf522SAndroid Build Coastguard Worker     uint32_t reserved;
519*288bf522SAndroid Build Coastguard Worker     uint64_t version;
520*288bf522SAndroid Build Coastguard Worker     uint32_t nr_cpu;
521*288bf522SAndroid Build Coastguard Worker     uint32_t pmu_type;
522*288bf522SAndroid Build Coastguard Worker     uint64_t snapshot;
523*288bf522SAndroid Build Coastguard Worker     uint64_t info[0];
524*288bf522SAndroid Build Coastguard Worker   }* data;
525*288bf522SAndroid Build Coastguard Worker 
AuxTraceInfoRecordAuxTraceInfoRecord526*288bf522SAndroid Build Coastguard Worker   AuxTraceInfoRecord() {}
527*288bf522SAndroid Build Coastguard Worker   AuxTraceInfoRecord(const DataType& data, const std::vector<ETEInfo>& ete_info);
528*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
529*288bf522SAndroid Build Coastguard Worker 
530*288bf522SAndroid Build Coastguard Worker  protected:
531*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
532*288bf522SAndroid Build Coastguard Worker };
533*288bf522SAndroid Build Coastguard Worker 
534*288bf522SAndroid Build Coastguard Worker struct AuxTraceRecord : public Record {
535*288bf522SAndroid Build Coastguard Worker   struct DataType {
536*288bf522SAndroid Build Coastguard Worker     uint64_t aux_size;
537*288bf522SAndroid Build Coastguard Worker     uint64_t offset;
538*288bf522SAndroid Build Coastguard Worker     uint64_t reserved0;  // reference
539*288bf522SAndroid Build Coastguard Worker     uint32_t idx;
540*288bf522SAndroid Build Coastguard Worker     uint32_t tid;
541*288bf522SAndroid Build Coastguard Worker     uint32_t cpu;
542*288bf522SAndroid Build Coastguard Worker     uint32_t reserved1;
543*288bf522SAndroid Build Coastguard Worker   }* data;
544*288bf522SAndroid Build Coastguard Worker   // AuxTraceRecord is followed by aux tracing data with size data->aux_size.
545*288bf522SAndroid Build Coastguard Worker   // The location of aux tracing data in memory or file is kept in location.
546*288bf522SAndroid Build Coastguard Worker   struct AuxDataLocation {
547*288bf522SAndroid Build Coastguard Worker     const char* addr = nullptr;
548*288bf522SAndroid Build Coastguard Worker     uint64_t file_offset = 0;
549*288bf522SAndroid Build Coastguard Worker   } location;
550*288bf522SAndroid Build Coastguard Worker 
AuxTraceRecordAuxTraceRecord551*288bf522SAndroid Build Coastguard Worker   AuxTraceRecord() {}
552*288bf522SAndroid Build Coastguard Worker   AuxTraceRecord(uint64_t aux_size, uint64_t offset, uint32_t idx, uint32_t tid, uint32_t cpu);
553*288bf522SAndroid Build Coastguard Worker 
554*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
CpuAuxTraceRecord555*288bf522SAndroid Build Coastguard Worker   uint32_t Cpu() const override { return data->cpu; }
SizeAuxTraceRecord556*288bf522SAndroid Build Coastguard Worker   static size_t Size() { return sizeof(perf_event_header) + sizeof(DataType); }
557*288bf522SAndroid Build Coastguard Worker 
558*288bf522SAndroid Build Coastguard Worker  protected:
559*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
560*288bf522SAndroid Build Coastguard Worker };
561*288bf522SAndroid Build Coastguard Worker 
562*288bf522SAndroid Build Coastguard Worker struct KernelSymbolRecord : public Record {
563*288bf522SAndroid Build Coastguard Worker   uint32_t kallsyms_size;
564*288bf522SAndroid Build Coastguard Worker   const char* kallsyms;
565*288bf522SAndroid Build Coastguard Worker 
KernelSymbolRecordKernelSymbolRecord566*288bf522SAndroid Build Coastguard Worker   KernelSymbolRecord() {}
567*288bf522SAndroid Build Coastguard Worker   explicit KernelSymbolRecord(const std::string& kallsyms);
568*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
569*288bf522SAndroid Build Coastguard Worker 
570*288bf522SAndroid Build Coastguard Worker  protected:
571*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
572*288bf522SAndroid Build Coastguard Worker };
573*288bf522SAndroid Build Coastguard Worker 
574*288bf522SAndroid Build Coastguard Worker struct DsoRecord : public Record {
575*288bf522SAndroid Build Coastguard Worker   uint64_t dso_type;
576*288bf522SAndroid Build Coastguard Worker   uint64_t dso_id;
577*288bf522SAndroid Build Coastguard Worker   uint64_t min_vaddr;
578*288bf522SAndroid Build Coastguard Worker   const char* dso_name;
579*288bf522SAndroid Build Coastguard Worker 
DsoRecordDsoRecord580*288bf522SAndroid Build Coastguard Worker   DsoRecord() {}
581*288bf522SAndroid Build Coastguard Worker   DsoRecord(uint64_t dso_type, uint64_t dso_id, const std::string& dso_name, uint64_t min_vaddr);
582*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
583*288bf522SAndroid Build Coastguard Worker 
584*288bf522SAndroid Build Coastguard Worker  protected:
585*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
586*288bf522SAndroid Build Coastguard Worker };
587*288bf522SAndroid Build Coastguard Worker 
588*288bf522SAndroid Build Coastguard Worker struct SymbolRecord : public Record {
589*288bf522SAndroid Build Coastguard Worker   uint64_t addr;
590*288bf522SAndroid Build Coastguard Worker   uint64_t len;
591*288bf522SAndroid Build Coastguard Worker   uint64_t dso_id;
592*288bf522SAndroid Build Coastguard Worker   const char* name;
593*288bf522SAndroid Build Coastguard Worker 
SymbolRecordSymbolRecord594*288bf522SAndroid Build Coastguard Worker   SymbolRecord() {}
595*288bf522SAndroid Build Coastguard Worker   SymbolRecord(uint64_t addr, uint64_t len, const std::string& name, uint64_t dso_id);
596*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
597*288bf522SAndroid Build Coastguard Worker 
598*288bf522SAndroid Build Coastguard Worker  protected:
599*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
600*288bf522SAndroid Build Coastguard Worker };
601*288bf522SAndroid Build Coastguard Worker 
602*288bf522SAndroid Build Coastguard Worker struct TracingDataRecord : public Record {
603*288bf522SAndroid Build Coastguard Worker   uint32_t data_size;
604*288bf522SAndroid Build Coastguard Worker   const char* data;
605*288bf522SAndroid Build Coastguard Worker 
TracingDataRecordTracingDataRecord606*288bf522SAndroid Build Coastguard Worker   TracingDataRecord() {}
607*288bf522SAndroid Build Coastguard Worker   explicit TracingDataRecord(const std::vector<char>& tracing_data);
608*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
609*288bf522SAndroid Build Coastguard Worker 
610*288bf522SAndroid Build Coastguard Worker  protected:
611*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
612*288bf522SAndroid Build Coastguard Worker };
613*288bf522SAndroid Build Coastguard Worker 
614*288bf522SAndroid Build Coastguard Worker struct EventIdRecord : public Record {
615*288bf522SAndroid Build Coastguard Worker   uint64_t count;
616*288bf522SAndroid Build Coastguard Worker   struct EventIdData {
617*288bf522SAndroid Build Coastguard Worker     uint64_t attr_id;
618*288bf522SAndroid Build Coastguard Worker     uint64_t event_id;
619*288bf522SAndroid Build Coastguard Worker   } const* data;
620*288bf522SAndroid Build Coastguard Worker 
EventIdRecordEventIdRecord621*288bf522SAndroid Build Coastguard Worker   EventIdRecord() {}
622*288bf522SAndroid Build Coastguard Worker   explicit EventIdRecord(const std::vector<uint64_t>& data);
623*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
624*288bf522SAndroid Build Coastguard Worker 
625*288bf522SAndroid Build Coastguard Worker  protected:
626*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
627*288bf522SAndroid Build Coastguard Worker };
628*288bf522SAndroid Build Coastguard Worker 
629*288bf522SAndroid Build Coastguard Worker struct CallChainRecord : public Record {
630*288bf522SAndroid Build Coastguard Worker   uint32_t pid;
631*288bf522SAndroid Build Coastguard Worker   uint32_t tid;
632*288bf522SAndroid Build Coastguard Worker   uint64_t chain_type;
633*288bf522SAndroid Build Coastguard Worker   uint64_t time;
634*288bf522SAndroid Build Coastguard Worker   uint64_t ip_nr;
635*288bf522SAndroid Build Coastguard Worker   uint64_t* ips;
636*288bf522SAndroid Build Coastguard Worker   uint64_t* sps;
637*288bf522SAndroid Build Coastguard Worker 
CallChainRecordCallChainRecord638*288bf522SAndroid Build Coastguard Worker   CallChainRecord() {}
639*288bf522SAndroid Build Coastguard Worker 
640*288bf522SAndroid Build Coastguard Worker   CallChainRecord(pid_t pid, pid_t tid, simpleperf::CallChainJoiner::ChainType type, uint64_t time,
641*288bf522SAndroid Build Coastguard Worker                   const std::vector<uint64_t>& ips, const std::vector<uint64_t>& sps);
642*288bf522SAndroid Build Coastguard Worker 
643*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
TimestampCallChainRecord644*288bf522SAndroid Build Coastguard Worker   uint64_t Timestamp() const override { return time; }
645*288bf522SAndroid Build Coastguard Worker 
646*288bf522SAndroid Build Coastguard Worker  protected:
647*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
648*288bf522SAndroid Build Coastguard Worker };
649*288bf522SAndroid Build Coastguard Worker 
650*288bf522SAndroid Build Coastguard Worker struct UnwindingResultRecord : public Record {
651*288bf522SAndroid Build Coastguard Worker   uint64_t time;
652*288bf522SAndroid Build Coastguard Worker   UnwindingResult unwinding_result;
653*288bf522SAndroid Build Coastguard Worker   PerfSampleRegsUserType regs_user_data;
654*288bf522SAndroid Build Coastguard Worker   PerfSampleStackUserType stack_user_data;
655*288bf522SAndroid Build Coastguard Worker 
656*288bf522SAndroid Build Coastguard Worker   struct CallChain {
657*288bf522SAndroid Build Coastguard Worker     uint64_t length = 0;
658*288bf522SAndroid Build Coastguard Worker     uint64_t* ips = nullptr;
659*288bf522SAndroid Build Coastguard Worker     uint64_t* sps = nullptr;
660*288bf522SAndroid Build Coastguard Worker   } callchain;
661*288bf522SAndroid Build Coastguard Worker 
UnwindingResultRecordUnwindingResultRecord662*288bf522SAndroid Build Coastguard Worker   UnwindingResultRecord() {}
663*288bf522SAndroid Build Coastguard Worker 
664*288bf522SAndroid Build Coastguard Worker   UnwindingResultRecord(uint64_t time, const simpleperf::UnwindingResult& unwinding_result,
665*288bf522SAndroid Build Coastguard Worker                         const PerfSampleRegsUserType& regs_user_data,
666*288bf522SAndroid Build Coastguard Worker                         const PerfSampleStackUserType& stack_user_data,
667*288bf522SAndroid Build Coastguard Worker                         const std::vector<uint64_t>& ips, const std::vector<uint64_t>& sps);
668*288bf522SAndroid Build Coastguard Worker 
669*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
TimestampUnwindingResultRecord670*288bf522SAndroid Build Coastguard Worker   uint64_t Timestamp() const override { return time; }
671*288bf522SAndroid Build Coastguard Worker 
672*288bf522SAndroid Build Coastguard Worker  protected:
673*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
674*288bf522SAndroid Build Coastguard Worker };
675*288bf522SAndroid Build Coastguard Worker 
676*288bf522SAndroid Build Coastguard Worker // Add a debug string in the recording file.
677*288bf522SAndroid Build Coastguard Worker struct DebugRecord : public Record {
678*288bf522SAndroid Build Coastguard Worker   uint64_t time = 0;
679*288bf522SAndroid Build Coastguard Worker   char* s = nullptr;
680*288bf522SAndroid Build Coastguard Worker 
DebugRecordDebugRecord681*288bf522SAndroid Build Coastguard Worker   DebugRecord() {}
682*288bf522SAndroid Build Coastguard Worker 
683*288bf522SAndroid Build Coastguard Worker   DebugRecord(uint64_t time, const std::string& s);
684*288bf522SAndroid Build Coastguard Worker 
685*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
TimestampDebugRecord686*288bf522SAndroid Build Coastguard Worker   uint64_t Timestamp() const override { return time; }
687*288bf522SAndroid Build Coastguard Worker 
688*288bf522SAndroid Build Coastguard Worker  protected:
689*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
690*288bf522SAndroid Build Coastguard Worker };
691*288bf522SAndroid Build Coastguard Worker 
692*288bf522SAndroid Build Coastguard Worker // UnknownRecord is used for unknown record types, it makes sure all unknown
693*288bf522SAndroid Build Coastguard Worker // records are not changed when modifying perf.data.
694*288bf522SAndroid Build Coastguard Worker struct UnknownRecord : public Record {
695*288bf522SAndroid Build Coastguard Worker   const char* data;
696*288bf522SAndroid Build Coastguard Worker 
697*288bf522SAndroid Build Coastguard Worker   bool Parse(const perf_event_attr& attr, char* p, char* end) override;
698*288bf522SAndroid Build Coastguard Worker 
699*288bf522SAndroid Build Coastguard Worker  protected:
700*288bf522SAndroid Build Coastguard Worker   void DumpData(size_t indent) const override;
701*288bf522SAndroid Build Coastguard Worker };
702*288bf522SAndroid Build Coastguard Worker 
703*288bf522SAndroid Build Coastguard Worker // Read record from the buffer pointed by [p]. But the record doesn't own
704*288bf522SAndroid Build Coastguard Worker // the buffer.
705*288bf522SAndroid Build Coastguard Worker std::unique_ptr<Record> ReadRecordFromBuffer(const perf_event_attr& attr, uint32_t type, char* p,
706*288bf522SAndroid Build Coastguard Worker                                              char* end);
707*288bf522SAndroid Build Coastguard Worker 
708*288bf522SAndroid Build Coastguard Worker // Read records from the buffer pointed by [buf]. None of the records own
709*288bf522SAndroid Build Coastguard Worker // the buffer.
710*288bf522SAndroid Build Coastguard Worker std::vector<std::unique_ptr<Record>> ReadRecordsFromBuffer(const perf_event_attr& attr, char* buf,
711*288bf522SAndroid Build Coastguard Worker                                                            size_t buf_size);
712*288bf522SAndroid Build Coastguard Worker 
713*288bf522SAndroid Build Coastguard Worker // Read one record from the buffer pointed by [p]. But the record doesn't
714*288bf522SAndroid Build Coastguard Worker // own the buffer.
715*288bf522SAndroid Build Coastguard Worker std::unique_ptr<Record> ReadRecordFromBuffer(const perf_event_attr& attr, char* p, char* end);
716*288bf522SAndroid Build Coastguard Worker 
717*288bf522SAndroid Build Coastguard Worker }  // namespace simpleperf
718*288bf522SAndroid Build Coastguard Worker 
719*288bf522SAndroid Build Coastguard Worker #endif  // SIMPLE_PERF_RECORD_H_
720