// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// 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 "snapshot/linux/exception_snapshot_linux.h"

#include <signal.h>

#include "base/logging.h"
#include "snapshot/linux/cpu_context_linux.h"
#include "snapshot/linux/process_reader_linux.h"
#include "snapshot/linux/signal_context.h"
#include "util/linux/traits.h"
#include "util/misc/reinterpret_bytes.h"
#include "util/numeric/safe_assignment.h"

namespace crashpad {
namespace internal {

ExceptionSnapshotLinux::ExceptionSnapshotLinux()
    : ExceptionSnapshot(),
      context_union_(),
      context_(),
      codes_(),
      thread_id_(0),
      exception_address_(0),
      signal_number_(0),
      signal_code_(0),
      initialized_() {}

ExceptionSnapshotLinux::~ExceptionSnapshotLinux() {}

#if defined(ARCH_CPU_X86_FAMILY)
template <>
bool ExceptionSnapshotLinux::ReadContext<ContextTraits32>(
    ProcessReaderLinux* reader,
    LinuxVMAddress context_address) {
  UContext<ContextTraits32> ucontext;
  if (!reader->Memory()->Read(context_address, sizeof(ucontext), &ucontext)) {
    LOG(ERROR) << "Couldn't read ucontext";
    return false;
  }

  context_.architecture = kCPUArchitectureX86;
  context_.x86 = &context_union_.x86;

  if (ucontext.fprs.magic == X86_FXSR_MAGIC) {
    if (!reader->Memory()->Read(context_address +
                                    offsetof(UContext<ContextTraits32>, fprs) +
                                    offsetof(SignalFloatContext32, fxsave),
                                sizeof(CPUContextX86::Fxsave),
                                &context_.x86->fxsave)) {
      LOG(ERROR) << "Couldn't read fxsave";
      return false;
    }
    InitializeCPUContextX86_NoFloatingPoint(ucontext.mcontext.gprs,
                                            context_.x86);

  } else {
    if (ucontext.fprs.magic != 0xffff) {
      LOG(ERROR) << "unexpected magic 0x" << std::hex << ucontext.fprs.magic;
      return false;
    }
    InitializeCPUContextX86(
        ucontext.mcontext.gprs, ucontext.fprs, context_.x86);
  }
  return true;
}

template <>
bool ExceptionSnapshotLinux::ReadContext<ContextTraits64>(
    ProcessReaderLinux* reader,
    LinuxVMAddress context_address) {
  UContext<ContextTraits64> ucontext;
  if (!reader->Memory()->Read(context_address, sizeof(ucontext), &ucontext)) {
    LOG(ERROR) << "Couldn't read ucontext";
    return false;
  }

  context_.architecture = kCPUArchitectureX86_64;
  context_.x86_64 = &context_union_.x86_64;

  InitializeCPUContextX86_64(
      ucontext.mcontext.gprs, ucontext.fprs, context_.x86_64);
  return true;
}

#elif defined(ARCH_CPU_ARM_FAMILY)

template <>
bool ExceptionSnapshotLinux::ReadContext<ContextTraits32>(
    ProcessReaderLinux* reader,
    LinuxVMAddress context_address) {
  context_.architecture = kCPUArchitectureARM;
  context_.arm = &context_union_.arm;

  CPUContextARM* dest_context = context_.arm;
  ProcessMemory* memory = reader->Memory();

  LinuxVMAddress gprs_address =
      context_address + offsetof(UContext<ContextTraits32>, mcontext32) +
      offsetof(MContext32, gprs);

  SignalThreadContext32 thread_context;
  if (!memory->Read(gprs_address, sizeof(thread_context), &thread_context)) {
    LOG(ERROR) << "Couldn't read gprs";
    return false;
  }
  InitializeCPUContextARM_NoFloatingPoint(thread_context, dest_context);

  dest_context->have_fpa_regs = false;

  LinuxVMAddress reserved_address =
      context_address + offsetof(UContext<ContextTraits32>, reserved);
  if ((reserved_address & 7) != 0) {
    LOG(ERROR) << "invalid alignment 0x" << std::hex << reserved_address;
    return false;
  }

  constexpr VMSize kMaxContextSpace = 1024;

  ProcessMemoryRange range;
  if (!range.Initialize(memory, false, reserved_address, kMaxContextSpace)) {
    return false;
  }

  dest_context->have_vfp_regs = false;
  do {
    CoprocessorContextHead head;
    if (!range.Read(reserved_address, sizeof(head), &head)) {
      LOG(ERROR) << "missing context terminator";
      return false;
    }
    reserved_address += sizeof(head);

    switch (head.magic) {
      case VFP_MAGIC:
        if (head.size != sizeof(SignalVFPContext) + sizeof(head)) {
          LOG(ERROR) << "unexpected vfp context size " << head.size;
          return false;
        }
        static_assert(
            sizeof(SignalVFPContext::vfp) == sizeof(dest_context->vfp_regs),
            "vfp context size mismatch");
        if (!range.Read(reserved_address + offsetof(SignalVFPContext, vfp),
                        sizeof(dest_context->vfp_regs),
                        &dest_context->vfp_regs)) {
          LOG(ERROR) << "Couldn't read vfp";
          return false;
        }
        dest_context->have_vfp_regs = true;
        return true;

      case CRUNCH_MAGIC:
      case IWMMXT_MAGIC:
      case DUMMY_MAGIC:
        reserved_address += head.size - sizeof(head);
        continue;

      case 0:
        return true;

      default:
        LOG(ERROR) << "invalid magic number 0x" << std::hex << head.magic;
        return false;
    }
  } while (true);
}

template <>
bool ExceptionSnapshotLinux::ReadContext<ContextTraits64>(
    ProcessReaderLinux* reader,
    LinuxVMAddress context_address) {
  context_.architecture = kCPUArchitectureARM64;
  context_.arm64 = &context_union_.arm64;

  CPUContextARM64* dest_context = context_.arm64;
  ProcessMemory* memory = reader->Memory();

  LinuxVMAddress gprs_address =
      context_address + offsetof(UContext<ContextTraits64>, mcontext64) +
      offsetof(MContext64, gprs);

  ThreadContext::t64_t thread_context;
  if (!memory->Read(gprs_address, sizeof(thread_context), &thread_context)) {
    LOG(ERROR) << "Couldn't read gprs";
    return false;
  }
  InitializeCPUContextARM64_NoFloatingPoint(thread_context, dest_context);

  LinuxVMAddress reserved_address =
      context_address + offsetof(UContext<ContextTraits64>, reserved);
  if ((reserved_address & 15) != 0) {
    LOG(ERROR) << "invalid alignment 0x" << std::hex << reserved_address;
    return false;
  }

  constexpr VMSize kMaxContextSpace = 4096;

  ProcessMemoryRange range;
  if (!range.Initialize(memory, true, reserved_address, kMaxContextSpace)) {
    return false;
  }

  do {
    CoprocessorContextHead head;
    if (!range.Read(reserved_address, sizeof(head), &head)) {
      LOG(ERROR) << "missing context terminator";
      return false;
    }
    reserved_address += sizeof(head);

    switch (head.magic) {
      case FPSIMD_MAGIC:
        if (head.size != sizeof(SignalFPSIMDContext) + sizeof(head)) {
          LOG(ERROR) << "unexpected fpsimd context size " << head.size;
          return false;
        }
        SignalFPSIMDContext fpsimd;
        if (!range.Read(reserved_address, sizeof(fpsimd), &fpsimd)) {
          LOG(ERROR) << "Couldn't read fpsimd " << head.size;
          return false;
        }
        InitializeCPUContextARM64_OnlyFPSIMD(fpsimd, dest_context);
        return true;

      case ESR_MAGIC:
      case EXTRA_MAGIC:
        reserved_address += head.size - sizeof(head);
        continue;

      case 0:
        LOG(WARNING) << "fpsimd not found";
        InitializeCPUContextARM64_ClearFPSIMD(dest_context);
        return true;

      default:
        LOG(ERROR) << "invalid magic number 0x" << std::hex << head.magic;
        return false;
    }
  } while (true);
}

#endif  // ARCH_CPU_X86_FAMILY

bool ExceptionSnapshotLinux::Initialize(ProcessReaderLinux* process_reader,
                                        LinuxVMAddress siginfo_address,
                                        LinuxVMAddress context_address,
                                        pid_t thread_id) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  thread_id_ = thread_id;

