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