/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "fault_handler.h"
#include <sys/ucontext.h>
#include "base/macros.h"
#include "globals.h"
#include "base/logging.h"
#include "base/hex_dump.h"
#include "mirror/art_method.h"
#include "mirror/art_method-inl.h"
#include "thread.h"
#include "thread-inl.h"

#if defined(__APPLE__)
#define ucontext __darwin_ucontext

#if defined(__x86_64__)
// 64 bit mac build.
#define CTX_ESP uc_mcontext->__ss.__rsp
#define CTX_EIP uc_mcontext->__ss.__rip
#define CTX_EAX uc_mcontext->__ss.__rax
#define CTX_METHOD uc_mcontext->__ss.__rdi
#define CTX_JMP_BUF uc_mcontext->__ss.__rdi
#else
// 32 bit mac build.
#define CTX_ESP uc_mcontext->__ss.__esp
#define CTX_EIP uc_mcontext->__ss.__eip
#define CTX_EAX uc_mcontext->__ss.__eax
#define CTX_METHOD uc_mcontext->__ss.__eax
#define CTX_JMP_BUF uc_mcontext->__ss.__eax
#endif

#elif defined(__x86_64__)
// 64 bit linux build.
#define CTX_ESP uc_mcontext.gregs[REG_RSP]
#define CTX_EIP uc_mcontext.gregs[REG_RIP]
#define CTX_EAX uc_mcontext.gregs[REG_RAX]
#define CTX_METHOD uc_mcontext.gregs[REG_RDI]
#define CTX_RDI uc_mcontext.gregs[REG_RDI]
#define CTX_JMP_BUF uc_mcontext.gregs[REG_RDI]
#else
// 32 bit linux build.
#define CTX_ESP uc_mcontext.gregs[REG_ESP]
#define CTX_EIP uc_mcontext.gregs[REG_EIP]
#define CTX_EAX uc_mcontext.gregs[REG_EAX]
#define CTX_METHOD uc_mcontext.gregs[REG_EAX]
#define CTX_JMP_BUF uc_mcontext.gregs[REG_EAX]
#endif

//
// X86 (and X86_64) specific fault handler functions.
//

