// Copyright 2014 The Crashpad Authors
//
// 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/check_op.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "build/build_config.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 BUILDFLAG(IS_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  // BUILDFLAG(IS_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;
    }

    case kCPUArchitectureRISCV64: {
      context = std::make_unique<MinidumpContextRISCV64Writer>();
      reinterpret_cast<MinidumpContextRISCV64Writer*>(context.get())
          ->InitializeFromSnapshot(context_snapshot->riscv64);
      break;
    }

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

  return context;
}

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

  return ContextSize();
}

size_t MinidumpContextWriter::FreezeAndGetSizeOfObject() {
  Freeze();
  return SizeOfObject();
}

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);

  if (context_snapshot->xstate.enabled_features != 0) {
    // Extended context.
    context_.context_flags =
        kMinidumpContextAMD64All | kMinidumpContextAMD64Xstate;
  } else {
    // Fixed size context - no xsave components.
    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;

  // If XSave features are being recorded store in xsave_entries in xcomp_bv
  // order. We will not see features we do not support as we provide flags
  // to the OS when first obtaining a snapshot.
  if (context_snapshot->xstate.enabled_features & XSTATE_MASK_CET_U) {
    auto cet_u = std::make_unique<MinidumpXSaveAMD64CetU>();
    cet_u->InitializeFromSnapshot(context_snapshot);
    xsave_entries_.push_back(std::move(cet_u));
  }
}

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);
  // Note: all sizes here come from our constants, not from untrustworthy data.
  std::vector<unsigned char> data(ContextSize());
  unsigned char* const buf = data.data();

  // CONTEXT always comes first.
  DCHECK_LE(sizeof(context_), data.size());
  memcpy(buf, &context_, sizeof(context_));

  if (xsave_entries_.size() > 0) {
    MinidumpContextExHeader context_ex = {{0, 0}, {0, 0}, {0, 0}};
    MinidumpXSaveAreaHeader xsave_header = {0, 0, {}};

    // CONTEXT_EX goes directly after the CONTEXT. |offset| is relative to
    // &CONTEXT_EX.
    context_ex.all.offset = -static_cast<int32_t>(sizeof(context_));
    context_ex.all.size = static_cast<uint32_t>(ContextSize());
    context_ex.legacy.offset = context_ex.all.offset;
    context_ex.legacy.size = sizeof(context_);
    // Then... there is a gap.
    //
    // In the compacted format the XSave area header goes just before
    // the first xsave entry.  It has a total size given by the header
    // + (padded) sizes of all the entries.
    context_ex.xstate.offset = static_cast<int32_t>(
        kMinidumpAMD64XSaveOffset - sizeof(MinidumpXSaveAreaHeader) -
        sizeof(context_));
    context_ex.xstate.size =
        static_cast<uint32_t>(sizeof(MinidumpXSaveAreaHeader) + ContextSize() -
                              kMinidumpAMD64XSaveOffset);

    // Store CONTEXT_EX now it is complete.
    DCHECK_LE(sizeof(context_) + sizeof(context_ex), data.size());
    memcpy(&buf[sizeof(context_)], &context_ex, sizeof(context_ex));

    // Calculate flags for xsave header & write entries (they will be
    // *after* the xsave header).
    size_t cursor = kMinidumpAMD64XSaveOffset;
    for (auto const& entry : xsave_entries_) {
      xsave_header.mask |= 1ull << entry->XCompBVBit();
      DCHECK_LE(cursor + entry->Size(), data.size());
      entry->Copy(&buf[cursor]);
      cursor += entry->Size();
    }

    xsave_header.compaction_mask =
        xsave_header.mask | XSTATE_COMPACTION_ENABLE_MASK;

    // Store xsave header at its calculated offset. It is before the entries
    // above, but we need to add the |mask| bits before writing it.
    DCHECK_LE(
        context_ex.xstate.offset + sizeof(context_) + sizeof(xsave_header),
        data.size());
    memcpy(&buf[context_ex.xstate.offset + sizeof(context_)],
           &xsave_header,
           sizeof(xsave_header));
  }

  if (!file_writer->Write(data.data(), data.size()))
    return false;

  return true;
}

size_t MinidumpContextAMD64Writer::ContextSize() const {
  DCHECK_GE(state(), kStateFrozen);
  if (xsave_entries_.size() == 0) {
    return sizeof(context_);
  } else {
    DCHECK_EQ(context_.context_flags,
              kMinidumpContextAMD64All | kMinidumpContextAMD64Xstate);
    DCHECK(xsave_entries_.size() != 0);
    size_t size = kMinidumpAMD64XSaveOffset;
    for (auto& entry : xsave_entries_) {
      size += entry->Size();
    }
    return size;
  }
}

bool MinidumpXSaveAMD64CetU::InitializeFromSnapshot(
    const CPUContextX86_64* context_snapshot) {
  // Exception records do not carry CET registers but we have to provide the
  // same shaped context for threads and exception contexts, so both 0 (no ssp
  // present) and 1 (ssp present) are expected.
  DCHECK(context_snapshot->xstate.cet_u.cetmsr == 0ull ||
         context_snapshot->xstate.cet_u.cetmsr == 1ull);
  cet_u_.cetmsr = context_snapshot->xstate.cet_u.cetmsr;
  cet_u_.ssp = context_snapshot->xstate.cet_u.ssp;
  return true;
}

bool MinidumpXSaveAMD64CetU::Copy(void* dst) const {
  memcpy(dst, &cet_u_, sizeof(cet_u_));
  return true;
}

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_);
}

MinidumpContextRISCV64Writer::MinidumpContextRISCV64Writer()
    : MinidumpContextWriter(), context_() {
  context_.context_flags = kMinidumpContextRISCV64;
  context_.version = MinidumpContextRISCV64::kVersion;
}

MinidumpContextRISCV64Writer::~MinidumpContextRISCV64Writer() = default;

void MinidumpContextRISCV64Writer::InitializeFromSnapshot(
    const CPUContextRISCV64* context_snapshot) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK_EQ(context_.context_flags, kMinidumpContextRISCV64);

  context_.context_flags = kMinidumpContextRISCV64All;
  context_.version = MinidumpContextRISCV64::kVersion;
  context_.pc = context_snapshot->pc;

  static_assert(sizeof(context_.regs) == sizeof(context_snapshot->regs),
                "GPRs size mismatch");
  memcpy(context_.regs, context_snapshot->regs, sizeof(context_.regs));

  static_assert(sizeof(context_.fpregs) == sizeof(context_snapshot->fpregs),
                "FPRs size mismatch");
  memcpy(context_.fpregs, context_snapshot->fpregs, sizeof(context_.fpregs));
  context_.fcsr = context_snapshot->fcsr;
}

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

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

}  // namespace crashpad
