//===-- NativeRegisterContextLinux_x86.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#if defined(__i386__) || defined(__x86_64__)

#include "NativeRegisterContextLinux_x86.h"

#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/Linux/NativeThreadLinux.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"

#include <algorithm>
#include <optional>

// System includes - They have to be included after framework includes because
// they define some macros which collide with variable names in other modules.
#include <asm/ldt.h>
#include <cpuid.h>
#include <linux/elf.h>
#include <sys/ptrace.h>

#ifndef PTRACE_GET_THREAD_AREA
#define PTRACE_GET_THREAD_AREA 25
#endif

// Newer toolchains define __get_cpuid_count in cpuid.h, but some
// older-but-still-supported ones (e.g. gcc 5.4.0) don't, so we
// define it locally here, following the definition in clang/lib/Headers.
static inline int get_cpuid_count(unsigned int __leaf,
                                  unsigned int __subleaf,
                                  unsigned int *__eax, unsigned int *__ebx,
                                  unsigned int *__ecx, unsigned int *__edx)
{
  unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, nullptr);

  if (__max_leaf == 0 || __max_leaf < __leaf)
    return 0;

  __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
  return 1;
}

using namespace lldb_private;
using namespace lldb_private::process_linux;

// Linux exposes the i386 thread pointer as a synthetic register between the
// always-available FPU registers and the optional extended register sets.
constexpr uint32_t k_i386_thread_pointer_index = k_first_avx_i386;

// x86 32-bit general purpose registers.
static const uint32_t g_gpr_regnums_i386[] = {
    lldb_eax_i386,      lldb_ebx_i386,    lldb_ecx_i386, lldb_edx_i386,
    lldb_edi_i386,      lldb_esi_i386,    lldb_ebp_i386, lldb_esp_i386,
    lldb_eip_i386,      lldb_eflags_i386, lldb_cs_i386,  lldb_fs_i386,
    lldb_gs_i386,       lldb_ss_i386,     lldb_ds_i386,  lldb_es_i386,
    lldb_ax_i386,       lldb_bx_i386,     lldb_cx_i386,  lldb_dx_i386,
    lldb_di_i386,       lldb_si_i386,     lldb_bp_i386,  lldb_sp_i386,
    lldb_ah_i386,       lldb_bh_i386,     lldb_ch_i386,  lldb_dh_i386,
    lldb_al_i386,       lldb_bl_i386,     lldb_cl_i386,  lldb_dl_i386,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
                      1 ==
                  k_num_gpr_registers_i386,
              "g_gpr_regnums_i386 has wrong number of register infos");

// x86 32-bit floating point registers.
static const uint32_t g_fpu_regnums_i386[] = {
    lldb_fctrl_i386,    lldb_fstat_i386,     lldb_ftag_i386,  lldb_fop_i386,
    lldb_fiseg_i386,    lldb_fioff_i386,     lldb_foseg_i386, lldb_fooff_i386,
    lldb_mxcsr_i386,    lldb_mxcsrmask_i386, lldb_st0_i386,   lldb_st1_i386,
    lldb_st2_i386,      lldb_st3_i386,       lldb_st4_i386,   lldb_st5_i386,
    lldb_st6_i386,      lldb_st7_i386,       lldb_mm0_i386,   lldb_mm1_i386,
    lldb_mm2_i386,      lldb_mm3_i386,       lldb_mm4_i386,   lldb_mm5_i386,
    lldb_mm6_i386,      lldb_mm7_i386,       lldb_xmm0_i386,  lldb_xmm1_i386,
    lldb_xmm2_i386,     lldb_xmm3_i386,      lldb_xmm4_i386,  lldb_xmm5_i386,
    lldb_xmm6_i386,     lldb_xmm7_i386,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
                      1 ==
                  k_num_fpr_registers_i386,
              "g_fpu_regnums_i386 has wrong number of register infos");

// x86 32-bit AVX registers.
static const uint32_t g_avx_regnums_i386[] = {
    lldb_ymm0_i386,     lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
    lldb_ymm4_i386,     lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
                      1 ==
                  k_num_avx_registers_i386,
              " g_avx_regnums_i386 has wrong number of register infos");

// x64 32-bit MPX registers.
static const uint32_t g_mpx_regnums_i386[] = {
    lldb_bnd0_i386,     lldb_bnd1_i386, lldb_bnd2_i386, lldb_bnd3_i386,
    lldb_bndcfgu_i386,  lldb_bndstatus_i386,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
                      1 ==
                  k_num_mpx_registers_i386,
              "g_mpx_regnums_x86_64 has wrong number of register infos");