namespace art {

#if defined(__APPLE__) && defined(__x86_64__)
// mac symbols have a prefix of _ on x86_64
extern "C" void _art_quick_throw_null_pointer_exception();
extern "C" void _art_quick_throw_stack_overflow();
extern "C" void _art_quick_test_suspend();
#define EXT_SYM(sym) _ ## sym
#else
extern "C" void art_quick_throw_null_pointer_exception();
extern "C" void art_quick_throw_stack_overflow();
extern "C" void art_quick_test_suspend();
#define EXT_SYM(sym) sym
#endif

// Note this is different from the others (no underscore on 64 bit mac) due to
// the way the symbol is defined in the .S file.
// TODO: fix the symbols for 64 bit mac - there is a double underscore prefix for some
// of them.
extern "C" void art_nested_signal_return();

// Get the size of an instruction in bytes.
// Return 0 if the instruction is not handled.
static uint32_t GetInstructionSize(const uint8_t* pc) {
#if defined(__x86_64)
  const bool x86_64 = true;
#else
  const bool x86_64 = false;
#endif

  const uint8_t* startpc = pc;

  uint8_t opcode = *pc++;
  uint8_t modrm;
  bool has_modrm = false;
  bool two_byte = false;
  uint32_t displacement_size = 0;
  uint32_t immediate_size = 0;

  // Prefixes.
  while (true) {
    bool prefix_present = false;
    switch (opcode) {
      // Group 1
      case 0xf0:
      case 0xf2:
      case 0xf3:

      // Group 2
      case 0x2e:
      case 0x36:
      case 0x3e:
      case 0x26:
      case 0x64:
      case 0x65:

      // Group 3
      case 0x66:

      // Group 4
      case 0x67:
        opcode = *pc++;
        prefix_present = true;
        break;
    }
    if (!prefix_present) {
      break;
    }
  }

  if (x86_64 && opcode >= 0x40 && opcode <= 0x4f) {
    opcode = *pc++;
  }

  if (opcode == 0x0f) {
    // Two byte opcode
    two_byte = true;
    opcode = *pc++;
  }

  bool unhandled_instruction = false;

  if (two_byte) {
    switch (opcode) {
      case 0x10:            // vmovsd/ss
      case 0x11:            // vmovsd/ss
      case 0xb6:        // movzx
      case 0xb7:
      case 0xbe:        // movsx
      case 0xbf:
        modrm = *pc++;
        has_modrm = true;
        break;
      default:
        unhandled_instruction = true;
        break;
    }
  } else {
    switch (opcode) {
      case 0x89:            // mov
      case 0x8b:
      case 0x38:        // cmp with memory.
      case 0x39:
      case 0x3a:
      case 0x3b:
      case 0x3c:
      case 0x3d:
      case 0x85:        // test.
        modrm = *pc++;
        has_modrm = true;
        break;

      case 0x80:        // group 1, byte immediate.
      case 0x83:
        modrm = *pc++;
        has_modrm = true;
        immediate_size = 1;
        break;

      case 0x81:        // group 1, word immediate.
        modrm = *pc++;
        has_modrm = true;
        immediate_size = 4;
        break;

      default:
        unhandled_instruction = true;
        break;
    }
  }

  if (unhandled_instruction) {
    VLOG(signals) << "Unhandled x86 instruction with opcode " << static_cast<int>(opcode);
    return 0;
  }

  if (has_modrm) {
    uint8_t mod = (modrm >> 6) & 0b11;

    // Check for SIB.
    if (mod != 0b11 && (modrm & 0b111) == 4) {
      ++pc;     // SIB
    }

    switch (mod) {
      case 0b00: break;
      case 0b01: displacement_size = 1; break;
      case 0b10: displacement_size = 4; break;
      case 0b11:
        break;
    }
  }

  // Skip displacement and immediate.
  pc += displacement_size + immediate_size;

  VLOG(signals) << "x86 instruction length calculated as " << (pc - startpc);
  return pc - startpc;
}

void FaultManager::HandleNestedSignal(int sig, siginfo_t* info, void* context) {
  // For the Intel architectures we need to go to an assembly language
  // stub.  This is because the 32 bit call to longjmp is much different
  // from the 64 bit ABI call and pushing things onto the stack inside this
  // handler was unwieldy and ugly.  The use of the stub means we can keep
  // this code the same for both 32 and 64 bit.

  Thread* self = Thread::Current();
  CHECK(self != nullptr);       // This will cause a SIGABRT if self is nullptr.

  struct ucontext* uc = reinterpret_cast<struct ucontext*>(context);
  uc->CTX_JMP_BUF = reinterpret_cast<uintptr_t>(*self->GetNestedSignalState());
  uc->CTX_EIP = reinterpret_cast<uintptr_t>(art_nested_signal_return);
}

void FaultManager::GetMethodAndReturnPcAndSp(siginfo_t* siginfo, void* context,
                                             mirror::ArtMethod** out_method,
                                             uintptr_t* out_return_pc, uintptr_t* out_sp) {
  struct ucontext* uc = reinterpret_cast<struct ucontext*>(context);
  *out_sp = static_cast<uintptr_t>(uc->CTX_ESP);
  VLOG(signals) << "sp: " << std::hex << *out_sp;
  if (*out_sp == 0) {
    return;
  }

  // In the case of a stack overflow, the stack is not valid and we can't
  // get the method from the top of the stack.  However it's in EAX(x86)/RDI(x86_64).
  uintptr_t* fault_addr = reinterpret_cast<uintptr_t*>(siginfo->si_addr);
  uintptr_t* overflow_addr = reinterpret_cast<uintptr_t*>(
#if defined(__x86_64__)
      reinterpret_cast<uint8_t*>(*out_sp) - GetStackOverflowReservedBytes(kX86_64));
#else
      reinterpret_cast<uint8_t*>(*out_sp) - GetStackOverflowReservedBytes(kX86));
#endif
  if (overflow_addr == fault_addr) {
    *out_method = reinterpret_cast<mirror::ArtMethod*>(uc->CTX_METHOD);
  } else {
    // The method is at the top of the stack.
    *out_method = (reinterpret_cast<StackReference<mirror::ArtMethod>* >(*out_sp)[0]).AsMirrorPtr();
  }

  uint8_t* pc = reinterpret_cast<uint8_t*>(uc->CTX_EIP);
  VLOG(signals) << HexDump(pc, 32, true, "PC ");

  uint32_t instr_size = GetInstructionSize(pc);
  if (instr_size == 0) {
    // Unknown instruction, tell caller it's not ours.
    *out_method = nullptr;
    return;
  }
  *out_return_pc = reinterpret_cast<uintptr_t>(pc + instr_size);
}

bool NullPointerHandler::Action(int sig, siginfo_t* info, void* context) {
  struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
  uint8_t* pc = reinterpret_cast<uint8_t*>(uc->CTX_EIP);
  uint8_t* sp = reinterpret_cast<uint8_t*>(uc->CTX_ESP);

  uint32_t instr_size = GetInstructionSize(pc);
  if (instr_size == 0) {
    // Unknown instruction, can't really happen.
    return false;
  }

  // We need to arrange for the signal handler to return to the null pointer
  // exception generator.  The return address must be the address of the
  // next instruction (this instruction + instruction size).  The return address
  // is on the stack at the top address of the current frame.

  // Push the return address onto the stack.
  uintptr_t retaddr = reinterpret_cast<uintptr_t>(pc + instr_size);
  uintptr_t* next_sp = reinterpret_cast<uintptr_t*>(sp - sizeof(uintptr_t));
  *next_sp = retaddr;
  uc->CTX_ESP = reinterpret_cast<uintptr_t>(next_sp);

  uc->CTX_EIP = reinterpret_cast<uintptr_t>(EXT_SYM(art_quick_throw_null_pointer_exception));
  VLOG(signals) << "Generating null pointer exception";
  return true;
}

