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