// x86 64-bit general purpose registers.
static const uint32_t g_gpr_regnums_x86_64[] = {
    x86_64_with_base::lldb_rax,    x86_64_with_base::lldb_rbx,    x86_64_with_base::lldb_rcx, x86_64_with_base::lldb_rdx,
    x86_64_with_base::lldb_rdi,    x86_64_with_base::lldb_rsi,    x86_64_with_base::lldb_rbp, x86_64_with_base::lldb_rsp,
    x86_64_with_base::lldb_r8,     x86_64_with_base::lldb_r9,     x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r11,
    x86_64_with_base::lldb_r12,    x86_64_with_base::lldb_r13,    x86_64_with_base::lldb_r14, x86_64_with_base::lldb_r15,
    x86_64_with_base::lldb_rip,    x86_64_with_base::lldb_rflags, x86_64_with_base::lldb_cs,  x86_64_with_base::lldb_fs,
    x86_64_with_base::lldb_gs,     x86_64_with_base::lldb_ss,     x86_64_with_base::lldb_fs_base, x86_64_with_base::lldb_gs_base,
    x86_64_with_base::lldb_ds,  x86_64_with_base::lldb_es,
    x86_64_with_base::lldb_eax,    x86_64_with_base::lldb_ebx,    x86_64_with_base::lldb_ecx, x86_64_with_base::lldb_edx,
    x86_64_with_base::lldb_edi,    x86_64_with_base::lldb_esi,    x86_64_with_base::lldb_ebp, x86_64_with_base::lldb_esp,
    x86_64_with_base::lldb_r8d,  // Low 32 bits or r8
    x86_64_with_base::lldb_r9d,  // Low 32 bits or r9
    x86_64_with_base::lldb_r10d, // Low 32 bits or r10
    x86_64_with_base::lldb_r11d, // Low 32 bits or r11
    x86_64_with_base::lldb_r12d, // Low 32 bits or r12
    x86_64_with_base::lldb_r13d, // Low 32 bits or r13
    x86_64_with_base::lldb_r14d, // Low 32 bits or r14
    x86_64_with_base::lldb_r15d, // Low 32 bits or r15
    x86_64_with_base::lldb_ax,     x86_64_with_base::lldb_bx,     x86_64_with_base::lldb_cx,  x86_64_with_base::lldb_dx,
    x86_64_with_base::lldb_di,     x86_64_with_base::lldb_si,     x86_64_with_base::lldb_bp,  x86_64_with_base::lldb_sp,
    x86_64_with_base::lldb_r8w,  // Low 16 bits or r8
    x86_64_with_base::lldb_r9w,  // Low 16 bits or r9
    x86_64_with_base::lldb_r10w, // Low 16 bits or r10
    x86_64_with_base::lldb_r11w, // Low 16 bits or r11
    x86_64_with_base::lldb_r12w, // Low 16 bits or r12
    x86_64_with_base::lldb_r13w, // Low 16 bits or r13
    x86_64_with_base::lldb_r14w, // Low 16 bits or r14
    x86_64_with_base::lldb_r15w, // Low 16 bits or r15
    x86_64_with_base::lldb_ah,     x86_64_with_base::lldb_bh,     x86_64_with_base::lldb_ch,  x86_64_with_base::lldb_dh,
    x86_64_with_base::lldb_al,     x86_64_with_base::lldb_bl,     x86_64_with_base::lldb_cl,  x86_64_with_base::lldb_dl,
    x86_64_with_base::lldb_dil,    x86_64_with_base::lldb_sil,    x86_64_with_base::lldb_bpl, x86_64_with_base::lldb_spl,
    x86_64_with_base::lldb_r8l,    // Low 8 bits or r8
    x86_64_with_base::lldb_r9l,    // Low 8 bits or r9
    x86_64_with_base::lldb_r10l,   // Low 8 bits or r10
    x86_64_with_base::lldb_r11l,   // Low 8 bits or r11
    x86_64_with_base::lldb_r12l,   // Low 8 bits or r12
    x86_64_with_base::lldb_r13l,   // Low 8 bits or r13
    x86_64_with_base::lldb_r14l,   // Low 8 bits or r14
    x86_64_with_base::lldb_r15l,   // Low 8 bits or r15
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
                      1 ==
                  x86_64_with_base::k_num_gpr_registers,
              "g_gpr_regnums_x86_64 has wrong number of register infos");

// x86 64-bit floating point registers.
static const uint32_t g_fpu_regnums_x86_64[] = {
    x86_64_with_base::lldb_fctrl,  x86_64_with_base::lldb_fstat, x86_64_with_base::lldb_ftag,
    x86_64_with_base::lldb_fop,    x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff,
    x86_64_with_base::lldb_fip,    x86_64_with_base::lldb_foseg, x86_64_with_base::lldb_fooff,
    x86_64_with_base::lldb_fdp,    x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask,
    x86_64_with_base::lldb_st0,    x86_64_with_base::lldb_st1,   x86_64_with_base::lldb_st2,
    x86_64_with_base::lldb_st3,    x86_64_with_base::lldb_st4,   x86_64_with_base::lldb_st5,
    x86_64_with_base::lldb_st6,    x86_64_with_base::lldb_st7,   x86_64_with_base::lldb_mm0,
    x86_64_with_base::lldb_mm1,    x86_64_with_base::lldb_mm2,   x86_64_with_base::lldb_mm3,
    x86_64_with_base::lldb_mm4,    x86_64_with_base::lldb_mm5,   x86_64_with_base::lldb_mm6,
    x86_64_with_base::lldb_mm7,    x86_64_with_base::lldb_xmm0,  x86_64_with_base::lldb_xmm1,
    x86_64_with_base::lldb_xmm2,   x86_64_with_base::lldb_xmm3,  x86_64_with_base::lldb_xmm4,
    x86_64_with_base::lldb_xmm5,   x86_64_with_base::lldb_xmm6,  x86_64_with_base::lldb_xmm7,
    x86_64_with_base::lldb_xmm8,   x86_64_with_base::lldb_xmm9,  x86_64_with_base::lldb_xmm10,
    x86_64_with_base::lldb_xmm11,  x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13,
    x86_64_with_base::lldb_xmm14,  x86_64_with_base::lldb_xmm15,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
                      1 ==
                  x86_64_with_base::k_num_fpr_registers,
              "g_fpu_regnums_x86_64 has wrong number of register infos");

