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 
23 namespace OHOS {
24 namespace Developtools {
25 namespace 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 
31 struct 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
43 struct 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 
50 struct 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 */
73 struct 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 */
108 struct 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 */
131 struct 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 */
145 struct 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 
154 struct PerfBranchEntry {
155     u64 from = 0;
156     u64 to = 0;
157     u64 flags = 0;
158 };
159 
160 // This record indicates a sample.
161 struct 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 */
202 struct 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 */
216 struct 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 */
228 struct 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 */
244 struct 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 */
262 struct 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 */
286 struct 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 */
296 struct 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 */
311 struct 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 */
335 struct 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 */
371 struct 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