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 <assert.h>
18 #include <elf.h>
19 #include <stdint.h>
20 #include <sys/ptrace.h>
21 #include <sys/uio.h>
22 
23 #include <vector>
24 
25 #include "Elf.h"
26 #include "ElfInterface.h"
27 #include "Machine.h"
28 #include "MapInfo.h"
29 #include "Regs.h"
30 #include "User.h"
31 
32 template <typename AddressType>
GetRelPc(Elf * elf,const MapInfo * map_info)33 uint64_t RegsTmpl<AddressType>::GetRelPc(Elf* elf, const MapInfo* map_info) {
34   uint64_t load_bias = 0;
35   if (elf->valid()) {
36     load_bias = elf->interface()->load_bias();
37   }
38 
39   return pc_ - map_info->start + load_bias + map_info->elf_offset;
40 }
41 
42 template <typename AddressType>
GetReturnAddressFromDefault(Memory * memory,uint64_t * value)43 bool RegsTmpl<AddressType>::GetReturnAddressFromDefault(Memory* memory, uint64_t* value) {
44   switch (return_loc_.type) {
45   case LOCATION_REGISTER:
46     assert(return_loc_.value < total_regs_);
47     *value = regs_[return_loc_.value];
48     return true;
49   case LOCATION_SP_OFFSET:
50     AddressType return_value;
51     if (!memory->Read(sp_ + return_loc_.value, &return_value, sizeof(return_value))) {
52       return false;
53     }
54     *value = return_value;
55     return true;
56   case LOCATION_UNKNOWN:
57   default:
58     return false;
59   }
60 }
61 
RegsArm()62 RegsArm::RegsArm() : RegsTmpl<uint32_t>(ARM_REG_LAST, ARM_REG_SP,
63                                         Location(LOCATION_REGISTER, ARM_REG_LR)) {
64 }
65 
GetAdjustedPc(uint64_t rel_pc,Elf * elf)66 uint64_t RegsArm::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
67   if (!elf->valid()) {
68     return rel_pc;
69   }
70 
71   uint64_t load_bias = elf->interface()->load_bias();
72   if (rel_pc < load_bias) {
73     return rel_pc;
74   }
75   uint64_t adjusted_rel_pc = rel_pc - load_bias;
76 
77   if (adjusted_rel_pc < 5) {
78     return rel_pc;
79   }
80 
81   if (adjusted_rel_pc & 1) {
82     // This is a thumb instruction, it could be 2 or 4 bytes.
83     uint32_t value;
84     if (rel_pc < 5 || !elf->memory()->Read(adjusted_rel_pc - 5, &value, sizeof(value)) ||
85         (value & 0xe000f000) != 0xe000f000) {
86       return rel_pc - 2;
87     }
88   }
89   return rel_pc - 4;
90 }
91 
RegsArm64()92 RegsArm64::RegsArm64() : RegsTmpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP,
93                                             Location(LOCATION_REGISTER, ARM64_REG_LR)) {
94 }
95 
GetAdjustedPc(uint64_t rel_pc,Elf * elf)96 uint64_t RegsArm64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
97   if (!elf->valid()) {
98     return rel_pc;
99   }
100 
101   if (rel_pc < 4) {
102     return rel_pc;
103   }
104   return rel_pc - 4;
105 }
106 
RegsX86()107 RegsX86::RegsX86() : RegsTmpl<uint32_t>(X86_REG_LAST, X86_REG_SP,
108                                         Location(LOCATION_SP_OFFSET, -4)) {
109 }
110 
GetAdjustedPc(uint64_t rel_pc,Elf * elf)111 uint64_t RegsX86::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
112   if (!elf->valid()) {
113     return rel_pc;
114   }
115 
116   if (rel_pc == 0) {
117     return 0;
118   }
119   return rel_pc - 1;
120 }
121 
RegsX86_64()122 RegsX86_64::RegsX86_64() : RegsTmpl<uint64_t>(X86_64_REG_LAST, X86_64_REG_SP,
123                                               Location(LOCATION_SP_OFFSET, -8)) {
124 }
125 
GetAdjustedPc(uint64_t rel_pc,Elf * elf)126 uint64_t RegsX86_64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
127   if (!elf->valid()) {
128     return rel_pc;
129   }
130 
131   if (rel_pc == 0) {
132     return 0;
133   }
134 
135   return rel_pc - 1;
136 }
137 
ReadArm(void * remote_data)138 static Regs* ReadArm(void* remote_data) {
139   arm_user_regs* user = reinterpret_cast<arm_user_regs*>(remote_data);
140 
141   RegsArm* regs = new RegsArm();
142   memcpy(regs->RawData(), &user->regs[0], ARM_REG_LAST * sizeof(uint32_t));
143 
144   regs->set_pc(user->regs[ARM_REG_PC]);
145   regs->set_sp(user->regs[ARM_REG_SP]);
146 
147   return regs;
148 }
149 
ReadArm64(void * remote_data)150 static Regs* ReadArm64(void* remote_data) {
151   arm64_user_regs* user = reinterpret_cast<arm64_user_regs*>(remote_data);
152 
153   RegsArm64* regs = new RegsArm64();
154   memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R31 + 1) * sizeof(uint64_t));
155   regs->set_pc(user->pc);
156   regs->set_sp(user->sp);
157 
158   return regs;
159 }
160 
ReadX86(void * remote_data)161 static Regs* ReadX86(void* remote_data) {
162   x86_user_regs* user = reinterpret_cast<x86_user_regs*>(remote_data);
163 
164   RegsX86* regs = new RegsX86();
165   (*regs)[X86_REG_EAX] = user->eax;
166   (*regs)[X86_REG_EBX] = user->ebx;
167   (*regs)[X86_REG_ECX] = user->ecx;
168   (*regs)[X86_REG_EDX] = user->edx;
169   (*regs)[X86_REG_EBP] = user->ebp;
170   (*regs)[X86_REG_EDI] = user->edi;
171   (*regs)[X86_REG_ESI] = user->esi;
172   (*regs)[X86_REG_ESP] = user->esp;
173   (*regs)[X86_REG_EIP] = user->eip;
174 
175   regs->set_pc(user->eip);
176   regs->set_sp(user->esp);
177 
178   return regs;
179 }
180 
ReadX86_64(void * remote_data)181 static Regs* ReadX86_64(void* remote_data) {
182   x86_64_user_regs* user = reinterpret_cast<x86_64_user_regs*>(remote_data);
183 
184   RegsX86_64* regs = new RegsX86_64();
185   (*regs)[X86_64_REG_RAX] = user->rax;
186   (*regs)[X86_64_REG_RBX] = user->rbx;
187   (*regs)[X86_64_REG_RCX] = user->rcx;
188   (*regs)[X86_64_REG_RDX] = user->rdx;
189   (*regs)[X86_64_REG_R8] = user->r8;
190   (*regs)[X86_64_REG_R9] = user->r9;
191   (*regs)[X86_64_REG_R10] = user->r10;
192   (*regs)[X86_64_REG_R11] = user->r11;
193   (*regs)[X86_64_REG_R12] = user->r12;
194   (*regs)[X86_64_REG_R13] = user->r13;
195   (*regs)[X86_64_REG_R14] = user->r14;
196   (*regs)[X86_64_REG_R15] = user->r15;
197   (*regs)[X86_64_REG_RDI] = user->rdi;
198   (*regs)[X86_64_REG_RSI] = user->rsi;
199   (*regs)[X86_64_REG_RBP] = user->rbp;
200   (*regs)[X86_64_REG_RSP] = user->rsp;
201   (*regs)[X86_64_REG_RIP] = user->rip;
202 
203   regs->set_pc(user->rip);
204   regs->set_sp(user->rsp);
205 
206   return regs;
207 }
208 
209 // This function assumes that reg_data is already aligned to a 64 bit value.
210 // If not this could crash with an unaligned access.
RemoteGet(pid_t pid,uint32_t * machine_type)211 Regs* Regs::RemoteGet(pid_t pid, uint32_t* machine_type) {
212   // Make the buffer large enough to contain the largest registers type.
213   std::vector<uint64_t> buffer(MAX_USER_REGS_SIZE / sizeof(uint64_t));
214   struct iovec io;
215   io.iov_base = buffer.data();
216   io.iov_len = buffer.size() * sizeof(uint64_t);
217 
218   if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, reinterpret_cast<void*>(&io)) == -1) {
219     return nullptr;
220   }
221 
222   switch (io.iov_len) {
223   case sizeof(x86_user_regs):
224     *machine_type = EM_386;
225     return ReadX86(buffer.data());
226   case sizeof(x86_64_user_regs):
227     *machine_type = EM_X86_64;
228     return ReadX86_64(buffer.data());
229   case sizeof(arm_user_regs):
230     *machine_type = EM_ARM;
231     return ReadArm(buffer.data());
232   case sizeof(arm64_user_regs):
233     *machine_type = EM_AARCH64;
234     return ReadArm64(buffer.data());
235   }
236   return nullptr;
237 }
238