// x86 64-bit AVX registers.
static const uint32_t g_avx_regnums_x86_64[] = {
    x86_64_with_base::lldb_ymm0,   x86_64_with_base::lldb_ymm1,  x86_64_with_base::lldb_ymm2,  x86_64_with_base::lldb_ymm3,
    x86_64_with_base::lldb_ymm4,   x86_64_with_base::lldb_ymm5,  x86_64_with_base::lldb_ymm6,  x86_64_with_base::lldb_ymm7,
    x86_64_with_base::lldb_ymm8,   x86_64_with_base::lldb_ymm9,  x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11,
    x86_64_with_base::lldb_ymm12,  x86_64_with_base::lldb_ymm13, x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
                      1 ==
                  x86_64_with_base::k_num_avx_registers,
              "g_avx_regnums_x86_64 has wrong number of register infos");

// x86 64-bit MPX registers.
static const uint32_t g_mpx_regnums_x86_64[] = {
    x86_64_with_base::lldb_bnd0,    x86_64_with_base::lldb_bnd1,    x86_64_with_base::lldb_bnd2,
    x86_64_with_base::lldb_bnd3,    x86_64_with_base::lldb_bndcfgu, x86_64_with_base::lldb_bndstatus,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
                      1 ==
                  x86_64_with_base::k_num_mpx_registers,
              "g_mpx_regnums_x86_64 has wrong number of register infos");

// Number of register sets provided by this context.
constexpr unsigned k_num_extended_register_sets = 2, k_num_register_sets = 4;

// Register sets for x86 32-bit.
static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
    {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
     g_gpr_regnums_i386},
    {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
     g_fpu_regnums_i386},
    {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
     g_avx_regnums_i386},
    { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
     g_mpx_regnums_i386}};

// Register sets for x86 64-bit.
static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
    {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers,
     g_gpr_regnums_x86_64},
    {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers,
     g_fpu_regnums_x86_64},
    {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers,
     g_avx_regnums_x86_64},
    { "Memory Protection Extensions", "mpx", x86_64_with_base::k_num_mpx_registers,
     g_mpx_regnums_x86_64}};

#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))

// Required ptrace defines.

// Support ptrace extensions even when compiled without required kernel support
#ifndef NT_X86_XSTATE
#define NT_X86_XSTATE 0x202
#endif
#ifndef NT_PRXFPREG
#define NT_PRXFPREG 0x46e62b7f
#endif

// On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to
// use NT_PRXFPREG.
static inline unsigned int fxsr_regset(const ArchSpec &arch) {
  return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;
}

// Required MPX define.

// Support MPX extensions also if compiled with compiler without MPX support.
#ifndef bit_MPX
#define bit_MPX 0x4000
#endif

// XCR0 extended register sets masks.
#define mask_XSTATE_AVX (1ULL << 2)
#define mask_XSTATE_BNDREGS (1ULL << 3)
#define mask_XSTATE_BNDCFG (1ULL << 4)
#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)

std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
    const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
  return std::unique_ptr<NativeRegisterContextLinux>(
      new NativeRegisterContextLinux_x86(target_arch, native_thread));
}

llvm::Expected<ArchSpec>
NativeRegisterContextLinux::DetermineArchitecture(lldb::tid_t tid) {
  return DetermineArchitectureViaGPR(
      tid, RegisterContextLinux_x86_64::GetGPRSizeStatic());
}

// NativeRegisterContextLinux_x86 members.

static std::unique_ptr<RegisterContextLinux_x86>
CreateRegisterInfoInterface(const ArchSpec &target_arch) {
  if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
    // 32-bit hosts run with a RegisterContextLinux_i386 context.
    return std::make_unique<RegisterContextLinux_i386>(target_arch);
  } else {
    assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
           "Register setting path assumes this is a 64-bit host");
    // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
    // x86_64 register context.
    return std::make_unique<RegisterContextLinux_x86_64>(target_arch);
  }
}

// Return the size of the XSTATE area supported on this cpu. It is necessary to
// allocate the full size of the area even if we do not use/recognise all of it
// because ptrace(PTRACE_SETREGSET, NT_X86_XSTATE) will refuse to write to it if
// we do not pass it a buffer of sufficient size. The size is always at least
// sizeof(FPR) so that the allocated buffer can be safely cast to FPR*.
static std::size_t GetXSTATESize() {
  unsigned int eax, ebx, ecx, edx;
  // First check whether the XSTATE are is supported at all.
  if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx) || !(ecx & bit_XSAVE))
    return sizeof(FPR);

  // Then fetch the maximum size of the area.
  if (!get_cpuid_count(0x0d, 0, &eax, &ebx, &ecx, &edx))
    return sizeof(FPR);
  return std::max<std::size_t>(ecx, sizeof(FPR));
}

