// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"
#include "vm/instructions.h"
#include "vm/signal_handler.h"
#include "vm/simulator.h"
#if defined(DART_HOST_OS_ANDROID)

namespace dart {

uintptr_t SignalHandler::GetProgramCounter(const mcontext_t& mcontext) {
  uintptr_t pc = 0;

#if defined(HOST_ARCH_IA32)
  pc = static_cast<uintptr_t>(mcontext.gregs[REG_EIP]);
#elif defined(HOST_ARCH_X64)
  pc = static_cast<uintptr_t>(mcontext.gregs[REG_RIP]);
#elif defined(HOST_ARCH_ARM)
  pc = static_cast<uintptr_t>(mcontext.arm_pc);
#elif defined(HOST_ARCH_ARM64)
  pc = static_cast<uintptr_t>(mcontext.pc);
#elif defined(HOST_ARCH_RISCV64)
  pc = static_cast<uintptr_t>(mcontext.__gregs[REG_PC]);
#else
#error Unsupported architecture.
#endif  // HOST_ARCH_...
  return pc;
}

uintptr_t SignalHandler::GetFramePointer(const mcontext_t& mcontext) {
  uintptr_t fp = 0;

#if defined(HOST_ARCH_IA32)
  fp = static_cast<uintptr_t>(mcontext.gregs[REG_EBP]);
#elif defined(HOST_ARCH_X64)
  fp = static_cast<uintptr_t>(mcontext.gregs[REG_RBP]);
#elif defined(HOST_ARCH_ARM)
  // B1.3.3 Program Status Registers (PSRs)
  if ((mcontext.arm_cpsr & (1 << 5)) != 0) {
    // Thumb mode.
    fp = static_cast<uintptr_t>(mcontext.arm_r7);
  } else {
    // ARM mode.
    fp = static_cast<uintptr_t>(mcontext.arm_fp);
  }
#elif defined(HOST_ARCH_ARM64)
  fp = static_cast<uintptr_t>(mcontext.regs[29]);
#elif defined(HOST_ARCH_RISCV64)
  fp = static_cast<uintptr_t>(mcontext.__gregs[REG_S0]);
#else
#error Unsupported architecture.
#endif  // HOST_ARCH_...

  return fp;
}

uintptr_t SignalHandler::GetCStackPointer(const mcontext_t& mcontext) {
  uintptr_t sp = 0;

#if defined(HOST_ARCH_IA32)
  sp = static_cast<uintptr_t>(mcontext.gregs[REG_ESP]);
#elif defined(HOST_ARCH_X64)
  sp = static_cast<uintptr_t>(mcontext.gregs[REG_RSP]);
#elif defined(HOST_ARCH_ARM)
  sp = static_cast<uintptr_t>(mcontext.arm_sp);
#elif defined(HOST_ARCH_ARM64)
  sp = static_cast<uintptr_t>(mcontext.sp);
#elif defined(HOST_ARCH_RISCV64)
  sp = static_cast<uintptr_t>(mcontext.__gregs[REG_SP]);
#else
#error Unsupported architecture.
#endif  // HOST_ARCH_...
  return sp;
}

uintptr_t SignalHandler::GetDartStackPointer(const mcontext_t& mcontext) {
#if defined(TARGET_ARCH_ARM64) && !defined(DART_INCLUDE_SIMULATOR)
  return static_cast<uintptr_t>(mcontext.regs[SPREG]);
#else
  return GetCStackPointer(mcontext);
#endif
}

uintptr_t SignalHandler::GetLinkRegister(const mcontext_t& mcontext) {
  uintptr_t lr = 0;

#if defined(HOST_ARCH_IA32)
  lr = 0;
#elif defined(HOST_ARCH_X64)
  lr = 0;
#elif defined(HOST_ARCH_ARM)
  lr = static_cast<uintptr_t>(mcontext.arm_lr);
#elif defined(HOST_ARCH_ARM64)
  lr = static_cast<uintptr_t>(mcontext.regs[30]);
#elif defined(HOST_ARCH_RISCV64)
  lr = static_cast<uintptr_t>(mcontext.__gregs[REG_RA]);
#else
#error Unsupported architecture.
#endif  // HOST_ARCH_...
  return lr;
}

void SignalHandler::Install(SignalAction action) {
  // Bionic implementation of setjmp temporary mangles SP register
  // in place which breaks signal delivery on the thread stack - when
  // kernel tries to deliver SIGPROF and we are in the middle of
  // setjmp SP value is invalid - might be pointing to random memory
  // or outside of writable space at all. In the first case we
  // get memory corruption and in the second case kernel would send
  // SIGSEGV to the process. See b/152210274 for details.
  // To work around this issue we request SIGPROF signals to be delivered
  // on the alternative signal stack by setting SA_ONSTACK. The stack itself
  // is configured when interrupts are enabled for a particular thread.
  // In reality Bionic's |pthread_create| eagerly creates and assigns an
  // alternative signal stack for each thread. However older versions of Bionic
  // (L and below) make the size of alternative stack too small which causes
  // stack overflows and crashes.
  struct sigaction act = {};
  act.sa_sigaction = action;
  sigemptyset(&act.sa_mask);
  sigaddset(&act.sa_mask, SIGPROF);  // Prevent nested signals.
  act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
  int r = sigaction(SIGPROF, &act, nullptr);
  ASSERT(r == 0);
}

void SignalHandler::Remove() {
  // Ignore future SIGPROF signals because by default SIGPROF will terminate
  // the process and we may have some signals in flight.
  struct sigaction act = {};
  act.sa_handler = SIG_IGN;
  sigemptyset(&act.sa_mask);
  int r = sigaction(SIGPROF, &act, nullptr);
  RELEASE_ASSERT(r == 0);
}

void* SignalHandler::PrepareCurrentThread() {
  // These constants are selected to prevent allocating alternative signal
  // stack if Bionic has already allocated large enough one for us. They
  // match current values used in Bionic[1].
  //
  // [1]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/pthread_internal.h;drc=3649db34a154cedb8ef53a5adbaa349970159b58;l=243
  const intptr_t kGuardPageSize = 4 * KB;
#if defined(TARGET_ARCH_IS_64_BIT)
  const intptr_t kSigAltStackSize = 32 * KB;
#else
  const intptr_t kSigAltStackSize = 16 * KB;
#endif

  // First check if the alternative signal stack is already installed and
  // large enough.
  int r;
  stack_t ss;
  memset(&ss, 0, sizeof(ss));
  r = sigaltstack(nullptr, &ss);
  ASSERT(r == 0);
  if (ss.ss_flags == 0 && ss.ss_size >= (kSigAltStackSize - kGuardPageSize)) {
    // Bionic has created a large enough stack already.
    return nullptr;
  }

  // We are running on an older version of Android, where Bionic creates
  // stacks which are too small.
  ss.ss_sp = malloc(kSigAltStackSize);
  ss.ss_size = kSigAltStackSize;
  ss.ss_flags = 0;
  r = sigaltstack(&ss, nullptr);
  ASSERT(r == 0);

  return ss.ss_sp;
}

void SignalHandler::CleanupCurrentThreadState(void* stack) {
  if (stack != nullptr) {
    // Disable alternative stack then free allocated memory.
    stack_t ss, old_ss;
    memset(&ss, 0, sizeof(ss));
    ss.ss_flags = SS_DISABLE;
    int r = sigaltstack(&ss, &old_ss);
    ASSERT(r == 0);
    ASSERT(old_ss.ss_sp == stack);
    free(stack);
  }
}

}  // namespace dart

#endif  // defined(DART_HOST_OS_ANDROID)
