blob: f62200aabe6c9a26bdcfe1d084afdb3bc2c299fd [file] [log] [blame]
Dave Allisonb373e092014-02-20 16:06:36 -08001/*
2 * Copyright (C) 2008 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
18#include "fault_handler.h"
19#include <sys/ucontext.h>
20#include "base/macros.h"
21#include "globals.h"
22#include "base/logging.h"
23#include "base/hex_dump.h"
Dave Allison34e826c2014-05-29 08:20:04 -070024#include "mirror/art_method.h"
25#include "mirror/art_method-inl.h"
26#include "thread.h"
27#include "thread-inl.h"
Dave Allisonb373e092014-02-20 16:06:36 -080028
29
30//
31// X86 specific fault handler functions.
32//
33
34namespace art {
35
Dave Allison34e826c2014-05-29 08:20:04 -070036extern "C" void art_quick_throw_null_pointer_exception();
37extern "C" void art_quick_throw_stack_overflow_from_signal();
38extern "C" void art_quick_test_suspend();
39
40// From the x86 disassembler...
41enum SegmentPrefix {
42 kCs = 0x2e,
43 kSs = 0x36,
44 kDs = 0x3e,
45 kEs = 0x26,
46 kFs = 0x64,
47 kGs = 0x65,
48};
49
50// Get the size of an instruction in bytes.
51static uint32_t GetInstructionSize(uint8_t* pc) {
52 uint8_t* instruction_start = pc;
53 bool have_prefixes = true;
54 bool two_byte = false;
55
56 // Skip all the prefixes.
57 do {
58 switch (*pc) {
59 // Group 1 - lock and repeat prefixes:
60 case 0xF0:
61 case 0xF2:
62 case 0xF3:
63 // Group 2 - segment override prefixes:
64 case kCs:
65 case kSs:
66 case kDs:
67 case kEs:
68 case kFs:
69 case kGs:
70 // Group 3 - operand size override:
71 case 0x66:
72 // Group 4 - address size override:
73 case 0x67:
74 break;
75 default:
76 have_prefixes = false;
77 break;
78 }
79 if (have_prefixes) {
80 pc++;
81 }
82 } while (have_prefixes);
83
84#if defined(__x86_64__)
85 // Skip REX is present.
86 if (*pc >= 0x40 && *pc <= 0x4F) {
87 ++pc;
88 }
89#endif
90
91 // Check for known instructions.
92 uint32_t known_length = 0;
93 switch (*pc) {
94 case 0x83: // cmp [r + v], b: 4 byte instruction
95 known_length = 4;
96 break;
97 }
98
99 if (known_length > 0) {
100 VLOG(signals) << "known instruction with length " << known_length;
101 return known_length;
102 }
103
104 // Unknown instruction, work out length.
105
106 // Work out if we have a ModR/M byte.
107 uint8_t opcode = *pc++;
108 if (opcode == 0xf) {
109 two_byte = true;
110 opcode = *pc++;
111 }
112
113 bool has_modrm = false; // Is ModR/M byte present?
114 uint8_t hi = opcode >> 4; // Opcode high nybble.
115 uint8_t lo = opcode & 0b1111; // Opcode low nybble.
116
117 // From the Intel opcode tables.
118 if (two_byte) {
119 has_modrm = true; // TODO: all of these?
120 } else if (hi < 4) {
121 has_modrm = lo < 4 || (lo >= 8 && lo <= 0xb);
122 } else if (hi == 6) {
123 has_modrm = lo == 3 || lo == 9 || lo == 0xb;
124 } else if (hi == 8) {
125 has_modrm = lo != 0xd;
126 } else if (hi == 0xc) {
127 has_modrm = lo == 1 || lo == 2 || lo == 6 || lo == 7;
128 } else if (hi == 0xd) {
129 has_modrm = lo < 4;
130 } else if (hi == 0xf) {
131 has_modrm = lo == 6 || lo == 7;
132 }
133
134 if (has_modrm) {
135 uint8_t modrm = *pc++;
136 uint8_t mod = (modrm >> 6) & 0b11;
137 uint8_t reg = (modrm >> 3) & 0b111;
138 switch (mod) {
139 case 0:
140 break;
141 case 1:
142 if (reg == 4) {
143 // SIB + 1 byte displacement.
144 pc += 2;
145 } else {
146 pc += 1;
147 }
148 break;
149 case 2:
150 // SIB + 4 byte displacement.
151 pc += 5;
152 break;
153 case 3:
154 break;
155 }
156 }
157
158 VLOG(signals) << "calculated X86 instruction size is " << (pc - instruction_start);
159 return pc - instruction_start;
160}
161
162void FaultManager::GetMethodAndReturnPCAndSP(siginfo_t* siginfo, void* context,
163 mirror::ArtMethod** out_method,
Mathieu Chartierc751fdc2014-03-30 15:25:44 -0700164 uintptr_t* out_return_pc, uintptr_t* out_sp) {
Dave Allison34e826c2014-05-29 08:20:04 -0700165 struct ucontext* uc = reinterpret_cast<struct ucontext*>(context);
166 *out_sp = static_cast<uintptr_t>(uc->uc_mcontext.gregs[REG_ESP]);
167 VLOG(signals) << "sp: " << std::hex << *out_sp;
168 if (*out_sp == 0) {
169 return;
170 }
171
172 // In the case of a stack overflow, the stack is not valid and we can't
173 // get the method from the top of the stack. However it's in EAX.
174 uintptr_t* fault_addr = reinterpret_cast<uintptr_t*>(siginfo->si_addr);
175 uintptr_t* overflow_addr = reinterpret_cast<uintptr_t*>(
176 reinterpret_cast<uint8_t*>(*out_sp) - GetStackOverflowReservedBytes(kX86));
177 if (overflow_addr == fault_addr) {
178 *out_method = reinterpret_cast<mirror::ArtMethod*>(uc->uc_mcontext.gregs[REG_EAX]);
179 } else {
180 // The method is at the top of the stack.
181 *out_method = reinterpret_cast<mirror::ArtMethod*>(reinterpret_cast<uintptr_t*>(*out_sp)[0]);
182 }
183
184 uint8_t* pc = reinterpret_cast<uint8_t*>(uc->uc_mcontext.gregs[REG_EIP]);
185 VLOG(signals) << HexDump(pc, 32, true, "PC ");
186
187 uint32_t instr_size = GetInstructionSize(pc);
188 *out_return_pc = reinterpret_cast<uintptr_t>(pc + instr_size);
Dave Allisonb373e092014-02-20 16:06:36 -0800189}
190
191bool NullPointerHandler::Action(int sig, siginfo_t* info, void* context) {
Dave Allison34e826c2014-05-29 08:20:04 -0700192 struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
193 uint8_t* pc = reinterpret_cast<uint8_t*>(uc->uc_mcontext.gregs[REG_EIP]);
194 uint8_t* sp = reinterpret_cast<uint8_t*>(uc->uc_mcontext.gregs[REG_ESP]);
195
196 uint32_t instr_size = GetInstructionSize(pc);
197 // We need to arrange for the signal handler to return to the null pointer
198 // exception generator. The return address must be the address of the
199 // next instruction (this instruction + instruction size). The return address
200 // is on the stack at the top address of the current frame.
201
202 // Push the return address onto the stack.
203 uint32_t retaddr = reinterpret_cast<uint32_t>(pc + instr_size);
204 uint32_t* next_sp = reinterpret_cast<uint32_t*>(sp - 4);
205 *next_sp = retaddr;
206 uc->uc_mcontext.gregs[REG_ESP] = reinterpret_cast<uint32_t>(next_sp);
207
208 uc->uc_mcontext.gregs[REG_EIP] =
209 reinterpret_cast<uintptr_t>(art_quick_throw_null_pointer_exception);
210 VLOG(signals) << "Generating null pointer exception";
211 return true;
212}
213
214// A suspend check is done using the following instruction sequence:
215// 0xf720f1df: 648B058C000000 mov eax, fs:[0x8c] ; suspend_trigger
216// .. some intervening instructions.
217// 0xf720f1e6: 8500 test eax, [eax]
218
219// The offset from fs is Thread::ThreadSuspendTriggerOffset().
220// To check for a suspend check, we examine the instructions that caused
221// the fault.
222bool SuspensionHandler::Action(int sig, siginfo_t* info, void* context) {
223 // These are the instructions to check for. The first one is the mov eax, fs:[xxx]
224 // where xxx is the offset of the suspend trigger.
225 uint32_t trigger = Thread::ThreadSuspendTriggerOffset<4>().Int32Value();
226
227 VLOG(signals) << "Checking for suspension point";
228 uint8_t checkinst1[] = {0x64, 0x8b, 0x05, static_cast<uint8_t>(trigger & 0xff),
229 static_cast<uint8_t>((trigger >> 8) & 0xff), 0, 0};
230 uint8_t checkinst2[] = {0x85, 0x00};
231
232 struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
233 uint8_t* pc = reinterpret_cast<uint8_t*>(uc->uc_mcontext.gregs[REG_EIP]);
234 uint8_t* sp = reinterpret_cast<uint8_t*>(uc->uc_mcontext.gregs[REG_ESP]);
235
236 if (pc[0] != checkinst2[0] || pc[1] != checkinst2[1]) {
237 // Second instruction is not correct (test eax,[eax]).
238 VLOG(signals) << "Not a suspension point";
239 return false;
240 }
241
242 // The first instruction can a little bit up the stream due to load hoisting
243 // in the compiler.
244 uint8_t* limit = pc - 100; // Compiler will hoist to a max of 20 instructions.
245 uint8_t* ptr = pc - sizeof(checkinst1);
246 bool found = false;
247 while (ptr > limit) {
248 if (memcmp(ptr, checkinst1, sizeof(checkinst1)) == 0) {
249 found = true;
250 break;
251 }
252 ptr -= 1;
253 }
254
255 if (found) {
256 VLOG(signals) << "suspend check match";
257
258 // We need to arrange for the signal handler to return to the null pointer
259 // exception generator. The return address must be the address of the
260 // next instruction (this instruction + 2). The return address
261 // is on the stack at the top address of the current frame.
262
263 // Push the return address onto the stack.
264 uint32_t retaddr = reinterpret_cast<uint32_t>(pc + 2);
265 uint32_t* next_sp = reinterpret_cast<uint32_t*>(sp - 4);
266 *next_sp = retaddr;
267 uc->uc_mcontext.gregs[REG_ESP] = reinterpret_cast<uint32_t>(next_sp);
268
269 uc->uc_mcontext.gregs[REG_EIP] = reinterpret_cast<uintptr_t>(art_quick_test_suspend);
270
271 // Now remove the suspend trigger that caused this fault.
272 Thread::Current()->RemoveSuspendTrigger();
273 VLOG(signals) << "removed suspend trigger invoking test suspend";
274 return true;
275 }
276 VLOG(signals) << "Not a suspend check match, first instruction mismatch";
Dave Allisonb373e092014-02-20 16:06:36 -0800277 return false;
278}
279
Dave Allison34e826c2014-05-29 08:20:04 -0700280// The stack overflow check is done using the following instruction:
281// test eax, [esp+ -xxx]
282// where 'xxx' is the size of the overflow area.
283//
284// This is done before any frame is established in the method. The return
285// address for the previous method is on the stack at ESP.
Dave Allisonb373e092014-02-20 16:06:36 -0800286
287bool StackOverflowHandler::Action(int sig, siginfo_t* info, void* context) {
Dave Allison34e826c2014-05-29 08:20:04 -0700288 struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
289 uintptr_t sp = static_cast<uintptr_t>(uc->uc_mcontext.gregs[REG_ESP]);
290
291 uintptr_t fault_addr = reinterpret_cast<uintptr_t>(info->si_addr);
292 VLOG(signals) << "fault_addr: " << std::hex << fault_addr;
293 VLOG(signals) << "checking for stack overflow, sp: " << std::hex << sp <<
294 ", fault_addr: " << fault_addr;
295
296 uintptr_t overflow_addr = sp - GetStackOverflowReservedBytes(kX86);
297
298 Thread* self = Thread::Current();
299 uintptr_t pregion = reinterpret_cast<uintptr_t>(self->GetStackEnd()) -
300 Thread::kStackOverflowProtectedSize;
301
302 // Check that the fault address is the value expected for a stack overflow.
303 if (fault_addr != overflow_addr) {
304 VLOG(signals) << "Not a stack overflow";
305 return false;
306 }
307
308 // We know this is a stack overflow. We need to move the sp to the overflow region
309 // that exists below the protected region. Determine the address of the next
310 // available valid address below the protected region.
311 VLOG(signals) << "setting sp to overflow region at " << std::hex << pregion;
312
313 // Since the compiler puts the implicit overflow
314 // check before the callee save instructions, the SP is already pointing to
315 // the previous frame.
316
317 // Tell the stack overflow code where the new stack pointer should be.
318 uc->uc_mcontext.gregs[REG_EAX] = pregion;
319
320 // Now arrange for the signal handler to return to art_quick_throw_stack_overflow_from_signal.
321 uc->uc_mcontext.gregs[REG_EIP] = reinterpret_cast<uintptr_t>(
322 art_quick_throw_stack_overflow_from_signal);
323
324 return true;
Dave Allisonb373e092014-02-20 16:06:36 -0800325}
326} // namespace art