NativeRegisterContextLinux_x86::NativeRegisterContextLinux_x86(
    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
    : NativeRegisterContextRegisterInfo(
          native_thread, CreateRegisterInfoInterface(target_arch).release()),
      NativeRegisterContextLinux(native_thread),
      m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(),
      m_reg_info(), m_gpr_x86_64() {
  // Set up data about ranges of valid registers.
  switch (target_arch.GetMachine()) {
  case llvm::Triple::x86: {
    const RegisterInfoInterface &register_info = GetRegisterInfoInterface();
    // Place the synthetic value after all existing user data so existing
    // g-packet offsets remain unchanged.
    uint32_t byte_offset = 0;
    for (uint32_t i = 0; i < register_info.GetUserRegisterCount(); ++i) {
      const RegisterInfo &info = register_info.GetRegisterInfo()[i];
      byte_offset = std::max(byte_offset, info.byte_offset + info.byte_size);
    }
    m_i386_thread_pointer_info = {"gs_base",
                                  nullptr,
                                  sizeof(uint32_t),
                                  byte_offset,
                                  lldb::eEncodingUint,
                                  lldb::eFormatHex,
                                  {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
                                   LLDB_REGNUM_GENERIC_TP, LLDB_INVALID_REGNUM,
                                   LLDB_INVALID_REGNUM},
                                  nullptr,
                                  nullptr,
                                  nullptr};

    m_reg_info.num_registers = k_num_registers_i386 + 1;
    m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
    m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
    m_reg_info.num_avx_registers = k_num_avx_registers_i386;
    m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;
    m_reg_info.last_gpr = k_last_gpr_i386;
    m_reg_info.first_fpr = k_first_fpr_i386;
    m_reg_info.last_fpr = k_last_fpr_i386;
    m_reg_info.first_st = lldb_st0_i386;
    m_reg_info.last_st = lldb_st7_i386;
    m_reg_info.first_mm = lldb_mm0_i386;
    m_reg_info.last_mm = lldb_mm7_i386;
    m_reg_info.first_xmm = lldb_xmm0_i386;
    m_reg_info.last_xmm = lldb_xmm7_i386;
    m_reg_info.first_ymm = lldb_ymm0_i386;
    m_reg_info.last_ymm = lldb_ymm7_i386;
    m_reg_info.first_mpxr = lldb_bnd0_i386;
    m_reg_info.last_mpxr = lldb_bnd3_i386;
    m_reg_info.first_mpxc = lldb_bndcfgu_i386;
    m_reg_info.last_mpxc = lldb_bndstatus_i386;
    m_reg_info.first_dr = lldb_dr0_i386;
    m_reg_info.last_dr = lldb_dr7_i386;
    m_reg_info.gpr_flags = lldb_eflags_i386;
    break;
  }
  case llvm::Triple::x86_64:
    m_reg_info.num_registers = x86_64_with_base::k_num_registers;
    m_reg_info.num_gpr_registers = x86_64_with_base::k_num_gpr_registers;
    m_reg_info.num_fpr_registers = x86_64_with_base::k_num_fpr_registers;
    m_reg_info.num_avx_registers = x86_64_with_base::k_num_avx_registers;
    m_reg_info.num_mpx_registers = x86_64_with_base::k_num_mpx_registers;
    m_reg_info.last_gpr = x86_64_with_base::k_last_gpr;
    m_reg_info.first_fpr = x86_64_with_base::k_first_fpr;
    m_reg_info.last_fpr = x86_64_with_base::k_last_fpr;
    m_reg_info.first_st = x86_64_with_base::lldb_st0;
    m_reg_info.last_st = x86_64_with_base::lldb_st7;
    m_reg_info.first_mm = x86_64_with_base::lldb_mm0;
    m_reg_info.last_mm = x86_64_with_base::lldb_mm7;
    m_reg_info.first_xmm = x86_64_with_base::lldb_xmm0;
    m_reg_info.last_xmm = x86_64_with_base::lldb_xmm15;
    m_reg_info.first_ymm = x86_64_with_base::lldb_ymm0;
    m_reg_info.last_ymm = x86_64_with_base::lldb_ymm15;
    m_reg_info.first_mpxr = x86_64_with_base::lldb_bnd0;
    m_reg_info.last_mpxr = x86_64_with_base::lldb_bnd3;
    m_reg_info.first_mpxc = x86_64_with_base::lldb_bndcfgu;
    m_reg_info.last_mpxc = x86_64_with_base::lldb_bndstatus;
    m_reg_info.first_dr = x86_64_with_base::lldb_dr0;
    m_reg_info.last_dr = x86_64_with_base::lldb_dr7;
    m_reg_info.gpr_flags = x86_64_with_base::lldb_rflags;
    break;
  default:
    assert(false && "Unhandled target architecture.");
    break;
  }

  std::size_t xstate_size = GetXSTATESize();
  m_xstate.reset(static_cast<FPR *>(std::malloc(xstate_size)));
  m_iovec.iov_base = m_xstate.get();
  m_iovec.iov_len = xstate_size;

  // Clear out the FPR state.
  ::memset(m_xstate.get(), 0, xstate_size);

  // Store byte offset of fctrl (i.e. first register of FPR)
  const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
  m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
}

uint32_t NativeRegisterContextLinux_x86::GetRegisterCount() const {
  uint32_t count = NativeRegisterContextRegisterInfo::GetRegisterCount();
  if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
      llvm::Triple::x86)
    ++count;
  return count;
}

const RegisterInfo *
NativeRegisterContextLinux_x86::GetRegisterInfoAtIndex(uint32_t reg) const {
  if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
      llvm::Triple::x86) {
    if (reg == k_i386_thread_pointer_index)
      return &m_i386_thread_pointer_info;
    // Translate the public index back to the unchanged underlying table.
    if (reg > k_i386_thread_pointer_index)
      --reg;
  }
  return NativeRegisterContextRegisterInfo::GetRegisterInfoAtIndex(reg);
}

// CONSIDER after local and llgs debugging are merged, register set support can
// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
uint32_t NativeRegisterContextLinux_x86::GetRegisterSetCount() const {
  uint32_t sets = 0;
  for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
    if (IsRegisterSetAvailable(set_index))
      ++sets;
  }

  return sets;
}

uint32_t NativeRegisterContextLinux_x86::GetUserRegisterCount() const {
  uint32_t count = 0;
  for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
    const RegisterSet *set = GetRegisterSet(set_index);
    if (set)
      count += set->num_registers;
  }
  if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
      llvm::Triple::x86)
    ++count;
  return count;
}

const RegisterSet *
NativeRegisterContextLinux_x86::GetRegisterSet(uint32_t set_index) const {
  if (!IsRegisterSetAvailable(set_index))
    return nullptr;

  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
  case llvm::Triple::x86:
    return &g_reg_sets_i386[set_index];
  case llvm::Triple::x86_64:
    return &g_reg_sets_x86_64[set_index];
  default:
    assert(false && "Unhandled target architecture.");
    return nullptr;
  }

  return nullptr;
}

