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