  if (process_reader->Is64Bit()) {
    if (!ReadContext<ContextTraits64>(process_reader, context_address) ||
        !ReadSiginfo<Traits64>(process_reader, siginfo_address)) {
      return false;
    }
  } else {
    if (!ReadContext<ContextTraits32>(process_reader, context_address) ||
        !ReadSiginfo<Traits32>(process_reader, siginfo_address)) {
      return false;
    }
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

template <typename Traits>
bool ExceptionSnapshotLinux::ReadSiginfo(ProcessReaderLinux* reader,
                                         LinuxVMAddress siginfo_address) {
  Siginfo<Traits> siginfo;
  if (!reader->Memory()->Read(siginfo_address, sizeof(siginfo), &siginfo)) {
    LOG(ERROR) << "Couldn't read siginfo";
    return false;
  }

  signal_number_ = siginfo.signo;
  signal_code_ = siginfo.code;

  uint64_t extra_code;
#define PUSH_CODE(value)                         \
  do {                                           \
    if (!ReinterpretBytes(value, &extra_code)) { \
      LOG(ERROR) << "bad code";                  \
      return false;                              \
    }                                            \
    codes_.push_back(extra_code);                \
  } while (false)

  switch (siginfo.signo) {
    case SIGILL:
    case SIGFPE:
    case SIGSEGV:
    case SIGBUS:
    case SIGTRAP:
      exception_address_ = siginfo.address;
      break;

    case SIGPOLL:  // SIGIO
      PUSH_CODE(siginfo.band);
      PUSH_CODE(siginfo.fd);
      break;

    case SIGSYS:
      exception_address_ = siginfo.call_address;
      PUSH_CODE(siginfo.syscall);
      PUSH_CODE(siginfo.arch);
      break;

    case SIGALRM:
    case SIGVTALRM:
    case SIGPROF:
      PUSH_CODE(siginfo.timerid);
      PUSH_CODE(siginfo.overrun);
      PUSH_CODE(siginfo.sigval.sigval);
      break;

    case SIGABRT:
    case SIGQUIT:
    case SIGXCPU:
    case SIGXFSZ:
    case SIGHUP:
    case SIGINT:
    case SIGPIPE:
    case SIGTERM:
    case SIGUSR1:
    case SIGUSR2:
#if defined(SIGEMT)
    case SIGEMT:
#endif  // SIGEMT
#if defined(SIGPWR)
    case SIGPWR:
#endif  // SIGPWR
#if defined(SIGSTKFLT)
    case SIGSTKFLT:
#endif  // SIGSTKFLT
      PUSH_CODE(siginfo.pid);
      PUSH_CODE(siginfo.uid);
      PUSH_CODE(siginfo.sigval.sigval);
      break;

    default:
      LOG(WARNING) << "Unhandled signal " << siginfo.signo;
  }

  return true;
}

const CPUContext* ExceptionSnapshotLinux::Context() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return &context_;
}

uint64_t ExceptionSnapshotLinux::ThreadID() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return thread_id_;
}

uint32_t ExceptionSnapshotLinux::Exception() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return signal_number_;
}

uint32_t ExceptionSnapshotLinux::ExceptionInfo() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return signal_code_;
}

uint64_t ExceptionSnapshotLinux::ExceptionAddress() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return exception_address_;
}

const std::vector<uint64_t>& ExceptionSnapshotLinux::Codes() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return codes_;
}

std::vector<const MemorySnapshot*> ExceptionSnapshotLinux::ExtraMemory() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return std::vector<const MemorySnapshot*>();
}

}  // namespace internal
}  // namespace crashpad
