// 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 "snapshot/mac/cpu_context_mac.h"

#include <stddef.h>
#include <string.h>

#include "base/logging.h"
#include "base/notreached.h"

namespace crashpad {

#if defined(ARCH_CPU_X86_FAMILY)

namespace {

void InitializeCPUContextX86Thread(
    CPUContextX86* context,
    const x86_thread_state32_t* x86_thread_state32) {
  context->eax = x86_thread_state32->__eax;
  context->ebx = x86_thread_state32->__ebx;
  context->ecx = x86_thread_state32->__ecx;
  context->edx = x86_thread_state32->__edx;
  context->edi = x86_thread_state32->__edi;
  context->esi = x86_thread_state32->__esi;
  context->ebp = x86_thread_state32->__ebp;
  context->esp = x86_thread_state32->__esp;
  context->eip = x86_thread_state32->__eip;
  context->eflags = x86_thread_state32->__eflags;
  context->cs = x86_thread_state32->__cs;
  context->ds = x86_thread_state32->__ds;
  context->es = x86_thread_state32->__es;
  context->fs = x86_thread_state32->__fs;
  context->gs = x86_thread_state32->__gs;
  context->ss = x86_thread_state32->__ss;
}

void InitializeCPUContextX86Float(
    CPUContextX86* context, const x86_float_state32_t* x86_float_state32) {
  // This relies on both x86_float_state32_t and context->fxsave having
  // identical (fxsave) layout.
  static_assert(offsetof(x86_float_state32_t, __fpu_reserved1) -
                         offsetof(x86_float_state32_t, __fpu_fcw) ==
                     sizeof(context->fxsave),
                "types must be equivalent");

  memcpy(
      &context->fxsave, &x86_float_state32->__fpu_fcw, sizeof(context->fxsave));
}

void InitializeCPUContextX86Debug(
    CPUContextX86* context, const x86_debug_state32_t* x86_debug_state32) {
  context->dr0 = x86_debug_state32->__dr0;
  context->dr1 = x86_debug_state32->__dr1;
  context->dr2 = x86_debug_state32->__dr2;
  context->dr3 = x86_debug_state32->__dr3;
  context->dr4 = x86_debug_state32->__dr4;
  context->dr5 = x86_debug_state32->__dr5;
  context->dr6 = x86_debug_state32->__dr6;
  context->dr7 = x86_debug_state32->__dr7;
}

// Initializes |context| from the native thread state structure |state|, which
// is interpreted according to |flavor|. |state_count| must be at least the
// expected size for |flavor|. This handles the architecture-specific
// x86_THREAD_STATE32, x86_FLOAT_STATE32, and x86_DEBUG_STATE32 flavors. It also
// handles the universal x86_THREAD_STATE, x86_FLOAT_STATE, and x86_DEBUG_STATE
// flavors provided that the associated structure carries 32-bit data of the
// corresponding state type. |flavor| may be THREAD_STATE_NONE to avoid setting
// any thread state in |context|. This returns the architecture-specific flavor
// value for the thread state that was actually set, or THREAD_STATE_NONE if no
// thread state was set.
thread_state_flavor_t InitializeCPUContextX86Flavor(
    CPUContextX86* context,
    thread_state_flavor_t flavor,
    ConstThreadState state,
    mach_msg_type_number_t state_count) {
  mach_msg_type_number_t expected_state_count;
  switch (flavor) {
    case x86_THREAD_STATE:
      expected_state_count = x86_THREAD_STATE_COUNT;
      break;
    case x86_FLOAT_STATE:
      expected_state_count = x86_FLOAT_STATE_COUNT;
      break;
    case x86_DEBUG_STATE:
      expected_state_count = x86_DEBUG_STATE_COUNT;
      break;
    case x86_THREAD_STATE32:
      expected_state_count = x86_THREAD_STATE32_COUNT;
      break;
    case x86_FLOAT_STATE32:
      expected_state_count = x86_FLOAT_STATE32_COUNT;
      break;
    case x86_DEBUG_STATE32:
      expected_state_count = x86_DEBUG_STATE32_COUNT;
      break;
    case THREAD_STATE_NONE:
      expected_state_count = 0;
      break;
    default:
      LOG(WARNING) << "unhandled flavor " << flavor;
      return THREAD_STATE_NONE;
  }

  if (state_count < expected_state_count) {
    LOG(WARNING) << "expected state_count " << expected_state_count
                 << " for flavor " << flavor << ", observed " << state_count;
    return THREAD_STATE_NONE;
  }

  switch (flavor) {
    case x86_THREAD_STATE: {
      const x86_thread_state_t* x86_thread_state =
          reinterpret_cast<const x86_thread_state_t*>(state);
      if (x86_thread_state->tsh.flavor != x86_THREAD_STATE32) {
        LOG(WARNING) << "expected flavor x86_THREAD_STATE32, observed "
                     << x86_thread_state->tsh.flavor;
        return THREAD_STATE_NONE;
      }
      return InitializeCPUContextX86Flavor(
          context,
          x86_thread_state->tsh.flavor,
          reinterpret_cast<ConstThreadState>(&x86_thread_state->uts.ts32),
          x86_thread_state->tsh.count);
    }

    case x86_FLOAT_STATE: {
      const x86_float_state_t* x86_float_state =
          reinterpret_cast<const x86_float_state_t*>(state);
      if (x86_float_state->fsh.flavor != x86_FLOAT_STATE32) {
        LOG(WARNING) << "expected flavor x86_FLOAT_STATE32, observed "
                     << x86_float_state->fsh.flavor;
        return THREAD_STATE_NONE;
      }
      return InitializeCPUContextX86Flavor(
          context,
          x86_float_state->fsh.flavor,
          reinterpret_cast<ConstThreadState>(&x86_float_state->ufs.fs32),
          x86_float_state->fsh.count);
    }

    case x86_DEBUG_STATE: {
      const x86_debug_state_t* x86_debug_state =
          reinterpret_cast<const x86_debug_state_t*>(state);
      if (x86_debug_state->dsh.flavor != x86_DEBUG_STATE32) {
        LOG(WARNING) << "expected flavor x86_DEBUG_STATE32, observed "
                     << x86_debug_state->dsh.flavor;
        return THREAD_STATE_NONE;
      }
      return InitializeCPUContextX86Flavor(
          context,
          x86_debug_state->dsh.flavor,
          reinterpret_cast<ConstThreadState>(&x86_debug_state->uds.ds32),
          x86_debug_state->dsh.count);
    }

    case x86_THREAD_STATE32: {
      const x86_thread_state32_t* x86_thread_state32 =
          reinterpret_cast<const x86_thread_state32_t*>(state);
      InitializeCPUContextX86Thread(context, x86_thread_state32);
      return flavor;
    }

    case x86_FLOAT_STATE32: {
      const x86_float_state32_t* x86_float_state32 =
          reinterpret_cast<const x86_float_state32_t*>(state);
      InitializeCPUContextX86Float(context, x86_float_state32);
      return flavor;
    }

    case x86_DEBUG_STATE32: {
      const x86_debug_state32_t* x86_debug_state32 =
          reinterpret_cast<const x86_debug_state32_t*>(state);
      InitializeCPUContextX86Debug(context, x86_debug_state32);
      return flavor;
    }

    case THREAD_STATE_NONE: {
      // This may happen without error when called without exception-style
      // flavor data, or even from an exception handler when the exception
      // behavior is EXCEPTION_DEFAULT.
      return flavor;
    }

    default: {
      NOTREACHED();
    }
  }
}

void InitializeCPUContextX86_64Thread(
    CPUContextX86_64* context, const x86_thread_state64_t* x86_thread_state64) {
  context->rax = x86_thread_state64->__rax;
  context->rbx = x86_thread_state64->__rbx;
  context->rcx = x86_thread_state64->__rcx;
  context->rdx = x86_thread_state64->__rdx;
  context->rdi = x86_thread_state64->__rdi;
  context->rsi = x86_thread_state64->__rsi;
  context->rbp = x86_thread_state64->__rbp;
  context->rsp = x86_thread_state64->__rsp;
  context->r8 = x86_thread_state64->__r8;
  context->r9 = x86_thread_state64->__r9;
  context->r10 = x86_thread_state64->__r10;
  context->r11 = x86_thread_state64->__r11;
  context->r12 = x86_thread_state64->__r12;
  context->r13 = x86_thread_state64->__r13;
  context->r14 = x86_thread_state64->__r14;
  context->r15 = x86_thread_state64->__r15;
  context->rip = x86_thread_state64->__rip;
  context->rflags = x86_thread_state64->__rflags;
  context->cs = x86_thread_state64->__cs;
  context->fs = x86_thread_state64->__fs;
  context->gs = x86_thread_state64->__gs;
}

void InitializeCPUContextX86_64Float(
    CPUContextX86_64* context, const x86_float_state64_t* x86_float_state64) {
  // This relies on both x86_float_state64_t and context->fxsave having
  // identical (fxsave) layout.
  static_assert(offsetof(x86_float_state64_t, __fpu_reserved1) -
                         offsetof(x86_float_state64_t, __fpu_fcw) ==
                     sizeof(context->fxsave),
                "types must be equivalent");

  memcpy(&context->fxsave,
         &x86_float_state64->__fpu_fcw,
         sizeof(context->fxsave));
}

void InitializeCPUContextX86_64Debug(
    CPUContextX86_64* context, const x86_debug_state64_t* x86_debug_state64) {
  context->dr0 = x86_debug_state64->__dr0;
  context->dr1 = x86_debug_state64->__dr1;
  context->dr2 = x86_debug_state64->__dr2;
  context->dr3 = x86_debug_state64->__dr3;
  context->dr4 = x86_debug_state64->__dr4;
  context->dr5 = x86_debug_state64->__dr5;
  context->dr6 = x86_debug_state64->__dr6;
  context->dr7 = x86_debug_state64->__dr7;
}

// Initializes |context| from the native thread state structure |state|, which
// is interpreted according to |flavor|. |state_count| must be at least the
// expected size for |flavor|. This handles the architecture-specific
// x86_THREAD_STATE64, x86_FLOAT_STATE64, and x86_DEBUG_STATE64 flavors. It also
// handles the universal x86_THREAD_STATE, x86_FLOAT_STATE, and x86_DEBUG_STATE
// flavors provided that the associated structure carries 64-bit data of the
// corresponding state type. |flavor| may be THREAD_STATE_NONE to avoid setting
// any thread state in |context|. This returns the architecture-specific flavor
// value for the thread state that was actually set, or THREAD_STATE_NONE if no
// thread state was set.
thread_state_flavor_t InitializeCPUContextX86_64Flavor(
    CPUContextX86_64* context,
    thread_state_flavor_t flavor,
    ConstThreadState state,
    mach_msg_type_number_t state_count) {
  mach_msg_type_number_t expected_state_count;
  switch (flavor) {
    case x86_THREAD_STATE:
      expected_state_count = x86_THREAD_STATE_COUNT;
      break;
    case x86_FLOAT_STATE:
      expected_state_count = x86_FLOAT_STATE_COUNT;
      break;
    case x86_DEBUG_STATE:
      expected_state_count = x86_DEBUG_STATE_COUNT;
      break;
    case x86_THREAD_STATE64:
      expected_state_count = x86_THREAD_STATE64_COUNT;
      break;
    case x86_FLOAT_STATE64:
      expected_state_count = x86_FLOAT_STATE64_COUNT;
      break;
    case x86_DEBUG_STATE64:
      expected_state_count = x86_DEBUG_STATE64_COUNT;
      break;
    case THREAD_STATE_NONE:
      expected_state_count = 0;
      break;
    default:
      LOG(WARNING) << "unhandled flavor " << flavor;
      return THREAD_STATE_NONE;
  }

  if (state_count < expected_state_count) {
    LOG(WARNING) << "expected state_count " << expected_state_count
                 << " for flavor " << flavor << ", observed " << state_count;
    return THREAD_STATE_NONE;
  }

  switch (flavor) {
    case x86_THREAD_STATE: {
      const x86_thread_state_t* x86_thread_state =
          reinterpret_cast<const x86_thread_state_t*>(state);
      if (x86_thread_state->tsh.flavor != x86_THREAD_STATE64) {
        LOG(WARNING) << "expected flavor x86_THREAD_STATE64, observed "
                     << x86_thread_state->tsh.flavor;
        return THREAD_STATE_NONE;
      }
      return InitializeCPUContextX86_64Flavor(
          context,
          x86_thread_state->tsh.flavor,
          reinterpret_cast<ConstThreadState>(&x86_thread_state->uts.ts64),
          x86_thread_state->tsh.count);
    }

    case x86_FLOAT_STATE: {
      const x86_float_state_t* x86_float_state =
          reinterpret_cast<const x86_float_state_t*>(state);
      if (x86_float_state->fsh.flavor != x86_FLOAT_STATE64) {
        LOG(WARNING) << "expected flavor x86_FLOAT_STATE64, observed "
                     << x86_float_state->fsh.flavor;
        return THREAD_STATE_NONE;
      }
      return InitializeCPUContextX86_64Flavor(
          context,
          x86_float_state->fsh.flavor,
          reinterpret_cast<ConstThreadState>(&x86_float_state->ufs.fs64),
          x86_float_state->fsh.count);
    }

    case x86_DEBUG_STATE: {
      const x86_debug_state_t* x86_debug_state =
          reinterpret_cast<const x86_debug_state_t*>(state);
      if (x86_debug_state->dsh.flavor != x86_DEBUG_STATE64) {
        LOG(WARNING) << "expected flavor x86_DEBUG_STATE64, observed "
                     << x86_debug_state->dsh.flavor;
        return THREAD_STATE_NONE;
      }
      return InitializeCPUContextX86_64Flavor(
          context,
          x86_debug_state->dsh.flavor,
          reinterpret_cast<ConstThreadState>(&x86_debug_state->uds.ds64),
          x86_debug_state->dsh.count);
    }

    case x86_THREAD_STATE64: {
      const x86_thread_state64_t* x86_thread_state64 =
          reinterpret_cast<const x86_thread_state64_t*>(state);
      InitializeCPUContextX86_64Thread(context, x86_thread_state64);
      return flavor;
    }

    case x86_FLOAT_STATE64: {
      const x86_float_state64_t* x86_float_state64 =
          reinterpret_cast<const x86_float_state64_t*>(state);
      InitializeCPUContextX86_64Float(context, x86_float_state64);
      return flavor;
    }

    case x86_DEBUG_STATE64: {
      const x86_debug_state64_t* x86_debug_state64 =
          reinterpret_cast<const x86_debug_state64_t*>(state);
      InitializeCPUContextX86_64Debug(context, x86_debug_state64);
      return flavor;
    }

    case THREAD_STATE_NONE: {
      // This may happen without error when called without exception-style
      // flavor data, or even from an exception handler when the exception
      // behavior is EXCEPTION_DEFAULT.
      return flavor;
    }

    default: {
      NOTREACHED();
    }
  }
}

}  // namespace

namespace internal {

void InitializeCPUContextX86(CPUContextX86* context,
                             thread_state_flavor_t flavor,
                             ConstThreadState state,
                             mach_msg_type_number_t state_count,
                             const x86_thread_state32_t* x86_thread_state32,
                             const x86_float_state32_t* x86_float_state32,
                             const x86_debug_state32_t* x86_debug_state32) {
  thread_state_flavor_t set_flavor = THREAD_STATE_NONE;
  if (flavor != THREAD_STATE_NONE) {
    set_flavor =
        InitializeCPUContextX86Flavor(context, flavor, state, state_count);
  }

  if (set_flavor != x86_THREAD_STATE32) {
    InitializeCPUContextX86Thread(context, x86_thread_state32);
  }
  if (set_flavor != x86_FLOAT_STATE32) {
    InitializeCPUContextX86Float(context, x86_float_state32);
  }
  if (set_flavor != x86_DEBUG_STATE32) {
    InitializeCPUContextX86Debug(context, x86_debug_state32);
  }
}

void InitializeCPUContextX86_64(CPUContextX86_64* context,
                                thread_state_flavor_t flavor,
                                ConstThreadState state,
                                mach_msg_type_number_t state_count,
                                const x86_thread_state64_t* x86_thread_state64,
                                const x86_float_state64_t* x86_float_state64,
                                const x86_debug_state64_t* x86_debug_state64) {
  thread_state_flavor_t set_flavor = THREAD_STATE_NONE;
  if (flavor != THREAD_STATE_NONE) {
    set_flavor =
        InitializeCPUContextX86_64Flavor(context, flavor, state, state_count);
  }

  if (set_flavor != x86_THREAD_STATE64) {
    InitializeCPUContextX86_64Thread(context, x86_thread_state64);
  }
  if (set_flavor != x86_FLOAT_STATE64) {
    InitializeCPUContextX86_64Float(context, x86_float_state64);
  }
  if (set_flavor != x86_DEBUG_STATE64) {
    InitializeCPUContextX86_64Debug(context, x86_debug_state64);
  }
}

}  // namespace internal

#elif defined(ARCH_CPU_ARM64)

namespace {

void InitializeCPUContextARM64Thread(
    CPUContextARM64* context,
    const arm_thread_state64_t* arm_thread_state64) {
  // The first 29 fields of context->regs is laid out identically to
  // arm_thread_state64->__x.
  memcpy(
      context->regs, arm_thread_state64->__x, sizeof(arm_thread_state64->__x));

  context->regs[29] = arm_thread_state64_get_fp(*arm_thread_state64);
  context->regs[30] = arm_thread_state64_get_lr(*arm_thread_state64);
  context->sp = arm_thread_state64_get_sp(*arm_thread_state64);
  context->pc = arm_thread_state64_get_pc(*arm_thread_state64);
  context->spsr =
      static_cast<decltype(context->spsr)>(arm_thread_state64->__cpsr);
}

void InitializeCPUContextARM64Neon(CPUContextARM64* context,
                                   const arm_neon_state64_t* arm_neon_state64) {
  static_assert(sizeof(context->fpsimd) == sizeof(arm_neon_state64->__v),
                "fpsimd context size mismatch");
  memcpy(context->fpsimd, arm_neon_state64->__v, sizeof(arm_neon_state64->__v));
  context->fpsr = arm_neon_state64->__fpsr;
  context->fpcr = arm_neon_state64->__fpcr;
}

void InitializeCPUContextARM64Debug(
    CPUContextARM64* context,
    const arm_debug_state64_t* arm_debug_state64) {
  // TODO(macos_arm64): Create a spot in CPUContextARM64 to keep this.
}

thread_state_flavor_t InitializeCPUContextARM64Flavor(
    CPUContextARM64* context,
    thread_state_flavor_t flavor,
    ConstThreadState state,
    mach_msg_type_number_t state_count) {
  mach_msg_type_number_t expected_state_count;
  switch (flavor) {
    case ARM_UNIFIED_THREAD_STATE:
      expected_state_count = ARM_UNIFIED_THREAD_STATE_COUNT;
      break;
    case ARM_THREAD_STATE64:
      expected_state_count = ARM_THREAD_STATE64_COUNT;
      break;
    case ARM_NEON_STATE64:
      expected_state_count = ARM_NEON_STATE64_COUNT;
      break;
    case ARM_DEBUG_STATE64:
      expected_state_count = ARM_DEBUG_STATE64_COUNT;
      break;
    case THREAD_STATE_NONE: {
      // This may happen without error when called without exception-style
      // flavor data, or even from an exception handler when the exception
      // behavior is EXCEPTION_DEFAULT.
      return flavor;
    }
    default:
      LOG(WARNING) << "unhandled flavor " << flavor;
      return THREAD_STATE_NONE;
  }

  if (state_count < expected_state_count) {
    LOG(WARNING) << "expected state_count " << expected_state_count
                 << " for flavor " << flavor << ", observed " << state_count;
    return THREAD_STATE_NONE;
  }

  switch (flavor) {
    case ARM_UNIFIED_THREAD_STATE: {
      const arm_unified_thread_state_t* arm_thread_state =
          reinterpret_cast<const arm_unified_thread_state_t*>(state);
      if (arm_thread_state->ash.flavor != ARM_THREAD_STATE64) {
        LOG(WARNING) << "expected flavor ARM_THREAD_STATE64, observed "
                     << arm_thread_state->ash.flavor;
        return THREAD_STATE_NONE;
      }
      return InitializeCPUContextARM64Flavor(
          context,
          arm_thread_state->ash.flavor,
          reinterpret_cast<ConstThreadState>(&arm_thread_state->ts_64),
          arm_thread_state->ash.count);
    }

    case ARM_THREAD_STATE64: {
      const arm_thread_state64_t* arm_thread_state =
          reinterpret_cast<const arm_thread_state64_t*>(state);
      InitializeCPUContextARM64Thread(context, arm_thread_state);
      return ARM_THREAD_STATE64;
    }

    case ARM_NEON_STATE64: {
      const arm_neon_state64_t* arm_neon_state =
          reinterpret_cast<const arm_neon_state64_t*>(state);
      InitializeCPUContextARM64Neon(context, arm_neon_state);
      return ARM_NEON_STATE64;
    }

    case ARM_DEBUG_STATE64: {
      const arm_debug_state64_t* arm_debug_state =
          reinterpret_cast<const arm_debug_state64_t*>(state);
      InitializeCPUContextARM64Debug(context, arm_debug_state);
      return ARM_DEBUG_STATE64;
    }

    case THREAD_STATE_NONE: {
      // This may happen without error when called without exception-style
      // flavor data, or even from an exception handler when the exception
      // behavior is EXCEPTION_DEFAULT.
      return flavor;
    }

    default: {
      NOTREACHED();
    }
  }
}

}  // namespace

namespace internal {

void InitializeCPUContextARM64(CPUContextARM64* context,
                               thread_state_flavor_t flavor,
                               ConstThreadState state,
                               mach_msg_type_number_t state_count,
                               const arm_thread_state64_t* arm_thread_state64,
                               const arm_neon_state64_t* arm_neon_state64,
                               const arm_debug_state64_t* arm_debug_state64) {
  thread_state_flavor_t set_flavor = THREAD_STATE_NONE;
  if (flavor != THREAD_STATE_NONE) {
    set_flavor =
        InitializeCPUContextARM64Flavor(context, flavor, state, state_count);
  }

  if (set_flavor != ARM_THREAD_STATE64) {
    InitializeCPUContextARM64Thread(context, arm_thread_state64);
  }
  if (set_flavor != ARM_NEON_STATE64) {
    InitializeCPUContextARM64Neon(context, arm_neon_state64);
  }
  if (set_flavor != ARM_DEBUG_STATE64) {
    InitializeCPUContextARM64Debug(context, arm_debug_state64);
  }
}

}  // namespace internal

#endif

}  // namespace crashpad
