1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <errno.h>
18 #include <stdint.h>
19 #include <string.h>
20 #include <sys/ptrace.h>
21 #include <sys/uio.h>
22
23 #include <algorithm>
24 #include <vector>
25
26 #include <unwindstack/Elf.h>
27 #include <unwindstack/Log.h>
28 #include <unwindstack/MapInfo.h>
29 #include <unwindstack/Regs.h>
30 #include <unwindstack/RegsArm.h>
31 #include <unwindstack/RegsArm64.h>
32 #include <unwindstack/RegsRiscv64.h>
33 #include <unwindstack/RegsX86.h>
34 #include <unwindstack/RegsX86_64.h>
35 #include <unwindstack/UserArm.h>
36 #include <unwindstack/UserArm64.h>
37 #include <unwindstack/UserRiscv64.h>
38 #include <unwindstack/UserX86.h>
39 #include <unwindstack/UserX86_64.h>
40
41 namespace unwindstack {
42
43 // The largest user structure.
44 // constexpr size_t MAX_USER_REGS_SIZE = sizeof(mips64_user_regs) + 10;
45 static constexpr size_t kMaxUserRegsSize = std::max(
46 sizeof(arm_user_regs),
47 std::max(sizeof(arm64_user_regs), std::max(sizeof(x86_user_regs), sizeof(x86_64_user_regs))));
48
49 // This function assumes that reg_data is already aligned to a 64 bit value.
50 // If not this could crash with an unaligned access.
RemoteGet(pid_t pid,ErrorCode * error_code)51 Regs* Regs::RemoteGet(pid_t pid, ErrorCode* error_code) {
52 // Make the buffer large enough to contain the largest registers type.
53 std::vector<uint64_t> buffer(kMaxUserRegsSize / sizeof(uint64_t));
54 struct iovec io {
55 .iov_base = buffer.data(), .iov_len = buffer.size() * sizeof(uint64_t)
56 };
57
58 if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, reinterpret_cast<void*>(&io)) == -1) {
59 Log::Error("PTRACE_GETREGSET failed for pid %d: %s", pid, strerror(errno));
60 if (error_code != nullptr) {
61 *error_code = ERROR_PTRACE_CALL;
62 }
63 return nullptr;
64 }
65
66 // Infer the process architecture from the size of its register structure.
67 switch (io.iov_len) {
68 case sizeof(x86_user_regs):
69 return RegsX86::Read(buffer.data());
70 case sizeof(x86_64_user_regs):
71 return RegsX86_64::Read(buffer.data());
72 case sizeof(arm_user_regs):
73 return RegsArm::Read(buffer.data());
74 case sizeof(arm64_user_regs):
75 return RegsArm64::Read(buffer.data());
76 case sizeof(riscv64_user_regs):
77 return RegsRiscv64::Read(buffer.data(), pid);
78 }
79
80 Log::Error("No matching size of user regs structure for pid %d: size %zu", pid, io.iov_len);
81 if (error_code != nullptr) {
82 *error_code = ERROR_UNSUPPORTED;
83 }
84 return nullptr;
85 }
86
RemoteGetArch(pid_t pid,ErrorCode * error_code)87 ArchEnum Regs::RemoteGetArch(pid_t pid, ErrorCode* error_code) {
88 // Make the buffer large enough to contain the largest registers type.
89 std::vector<uint64_t> buffer(kMaxUserRegsSize / sizeof(uint64_t));
90 struct iovec io;
91 io.iov_base = buffer.data();
92 io.iov_len = buffer.size() * sizeof(uint64_t);
93
94 if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, reinterpret_cast<void*>(&io)) == -1) {
95 Log::Error("PTRACE_GETREGSET failed for pid %d: %s", pid, strerror(errno));
96 if (error_code != nullptr) {
97 *error_code = ERROR_PTRACE_CALL;
98 }
99 return ARCH_UNKNOWN;
100 }
101
102 // Infer the process architecture from the size of its register structure.
103 switch (io.iov_len) {
104 case sizeof(x86_user_regs):
105 return ARCH_X86;
106 case sizeof(x86_64_user_regs):
107 return ARCH_X86_64;
108 case sizeof(arm_user_regs):
109 return ARCH_ARM;
110 case sizeof(arm64_user_regs):
111 return ARCH_ARM64;
112 case sizeof(riscv64_user_regs):
113 return ARCH_RISCV64;
114 }
115
116 Log::Error("No matching size of user regs structure for pid %d: size %zu", pid, io.iov_len);
117 if (error_code != nullptr) {
118 *error_code = ERROR_UNSUPPORTED;
119 }
120 return ARCH_UNKNOWN;
121 }
122
CreateFromUcontext(ArchEnum arch,void * ucontext)123 Regs* Regs::CreateFromUcontext(ArchEnum arch, void* ucontext) {
124 switch (arch) {
125 case ARCH_X86:
126 return RegsX86::CreateFromUcontext(ucontext);
127 case ARCH_X86_64:
128 return RegsX86_64::CreateFromUcontext(ucontext);
129 case ARCH_ARM:
130 return RegsArm::CreateFromUcontext(ucontext);
131 case ARCH_ARM64:
132 return RegsArm64::CreateFromUcontext(ucontext);
133 case ARCH_RISCV64:
134 return RegsRiscv64::CreateFromUcontext(ucontext);
135 case ARCH_UNKNOWN:
136 default:
137 return nullptr;
138 }
139 }
140
CurrentArch()141 ArchEnum Regs::CurrentArch() {
142 #if defined(__arm__)
143 return ARCH_ARM;
144 #elif defined(__aarch64__)
145 return ARCH_ARM64;
146 #elif defined(__i386__)
147 return ARCH_X86;
148 #elif defined(__x86_64__)
149 return ARCH_X86_64;
150 #elif defined(__riscv)
151 return ARCH_RISCV64;
152 #else
153 abort();
154 #endif
155 }
156
CreateFromLocal()157 Regs* Regs::CreateFromLocal() {
158 Regs* regs;
159 #if defined(__arm__)
160 regs = new RegsArm();
161 #elif defined(__aarch64__)
162 regs = new RegsArm64();
163 #elif defined(__i386__)
164 regs = new RegsX86();
165 #elif defined(__x86_64__)
166 regs = new RegsX86_64();
167 #elif defined(__riscv)
168 regs = new RegsRiscv64();
169 #else
170 abort();
171 #endif
172 return regs;
173 }
174
GetPcAdjustment(uint64_t rel_pc,Elf * elf,ArchEnum arch)175 uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf, ArchEnum arch) {
176 switch (arch) {
177 case ARCH_ARM: {
178 if (!elf->valid()) {
179 return 2;
180 }
181
182 uint64_t load_bias = elf->GetLoadBias();
183 if (rel_pc < load_bias) {
184 if (rel_pc < 2) {
185 return 0;
186 }
187 return 2;
188 }
189 uint64_t adjusted_rel_pc = rel_pc - load_bias;
190 if (adjusted_rel_pc < 5) {
191 if (adjusted_rel_pc < 2) {
192 return 0;
193 }
194 return 2;
195 }
196
197 if (adjusted_rel_pc & 1) {
198 // This is a thumb instruction, it could be 2 or 4 bytes.
199 uint32_t value;
200 if (!elf->memory()->ReadFully(adjusted_rel_pc - 5, &value, sizeof(value)) ||
201 (value & 0xe000f000) != 0xe000f000) {
202 return 2;
203 }
204 }
205 return 4;
206 }
207 case ARCH_ARM64:
208 case ARCH_RISCV64: {
209 if (rel_pc < 4) {
210 return 0;
211 }
212 return 4;
213 }
214 case ARCH_X86:
215 case ARCH_X86_64: {
216 if (rel_pc == 0) {
217 return 0;
218 }
219 return 1;
220 }
221 case ARCH_UNKNOWN:
222 return 0;
223 }
224 }
225
226 } // namespace unwindstack
227