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