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