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