Status
NativeRegisterContextLinux_x86::ReadRegister(const RegisterInfo *reg_info,
                                                RegisterValue &reg_value) {
  Status error;

  if (!reg_info) {
    error = Status::FromErrorString("reg_info NULL");
    return error;
  }

  if (IsThreadPointer(*reg_info))
    return ReadThreadPointer(reg_value);

  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
  if (reg == LLDB_INVALID_REGNUM) {
    // This is likely an internal register for lldb use only and should not be
    // directly queried.
    error = Status::FromErrorStringWithFormat(
        "register \"%s\" is an internal-only lldb "
        "register, cannot read directly",
        reg_info->name);
    return error;
  }

  if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
    error = ReadFPR();
    if (error.Fail())
      return error;
  } else {
    uint32_t full_reg = reg;
    bool is_subreg = reg_info->invalidate_regs &&
                     (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);

    if (is_subreg) {
      // Read the full aligned 64-bit register.
      full_reg = reg_info->invalidate_regs[0];
    }

    error = ReadRegisterRaw(GetRegisterInfoIndex(full_reg), reg_value);

    if (error.Success()) {
      // If our read was not aligned (for ah,bh,ch,dh), shift our returned
      // value one byte to the right.
      if (is_subreg && (reg_info->byte_offset & 0x1))
        reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);

      // If our return byte size was greater than the return value reg size,
      // then use the type specified by reg_info rather than the uint64_t
      // default
      if (reg_value.GetByteSize() > reg_info->byte_size)
        reg_value.SetType(*reg_info);
    }
    return error;
  }

  if (reg_info->encoding == lldb::eEncodingVector) {
    lldb::ByteOrder byte_order = GetByteOrder();

    if (byte_order != lldb::eByteOrderInvalid) {
      if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
        reg_value.SetBytes(
            m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,
            reg_info->byte_size, byte_order);
      if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
        reg_value.SetBytes(
            m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,
            reg_info->byte_size, byte_order);
      if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
        reg_value.SetBytes(
            m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
            reg_info->byte_size, byte_order);
      if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
        // Concatenate ymm using the register halves in xmm.bytes and
        // ymmh.bytes
        if (CopyXSTATEtoYMM(reg, byte_order))
          reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
                             reg_info->byte_size, byte_order);
        else {
          error = Status::FromErrorString("failed to copy ymm register value");
          return error;
        }
      }
      if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
        if (CopyXSTATEtoMPX(reg))
          reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
                             reg_info->byte_size, byte_order);
        else {
          error = Status::FromErrorString("failed to copy mpx register value");
          return error;
        }
      }
      if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
        if (CopyXSTATEtoMPX(reg))
          reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
                             reg_info->byte_size, byte_order);
        else {
          error = Status::FromErrorString("failed to copy mpx register value");
          return error;
        }
      }

      if (reg_value.GetType() != RegisterValue::eTypeBytes)
        error = Status::FromErrorString(
            "write failed - type was expected to be RegisterValue::eTypeBytes");

      return error;
    }

    error = Status::FromErrorString("byte order is invalid");
    return error;
  }

  // Get pointer to m_xstate->fxsave variable and set the data from it.

  // Byte offsets of all registers are calculated wrt 'UserArea' structure.
  // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
  // and stores them in 'm_fpr' (of type FPR structure). To extract values of
  // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR
  // structure.

  // Since, FPR structure is also one of the member of UserArea structure.
  // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
  // byte_offset(fctrl wrt UserArea)
  assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(FPR));
  uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
                 m_fctrl_offset_in_userarea;

  if (src == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag)) {
    reg_value.SetUInt16(AbridgedToFullTagWord(
        m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));
    return error;
  }

  switch (reg_info->byte_size) {
  case 1:
    reg_value.SetUInt8(*(uint8_t *)src);
    break;
  case 2:
    reg_value.SetUInt16(*(uint16_t *)src);
    break;
  case 4:
    reg_value.SetUInt32(*(uint32_t *)src);
    break;
  case 8:
    reg_value.SetUInt64(*(uint64_t *)src);
    break;
  default:
    assert(false && "Unhandled data size.");
    error = Status::FromErrorStringWithFormat("unhandled byte size: %" PRIu32,
                                              reg_info->byte_size);
    break;
  }

  return error;
}

void NativeRegisterContextLinux_x86::UpdateXSTATEforWrite(
    uint32_t reg_index) {
  XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv;
  if (IsFPR(reg_index)) {
    // IsFPR considers both %st and %xmm registers as floating point, but these
    // map to two features. Set both flags, just in case.
    xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
  } else if (IsAVX(reg_index)) {
    // Lower bytes of some %ymm registers are shared with %xmm registers.
    xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
  } else if (IsMPX(reg_index)) {
    // MPX registers map to two XSAVE features.
    xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
  }
}

