// Copyright 2014 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 "minidump/minidump_context_writer.h"

#include <windows.h>
#include <dbghelp.h>
#include <stdint.h>
#include <string.h>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "nb/cpp14oncpp11.h"
#include "snapshot/cpu_context.h"
#include "util/file/file_writer.h"
#include "util/stdlib/aligned_allocator.h"

namespace crashpad {

namespace {

// Sanity-check complex structures to ensure interoperability.
static_assert(sizeof(MinidumpContextX86) == 716, "MinidumpContextX86 size");
static_assert(sizeof(MinidumpContextAMD64) == 1232,
              "MinidumpContextAMD64 size");

// These structures can also be checked against definitions in the Windows SDK.
#if defined(OS_WIN)
#if defined(ARCH_CPU_X86_FAMILY)
static_assert(sizeof(MinidumpContextX86) == sizeof(WOW64_CONTEXT),
              "WOW64_CONTEXT size");
#if defined(ARCH_CPU_X86)
static_assert(sizeof(MinidumpContextX86) == sizeof(CONTEXT), "CONTEXT size");
#elif defined(ARCH_CPU_X86_64)
static_assert(sizeof(MinidumpContextAMD64) == sizeof(CONTEXT), "CONTEXT size");
#endif
#endif  // ARCH_CPU_X86_FAMILY
#endif  // OS_WIN

}  // namespace

MinidumpContextWriter::~MinidumpContextWriter() {
}

// static
std::unique_ptr<MinidumpContextWriter>
MinidumpContextWriter::CreateFromSnapshot(const CPUContext* context_snapshot) {
  std::unique_ptr<MinidumpContextWriter> context;

  switch (context_snapshot->architecture) {
    case kCPUArchitectureX86: {
      MinidumpContextX86Writer* context_x86 = new MinidumpContextX86Writer();
      context.reset(context_x86);
      context_x86->InitializeFromSnapshot(context_snapshot->x86);
      break;
    }

    case kCPUArchitectureX86_64: {
      MinidumpContextAMD64Writer* context_amd64 =
          new MinidumpContextAMD64Writer();
      context.reset(context_amd64);
      context_amd64->InitializeFromSnapshot(context_snapshot->x86_64);
      break;
    }

    case kCPUArchitectureARM: {
      context = std::make_unique<MinidumpContextARMWriter>();
      reinterpret_cast<MinidumpContextARMWriter*>(context.get())
          ->InitializeFromSnapshot(context_snapshot->arm);
      break;
    }

    case kCPUArchitectureARM64: {
      context = std::make_unique<MinidumpContextARM64Writer>();
      reinterpret_cast<MinidumpContextARM64Writer*>(context.get())
          ->InitializeFromSnapshot(context_snapshot->arm64);
      break;
    }

    case kCPUArchitectureMIPSEL: {
      context = std::make_unique<MinidumpContextMIPSWriter>();
      reinterpret_cast<MinidumpContextMIPSWriter*>(context.get())
          ->InitializeFromSnapshot(context_snapshot->mipsel);
      break;
    }

    case kCPUArchitectureMIPS64EL: {
      context = std::make_unique<MinidumpContextMIPS64Writer>();
      reinterpret_cast<MinidumpContextMIPS64Writer*>(context.get())
          ->InitializeFromSnapshot(context_snapshot->mips64);
      break;
    }

    default: {
      LOG(ERROR) << "unknown context architecture "
                 << context_snapshot->architecture;
      break;
    }
  }

  return context;
}

size_t MinidumpContextWriter::SizeOfObject() {
  DCHECK_GE(state(), kStateFrozen);

  return ContextSize();
}

MinidumpContextX86Writer::MinidumpContextX86Writer()
    : MinidumpContextWriter(), context_() {
  context_.context_flags = kMinidumpContextX86;
}

MinidumpContextX86Writer::~MinidumpContextX86Writer() {
}


void MinidumpContextX86Writer::InitializeFromSnapshot(
    const CPUContextX86* context_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK_EQ(context_.context_flags, kMinidumpContextX86);

  context_.context_flags = kMinidumpContextX86All;

  context_.dr0 = context_snapshot->dr0;
  context_.dr1 = context_snapshot->dr1;
  context_.dr2 = context_snapshot->dr2;
  context_.dr3 = context_snapshot->dr3;
  context_.dr6 = context_snapshot->dr6;
  context_.dr7 = context_snapshot->dr7;

  // The contents of context_.fsave effectively alias everything in
  // context_.fxsave that’s related to x87 FPU state. context_.fsave doesn’t
  // carry state specific to SSE (or later), such as mxcsr and the xmm
  // registers.
  CPUContextX86::FxsaveToFsave(context_snapshot->fxsave, &context_.fsave);

  context_.gs = context_snapshot->gs;
  context_.fs = context_snapshot->fs;
  context_.es = context_snapshot->es;
  context_.ds = context_snapshot->ds;
  context_.edi = context_snapshot->edi;
  context_.esi = context_snapshot->esi;
  context_.ebx = context_snapshot->ebx;
  context_.edx = context_snapshot->edx;
  context_.ecx = context_snapshot->ecx;
  context_.eax = context_snapshot->eax;
  context_.ebp = context_snapshot->ebp;
  context_.eip = context_snapshot->eip;
  context_.cs = context_snapshot->cs;
  context_.eflags = context_snapshot->eflags;
  context_.esp = context_snapshot->esp;
  context_.ss = context_snapshot->ss;

  // This is effectively a memcpy() of a big structure.
  context_.fxsave = context_snapshot->fxsave;
}

bool MinidumpContextX86Writer::WriteObject(FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);

