1/*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef HIPERF_PERF_RECORD_FORMAT_H
16#define HIPERF_PERF_RECORD_FORMAT_H
17
18#include <string>
19#include <linux/types.h>
20
21#include "utilities.h"
22
23namespace OHOS {
24namespace Developtools {
25namespace HiPerf {
26// description from https://man7.org/linux/man-pages/man2/perf_event_open.2.html
27
28#define SAMPLE_ID_ALL 0
29#define PERF_SAMPLE_SERVER_PID (1U << 31)
30
31struct sample_id {
32    u32 pid = 0;
33    u32 tid = 0;       /* if PERF_SAMPLE_TID set */
34    u64 time = 0;      /* if PERF_SAMPLE_TIME set */
35    u64 id = 0;        /* if PERF_SAMPLE_ID set */
36    u64 stream_id = 0; /* if PERF_SAMPLE_STREAM_ID set  */
37    u32 cpu = 0;
38    u32 res = 0;  /* if PERF_SAMPLE_CPU set */
39    u64 id2 = 0;       /* if PERF_SAMPLE_IDENTIFIER set */
40};
41
42// If PERF_FORMAT_GROUP was not specified
43struct read_format {
44    __u64 value = 0;        /* The value of the event */
45    __u64 timeEnabled = 0; /* if PERF_FORMAT_TOTAL_TIME_ENABLED */
46    __u64 timeRunning = 0; /* if PERF_FORMAT_TOTAL_TIME_RUNNING */
47    __u64 id = 0;           /* if PERF_FORMAT_ID */
48};
49
50struct PerfRecordAuxtraceData {
51    u64 size = 0;
52    u64 offset = 0;
53    u64 reference = 0;
54    u32 idx = 0;
55    u32 tid = 0;
56    u32 cpu = 0;
57    u32 reserved__ = 0;
58};
59
60/*
61    The MMAP events record the PROT_EXEC mappings so that
62    we can correlate user-space IPs to code.  They have
63    the following structure:
64        pid     is the process ID.
65        tid     is the thread ID.
66        addr    is the address of the allocated memory.
67        len     is the length of the allocated memory.
68        pgoff   is the page offset of the allocated memory.
69        filename
70            is a string describing the backing of
71            the allocated memory.
72*/
73struct PerfRecordMmapData {
74    u32 pid = 0;
75    u32 tid = 0;
76    u64 addr = 0;
77    u64 len = 0;
78    u64 pgoff = 0;
79    char filename[KILO] = {0};
80#if SAMPLE_ID_ALL
81    struct sample_id sample_id;
82#endif
83};
84
85/*
86    This record includes extended information on mmap(2)
87    calls returning executable mappings.  The format is
88    similar to that of the PERF_RECORD_MMAP record, but
89    includes extra values that allow uniquely identifying
90    shared mappings.
91
92    pid    is the process ID.
93    tid    is the thread ID.
94    addr   is the address of the allocated memory.
95    len    is the length of the allocated memory.
96    pgoff  is the page offset of the allocated memory.
97    maj    is the major ID of the underlying device.
98    min    is the minor ID of the underlying device.
99    ino    is the inode number.
100    ino_generation
101            is the inode generation.
102    prot   is the protection information.
103    flags  is the flags information.
104    filename
105            is a string describing the backing of the
106            allocated memory.
107*/
108struct PerfRecordMmap2Data {
109    u32 pid = 0;
110    u32 tid = 0;
111    u64 addr = 0;
112    u64 len = 0;
113    u64 pgoff = 0;
114    u32 maj = 0;
115    u32 min = 0;
116    u64 ino = 0;
117    u64 ino_generation = 0;
118    u32 prot = 0;
119    u32 flags = 0;
120    char filename[KILO] = {0};
121#if SAMPLE_ID_ALL
122    struct sample_id sample_id;
123#endif
124};
125
126/*
127    This record indicates when events are lost.
128    id     is the unique event ID for the samples that  were lost.
129    lost   is the number of events that were lost.
130*/
131struct PerfRecordLostData {
132    u64 id = 0;
133    u64 lost = 0;
134#if SAMPLE_ID_ALL
135    struct sample_id sample_id;
136#endif
137};
138
139/*
140    This record indicates a change in the process name.
141    pid    is the process ID.
142    tid    is the thread ID.
143    comm   is a string containing the new name of the process.
144*/
145struct PerfRecordCommData {
146    u32 pid = 0;
147    u32 tid = 0;
148    char comm[KILO] = {0};
149#if SAMPLE_ID_ALL
150    struct sample_id sample_id;
151#endif
152};
153
154struct PerfBranchEntry {
155    u64 from = 0;
156    u64 to = 0;
157    u64 flags = 0;
158};
159
160// This record indicates a sample.
161struct PerfRecordSampleData {
162    u64 sample_id = 0; /* if PERF_SAMPLE_IDENTIFIER */
163    u64 ip = 0;        /* if PERF_SAMPLE_IP */
164    u32 pid = 0;
165    u32 tid = 0;  /* if PERF_SAMPLE_TID */
166    u64 time = 0;      /* if PERF_SAMPLE_TIME */
167    u64 addr = 0;      /* if PERF_SAMPLE_ADDR */
168    u64 id = 0;        /* if PERF_SAMPLE_ID */
169    u64 stream_id = 0; /* if PERF_SAMPLE_STREAM_ID */
170    u32 cpu = 0;
171    u32 res = 0;  /* if PERF_SAMPLE_CPU */
172    u64 period = 0;    /* if PERF_SAMPLE_PERIOD */
173    struct read_format v;
174    /* if PERF_SAMPLE_READ */
175    u64 nr = 0;                        /* if PERF_SAMPLE_CALLCHAIN */
176    u64 *ips = nullptr;                /* if PERF_SAMPLE_CALLCHAIN */
177    u32 raw_size = 0;                  /* if PERF_SAMPLE_RAW */
178    u8 *raw_data = nullptr;                  /* if PERF_SAMPLE_RAW */
179    u64 bnr = 0;                       /* if PERF_SAMPLE_BRANCH_STACK */
180    struct PerfBranchEntry *lbr = nullptr; /* if PERF_SAMPLE_BRANCH_STACK */
181    u64 user_abi = 0;                  /* if PERF_SAMPLE_REGS_USER */
182    u64 reg_mask = 0;
183    u64 reg_nr = 0;
184    u64 *user_regs = nullptr;   /* if PERF_SAMPLE_REGS_USER */
185    u64 stack_size = 0;   /* if PERF_SAMPLE_STACK_USER */
186    u8 *stack_data = nullptr;   /* if PERF_SAMPLE_STACK_USER */
187    u64 dyn_size = 0;     /* if PERF_SAMPLE_STACK_USER && stack_size != 0 */
188    u64 weight = 0;       /* if PERF_SAMPLE_WEIGHT */
189    u64 data_src = 0;     /* if PERF_SAMPLE_DATA_SRC */
190    u64 transaction = 0;  /* if PERF_SAMPLE_TRANSACTION */
191    u64 intr_abi = 0;     /* if PERF_SAMPLE_REGS_INTR */
192    u64 intr_regs[0]; /* if PERF_SAMPLE_REGS_INTR */
193    u64 phys_addr = 0;    /* if PERF_SAMPLE_PHYS_ADDR */
194    u64 cgroup = 0;       /* if PERF_SAMPLE_CGROUP */
195    u64 server_nr = 0;    /* if PERF_SAMPLE_SERVER_PID */
196    u64 *server_pids = 0; /* if PERF_SAMPLE_SERVER_PID */
197};
198
199/*
200    This record indicates a process exit event.
201*/
202struct PerfRecordExitData {
203    u32 pid = 0;
204    u32 ppid = 0;
205    u32 tid = 0;
206    u32 ptid = 0;
207    u64 time = 0;
208#if SAMPLE_ID_ALL
209    struct sample_id sample_id;
210#endif
211};
212
213/*
214    This record indicates a throttle/unthrottle event.
215*/
216struct PerfRecordThrottleData {
217    u64 time = 0;
218    u64 id = 0;
219    u64 stream_id = 0;
220#if SAMPLE_ID_ALL
221    struct sample_id sample_id;
222#endif
223};
224
225/*
226    This record indicates a fork event.
227*/
228struct PerfRecordForkData {
229    u32 pid = 0;
230    u32 ppid = 0;
231    u32 tid = 0;
232    u32 ptid = 0;
233    u64 time = 0;
234#if SAMPLE_ID_ALL
235    struct sample_id sample_id;
236#endif
237};
238
239/*
240    When using hardware sampling (such as Intel PEBS) this
241    record indicates some number of samples that may have
242    been lost.
243*/
244struct PerfRecordLostSamplesData {
245    u64 lost = 0;
246#if SAMPLE_ID_ALL
247    struct sample_id sample_id;
248#endif
249};
250
251/*
252    This record indicates which process has initiated an
253    instruction trace event, allowing tools to properly
254    correlate the instruction addresses in the AUX buffer
255    with the proper executable.
256
257    pid    process ID of the thread starting an
258            instruction trace.
259    tid    thread ID of the thread starting an instruction
260            trace.
261*/
262struct PerfRecordItraceStartData {
263    u32 pid = 0;
264    u32 tid = 0;
265};
266
267/*
268    This record reports that new data is available in the
269    separate AUX buffer region.
270
271    aux_offset
272            offset in the AUX mmap region where the new
273            data begins.
274    aux_size
275            size of the data made available.
276    flags  describes the AUX update.
277            PERF_AUX_FLAG_TRUNCATED
278                if set, then the data returned was
279                truncated to fit the available buffer
280                size.
281
282            PERF_AUX_FLAG_OVERWRITE
283                if set, then the data returned has
284                overwritten previous data.
285*/
286struct PerfRecordAuxData {
287    u64 aux_offset = 0;
288    u64 aux_size = 0;
289    u64 flags = 0;
290    struct sample_id sample_id;
291};
292
293/*
294    This record indicates a read event.
295*/
296struct PerfRecordReadData {
297    u32 pid = 0;
298    u32 tid = 0;
299    read_format values;
300#if SAMPLE_ID_ALL
301    struct sample_id sample_id;
302#endif
303};
304
305/*
306    This record indicates a context switch has happened.
307    The PERF_RECORD_MISC_SWITCH_OUT bit in the misc field
308    indicates whether it was a context switch into or away
309    from the current process.
310*/
311struct PerfRecordSwitchData {
312#if SAMPLE_ID_ALL
313    struct sample_id sample_id;
314#endif
315};
316
317/*
318    As with PERF_RECORD_SWITCH this record indicates a
319    context switch has happened, but it only occurs when
320    sampling in CPU-wide mode and provides additional
321    information on the process being switched to/from.
322    The PERF_RECORD_MISC_SWITCH_OUT bit in the misc field
323    indicates whether it was a context switch into or away
324    from the current process.
325
326    next_prev_pid
327            The process ID of the previous (if switching
328            in) or next (if switching out) process on the
329            CPU.
330
331    next_prev_tid
332            The thread ID of the previous (if switching in)
333            or next (if switching out) thread on the CPU.
334*/
335struct PerfRecordSwitchCpuWideData {
336    u32 next_prev_pid = 0;
337    u32 next_prev_tid = 0;
338#if SAMPLE_ID_ALL
339    struct sample_id sample_id;
340#endif
341};
342
343/*
344    This record includes various namespace information of
345    a process.
346
347    pid    is the process ID
348    tid    is the thread ID
349
350    nr_namespace
351            is the number of namespaces in this record
352
353    Each namespace has dev and inode fields and is
354    recorded in the fixed position like below:
355
356    NET_NS_INDEX=0
357            Network namespace
358    UTS_NS_INDEX=1
359            UTS namespace
360    IPC_NS_INDEX=2
361            IPC namespace
362    PID_NS_INDEX=3
363            PID namespace
364    USER_NS_INDEX=4
365            User namespace
366    MNT_NS_INDEX=5
367            Mount namespace
368    CGROUP_NS_INDEX=6
369            Cgroup namespace
370*/
371struct PerfRecordNamespacesData {
372    u32 pid = 0;
373    u32 tid = 0;
374    u64 nr_namespaces = 0;
375    struct name_space {
376        u64 dev = 0;
377        u64 inode = 0;
378    } namespaces[0];
379#if SAMPLE_ID_ALL
380    struct sample_id sample_id;
381#endif
382};
383} // namespace HiPerf
384} // namespace Developtools
385} // namespace OHOS
386#endif // HIPERF_PERF_RECORD_FORMAT_H
387