1/* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved. 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_REGISTER_H 16#define HIPERF_REGISTER_H 17 18#include <linux/perf_event.h> 19 20#include <cinttypes> 21#include <string> 22 23#include "utilities.h" 24#include "unwind_define.h" 25 26namespace OHOS { 27namespace Developtools { 28namespace NativeDaemon { 29using namespace OHOS::HiviewDFX; 30 31// these define copy from kernel uapi 32enum perf_event_x86_regs { 33 PERF_REG_X86_AX, 34 PERF_REG_X86_BX, 35 PERF_REG_X86_CX, 36 PERF_REG_X86_DX, 37 PERF_REG_X86_SI, 38 PERF_REG_X86_DI, 39 PERF_REG_X86_BP, 40 PERF_REG_X86_SP, 41 PERF_REG_X86_IP, 42 PERF_REG_X86_FLAGS, 43 PERF_REG_X86_CS, 44 PERF_REG_X86_SS, 45 PERF_REG_X86_DS, 46 PERF_REG_X86_ES, 47 PERF_REG_X86_FS, 48 PERF_REG_X86_GS, 49 PERF_REG_X86_R8, 50 PERF_REG_X86_R9, 51 PERF_REG_X86_R10, 52 PERF_REG_X86_R11, 53 PERF_REG_X86_R12, 54 PERF_REG_X86_R13, 55 PERF_REG_X86_R14, 56 PERF_REG_X86_R15, 57 PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1, 58 PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1, 59}; 60 61enum perf_event_arm64_regs { 62 PERF_REG_ARM64_X0, 63 PERF_REG_ARM64_X1, 64 PERF_REG_ARM64_X2, 65 PERF_REG_ARM64_X3, 66 PERF_REG_ARM64_X4, 67 PERF_REG_ARM64_X5, 68 PERF_REG_ARM64_X6, 69 PERF_REG_ARM64_X7, 70 PERF_REG_ARM64_X8, 71 PERF_REG_ARM64_X9, 72 PERF_REG_ARM64_X10, 73 PERF_REG_ARM64_X11, 74 PERF_REG_ARM64_X12, 75 PERF_REG_ARM64_X13, 76 PERF_REG_ARM64_X14, 77 PERF_REG_ARM64_X15, 78 PERF_REG_ARM64_X16, 79 PERF_REG_ARM64_X17, 80 PERF_REG_ARM64_X18, 81 PERF_REG_ARM64_X19, 82 PERF_REG_ARM64_X20, 83 PERF_REG_ARM64_X21, 84 PERF_REG_ARM64_X22, 85 PERF_REG_ARM64_X23, 86 PERF_REG_ARM64_X24, 87 PERF_REG_ARM64_X25, 88 PERF_REG_ARM64_X26, 89 PERF_REG_ARM64_X27, 90 PERF_REG_ARM64_X28, 91 PERF_REG_ARM64_X29, 92 PERF_REG_ARM64_LR, 93 PERF_REG_ARM64_SP, 94 PERF_REG_ARM64_PC, 95 PERF_REG_ARM64_MAX, 96}; 97 98enum perf_event_arm_regs { 99 PERF_REG_ARM_R0, 100 PERF_REG_ARM_R1, 101 PERF_REG_ARM_R2, 102 PERF_REG_ARM_R3, 103 PERF_REG_ARM_R4, 104 PERF_REG_ARM_R5, 105 PERF_REG_ARM_R6, 106 PERF_REG_ARM_R7, 107 PERF_REG_ARM_R8, 108 PERF_REG_ARM_R9, 109 PERF_REG_ARM_R10, 110 PERF_REG_ARM_FP = 11, 111 PERF_REG_ARM_IP = 12, 112 PERF_REG_ARM_SP = 13, 113 PERF_REG_ARM_LR = 14, 114 PERF_REG_ARM_PC = 15, 115 PERF_REG_ARM_MAX, 116}; 117 118// order is IP , SP for ut 119static const std::map<size_t, const std::string> PERF_REG_NAME_MAP = { 120#if defined(target_cpu_x86_64) 121 {PERF_REG_X86_IP, "PERF_REG_X86_IP"}, 122 {PERF_REG_X86_SP, "PERF_REG_X86_SP"}, 123#elif defined(target_cpu_arm) 124 {PERF_REG_ARM_PC, "PERF_REG_ARM_PC"}, 125 {PERF_REG_ARM_SP, "PERF_REG_ARM_SP"}, 126#elif defined(target_cpu_arm64) 127 {PERF_REG_ARM64_PC, "PERF_REG_ARM64_PC"}, 128 {PERF_REG_ARM64_SP, "PERF_REG_ARM64_SP"}, 129#endif 130}; 131 132// context name 133static const std::map<uint64_t, const std::string> PERF_CONTEXT_NAME = { 134 {PERF_CONTEXT_HV, "PERF_CONTEXT_HV"}, 135 {PERF_CONTEXT_KERNEL, "PERF_CONTEXT_KERNEL"}, 136 {PERF_CONTEXT_USER, "PERF_CONTEXT_USER"}, 137 {PERF_CONTEXT_GUEST, "PERF_CONTEXT_GUEST"}, 138 {PERF_CONTEXT_GUEST_KERNEL, "PERF_CONTEXT_GUEST_KERNEL"}, 139 {PERF_CONTEXT_GUEST_USER, "PERF_CONTEXT_GUEST_USER"}, 140 {PERF_CONTEXT_MAX, "PERF_CONTEXT_MAX"}, 141}; 142 143#if defined(target_cpu_x86_64) 144constexpr ArchType buildArchType = ArchType::ARCH_X86_64; 145#elif defined(target_cpu_arm64) 146constexpr ArchType buildArchType = ArchType::ARCH_ARM64; 147#elif defined(target_cpu_arm) 148constexpr ArchType buildArchType = ArchType::ARCH_ARM; 149#else 150#error NOT SUPPORT ARCH 151#endif 152 153const std::string UpdatePerfContext(uint64_t addr, perf_callchain_context &perfCallchainContext); 154 155uint64_t GetSupportedRegMask(ArchType arch); 156 157// this is only for debug 158const std::string RegisterGetName(size_t registerIndex); 159 160size_t RegisterGetCount(); 161 162size_t RegisterGetSP(ArchType arch); 163 164inline const std::string GetArchName(ArchType arch) 165{ 166 switch (arch) { 167 case ArchType::ARCH_X86: 168 return "X86_32"; 169 case ArchType::ARCH_X86_64: 170 return "X86_64"; 171 case ArchType::ARCH_ARM: 172 return "ARM"; 173 case ArchType::ARCH_ARM64: 174 return "ARM64"; 175 default: 176 return "Unsupport"; 177 } 178} 179 180size_t RegisterGetIP(ArchType arch); 181 182inline size_t RegisterGetCount() 183{ 184 switch (buildArchType) { 185 case ArchType::ARCH_X86: 186 return PERF_REG_X86_32_MAX; 187 case ArchType::ARCH_X86_64: 188 return PERF_REG_X86_64_MAX; 189 case ArchType::ARCH_ARM: 190 return PERF_REG_ARM_MAX; 191 case ArchType::ARCH_ARM64: 192 return PERF_REG_ARM64_MAX; 193 default: { 194 HLOGM("Registers in an unknown CPU."); 195 return std::numeric_limits<size_t>::max(); 196 } 197 } 198} 199 200inline bool RegisterGetValue(uint64_t &value, const u64 registers[], const size_t registerIndex, 201 const size_t registerNumber) 202{ 203 if (registerIndex >= registerNumber) { 204 HLOGE("registerIndex is %zu, max is %zu", registerIndex, registerNumber); 205 return false; 206 } 207 value = registers[registerIndex]; 208 return true; 209} 210 211inline bool RegisterGetSPValue(uint64_t &value, ArchType arch, const u64 registers[], 212 const size_t registerNumber) 213{ 214 return RegisterGetValue(value, registers, RegisterGetSP(arch), registerNumber); 215} 216 217inline bool RegisterGetIPValue(uint64_t &value, ArchType arch, const u64 registers[], 218 const size_t registerNumber) 219{ 220 return RegisterGetValue(value, registers, RegisterGetIP(arch), registerNumber); 221} 222 223int LibunwindRegIdToPerfReg(int regnum); 224 225ArchType GetDeviceArch(); 226ArchType SetDeviceArch(ArchType arch); 227ArchType GetArchTypeFromUname(const std::string &machine); 228ArchType GetArchTypeFromABI(bool abi32); 229void UpdateRegForABI(ArchType arch, u64 registers[]); 230} // namespace NativeDaemon 231} // namespace Developtools 232} // namespace OHOS 233#endif