  return file_writer->Write(&context_, sizeof(context_));
}

size_t MinidumpContextX86Writer::ContextSize() const {
  DCHECK_GE(state(), kStateFrozen);

  return sizeof(context_);
}

static_assert(alignof(MinidumpContextAMD64) >= 16,
              "MinidumpContextAMD64 alignment");
static_assert(alignof(MinidumpContextAMD64Writer) >=
                  alignof(MinidumpContextAMD64),
              "MinidumpContextAMD64Writer alignment");

MinidumpContextAMD64Writer::MinidumpContextAMD64Writer()
    : MinidumpContextWriter(), context_() {
  context_.context_flags = kMinidumpContextAMD64;
}

MinidumpContextAMD64Writer::~MinidumpContextAMD64Writer() {
}

// static
void* MinidumpContextAMD64Writer::operator new(size_t size) {
  // MinidumpContextAMD64 requests an alignment of 16, which can be larger than
  // what standard new provides. This may trigger MSVC warning C4316. As a
  // workaround to this language deficiency, provide a custom allocation
  // function to allocate a block meeting the alignment requirement.
  return AlignedAllocate(alignof(MinidumpContextAMD64Writer), size);
}

// static
void MinidumpContextAMD64Writer::operator delete(void* pointer) {
  return AlignedFree(pointer);
}

void MinidumpContextAMD64Writer::InitializeFromSnapshot(
    const CPUContextX86_64* context_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK_EQ(context_.context_flags, kMinidumpContextAMD64);

  context_.context_flags = kMinidumpContextAMD64All;

  context_.mx_csr = context_snapshot->fxsave.mxcsr;
  context_.cs = context_snapshot->cs;
  context_.fs = context_snapshot->fs;
  context_.gs = context_snapshot->gs;
  // The top 32 bits of rflags are reserved/unused.
  context_.eflags = static_cast<uint32_t>(context_snapshot->rflags);
  context_.dr0 = context_snapshot->dr0;
  context_.dr1 = context_snapshot->dr1;
  context_.dr2 = context_snapshot->dr2;
  context_.dr3 = context_snapshot->dr3;
  context_.dr6 = context_snapshot->dr6;
  context_.dr7 = context_snapshot->dr7;
  context_.rax = context_snapshot->rax;
  context_.rcx = context_snapshot->rcx;
  context_.rdx = context_snapshot->rdx;
  context_.rbx = context_snapshot->rbx;
  context_.rsp = context_snapshot->rsp;
  context_.rbp = context_snapshot->rbp;
  context_.rsi = context_snapshot->rsi;
  context_.rdi = context_snapshot->rdi;
  context_.r8 = context_snapshot->r8;
  context_.r9 = context_snapshot->r9;
  context_.r10 = context_snapshot->r10;
  context_.r11 = context_snapshot->r11;
  context_.r12 = context_snapshot->r12;
  context_.r13 = context_snapshot->r13;
  context_.r14 = context_snapshot->r14;
  context_.r15 = context_snapshot->r15;
  context_.rip = context_snapshot->rip;

  // This is effectively a memcpy() of a big structure.
  context_.fxsave = context_snapshot->fxsave;
}