// A suspend check is done using the following instruction sequence:
// (x86)
// 0xf720f1df:         648B058C000000      mov     eax, fs:[0x8c]  ; suspend_trigger
// .. some intervening instructions.
// 0xf720f1e6:                   8500      test    eax, [eax]
// (x86_64)
// 0x7f579de45d9e: 65488B0425A8000000      movq    rax, gs:[0xa8]  ; suspend_trigger
// .. some intervening instructions.
// 0x7f579de45da7:               8500      test    eax, [eax]

// The offset from fs is Thread::ThreadSuspendTriggerOffset().
// To check for a suspend check, we examine the instructions that caused
// the fault.
bool SuspensionHandler::Action(int sig, siginfo_t* info, void* context) {
  // These are the instructions to check for.  The first one is the mov eax, fs:[xxx]
  // where xxx is the offset of the suspend trigger.
#if defined(__x86_64__)
  uint32_t trigger = Thread::ThreadSuspendTriggerOffset<8>().Int32Value();
#else
  uint32_t trigger = Thread::ThreadSuspendTriggerOffset<4>().Int32Value();
#endif

  VLOG(signals) << "Checking for suspension point";
#if defined(__x86_64__)
  uint8_t checkinst1[] = {0x65, 0x48, 0x8b, 0x04, 0x25, static_cast<uint8_t>(trigger & 0xff),
      static_cast<uint8_t>((trigger >> 8) & 0xff), 0, 0};
#else
  uint8_t checkinst1[] = {0x64, 0x8b, 0x05, static_cast<uint8_t>(trigger & 0xff),
      static_cast<uint8_t>((trigger >> 8) & 0xff), 0, 0};
#endif
  uint8_t checkinst2[] = {0x85, 0x00};

  struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
  uint8_t* pc = reinterpret_cast<uint8_t*>(uc->CTX_EIP);
  uint8_t* sp = reinterpret_cast<uint8_t*>(uc->CTX_ESP);

  if (pc[0] != checkinst2[0] || pc[1] != checkinst2[1]) {
    // Second instruction is not correct (test eax,[eax]).
    VLOG(signals) << "Not a suspension point";
    return false;
  }

  // The first instruction can a little bit up the stream due to load hoisting
  // in the compiler.
  uint8_t* limit = pc - 100;   // Compiler will hoist to a max of 20 instructions.
  uint8_t* ptr = pc - sizeof(checkinst1);
  bool found = false;
  while (ptr > limit) {
    if (memcmp(ptr, checkinst1, sizeof(checkinst1)) == 0) {
      found = true;
      break;
    }
    ptr -= 1;
  }

  if (found) {
    VLOG(signals) << "suspend check match";

    // We need to arrange for the signal handler to return to the null pointer
    // exception generator.  The return address must be the address of the
    // next instruction (this instruction + 2).  The return address
    // is on the stack at the top address of the current frame.

    // Push the return address onto the stack.
    uintptr_t retaddr = reinterpret_cast<uintptr_t>(pc + 2);
    uintptr_t* next_sp = reinterpret_cast<uintptr_t*>(sp - sizeof(uintptr_t));
    *next_sp = retaddr;
    uc->CTX_ESP = reinterpret_cast<uintptr_t>(next_sp);

    uc->CTX_EIP = reinterpret_cast<uintptr_t>(EXT_SYM(art_quick_test_suspend));

    // Now remove the suspend trigger that caused this fault.
    Thread::Current()->RemoveSuspendTrigger();
    VLOG(signals) << "removed suspend trigger invoking test suspend";
    return true;
  }
  VLOG(signals) << "Not a suspend check match, first instruction mismatch";
  return false;
}

// The stack overflow check is done using the following instruction:
// test eax, [esp+ -xxx]
// where 'xxx' is the size of the overflow area.
//
// This is done before any frame is established in the method.  The return
// address for the previous method is on the stack at ESP.

bool StackOverflowHandler::Action(int sig, siginfo_t* info, void* context) {
  struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
  uintptr_t sp = static_cast<uintptr_t>(uc->CTX_ESP);

  uintptr_t fault_addr = reinterpret_cast<uintptr_t>(info->si_addr);
  VLOG(signals) << "fault_addr: " << std::hex << fault_addr;
  VLOG(signals) << "checking for stack overflow, sp: " << std::hex << sp <<
    ", fault_addr: " << fault_addr;

#if defined(__x86_64__)
  uintptr_t overflow_addr = sp - GetStackOverflowReservedBytes(kX86_64);
#else
  uintptr_t overflow_addr = sp - GetStackOverflowReservedBytes(kX86);
#endif

  // Check that the fault address is the value expected for a stack overflow.
  if (fault_addr != overflow_addr) {
    VLOG(signals) << "Not a stack overflow";
    return false;
  }

  VLOG(signals) << "Stack overflow found";

  // Since the compiler puts the implicit overflow
  // check before the callee save instructions, the SP is already pointing to
  // the previous frame.

  // Now arrange for the signal handler to return to art_quick_throw_stack_overflow.
  uc->CTX_EIP = reinterpret_cast<uintptr_t>(EXT_SYM(art_quick_throw_stack_overflow));

  return true;
}
}       // namespace art
