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