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 32 #if defined(__x86_64__) 33 // 64 bit mac build. 34 #define CTX_ESP uc_mcontext->__ss.__rsp 35 #define CTX_EIP uc_mcontext->__ss.__rip 36 #define CTX_EAX uc_mcontext->__ss.__rax 37 #define CTX_METHOD uc_mcontext->__ss.__rdi 38 #define CTX_JMP_BUF uc_mcontext->__ss.__rdi 39 #else 40 // 32 bit mac build. 41 #define CTX_ESP uc_mcontext->__ss.__esp 42 #define CTX_EIP uc_mcontext->__ss.__eip 43 #define CTX_EAX uc_mcontext->__ss.__eax 44 #define CTX_METHOD uc_mcontext->__ss.__eax 45 #define CTX_JMP_BUF uc_mcontext->__ss.__eax 46 #endif 47 48 #elif defined(__x86_64__) 49 // 64 bit linux build. 50 #define CTX_ESP uc_mcontext.gregs[REG_RSP] 51 #define CTX_EIP uc_mcontext.gregs[REG_RIP] 52 #define CTX_EAX uc_mcontext.gregs[REG_RAX] 53 #define CTX_METHOD uc_mcontext.gregs[REG_RDI] 54 #define CTX_RDI uc_mcontext.gregs[REG_RDI] 55 #define CTX_JMP_BUF uc_mcontext.gregs[REG_RDI] 56 #else 57 // 32 bit linux build. 58 #define CTX_ESP uc_mcontext.gregs[REG_ESP] 59 #define CTX_EIP uc_mcontext.gregs[REG_EIP] 60 #define CTX_EAX uc_mcontext.gregs[REG_EAX] 61 #define CTX_METHOD uc_mcontext.gregs[REG_EAX] 62 #define CTX_JMP_BUF uc_mcontext.gregs[REG_EAX] 63 #endif 64 65 // 66 // X86 (and X86_64) specific fault handler functions. 67 // 68 69 namespace art { 70 71 #if defined(__APPLE__) && defined(__x86_64__) 72 // mac symbols have a prefix of _ on x86_64 73 extern "C" void _art_quick_throw_null_pointer_exception(); 74 extern "C" void _art_quick_throw_stack_overflow(); 75 extern "C" void _art_quick_test_suspend(); 76 #define EXT_SYM(sym) _ ## sym 77 #else 78 extern "C" void art_quick_throw_null_pointer_exception(); 79 extern "C" void art_quick_throw_stack_overflow(); 80 extern "C" void art_quick_test_suspend(); 81 #define EXT_SYM(sym) sym 82 #endif 83 84 // Note this is different from the others (no underscore on 64 bit mac) due to 85 // the way the symbol is defined in the .S file. 86 // TODO: fix the symbols for 64 bit mac - there is a double underscore prefix for some 87 // of them. 88 extern "C" void art_nested_signal_return(); 89 90 // Get the size of an instruction in bytes. 91 // Return 0 if the instruction is not handled. 92 static uint32_t GetInstructionSize(const uint8_t* pc) { 93 #if defined(__x86_64) 94 const bool x86_64 = true; 95 #else 96 const bool x86_64 = false; 97 #endif 98 99 const uint8_t* startpc = pc; 100 101 uint8_t opcode = *pc++; 102 uint8_t modrm; 103 bool has_modrm = false; 104 bool two_byte = false; 105 uint32_t displacement_size = 0; 106 uint32_t immediate_size = 0; 107 108 // Prefixes. 109 while (true) { 110 bool prefix_present = false; 111 switch (opcode) { 112 // Group 1 113 case 0xf0: 114 case 0xf2: 115 case 0xf3: 116 117 // Group 2 118 case 0x2e: 119 case 0x36: 120 case 0x3e: 121 case 0x26: 122 case 0x64: 123 case 0x65: 124 125 // Group 3 126 case 0x66: 127 128 // Group 4 129 case 0x67: 130 opcode = *pc++; 131 prefix_present = true; 132 break; 133 } 134 if (!prefix_present) { 135 break; 136 } 137 } 138 139 if (x86_64 && opcode >= 0x40 && opcode <= 0x4f) { 140 opcode = *pc++; 141 } 142 143 if (opcode == 0x0f) { 144 // Two byte opcode 145 two_byte = true; 146 opcode = *pc++; 147 } 148 149 bool unhandled_instruction = false; 150 151 if (two_byte) { 152 switch (opcode) { 153 case 0x10: // vmovsd/ss 154 case 0x11: // vmovsd/ss 155 case 0xb6: // movzx 156 case 0xb7: 157 case 0xbe: // movsx 158 case 0xbf: 159 modrm = *pc++; 160 has_modrm = true; 161 break; 162 default: 163 unhandled_instruction = true; 164 break; 165 } 166 } else { 167 switch (opcode) { 168 case 0x89: // mov 169 case 0x8b: 170 case 0x38: // cmp with memory. 171 case 0x39: 172 case 0x3a: 173 case 0x3b: 174 case 0x3c: 175 case 0x3d: 176 case 0x85: // test. 177 modrm = *pc++; 178 has_modrm = true; 179 break; 180 181 case 0x80: // group 1, byte immediate. 182 case 0x83: 183 modrm = *pc++; 184 has_modrm = true; 185 immediate_size = 1; 186 break; 187 188 case 0x81: // group 1, word immediate. 189 modrm = *pc++; 190 has_modrm = true; 191 immediate_size = 4; 192 break; 193 194 default: 195 unhandled_instruction = true; 196 break; 197 } 198 } 199 200 if (unhandled_instruction) { 201 VLOG(signals) << "Unhandled x86 instruction with opcode " << static_cast<int>(opcode); 202 return 0; 203 } 204 205 if (has_modrm) { 206 uint8_t mod = (modrm >> 6) & 0b11; 207 208 // Check for SIB. 209 if (mod != 0b11 && (modrm & 0b111) == 4) { 210 ++pc; // SIB 211 } 212 213 switch (mod) { 214 case 0b00: break; 215 case 0b01: displacement_size = 1; break; 216 case 0b10: displacement_size = 4; break; 217 case 0b11: 218 break; 219 } 220 } 221 222 // Skip displacement and immediate. 223 pc += displacement_size + immediate_size; 224 225 VLOG(signals) << "x86 instruction length calculated as " << (pc - startpc); 226 return pc - startpc; 227 } 228 229 void FaultManager::HandleNestedSignal(int sig, siginfo_t* info, void* context) { 230 // For the Intel architectures we need to go to an assembly language 231 // stub. This is because the 32 bit call to longjmp is much different 232 // from the 64 bit ABI call and pushing things onto the stack inside this 233 // handler was unwieldy and ugly. The use of the stub means we can keep 234 // this code the same for both 32 and 64 bit. 235 236 Thread* self = Thread::Current(); 237 CHECK(self != nullptr); // This will cause a SIGABRT if self is nullptr. 238 239 struct ucontext* uc = reinterpret_cast<struct ucontext*>(context); 240 uc->CTX_JMP_BUF = reinterpret_cast<uintptr_t>(*self->GetNestedSignalState()); 241 uc->CTX_EIP = reinterpret_cast<uintptr_t>(art_nested_signal_return); 242 } 243 244 void FaultManager::GetMethodAndReturnPcAndSp(siginfo_t* siginfo, void* context, 245 mirror::ArtMethod** out_method, 246 uintptr_t* out_return_pc, uintptr_t* out_sp) { 247 struct ucontext* uc = reinterpret_cast<struct ucontext*>(context); 248 *out_sp = static_cast<uintptr_t>(uc->CTX_ESP); 249 VLOG(signals) << "sp: " << std::hex << *out_sp; 250 if (*out_sp == 0) { 251 return; 252 } 253 254 // In the case of a stack overflow, the stack is not valid and we can't 255 // get the method from the top of the stack. However it's in EAX(x86)/RDI(x86_64). 256 uintptr_t* fault_addr = reinterpret_cast<uintptr_t*>(siginfo->si_addr); 257 uintptr_t* overflow_addr = reinterpret_cast<uintptr_t*>( 258 #if defined(__x86_64__) 259 reinterpret_cast<uint8_t*>(*out_sp) - GetStackOverflowReservedBytes(kX86_64)); 260 #else 261 reinterpret_cast<uint8_t*>(*out_sp) - GetStackOverflowReservedBytes(kX86)); 262 #endif 263 if (overflow_addr == fault_addr) { 264 *out_method = reinterpret_cast<mirror::ArtMethod*>(uc->CTX_METHOD); 265 } else { 266 // The method is at the top of the stack. 267 *out_method = (reinterpret_cast<StackReference<mirror::ArtMethod>* >(*out_sp)[0]).AsMirrorPtr(); 268 } 269 270 uint8_t* pc = reinterpret_cast<uint8_t*>(uc->CTX_EIP); 271 VLOG(signals) << HexDump(pc, 32, true, "PC "); 272 273 uint32_t instr_size = GetInstructionSize(pc); 274 if (instr_size == 0) { 275 // Unknown instruction, tell caller it's not ours. 276 *out_method = nullptr; 277 return; 278 } 279 *out_return_pc = reinterpret_cast<uintptr_t>(pc + instr_size); 280 } 281 282 bool NullPointerHandler::Action(int sig, siginfo_t* info, void* context) { 283 struct ucontext *uc = reinterpret_cast<struct ucontext*>(context); 284 uint8_t* pc = reinterpret_cast<uint8_t*>(uc->CTX_EIP); 285 uint8_t* sp = reinterpret_cast<uint8_t*>(uc->CTX_ESP); 286 287 uint32_t instr_size = GetInstructionSize(pc); 288 if (instr_size == 0) { 289 // Unknown instruction, can't really happen. 290 return false; 291 } 292 293 // We need to arrange for the signal handler to return to the null pointer 294 // exception generator. The return address must be the address of the 295 // next instruction (this instruction + instruction size). The return address 296 // is on the stack at the top address of the current frame. 297 298 // Push the return address onto the stack. 299 uintptr_t retaddr = reinterpret_cast<uintptr_t>(pc + instr_size); 300 uintptr_t* next_sp = reinterpret_cast<uintptr_t*>(sp - sizeof(uintptr_t)); 301 *next_sp = retaddr; 302 uc->CTX_ESP = reinterpret_cast<uintptr_t>(next_sp); 303 304 uc->CTX_EIP = reinterpret_cast<uintptr_t>(EXT_SYM(art_quick_throw_null_pointer_exception)); 305 VLOG(signals) << "Generating null pointer exception"; 306 return true; 307 } 308 309 // A suspend check is done using the following instruction sequence: 310 // (x86) 311 // 0xf720f1df: 648B058C000000 mov eax, fs:[0x8c] ; suspend_trigger 312 // .. some intervening instructions. 313 // 0xf720f1e6: 8500 test eax, [eax] 314 // (x86_64) 315 // 0x7f579de45d9e: 65488B0425A8000000 movq rax, gs:[0xa8] ; suspend_trigger 316 // .. some intervening instructions. 317 // 0x7f579de45da7: 8500 test eax, [eax] 318 319 // The offset from fs is Thread::ThreadSuspendTriggerOffset(). 320 // To check for a suspend check, we examine the instructions that caused 321 // the fault. 322 bool SuspensionHandler::Action(int sig, siginfo_t* info, void* context) { 323 // These are the instructions to check for. The first one is the mov eax, fs:[xxx] 324 // where xxx is the offset of the suspend trigger. 325 #if defined(__x86_64__) 326 uint32_t trigger = Thread::ThreadSuspendTriggerOffset<8>().Int32Value(); 327 #else 328 uint32_t trigger = Thread::ThreadSuspendTriggerOffset<4>().Int32Value(); 329 #endif 330 331 VLOG(signals) << "Checking for suspension point"; 332 #if defined(__x86_64__) 333 uint8_t checkinst1[] = {0x65, 0x48, 0x8b, 0x04, 0x25, static_cast<uint8_t>(trigger & 0xff), 334 static_cast<uint8_t>((trigger >> 8) & 0xff), 0, 0}; 335 #else 336 uint8_t checkinst1[] = {0x64, 0x8b, 0x05, static_cast<uint8_t>(trigger & 0xff), 337 static_cast<uint8_t>((trigger >> 8) & 0xff), 0, 0}; 338 #endif 339 uint8_t checkinst2[] = {0x85, 0x00}; 340 341 struct ucontext *uc = reinterpret_cast<struct ucontext*>(context); 342 uint8_t* pc = reinterpret_cast<uint8_t*>(uc->CTX_EIP); 343 uint8_t* sp = reinterpret_cast<uint8_t*>(uc->CTX_ESP); 344 345 if (pc[0] != checkinst2[0] || pc[1] != checkinst2[1]) { 346 // Second instruction is not correct (test eax,[eax]). 347 VLOG(signals) << "Not a suspension point"; 348 return false; 349 } 350 351 // The first instruction can a little bit up the stream due to load hoisting 352 // in the compiler. 353 uint8_t* limit = pc - 100; // Compiler will hoist to a max of 20 instructions. 354 uint8_t* ptr = pc - sizeof(checkinst1); 355 bool found = false; 356 while (ptr > limit) { 357 if (memcmp(ptr, checkinst1, sizeof(checkinst1)) == 0) { 358 found = true; 359 break; 360 } 361 ptr -= 1; 362 } 363 364 if (found) { 365 VLOG(signals) << "suspend check match"; 366 367 // We need to arrange for the signal handler to return to the null pointer 368 // exception generator. The return address must be the address of the 369 // next instruction (this instruction + 2). The return address 370 // is on the stack at the top address of the current frame. 371 372 // Push the return address onto the stack. 373 uintptr_t retaddr = reinterpret_cast<uintptr_t>(pc + 2); 374 uintptr_t* next_sp = reinterpret_cast<uintptr_t*>(sp - sizeof(uintptr_t)); 375 *next_sp = retaddr; 376 uc->CTX_ESP = reinterpret_cast<uintptr_t>(next_sp); 377 378 uc->CTX_EIP = reinterpret_cast<uintptr_t>(EXT_SYM(art_quick_test_suspend)); 379 380 // Now remove the suspend trigger that caused this fault. 381 Thread::Current()->RemoveSuspendTrigger(); 382 VLOG(signals) << "removed suspend trigger invoking test suspend"; 383 return true; 384 } 385 VLOG(signals) << "Not a suspend check match, first instruction mismatch"; 386 return false; 387 } 388 389 // The stack overflow check is done using the following instruction: 390 // test eax, [esp+ -xxx] 391 // where 'xxx' is the size of the overflow area. 392 // 393 // This is done before any frame is established in the method. The return 394 // address for the previous method is on the stack at ESP. 395 396 bool StackOverflowHandler::Action(int sig, siginfo_t* info, void* context) { 397 struct ucontext *uc = reinterpret_cast<struct ucontext*>(context); 398 uintptr_t sp = static_cast<uintptr_t>(uc->CTX_ESP); 399 400 uintptr_t fault_addr = reinterpret_cast<uintptr_t>(info->si_addr); 401 VLOG(signals) << "fault_addr: " << std::hex << fault_addr; 402 VLOG(signals) << "checking for stack overflow, sp: " << std::hex << sp << 403 ", fault_addr: " << fault_addr; 404 405 #if defined(__x86_64__) 406 uintptr_t overflow_addr = sp - GetStackOverflowReservedBytes(kX86_64); 407 #else 408 uintptr_t overflow_addr = sp - GetStackOverflowReservedBytes(kX86); 409 #endif 410 411 // Check that the fault address is the value expected for a stack overflow. 412 if (fault_addr != overflow_addr) { 413 VLOG(signals) << "Not a stack overflow"; 414 return false; 415 } 416 417 VLOG(signals) << "Stack overflow found"; 418 419 // Since the compiler puts the implicit overflow 420 // check before the callee save instructions, the SP is already pointing to 421 // the previous frame. 422 423 // Now arrange for the signal handler to return to art_quick_throw_stack_overflow. 424 uc->CTX_EIP = reinterpret_cast<uintptr_t>(EXT_SYM(art_quick_throw_stack_overflow)); 425 426 return true; 427 } 428 } // namespace art 429