size_t MinidumpContextAMD64Writer::Alignment() {
  DCHECK_GE(state(), kStateFrozen);

  // Match the alignment of MinidumpContextAMD64.
  return 16;
}

bool MinidumpContextAMD64Writer::WriteObject(FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);

  return file_writer->Write(&context_, sizeof(context_));
}

size_t MinidumpContextAMD64Writer::ContextSize() const {
  DCHECK_GE(state(), kStateFrozen);

  return sizeof(context_);
}

MinidumpContextARMWriter::MinidumpContextARMWriter()
    : MinidumpContextWriter(), context_() {
  context_.context_flags = kMinidumpContextARM;
}

MinidumpContextARMWriter::~MinidumpContextARMWriter() = default;

void MinidumpContextARMWriter::InitializeFromSnapshot(
    const CPUContextARM* context_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK_EQ(context_.context_flags, kMinidumpContextARM);

  context_.context_flags = kMinidumpContextARMAll;

  static_assert(sizeof(context_.regs) == sizeof(context_snapshot->regs),
                "GPRS size mismatch");
  memcpy(context_.regs, context_snapshot->regs, sizeof(context_.regs));
  context_.fp = context_snapshot->fp;
  context_.ip = context_snapshot->ip;
  context_.sp = context_snapshot->sp;
  context_.lr = context_snapshot->lr;
  context_.pc = context_snapshot->pc;
  context_.cpsr = context_snapshot->cpsr;

  context_.fpscr = context_snapshot->vfp_regs.fpscr;
  static_assert(sizeof(context_.vfp) == sizeof(context_snapshot->vfp_regs.vfp),
                "VFP size mismatch");
  memcpy(context_.vfp, context_snapshot->vfp_regs.vfp, sizeof(context_.vfp));

  memset(context_.extra, 0, sizeof(context_.extra));
}

bool MinidumpContextARMWriter::WriteObject(FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);
  return file_writer->Write(&context_, sizeof(context_));
}

size_t MinidumpContextARMWriter::ContextSize() const {
  DCHECK_GE(state(), kStateFrozen);
  return sizeof(context_);
}

MinidumpContextARM64Writer::MinidumpContextARM64Writer()
    : MinidumpContextWriter(), context_() {
  context_.context_flags = kMinidumpContextARM64;
}

MinidumpContextARM64Writer::~MinidumpContextARM64Writer() = default;

void MinidumpContextARM64Writer::InitializeFromSnapshot(
    const CPUContextARM64* context_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK_EQ(context_.context_flags, kMinidumpContextARM64);

  context_.context_flags = kMinidumpContextARM64Full;

  static_assert(
      sizeof(context_.regs) == sizeof(context_snapshot->regs) -
                                   2 * sizeof(context_snapshot->regs[0]),
      "GPRs size mismatch");
  memcpy(context_.regs, context_snapshot->regs, sizeof(context_.regs));
  context_.fp = context_snapshot->regs[29];
  context_.lr = context_snapshot->regs[30];
  context_.sp = context_snapshot->sp;
  context_.pc = context_snapshot->pc;
  context_.cpsr = context_snapshot->spsr;

  static_assert(sizeof(context_.fpsimd) == sizeof(context_snapshot->fpsimd),
                "FPSIMD size mismatch");
  memcpy(context_.fpsimd, context_snapshot->fpsimd, sizeof(context_.fpsimd));
  context_.fpcr = context_snapshot->fpcr;
  context_.fpsr = context_snapshot->fpsr;

  memset(context_.bcr, 0, sizeof(context_.bcr));
  memset(context_.bvr, 0, sizeof(context_.bvr));
  memset(context_.wcr, 0, sizeof(context_.wcr));
  memset(context_.wvr, 0, sizeof(context_.wvr));
}

