1 /*
2 * Copyright (c) 2021-2022 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 /* This files contains arm64 reg module. */
17
18 #include <securec.h>
19 #include "dfx_define.h"
20 #include "dfx_logger.h"
21 #include "dfx_regs.h"
22
23 namespace OHOS {
24 namespace HiviewDFX {
25 enum RegisterSeqNum {
26 REG_AARCH64_X0 = 0,
27 REG_AARCH64_X1,
28 REG_AARCH64_X2,
29 REG_AARCH64_X3,
30 REG_AARCH64_X4,
31 REG_AARCH64_X5,
32 REG_AARCH64_X6,
33 REG_AARCH64_X7,
34 REG_AARCH64_X8,
35 REG_AARCH64_X9,
36 REG_AARCH64_X10,
37 REG_AARCH64_X11,
38 REG_AARCH64_X12,
39 REG_AARCH64_X13,
40 REG_AARCH64_X14,
41 REG_AARCH64_X15,
42 REG_AARCH64_X16,
43 REG_AARCH64_X17,
44 REG_AARCH64_X18,
45 REG_AARCH64_X19,
46 REG_AARCH64_X20,
47 REG_AARCH64_X21,
48 REG_AARCH64_X22,
49 REG_AARCH64_X23,
50 REG_AARCH64_X24,
51 REG_AARCH64_X25,
52 REG_AARCH64_X26,
53 REG_AARCH64_X27,
54 REG_AARCH64_X28,
55 REG_AARCH64_X29,
56 REG_AARCH64_X30,
57 REG_AARCH64_SP = 31,
58 REG_AARCH64_PC
59 };
60
DfxRegsArm64(const ucontext_t & context)61 DfxRegsArm64::DfxRegsArm64(const ucontext_t &context)
62 {
63 std::vector<uintptr_t> regs {};
64 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X0])); // 0:x0
65 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X1])); // 1:x1
66 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X2])); // 2:x2
67 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X3])); // 3:x3
68 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X4])); // 4:x4
69 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X5])); // 5:x5
70 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X6])); // 6:x6
71 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X7])); // 7:x7
72 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X8])); // 8:x8
73 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X9])); // 9:x9
74 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X10])); // 10:x10
75 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X11])); // 11:x11
76 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X12])); // 12:x12
77 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X13])); // 13:x13
78 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X14])); // 14:x14
79 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X15])); // 15:x15
80 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X16])); // 16:x16
81 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X17])); // 17:x17
82 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X18])); // 18:x18
83 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X19])); // 19:x19
84 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X20])); // 20:x20
85 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X21])); // 21:x21
86 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X22])); // 22:x22
87 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X23])); // 23:x23
88 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X24])); // 24:x24
89 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X25])); // 25:x25
90 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X26])); // 26:x26
91 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X27])); // 27:x27
92 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X28])); // 28:x28
93 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X29])); // 29:x29
94 regs.push_back(uintptr_t(context.uc_mcontext.regs[REG_AARCH64_X30])); // 30:lr
95 regs.push_back(uintptr_t(context.uc_mcontext.sp)); // 31:sp
96 regs.push_back(uintptr_t(context.uc_mcontext.pc)); // 32:pc
97
98 SetRegs(regs);
99 DfxLogDebug("lr:%016lx sp:%016lx pc:%016lx\n", regs[REG_AARCH64_X30], regs[REG_AARCH64_SP], regs[REG_AARCH64_PC]);
100 }
101
GetSpecialRegisterName(uintptr_t val) const102 std::string DfxRegsArm64::GetSpecialRegisterName(uintptr_t val) const
103 {
104 if (val == regsData_[REG_AARCH64_PC]) {
105 return "pc";
106 } else if (val == regsData_[REG_AARCH64_X30]) {
107 return "lr";
108 } else if (val == regsData_[REG_AARCH64_SP]) {
109 return "sp";
110 } else if (val == regsData_[REG_AARCH64_X29]) {
111 return "fp";
112 }
113 return "";
114 }
115
PrintRegs() const116 std::string DfxRegsArm64::PrintRegs() const
117 {
118 std::string regString = "";
119 char buf[REGS_PRINT_LEN_ARM64] = {0};
120
121 regString = regString + "Registers:\n";
122
123 std::vector<uintptr_t> regs = GetRegsData();
124
125 PrintFormat(buf, sizeof(buf), "x0:%016lx x1:%016lx x2:%016lx x3:%016lx\n", \
126 regs[REG_AARCH64_X0], regs[REG_AARCH64_X1], regs[REG_AARCH64_X2], regs[REG_AARCH64_X3]);
127
128 PrintFormat(buf + strlen(buf), sizeof(buf) - strlen(buf), "x4:%016lx x5:%016lx x6:%016lx x7:%016lx\n", \
129 regs[REG_AARCH64_X4], regs[REG_AARCH64_X5], regs[REG_AARCH64_X6], regs[REG_AARCH64_X7]);
130
131 PrintFormat(buf + strlen(buf), sizeof(buf) - strlen(buf), "x8:%016lx x9:%016lx x10:%016lx x11:%016lx\n", \
132 regs[REG_AARCH64_X8], regs[REG_AARCH64_X9], regs[REG_AARCH64_X10], regs[REG_AARCH64_X11]);
133
134 PrintFormat(buf + strlen(buf), sizeof(buf) - strlen(buf), "x12:%016lx x13:%016lx x14:%016lx x15:%016lx\n", \
135 regs[REG_AARCH64_X12], regs[REG_AARCH64_X13], regs[REG_AARCH64_X14], regs[REG_AARCH64_X15]);
136
137 PrintFormat(buf + strlen(buf), sizeof(buf) - strlen(buf), "x16:%016lx x17:%016lx x18:%016lx x19:%016lx\n", \
138 regs[REG_AARCH64_X16], regs[REG_AARCH64_X17], regs[REG_AARCH64_X18], regs[REG_AARCH64_X19]);
139
140 PrintFormat(buf + strlen(buf), sizeof(buf) - strlen(buf), "x20:%016lx x21:%016lx x22:%016lx x23:%016lx\n", \
141 regs[REG_AARCH64_X20], regs[REG_AARCH64_X21], regs[REG_AARCH64_X22], regs[REG_AARCH64_X23]);
142
143 PrintFormat(buf + strlen(buf), sizeof(buf) - strlen(buf), "x24:%016lx x25:%016lx x26:%016lx x27:%016lx\n", \
144 regs[REG_AARCH64_X24], regs[REG_AARCH64_X25], regs[REG_AARCH64_X26], regs[REG_AARCH64_X27]);
145
146 PrintFormat(buf + strlen(buf), sizeof(buf) - strlen(buf), "x28:%016lx x29:%016lx\n", \
147 regs[REG_AARCH64_X28], regs[REG_AARCH64_X29]);
148
149 PrintFormat(buf + strlen(buf), sizeof(buf) - strlen(buf), "lr:%016lx sp:%016lx pc:%016lx\n", \
150 regs[REG_AARCH64_X30], regs[REG_AARCH64_SP], regs[REG_AARCH64_PC]);
151
152 regString = regString + std::string(buf);
153 return regString;
154 }
155
GetPC() const156 uintptr_t DfxRegsArm64::GetPC() const
157 {
158 return regsData_[REG_AARCH64_PC];
159 }
160
GetLR() const161 uintptr_t DfxRegsArm64::GetLR() const
162 {
163 return regsData_[REG_AARCH64_X30];
164 }
165 } // namespace HiviewDFX
166 } // namespace OHOS
167