Status NativeRegisterContextLinux_x86::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
  assert(reg_info && "reg_info is null");

  if (IsThreadPointer(*reg_info))
    return Status::FromErrorString("the i386 thread pointer is read-only");

  const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
  if (reg_index == LLDB_INVALID_REGNUM)
    return Status::FromErrorStringWithFormat(
        "no lldb regnum for %s",
        reg_info && reg_info->name ? reg_info->name : "<unknown register>");

  UpdateXSTATEforWrite(reg_index);

  if (IsGPR(reg_index) || IsDR(reg_index))
    return WriteRegisterRaw(GetRegisterInfoIndex(reg_index), reg_value);

  if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
    if (reg_info->encoding == lldb::eEncodingVector) {
      if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
        ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
                 reg_value.GetBytes(), reg_value.GetByteSize());

      if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
        ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
                 reg_value.GetBytes(), reg_value.GetByteSize());

      if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
        ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
                 reg_value.GetBytes(), reg_value.GetByteSize());

      if (reg_index >= m_reg_info.first_ymm &&
          reg_index <= m_reg_info.last_ymm) {
        // Store ymm register content, and split into the register halves in
        // xmm.bytes and ymmh.bytes
        ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
                 reg_value.GetBytes(), reg_value.GetByteSize());
        if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
          return Status::FromErrorString("CopyYMMtoXSTATE() failed");
      }

      if (reg_index >= m_reg_info.first_mpxr &&
          reg_index <= m_reg_info.last_mpxr) {
        ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
                 reg_value.GetBytes(), reg_value.GetByteSize());
        if (!CopyMPXtoXSTATE(reg_index))
          return Status::FromErrorString("CopyMPXtoXSTATE() failed");
      }

      if (reg_index >= m_reg_info.first_mpxc &&
          reg_index <= m_reg_info.last_mpxc) {
        ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
                 reg_value.GetBytes(), reg_value.GetByteSize());
        if (!CopyMPXtoXSTATE(reg_index))
          return Status::FromErrorString("CopyMPXtoXSTATE() failed");
      }
    } else {
      // Get pointer to m_xstate->fxsave variable and set the data to it.

      // Byte offsets of all registers are calculated wrt 'UserArea' structure.
      // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
      // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu
      // registers should be written in m_fpr at byte offsets calculated wrt
      // FPR structure.

      // Since, FPR structure is also one of the member of UserArea structure.
      // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
      // byte_offset(fctrl wrt UserArea)
      assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
             sizeof(FPR));
      uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
                     m_fctrl_offset_in_userarea;

      if (dst == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag))
        m_xstate->fxsave.ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());
      else {
        switch (reg_info->byte_size) {
        case 1:
          *(uint8_t *)dst = reg_value.GetAsUInt8();
          break;
        case 2:
          *(uint16_t *)dst = reg_value.GetAsUInt16();
          break;
        case 4:
          *(uint32_t *)dst = reg_value.GetAsUInt32();
          break;
        case 8:
          *(uint64_t *)dst = reg_value.GetAsUInt64();
          break;
        default:
          assert(false && "Unhandled data size.");
          return Status::FromErrorStringWithFormat(
              "unhandled register data size %" PRIu32, reg_info->byte_size);
        }
      }
    }

    Status error = WriteFPR();
    if (error.Fail())
      return error;

    if (IsAVX(reg_index)) {
      if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
        return Status::FromErrorString("CopyYMMtoXSTATE() failed");
    }

    if (IsMPX(reg_index)) {
      if (!CopyMPXtoXSTATE(reg_index))
        return Status::FromErrorString("CopyMPXtoXSTATE() failed");
    }
    return Status();
  }
  return Status::FromErrorString(
      "failed - register wasn't recognized to be a GPR or an FPR, "
      "write strategy unknown");
}

Status NativeRegisterContextLinux_x86::ReadAllRegisterValues(
    lldb::WritableDataBufferSP &data_sp) {
  Status error;

  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
  error = ReadGPR();
  if (error.Fail())
    return error;

  error = ReadFPR();
  if (error.Fail())
    return error;

  uint8_t *dst = data_sp->GetBytes();
  ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
  dst += GetRegisterInfoInterface().GetGPRSize();
  if (m_xstate_type == XStateType::FXSAVE)
    ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave));
  else if (m_xstate_type == XStateType::XSAVE) {
    lldb::ByteOrder byte_order = GetByteOrder();

    if (IsCPUFeatureAvailable(RegSet::avx)) {
      // Assemble the YMM register content from the register halves.
      for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
           ++reg) {
        if (!CopyXSTATEtoYMM(reg, byte_order)) {
          error = Status::FromErrorStringWithFormat(
              "NativeRegisterContextLinux_x86::%s "
              "CopyXSTATEtoYMM() failed for reg num "
              "%" PRIu32,
              __FUNCTION__, reg);
          return error;
        }
      }
    }

    if (IsCPUFeatureAvailable(RegSet::mpx)) {
      for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
           ++reg) {
        if (!CopyXSTATEtoMPX(reg)) {
          error = Status::FromErrorStringWithFormat(
              "NativeRegisterContextLinux_x86::%s "
              "CopyXSTATEtoMPX() failed for reg num "
              "%" PRIu32,
              __FUNCTION__, reg);
          return error;
        }
      }
    }
    // Copy the extended register state including the assembled ymm registers.
    ::memcpy(dst, m_xstate.get(), sizeof(FPR));
  } else {
    assert(false && "how do we save the floating point registers?");
    error = Status::FromErrorString(
        "unsure how to save the floating point registers");
  }
  /** The following code is specific to Linux x86 based architectures,
   *  where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
   *  -1 to solve the bug 23659, such a setting prevents the automatic
   *  decrement of the instruction pointer which was causing the SIGILL
   *  exception.
   * **/

  RegisterValue value((uint64_t)-1);
  const RegisterInfo &info = GetRegisterInfo().GetOrigAxInfo();
  return DoWriteRegisterValue(info.byte_offset, info.name, value);

  return error;
}

