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