bool MinidumpContextARM64Writer::WriteObject(FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);
  return file_writer->Write(&context_, sizeof(context_));
}

size_t MinidumpContextARM64Writer::ContextSize() const {
  DCHECK_GE(state(), kStateFrozen);
  return sizeof(context_);
}

MinidumpContextMIPSWriter::MinidumpContextMIPSWriter()
    : MinidumpContextWriter(), context_() {
  context_.context_flags = kMinidumpContextMIPS;
}

MinidumpContextMIPSWriter::~MinidumpContextMIPSWriter() = default;

void MinidumpContextMIPSWriter::InitializeFromSnapshot(
    const CPUContextMIPS* context_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK_EQ(context_.context_flags, kMinidumpContextMIPS);

  context_.context_flags = kMinidumpContextMIPSAll;

  static_assert(sizeof(context_.regs) == sizeof(context_snapshot->regs),
                "GPRs size mismatch");
  memcpy(context_.regs, context_snapshot->regs, sizeof(context_.regs));
  context_.mdhi = context_snapshot->mdhi;
  context_.mdlo = context_snapshot->mdlo;
  context_.epc = context_snapshot->cp0_epc;
  context_.badvaddr = context_snapshot->cp0_badvaddr;
  context_.status = context_snapshot->cp0_status;
  context_.cause = context_snapshot->cp0_cause;

  static_assert(sizeof(context_.fpregs) == sizeof(context_snapshot->fpregs),
                "FPRs size mismatch");
  memcpy(&context_.fpregs, &context_snapshot->fpregs, sizeof(context_.fpregs));
  context_.fpcsr = context_snapshot->fpcsr;
  context_.fir = context_snapshot->fir;

  for (size_t index = 0; index < 3; ++index) {
    context_.hi[index] = context_snapshot->hi[index];
    context_.lo[index] = context_snapshot->lo[index];
  }
  context_.dsp_control = context_snapshot->dsp_control;
}

bool MinidumpContextMIPSWriter::WriteObject(FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);
  return file_writer->Write(&context_, sizeof(context_));
}

size_t MinidumpContextMIPSWriter::ContextSize() const {
  DCHECK_GE(state(), kStateFrozen);
  return sizeof(context_);
}

MinidumpContextMIPS64Writer::MinidumpContextMIPS64Writer()
    : MinidumpContextWriter(), context_() {
  context_.context_flags = kMinidumpContextMIPS64;
}

MinidumpContextMIPS64Writer::~MinidumpContextMIPS64Writer() = default;

void MinidumpContextMIPS64Writer::InitializeFromSnapshot(
    const CPUContextMIPS64* context_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK_EQ(context_.context_flags, kMinidumpContextMIPS64);

  context_.context_flags = kMinidumpContextMIPS64All;

  static_assert(sizeof(context_.regs) == sizeof(context_snapshot->regs),
                "GPRs size mismatch");
  memcpy(context_.regs, context_snapshot->regs, sizeof(context_.regs));
  context_.mdhi = context_snapshot->mdhi;
  context_.mdlo = context_snapshot->mdlo;
  context_.epc = context_snapshot->cp0_epc;
  context_.badvaddr = context_snapshot->cp0_badvaddr;
  context_.status = context_snapshot->cp0_status;
  context_.cause = context_snapshot->cp0_cause;

  static_assert(sizeof(context_.fpregs) == sizeof(context_snapshot->fpregs),
                "FPRs size mismatch");
  memcpy(context_.fpregs.dregs,
         context_snapshot->fpregs.dregs,
         sizeof(context_.fpregs.dregs));
  context_.fpcsr = context_snapshot->fpcsr;
  context_.fir = context_snapshot->fir;

  for (size_t index = 0; index < 3; ++index) {
    context_.hi[index] = context_snapshot->hi[index];
    context_.lo[index] = context_snapshot->lo[index];
  }
  context_.dsp_control = context_snapshot->dsp_control;
}

bool MinidumpContextMIPS64Writer::WriteObject(
    FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);
  return file_writer->Write(&context_, sizeof(context_));
}

size_t MinidumpContextMIPS64Writer::ContextSize() const {
  DCHECK_GE(state(), kStateFrozen);
  return sizeof(context_);
}

}  // namespace crashpad