Status NativeRegisterContextLinux_x86::WriteAllRegisterValues(
    const lldb::DataBufferSP &data_sp) {
  Status error;

  if (!data_sp) {
    error = Status::FromErrorStringWithFormat(
        "NativeRegisterContextLinux_x86::%s invalid data_sp provided",
        __FUNCTION__);
    return error;
  }

  if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
    error = Status::FromErrorStringWithFormatv(
        "data_sp contained mismatched data size, expected {0}, actual {1}",
        REG_CONTEXT_SIZE, data_sp->GetByteSize());
    return error;
  }

  const uint8_t *src = data_sp->GetBytes();
  if (src == nullptr) {
    error = Status::FromErrorStringWithFormat(
        "NativeRegisterContextLinux_x86::%s "
        "DataBuffer::GetBytes() returned a null "
        "pointer",
        __FUNCTION__);
    return error;
  }
  ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());

  error = WriteGPR();
  if (error.Fail())
    return error;

  src += GetRegisterInfoInterface().GetGPRSize();
  if (m_xstate_type == XStateType::FXSAVE)
    ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave));
  else if (m_xstate_type == XStateType::XSAVE)
    ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave));

  error = WriteFPR();
  if (error.Fail())
    return error;

  if (m_xstate_type == XStateType::XSAVE) {
    lldb::ByteOrder byte_order = GetByteOrder();

    if (IsCPUFeatureAvailable(RegSet::avx)) {
      // Parse the YMM register content from the register halves.
      for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
           ++reg) {
        if (!CopyYMMtoXSTATE(reg, byte_order)) {
          error = Status::FromErrorStringWithFormat(
              "NativeRegisterContextLinux_x86::%s "
              "CopyYMMtoXSTATE() failed for reg num "
              "%" PRIu32,
              __FUNCTION__, reg);
          return error;
        }
      }
    }

    if (IsCPUFeatureAvailable(RegSet::mpx)) {
      for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
           ++reg) {
        if (!CopyMPXtoXSTATE(reg)) {
          error = Status::FromErrorStringWithFormat(
              "NativeRegisterContextLinux_x86::%s "
              "CopyMPXtoXSTATE() failed for reg num "
              "%" PRIu32,
              __FUNCTION__, reg);
          return error;
        }
      }
    }
  }

  return error;
}

bool NativeRegisterContextLinux_x86::IsCPUFeatureAvailable(
    RegSet feature_code) const {
  if (m_xstate_type == XStateType::Invalid) {
    if (const_cast<NativeRegisterContextLinux_x86 *>(this)->ReadFPR().Fail())
      return false;
  }
  switch (feature_code) {
  case RegSet::gpr:
  case RegSet::fpu:
    return true;
  case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
                    // reading in the XCR0 area of XSAVE.
    if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
      return true;
     break;
  case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
                    // reading in the XCR0 area of XSAVE.
    if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
      return true;
    break;
  }
  return false;
}

bool NativeRegisterContextLinux_x86::IsRegisterSetAvailable(
    uint32_t set_index) const {
  uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;

  switch (static_cast<RegSet>(set_index)) {
  case RegSet::gpr:
  case RegSet::fpu:
    return (set_index < num_sets);
  case RegSet::avx:
    return IsCPUFeatureAvailable(RegSet::avx);
  case RegSet::mpx:
    return IsCPUFeatureAvailable(RegSet::mpx);
  }
  return false;
}

bool NativeRegisterContextLinux_x86::IsGPR(uint32_t reg_index) const {
  // GPRs come first.
  return reg_index <= m_reg_info.last_gpr;
}

bool NativeRegisterContextLinux_x86::IsFPR(uint32_t reg_index) const {
  return (m_reg_info.first_fpr <= reg_index &&
          reg_index <= m_reg_info.last_fpr);
}

bool NativeRegisterContextLinux_x86::IsDR(uint32_t reg_index) const {
  return (m_reg_info.first_dr <= reg_index &&
          reg_index <= m_reg_info.last_dr);
}

