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