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