Status NativeRegisterContextLinux_x86::WriteFPR() {
  switch (m_xstate_type) {
  case XStateType::FXSAVE:
    return WriteRegisterSet(
        &m_iovec, sizeof(m_xstate->fxsave),
        fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
  case XStateType::XSAVE:
    return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
  default:
    return Status::FromErrorString("Unrecognized FPR type.");
  }
}

bool NativeRegisterContextLinux_x86::IsAVX(uint32_t reg_index) const {
  if (!IsCPUFeatureAvailable(RegSet::avx))
    return false;
  return (m_reg_info.first_ymm <= reg_index &&
          reg_index <= m_reg_info.last_ymm);
}

bool NativeRegisterContextLinux_x86::CopyXSTATEtoYMM(
    uint32_t reg_index, lldb::ByteOrder byte_order) {
  if (!IsAVX(reg_index))
    return false;

  if (byte_order == lldb::eByteOrderLittle) {
    uint32_t reg_no = reg_index - m_reg_info.first_ymm;
    m_ymm_set.ymm[reg_no] = XStateToYMM(
        m_xstate->fxsave.xmm[reg_no].bytes,
        m_xstate->xsave.ymmh[reg_no].bytes);
    return true;
  }

  return false; // unsupported or invalid byte order
}

bool NativeRegisterContextLinux_x86::CopyYMMtoXSTATE(
    uint32_t reg, lldb::ByteOrder byte_order) {
  if (!IsAVX(reg))
    return false;

  if (byte_order == lldb::eByteOrderLittle) {
    uint32_t reg_no = reg - m_reg_info.first_ymm;
    YMMToXState(m_ymm_set.ymm[reg_no],
        m_xstate->fxsave.xmm[reg_no].bytes,
        m_xstate->xsave.ymmh[reg_no].bytes);
    return true;
  }

  return false; // unsupported or invalid byte order
}

void *NativeRegisterContextLinux_x86::GetFPRBuffer() {
  switch (m_xstate_type) {
  case XStateType::FXSAVE:
    return &m_xstate->fxsave;
  case XStateType::XSAVE:
    return &m_iovec;
  default:
    return nullptr;
  }
}

size_t NativeRegisterContextLinux_x86::GetFPRSize() {
  switch (m_xstate_type) {
  case XStateType::FXSAVE:
    return sizeof(m_xstate->fxsave);
  case XStateType::XSAVE:
    return sizeof(m_iovec);
  default:
    return 0;
  }
}

Status NativeRegisterContextLinux_x86::ReadFPR() {
  Status error;

  // Probe XSAVE and if it is not supported fall back to FXSAVE.
  if (m_xstate_type != XStateType::FXSAVE) {
    error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
    if (!error.Fail()) {
      m_xstate_type = XStateType::XSAVE;
      return error;
    }
  }
  error = ReadRegisterSet(
      &m_iovec, sizeof(m_xstate->xsave),
      fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
  if (!error.Fail()) {
    m_xstate_type = XStateType::FXSAVE;
    return error;
  }
  return Status::FromErrorString("Unrecognized FPR type.");
}

bool NativeRegisterContextLinux_x86::IsMPX(uint32_t reg_index) const {
  if (!IsCPUFeatureAvailable(RegSet::mpx))
    return false;
  return (m_reg_info.first_mpxr <= reg_index &&
          reg_index <= m_reg_info.last_mpxc);
}

bool NativeRegisterContextLinux_x86::IsThreadPointer(
    const RegisterInfo &reg_info) const {
  return GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
             llvm::Triple::x86 &&
         reg_info.kinds[lldb::eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_TP;
}

Status
NativeRegisterContextLinux_x86::ReadThreadPointer(RegisterValue &reg_value) {
  RegisterValue selector;
  Status error = ReadRegisterRaw(lldb_gs_i386, selector);
  if (error.Fail())
    return error;

  const uint32_t gs = selector.GetAsUInt32();
  // Selectors 0 through 3 refer to the null GDT descriptor with different
  // requested privilege levels.
  if (gs < 4) {
    reg_value.SetUInt32(0);
    return Status();
  }
  if (gs & 4)
    return Status::FromErrorString(
        "cannot read the i386 thread pointer from an LDT selector");

  const uintptr_t entry_number = gs >> 3;
  user_desc descriptor = {};
  error = NativeProcessLinux::PtraceWrapper(
      PTRACE_GET_THREAD_AREA, m_thread.GetID(),
      reinterpret_cast<void *>(entry_number), &descriptor, sizeof(descriptor));
  if (error.Fail())
    return error;

  reg_value.SetUInt32(descriptor.base_addr);
  return Status();
}

uint32_t
NativeRegisterContextLinux_x86::GetRegisterInfoIndex(uint32_t lldb_reg) const {
  // Raw register helpers take register-info indices rather than LLDB numbers.
  if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
          llvm::Triple::x86 &&
      lldb_reg >= k_i386_thread_pointer_index)
    return lldb_reg + 1;
  return lldb_reg;
}

bool NativeRegisterContextLinux_x86::CopyXSTATEtoMPX(uint32_t reg) {
  if (!IsMPX(reg))
    return false;

  if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
    ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
             m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
             sizeof(MPXReg));
  } else {
    ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
             m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
             sizeof(MPXCsr));
  }
  return true;
}

bool NativeRegisterContextLinux_x86::CopyMPXtoXSTATE(uint32_t reg) {
  if (!IsMPX(reg))
    return false;

  if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
    ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
             m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
  } else {
    ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
             m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
  }
  return true;
}

uint32_t
NativeRegisterContextLinux_x86::GetPtraceOffset(uint32_t reg_index) {
  // If register is MPX, remove extra factor from gdb offset
  return GetRegisterInfoAtIndex(reg_index)->byte_offset -
         (IsMPX(reg_index) ? 128 : 0);
}

std::optional<NativeRegisterContextLinux::SyscallData>
NativeRegisterContextLinux_x86::GetSyscallData() {
  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
  case llvm::Triple::x86: {
    static const uint8_t Int80[] = {0xcd, 0x80};
    static const uint32_t Args[] = {lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386,
                                    lldb_edx_i386, lldb_esi_i386, lldb_edi_i386,
                                    lldb_ebp_i386};
    return SyscallData{Int80, Args, lldb_eax_i386};
  }
  case llvm::Triple::x86_64: {
    static const uint8_t Syscall[] = {0x0f, 0x05};
    static const uint32_t Args[] = {
        x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rdx,
        x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r8,  x86_64_with_base::lldb_r9};
    return SyscallData{Syscall, Args, x86_64_with_base::lldb_rax};
  }
  default:
    llvm_unreachable("Unhandled architecture!");
  }
}

std::optional<NativeRegisterContextLinux::MmapData>
NativeRegisterContextLinux_x86::GetMmapData() {
  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
  case llvm::Triple::x86:
    return MmapData{192, 91};
  case llvm::Triple::x86_64:
    return MmapData{9, 11};
  default:
    llvm_unreachable("Unhandled architecture!");
  }
}

const RegisterInfo *NativeRegisterContextLinux_x86::GetDR(int num) const {
  assert(num >= 0 && num <= 7);
  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
  case llvm::Triple::x86:
    return GetRegisterInfoAtIndex(GetRegisterInfoIndex(lldb_dr0_i386 + num));
  case llvm::Triple::x86_64:
    return GetRegisterInfoAtIndex(x86_64_with_base::lldb_dr0 + num);
  default:
    llvm_unreachable("Unhandled target architecture.");
  }
}

#endif // defined(__i386__) || defined(__x86_64__)
