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 #if SAMPLE_ID_ALL 59 struct sample_id sample_id; 60 #endif 61 }; 62 63 /* 64 The MMAP events record the PROT_EXEC mappings so that 65 we can correlate user-space IPs to code. They have 66 the following structure: 67 pid is the process ID. 68 tid is the thread ID. 69 addr is the address of the allocated memory. 70 len is the length of the allocated memory. 71 pgoff is the page offset of the allocated memory. 72 filename 73 is a string describing the backing of 74 the allocated memory. 75 */ 76 struct PerfRecordMmapData { 77 u32 pid = 0; 78 u32 tid = 0; 79 u64 addr = 0; 80 u64 len = 0; 81 u64 pgoff = 0; 82 char filename[KILO] = {0}; 83 #if SAMPLE_ID_ALL 84 struct sample_id sample_id; 85 #endif 86 }; 87 88 /* 89 This record includes extended information on mmap(2) 90 calls returning executable mappings. The format is 91 similar to that of the PERF_RECORD_MMAP record, but 92 includes extra values that allow uniquely identifying 93 shared mappings. 94 95 pid is the process ID. 96 tid is the thread ID. 97 addr is the address of the allocated memory. 98 len is the length of the allocated memory. 99 pgoff is the page offset of the allocated memory. 100 maj is the major ID of the underlying device. 101 min is the minor ID of the underlying device. 102 ino is the inode number. 103 ino_generation 104 is the inode generation. 105 prot is the protection information. 106 flags is the flags information. 107 filename 108 is a string describing the backing of the 109 allocated memory. 110 */ 111 struct PerfRecordMmap2Data { 112 u32 pid = 0; 113 u32 tid = 0; 114 u64 addr = 0; 115 u64 len = 0; 116 u64 pgoff = 0; 117 u32 maj = 0; 118 u32 min = 0; 119 u64 ino = 0; 120 u64 ino_generation = 0; 121 u32 prot = 0; 122 u32 flags = 0; 123 char filename[KILO] = {0}; 124 #if SAMPLE_ID_ALL 125 struct sample_id sample_id; 126 #endif 127 }; 128 129 /* 130 This record indicates when events are lost. 131 id is the unique event ID for the samples that were lost. 132 lost is the number of events that were lost. 133 */ 134 struct PerfRecordLostData { 135 u64 id = 0; 136 u64 lost = 0; 137 #if SAMPLE_ID_ALL 138 struct sample_id sample_id; 139 #endif 140 }; 141 142 /* 143 This record indicates a change in the process name. 144 pid is the process ID. 145 tid is the thread ID. 146 comm is a string containing the new name of the process. 147 */ 148 struct PerfRecordCommData { 149 u32 pid = 0; 150 u32 tid = 0; 151 char comm[KILO] = {0}; 152 #if SAMPLE_ID_ALL 153 struct sample_id sample_id; 154 #endif 155 }; 156 157 struct PerfBranchEntry { 158 u64 from = 0; 159 u64 to = 0; 160 u64 flags = 0; 161 }; 162 163 // This record indicates a sample. 164 struct PerfRecordSampleData { 165 u64 sample_id = 0; /* if PERF_SAMPLE_IDENTIFIER */ 166 u64 ip = 0; /* if PERF_SAMPLE_IP */ 167 u32 pid = 0; 168 u32 tid = 0; /* if PERF_SAMPLE_TID */ 169 u64 time = 0; /* if PERF_SAMPLE_TIME */ 170 u64 addr = 0; /* if PERF_SAMPLE_ADDR */ 171 u64 id = 0; /* if PERF_SAMPLE_ID */ 172 u64 stream_id = 0; /* if PERF_SAMPLE_STREAM_ID */ 173 u32 cpu = 0; 174 u32 res = 0; /* if PERF_SAMPLE_CPU */ 175 u64 period = 0; /* if PERF_SAMPLE_PERIOD */ 176 struct read_format v; 177 /* if PERF_SAMPLE_READ */ 178 u64 nr = 0; /* if PERF_SAMPLE_CALLCHAIN */ 179 u64 *ips = nullptr; /* if PERF_SAMPLE_CALLCHAIN */ 180 u32 raw_size = 0; /* if PERF_SAMPLE_RAW */ 181 u8 *raw_data = nullptr; /* if PERF_SAMPLE_RAW */ 182 u64 bnr = 0; /* if PERF_SAMPLE_BRANCH_STACK */ 183 struct PerfBranchEntry *lbr = nullptr; /* if PERF_SAMPLE_BRANCH_STACK */ 184 u64 user_abi = 0; /* if PERF_SAMPLE_REGS_USER */ 185 u64 reg_mask = 0; 186 u64 reg_nr = 0; 187 u64 *user_regs = nullptr; /* if PERF_SAMPLE_REGS_USER */ 188 u64 stack_size = 0; /* if PERF_SAMPLE_STACK_USER */ 189 u8 *stack_data = nullptr; /* if PERF_SAMPLE_STACK_USER */ 190 u64 dyn_size = 0; /* if PERF_SAMPLE_STACK_USER && stack_size != 0 */ 191 u64 weight = 0; /* if PERF_SAMPLE_WEIGHT */ 192 u64 data_src = 0; /* if PERF_SAMPLE_DATA_SRC */ 193 u64 transaction = 0; /* if PERF_SAMPLE_TRANSACTION */ 194 u64 intr_abi = 0; /* if PERF_SAMPLE_REGS_INTR */ 195 u64 intr_regs[0]; /* if PERF_SAMPLE_REGS_INTR */ 196 u64 phys_addr = 0; /* if PERF_SAMPLE_PHYS_ADDR */ 197 u64 cgroup = 0; /* if PERF_SAMPLE_CGROUP */ 198 u64 server_nr = 0; /* if PERF_SAMPLE_SERVER_PID */ 199 u64 *server_pids = 0; /* if PERF_SAMPLE_SERVER_PID */ 200 }; 201 202 /* 203 This record indicates a process exit event. 204 */ 205 struct PerfRecordExitData { 206 u32 pid = 0; 207 u32 ppid = 0; 208 u32 tid = 0; 209 u32 ptid = 0; 210 u64 time = 0; 211 #if SAMPLE_ID_ALL 212 struct sample_id sample_id; 213 #endif 214 }; 215 216 /* 217 This record indicates a throttle/unthrottle event. 218 */ 219 struct PerfRecordThrottleData { 220 u64 time = 0; 221 u64 id = 0; 222 u64 stream_id = 0; 223 #if SAMPLE_ID_ALL 224 struct sample_id sample_id; 225 #endif 226 }; 227 228 /* 229 This record indicates a fork event. 230 */ 231 struct PerfRecordForkData { 232 u32 pid = 0; 233 u32 ppid = 0; 234 u32 tid = 0; 235 u32 ptid = 0; 236 u64 time = 0; 237 #if SAMPLE_ID_ALL 238 struct sample_id sample_id; 239 #endif 240 }; 241 242 /* 243 When using hardware sampling (such as Intel PEBS) this 244 record indicates some number of samples that may have 245 been lost. 246 */ 247 struct PerfRecordLostSamplesData { 248 u64 lost = 0; 249 #if SAMPLE_ID_ALL 250 struct sample_id sample_id; 251 #endif 252 }; 253 254 /* 255 This record indicates which process has initiated an 256 instruction trace event, allowing tools to properly 257 correlate the instruction addresses in the AUX buffer 258 with the proper executable. 259 260 pid process ID of the thread starting an 261 instruction trace. 262 tid thread ID of the thread starting an instruction 263 trace. 264 */ 265 struct PerfRecordItraceStartData { 266 u32 pid = 0; 267 u32 tid = 0; 268 }; 269 270 /* 271 This record reports that new data is available in the 272 separate AUX buffer region. 273 274 aux_offset 275 offset in the AUX mmap region where the new 276 data begins. 277 aux_size 278 size of the data made available. 279 flags describes the AUX update. 280 PERF_AUX_FLAG_TRUNCATED 281 if set, then the data returned was 282 truncated to fit the available buffer 283 size. 284 285 PERF_AUX_FLAG_OVERWRITE 286 if set, then the data returned has 287 overwritten previous data. 288 */ 289 struct PerfRecordAuxData { 290 u64 aux_offset = 0; 291 u64 aux_size = 0; 292 u64 flags = 0; 293 struct sample_id sample_id; 294 }; 295 296 /* 297 This record indicates a read event. 298 */ 299 struct PerfRecordReadData { 300 u32 pid = 0; 301 u32 tid = 0; 302 read_format values; 303 #if SAMPLE_ID_ALL 304 struct sample_id sample_id; 305 #endif 306 }; 307 308 /* 309 This record indicates a context switch has happened. 310 The PERF_RECORD_MISC_SWITCH_OUT bit in the misc field 311 indicates whether it was a context switch into or away 312 from the current process. 313 */ 314 struct PerfRecordSwitchData { 315 #if SAMPLE_ID_ALL 316 struct sample_id sample_id; 317 #endif 318 }; 319 320 /* 321 As with PERF_RECORD_SWITCH this record indicates a 322 context switch has happened, but it only occurs when 323 sampling in CPU-wide mode and provides additional 324 information on the process being switched to/from. 325 The PERF_RECORD_MISC_SWITCH_OUT bit in the misc field 326 indicates whether it was a context switch into or away 327 from the current process. 328 329 next_prev_pid 330 The process ID of the previous (if switching 331 in) or next (if switching out) process on the 332 CPU. 333 334 next_prev_tid 335 The thread ID of the previous (if switching in) 336 or next (if switching out) thread on the CPU. 337 */ 338 struct PerfRecordSwitchCpuWideData { 339 u32 next_prev_pid = 0; 340 u32 next_prev_tid = 0; 341 #if SAMPLE_ID_ALL 342 struct sample_id sample_id; 343 #endif 344 }; 345 346 /* 347 This record includes various namespace information of 348 a process. 349 350 pid is the process ID 351 tid is the thread ID 352 353 nr_namespace 354 is the number of namespaces in this record 355 356 Each namespace has dev and inode fields and is 357 recorded in the fixed position like below: 358 359 NET_NS_INDEX=0 360 Network namespace 361 UTS_NS_INDEX=1 362 UTS namespace 363 IPC_NS_INDEX=2 364 IPC namespace 365 PID_NS_INDEX=3 366 PID namespace 367 USER_NS_INDEX=4 368 User namespace 369 MNT_NS_INDEX=5 370 Mount namespace 371 CGROUP_NS_INDEX=6 372 Cgroup namespace 373 */ 374 struct PerfRecordNamespacesData { 375 u32 pid = 0; 376 u32 tid = 0; 377 u64 nr_namespaces = 0; 378 struct name_space { 379 u64 dev = 0; 380 u64 inode = 0; 381 } namespaces[0]; 382 #if SAMPLE_ID_ALL 383 struct sample_id sample_id; 384 #endif 385 }; 386 387 struct PerfRecordTtimeConvData { 388 u64 time_shift = 0; 389 u64 time_mult = 0; 390 u64 time_zero = 0; 391 u64 time_cycles = 0; 392 u64 time_mask = 0; 393 u8 cap_user_time_zero = 0; 394 u8 cap_user_time_short = 0; 395 u8 reserved[6] = {0}; // 6 : For alignment 396 }; 397 398 struct PerfRecordAuxtraceInfoData { 399 u32 type = 0; 400 u32 reserved = 0; 401 u64 priv[2] = {0}; 402 }; 403 404 struct PerfRecordCpuMapData { 405 u16 type = 0; 406 u16 nr = 0; 407 u16 cpu[16] = {0}; // 16 : cpus 408 u8 reserved[4] = {0}; // 4 : For alignment 409 }; 410 } // namespace HiPerf 411 } // namespace Developtools 412 } // namespace OHOS 413 #endif // HIPERF_PERF_RECORD_FORMAT_H 414