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