brintos

brintos / llvm-project-archived public Read only

0
0
Text · 42.7 KiB · 77260c7 Raw
1090 lines · cpp
1//===-- NativeRegisterContextLinux_x86_64.cpp -----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#if defined(__i386__) || defined(__x86_64__)10 11#include "NativeRegisterContextLinux_x86_64.h"12#include "Plugins/Process/Linux/NativeThreadLinux.h"13#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"14#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"15#include "lldb/Host/HostInfo.h"16#include "lldb/Utility/DataBufferHeap.h"17#include "lldb/Utility/Log.h"18#include "lldb/Utility/RegisterValue.h"19#include "lldb/Utility/Status.h"20#include <cpuid.h>21#include <linux/elf.h>22#include <optional>23 24// Newer toolchains define __get_cpuid_count in cpuid.h, but some25// older-but-still-supported ones (e.g. gcc 5.4.0) don't, so we26// define it locally here, following the definition in clang/lib/Headers.27static inline int get_cpuid_count(unsigned int __leaf,28                                  unsigned int __subleaf,29                                  unsigned int *__eax, unsigned int *__ebx,30                                  unsigned int *__ecx, unsigned int *__edx)31{32  unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, nullptr);33 34  if (__max_leaf == 0 || __max_leaf < __leaf)35    return 0;36 37  __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);38  return 1;39}40 41using namespace lldb_private;42using namespace lldb_private::process_linux;43 44// x86 32-bit general purpose registers.45static const uint32_t g_gpr_regnums_i386[] = {46    lldb_eax_i386,      lldb_ebx_i386,    lldb_ecx_i386, lldb_edx_i386,47    lldb_edi_i386,      lldb_esi_i386,    lldb_ebp_i386, lldb_esp_i386,48    lldb_eip_i386,      lldb_eflags_i386, lldb_cs_i386,  lldb_fs_i386,49    lldb_gs_i386,       lldb_ss_i386,     lldb_ds_i386,  lldb_es_i386,50    lldb_ax_i386,       lldb_bx_i386,     lldb_cx_i386,  lldb_dx_i386,51    lldb_di_i386,       lldb_si_i386,     lldb_bp_i386,  lldb_sp_i386,52    lldb_ah_i386,       lldb_bh_i386,     lldb_ch_i386,  lldb_dh_i386,53    lldb_al_i386,       lldb_bl_i386,     lldb_cl_i386,  lldb_dl_i386,54    LLDB_INVALID_REGNUM // register sets need to end with this flag55};56static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -57                      1 ==58                  k_num_gpr_registers_i386,59              "g_gpr_regnums_i386 has wrong number of register infos");60 61// x86 32-bit floating point registers.62static const uint32_t g_fpu_regnums_i386[] = {63    lldb_fctrl_i386,    lldb_fstat_i386,     lldb_ftag_i386,  lldb_fop_i386,64    lldb_fiseg_i386,    lldb_fioff_i386,     lldb_foseg_i386, lldb_fooff_i386,65    lldb_mxcsr_i386,    lldb_mxcsrmask_i386, lldb_st0_i386,   lldb_st1_i386,66    lldb_st2_i386,      lldb_st3_i386,       lldb_st4_i386,   lldb_st5_i386,67    lldb_st6_i386,      lldb_st7_i386,       lldb_mm0_i386,   lldb_mm1_i386,68    lldb_mm2_i386,      lldb_mm3_i386,       lldb_mm4_i386,   lldb_mm5_i386,69    lldb_mm6_i386,      lldb_mm7_i386,       lldb_xmm0_i386,  lldb_xmm1_i386,70    lldb_xmm2_i386,     lldb_xmm3_i386,      lldb_xmm4_i386,  lldb_xmm5_i386,71    lldb_xmm6_i386,     lldb_xmm7_i386,72    LLDB_INVALID_REGNUM // register sets need to end with this flag73};74static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -75                      1 ==76                  k_num_fpr_registers_i386,77              "g_fpu_regnums_i386 has wrong number of register infos");78 79// x86 32-bit AVX registers.80static const uint32_t g_avx_regnums_i386[] = {81    lldb_ymm0_i386,     lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,82    lldb_ymm4_i386,     lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,83    LLDB_INVALID_REGNUM // register sets need to end with this flag84};85static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -86                      1 ==87                  k_num_avx_registers_i386,88              " g_avx_regnums_i386 has wrong number of register infos");89 90// x64 32-bit MPX registers.91static const uint32_t g_mpx_regnums_i386[] = {92    lldb_bnd0_i386,     lldb_bnd1_i386, lldb_bnd2_i386, lldb_bnd3_i386,93    lldb_bndcfgu_i386,  lldb_bndstatus_i386,94    LLDB_INVALID_REGNUM // register sets need to end with this flag95};96static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -97                      1 ==98                  k_num_mpx_registers_i386,99              "g_mpx_regnums_x86_64 has wrong number of register infos");100 101// x86 64-bit general purpose registers.102static const uint32_t g_gpr_regnums_x86_64[] = {103    x86_64_with_base::lldb_rax,    x86_64_with_base::lldb_rbx,    x86_64_with_base::lldb_rcx, x86_64_with_base::lldb_rdx,104    x86_64_with_base::lldb_rdi,    x86_64_with_base::lldb_rsi,    x86_64_with_base::lldb_rbp, x86_64_with_base::lldb_rsp,105    x86_64_with_base::lldb_r8,     x86_64_with_base::lldb_r9,     x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r11,106    x86_64_with_base::lldb_r12,    x86_64_with_base::lldb_r13,    x86_64_with_base::lldb_r14, x86_64_with_base::lldb_r15,107    x86_64_with_base::lldb_rip,    x86_64_with_base::lldb_rflags, x86_64_with_base::lldb_cs,  x86_64_with_base::lldb_fs,108    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,109    x86_64_with_base::lldb_ds,  x86_64_with_base::lldb_es,110    x86_64_with_base::lldb_eax,    x86_64_with_base::lldb_ebx,    x86_64_with_base::lldb_ecx, x86_64_with_base::lldb_edx,111    x86_64_with_base::lldb_edi,    x86_64_with_base::lldb_esi,    x86_64_with_base::lldb_ebp, x86_64_with_base::lldb_esp,112    x86_64_with_base::lldb_r8d,  // Low 32 bits or r8113    x86_64_with_base::lldb_r9d,  // Low 32 bits or r9114    x86_64_with_base::lldb_r10d, // Low 32 bits or r10115    x86_64_with_base::lldb_r11d, // Low 32 bits or r11116    x86_64_with_base::lldb_r12d, // Low 32 bits or r12117    x86_64_with_base::lldb_r13d, // Low 32 bits or r13118    x86_64_with_base::lldb_r14d, // Low 32 bits or r14119    x86_64_with_base::lldb_r15d, // Low 32 bits or r15120    x86_64_with_base::lldb_ax,     x86_64_with_base::lldb_bx,     x86_64_with_base::lldb_cx,  x86_64_with_base::lldb_dx,121    x86_64_with_base::lldb_di,     x86_64_with_base::lldb_si,     x86_64_with_base::lldb_bp,  x86_64_with_base::lldb_sp,122    x86_64_with_base::lldb_r8w,  // Low 16 bits or r8123    x86_64_with_base::lldb_r9w,  // Low 16 bits or r9124    x86_64_with_base::lldb_r10w, // Low 16 bits or r10125    x86_64_with_base::lldb_r11w, // Low 16 bits or r11126    x86_64_with_base::lldb_r12w, // Low 16 bits or r12127    x86_64_with_base::lldb_r13w, // Low 16 bits or r13128    x86_64_with_base::lldb_r14w, // Low 16 bits or r14129    x86_64_with_base::lldb_r15w, // Low 16 bits or r15130    x86_64_with_base::lldb_ah,     x86_64_with_base::lldb_bh,     x86_64_with_base::lldb_ch,  x86_64_with_base::lldb_dh,131    x86_64_with_base::lldb_al,     x86_64_with_base::lldb_bl,     x86_64_with_base::lldb_cl,  x86_64_with_base::lldb_dl,132    x86_64_with_base::lldb_dil,    x86_64_with_base::lldb_sil,    x86_64_with_base::lldb_bpl, x86_64_with_base::lldb_spl,133    x86_64_with_base::lldb_r8l,    // Low 8 bits or r8134    x86_64_with_base::lldb_r9l,    // Low 8 bits or r9135    x86_64_with_base::lldb_r10l,   // Low 8 bits or r10136    x86_64_with_base::lldb_r11l,   // Low 8 bits or r11137    x86_64_with_base::lldb_r12l,   // Low 8 bits or r12138    x86_64_with_base::lldb_r13l,   // Low 8 bits or r13139    x86_64_with_base::lldb_r14l,   // Low 8 bits or r14140    x86_64_with_base::lldb_r15l,   // Low 8 bits or r15141    LLDB_INVALID_REGNUM // register sets need to end with this flag142};143static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -144                      1 ==145                  x86_64_with_base::k_num_gpr_registers,146              "g_gpr_regnums_x86_64 has wrong number of register infos");147 148// x86 64-bit floating point registers.149static const uint32_t g_fpu_regnums_x86_64[] = {150    x86_64_with_base::lldb_fctrl,  x86_64_with_base::lldb_fstat, x86_64_with_base::lldb_ftag,151    x86_64_with_base::lldb_fop,    x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff,152    x86_64_with_base::lldb_fip,    x86_64_with_base::lldb_foseg, x86_64_with_base::lldb_fooff,153    x86_64_with_base::lldb_fdp,    x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask,154    x86_64_with_base::lldb_st0,    x86_64_with_base::lldb_st1,   x86_64_with_base::lldb_st2,155    x86_64_with_base::lldb_st3,    x86_64_with_base::lldb_st4,   x86_64_with_base::lldb_st5,156    x86_64_with_base::lldb_st6,    x86_64_with_base::lldb_st7,   x86_64_with_base::lldb_mm0,157    x86_64_with_base::lldb_mm1,    x86_64_with_base::lldb_mm2,   x86_64_with_base::lldb_mm3,158    x86_64_with_base::lldb_mm4,    x86_64_with_base::lldb_mm5,   x86_64_with_base::lldb_mm6,159    x86_64_with_base::lldb_mm7,    x86_64_with_base::lldb_xmm0,  x86_64_with_base::lldb_xmm1,160    x86_64_with_base::lldb_xmm2,   x86_64_with_base::lldb_xmm3,  x86_64_with_base::lldb_xmm4,161    x86_64_with_base::lldb_xmm5,   x86_64_with_base::lldb_xmm6,  x86_64_with_base::lldb_xmm7,162    x86_64_with_base::lldb_xmm8,   x86_64_with_base::lldb_xmm9,  x86_64_with_base::lldb_xmm10,163    x86_64_with_base::lldb_xmm11,  x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13,164    x86_64_with_base::lldb_xmm14,  x86_64_with_base::lldb_xmm15,165    LLDB_INVALID_REGNUM // register sets need to end with this flag166};167static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -168                      1 ==169                  x86_64_with_base::k_num_fpr_registers,170              "g_fpu_regnums_x86_64 has wrong number of register infos");171 172// x86 64-bit AVX registers.173static const uint32_t g_avx_regnums_x86_64[] = {174    x86_64_with_base::lldb_ymm0,   x86_64_with_base::lldb_ymm1,  x86_64_with_base::lldb_ymm2,  x86_64_with_base::lldb_ymm3,175    x86_64_with_base::lldb_ymm4,   x86_64_with_base::lldb_ymm5,  x86_64_with_base::lldb_ymm6,  x86_64_with_base::lldb_ymm7,176    x86_64_with_base::lldb_ymm8,   x86_64_with_base::lldb_ymm9,  x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11,177    x86_64_with_base::lldb_ymm12,  x86_64_with_base::lldb_ymm13, x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15,178    LLDB_INVALID_REGNUM // register sets need to end with this flag179};180static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -181                      1 ==182                  x86_64_with_base::k_num_avx_registers,183              "g_avx_regnums_x86_64 has wrong number of register infos");184 185// x86 64-bit MPX registers.186static const uint32_t g_mpx_regnums_x86_64[] = {187    x86_64_with_base::lldb_bnd0,    x86_64_with_base::lldb_bnd1,    x86_64_with_base::lldb_bnd2,188    x86_64_with_base::lldb_bnd3,    x86_64_with_base::lldb_bndcfgu, x86_64_with_base::lldb_bndstatus,189    LLDB_INVALID_REGNUM // register sets need to end with this flag190};191static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -192                      1 ==193                  x86_64_with_base::k_num_mpx_registers,194              "g_mpx_regnums_x86_64 has wrong number of register infos");195 196// Number of register sets provided by this context.197constexpr unsigned k_num_extended_register_sets = 2, k_num_register_sets = 4;198 199// Register sets for x86 32-bit.200static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {201    {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,202     g_gpr_regnums_i386},203    {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,204     g_fpu_regnums_i386},205    {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,206     g_avx_regnums_i386},207    { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,208     g_mpx_regnums_i386}};209 210// Register sets for x86 64-bit.211static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {212    {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers,213     g_gpr_regnums_x86_64},214    {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers,215     g_fpu_regnums_x86_64},216    {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers,217     g_avx_regnums_x86_64},218    { "Memory Protection Extensions", "mpx", x86_64_with_base::k_num_mpx_registers,219     g_mpx_regnums_x86_64}};220 221#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))222 223// Required ptrace defines.224 225// Support ptrace extensions even when compiled without required kernel support226#ifndef NT_X86_XSTATE227#define NT_X86_XSTATE 0x202228#endif229#ifndef NT_PRXFPREG230#define NT_PRXFPREG 0x46e62b7f231#endif232 233// On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to234// use NT_PRXFPREG.235static inline unsigned int fxsr_regset(const ArchSpec &arch) {236  return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;237}238 239// Required MPX define.240 241// Support MPX extensions also if compiled with compiler without MPX support.242#ifndef bit_MPX243#define bit_MPX 0x4000244#endif245 246// XCR0 extended register sets masks.247#define mask_XSTATE_AVX (1ULL << 2)248#define mask_XSTATE_BNDREGS (1ULL << 3)249#define mask_XSTATE_BNDCFG (1ULL << 4)250#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)251 252std::unique_ptr<NativeRegisterContextLinux>253NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(254    const ArchSpec &target_arch, NativeThreadLinux &native_thread) {255  return std::unique_ptr<NativeRegisterContextLinux>(256      new NativeRegisterContextLinux_x86_64(target_arch, native_thread));257}258 259llvm::Expected<ArchSpec>260NativeRegisterContextLinux::DetermineArchitecture(lldb::tid_t tid) {261  return DetermineArchitectureViaGPR(262      tid, RegisterContextLinux_x86_64::GetGPRSizeStatic());263}264 265// NativeRegisterContextLinux_x86_64 members.266 267static std::unique_ptr<RegisterContextLinux_x86>268CreateRegisterInfoInterface(const ArchSpec &target_arch) {269  if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {270    // 32-bit hosts run with a RegisterContextLinux_i386 context.271    return std::make_unique<RegisterContextLinux_i386>(target_arch);272  } else {273    assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&274           "Register setting path assumes this is a 64-bit host");275    // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the276    // x86_64 register context.277    return std::make_unique<RegisterContextLinux_x86_64>(target_arch);278  }279}280 281// Return the size of the XSTATE area supported on this cpu. It is necessary to282// allocate the full size of the area even if we do not use/recognise all of it283// because ptrace(PTRACE_SETREGSET, NT_X86_XSTATE) will refuse to write to it if284// we do not pass it a buffer of sufficient size. The size is always at least285// sizeof(FPR) so that the allocated buffer can be safely cast to FPR*.286static std::size_t GetXSTATESize() {287  unsigned int eax, ebx, ecx, edx;288  // First check whether the XSTATE are is supported at all.289  if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx) || !(ecx & bit_XSAVE))290    return sizeof(FPR);291 292  // Then fetch the maximum size of the area.293  if (!get_cpuid_count(0x0d, 0, &eax, &ebx, &ecx, &edx))294    return sizeof(FPR);295  return std::max<std::size_t>(ecx, sizeof(FPR));296}297 298NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(299    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)300    : NativeRegisterContextRegisterInfo(301          native_thread, CreateRegisterInfoInterface(target_arch).release()),302      NativeRegisterContextLinux(native_thread),303      NativeRegisterContextDBReg_x86(native_thread),304      m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(),305      m_reg_info(), m_gpr_x86_64() {306  // Set up data about ranges of valid registers.307  switch (target_arch.GetMachine()) {308  case llvm::Triple::x86:309    m_reg_info.num_registers = k_num_registers_i386;310    m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;311    m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;312    m_reg_info.num_avx_registers = k_num_avx_registers_i386;313    m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;314    m_reg_info.last_gpr = k_last_gpr_i386;315    m_reg_info.first_fpr = k_first_fpr_i386;316    m_reg_info.last_fpr = k_last_fpr_i386;317    m_reg_info.first_st = lldb_st0_i386;318    m_reg_info.last_st = lldb_st7_i386;319    m_reg_info.first_mm = lldb_mm0_i386;320    m_reg_info.last_mm = lldb_mm7_i386;321    m_reg_info.first_xmm = lldb_xmm0_i386;322    m_reg_info.last_xmm = lldb_xmm7_i386;323    m_reg_info.first_ymm = lldb_ymm0_i386;324    m_reg_info.last_ymm = lldb_ymm7_i386;325    m_reg_info.first_mpxr = lldb_bnd0_i386;326    m_reg_info.last_mpxr = lldb_bnd3_i386;327    m_reg_info.first_mpxc = lldb_bndcfgu_i386;328    m_reg_info.last_mpxc = lldb_bndstatus_i386;329    m_reg_info.first_dr = lldb_dr0_i386;330    m_reg_info.last_dr = lldb_dr7_i386;331    m_reg_info.gpr_flags = lldb_eflags_i386;332    break;333  case llvm::Triple::x86_64:334    m_reg_info.num_registers = x86_64_with_base::k_num_registers;335    m_reg_info.num_gpr_registers = x86_64_with_base::k_num_gpr_registers;336    m_reg_info.num_fpr_registers = x86_64_with_base::k_num_fpr_registers;337    m_reg_info.num_avx_registers = x86_64_with_base::k_num_avx_registers;338    m_reg_info.num_mpx_registers = x86_64_with_base::k_num_mpx_registers;339    m_reg_info.last_gpr = x86_64_with_base::k_last_gpr;340    m_reg_info.first_fpr = x86_64_with_base::k_first_fpr;341    m_reg_info.last_fpr = x86_64_with_base::k_last_fpr;342    m_reg_info.first_st = x86_64_with_base::lldb_st0;343    m_reg_info.last_st = x86_64_with_base::lldb_st7;344    m_reg_info.first_mm = x86_64_with_base::lldb_mm0;345    m_reg_info.last_mm = x86_64_with_base::lldb_mm7;346    m_reg_info.first_xmm = x86_64_with_base::lldb_xmm0;347    m_reg_info.last_xmm = x86_64_with_base::lldb_xmm15;348    m_reg_info.first_ymm = x86_64_with_base::lldb_ymm0;349    m_reg_info.last_ymm = x86_64_with_base::lldb_ymm15;350    m_reg_info.first_mpxr = x86_64_with_base::lldb_bnd0;351    m_reg_info.last_mpxr = x86_64_with_base::lldb_bnd3;352    m_reg_info.first_mpxc = x86_64_with_base::lldb_bndcfgu;353    m_reg_info.last_mpxc = x86_64_with_base::lldb_bndstatus;354    m_reg_info.first_dr = x86_64_with_base::lldb_dr0;355    m_reg_info.last_dr = x86_64_with_base::lldb_dr7;356    m_reg_info.gpr_flags = x86_64_with_base::lldb_rflags;357    break;358  default:359    assert(false && "Unhandled target architecture.");360    break;361  }362 363  std::size_t xstate_size = GetXSTATESize();364  m_xstate.reset(static_cast<FPR *>(std::malloc(xstate_size)));365  m_iovec.iov_base = m_xstate.get();366  m_iovec.iov_len = xstate_size;367 368  // Clear out the FPR state.369  ::memset(m_xstate.get(), 0, xstate_size);370 371  // Store byte offset of fctrl (i.e. first register of FPR)372  const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");373  m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;374}375 376// CONSIDER after local and llgs debugging are merged, register set support can377// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.378uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const {379  uint32_t sets = 0;380  for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {381    if (IsRegisterSetAvailable(set_index))382      ++sets;383  }384 385  return sets;386}387 388uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const {389  uint32_t count = 0;390  for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {391    const RegisterSet *set = GetRegisterSet(set_index);392    if (set)393      count += set->num_registers;394  }395  return count;396}397 398const RegisterSet *399NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const {400  if (!IsRegisterSetAvailable(set_index))401    return nullptr;402 403  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {404  case llvm::Triple::x86:405    return &g_reg_sets_i386[set_index];406  case llvm::Triple::x86_64:407    return &g_reg_sets_x86_64[set_index];408  default:409    assert(false && "Unhandled target architecture.");410    return nullptr;411  }412 413  return nullptr;414}415 416Status417NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,418                                                RegisterValue &reg_value) {419  Status error;420 421  if (!reg_info) {422    error = Status::FromErrorString("reg_info NULL");423    return error;424  }425 426  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];427  if (reg == LLDB_INVALID_REGNUM) {428    // This is likely an internal register for lldb use only and should not be429    // directly queried.430    error = Status::FromErrorStringWithFormat(431        "register \"%s\" is an internal-only lldb "432        "register, cannot read directly",433        reg_info->name);434    return error;435  }436 437  if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {438    error = ReadFPR();439    if (error.Fail())440      return error;441  } else {442    uint32_t full_reg = reg;443    bool is_subreg = reg_info->invalidate_regs &&444                     (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);445 446    if (is_subreg) {447      // Read the full aligned 64-bit register.448      full_reg = reg_info->invalidate_regs[0];449    }450 451    error = ReadRegisterRaw(full_reg, reg_value);452 453    if (error.Success()) {454      // If our read was not aligned (for ah,bh,ch,dh), shift our returned455      // value one byte to the right.456      if (is_subreg && (reg_info->byte_offset & 0x1))457        reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);458 459      // If our return byte size was greater than the return value reg size,460      // then use the type specified by reg_info rather than the uint64_t461      // default462      if (reg_value.GetByteSize() > reg_info->byte_size)463        reg_value.SetType(*reg_info);464    }465    return error;466  }467 468  if (reg_info->encoding == lldb::eEncodingVector) {469    lldb::ByteOrder byte_order = GetByteOrder();470 471    if (byte_order != lldb::eByteOrderInvalid) {472      if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)473        reg_value.SetBytes(474            m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,475            reg_info->byte_size, byte_order);476      if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)477        reg_value.SetBytes(478            m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,479            reg_info->byte_size, byte_order);480      if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)481        reg_value.SetBytes(482            m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,483            reg_info->byte_size, byte_order);484      if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {485        // Concatenate ymm using the register halves in xmm.bytes and486        // ymmh.bytes487        if (CopyXSTATEtoYMM(reg, byte_order))488          reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,489                             reg_info->byte_size, byte_order);490        else {491          error = Status::FromErrorString("failed to copy ymm register value");492          return error;493        }494      }495      if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {496        if (CopyXSTATEtoMPX(reg))497          reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,498                             reg_info->byte_size, byte_order);499        else {500          error = Status::FromErrorString("failed to copy mpx register value");501          return error;502        }503      }504      if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {505        if (CopyXSTATEtoMPX(reg))506          reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,507                             reg_info->byte_size, byte_order);508        else {509          error = Status::FromErrorString("failed to copy mpx register value");510          return error;511        }512      }513 514      if (reg_value.GetType() != RegisterValue::eTypeBytes)515        error = Status::FromErrorString(516            "write failed - type was expected to be RegisterValue::eTypeBytes");517 518      return error;519    }520 521    error = Status::FromErrorString("byte order is invalid");522    return error;523  }524 525  // Get pointer to m_xstate->fxsave variable and set the data from it.526 527  // Byte offsets of all registers are calculated wrt 'UserArea' structure.528  // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}529  // and stores them in 'm_fpr' (of type FPR structure). To extract values of530  // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR531  // structure.532 533  // Since, FPR structure is also one of the member of UserArea structure.534  // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -535  // byte_offset(fctrl wrt UserArea)536  assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(FPR));537  uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->byte_offset -538                 m_fctrl_offset_in_userarea;539 540  if (src == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag)) {541    reg_value.SetUInt16(AbridgedToFullTagWord(542        m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));543    return error;544  }545 546  switch (reg_info->byte_size) {547  case 1:548    reg_value.SetUInt8(*(uint8_t *)src);549    break;550  case 2:551    reg_value.SetUInt16(*(uint16_t *)src);552    break;553  case 4:554    reg_value.SetUInt32(*(uint32_t *)src);555    break;556  case 8:557    reg_value.SetUInt64(*(uint64_t *)src);558    break;559  default:560    assert(false && "Unhandled data size.");561    error = Status::FromErrorStringWithFormat("unhandled byte size: %" PRIu32,562                                              reg_info->byte_size);563    break;564  }565 566  return error;567}568 569void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(570    uint32_t reg_index) {571  XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv;572  if (IsFPR(reg_index)) {573    // IsFPR considers both %st and %xmm registers as floating point, but these574    // map to two features. Set both flags, just in case.575    xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;576  } else if (IsAVX(reg_index)) {577    // Lower bytes of some %ymm registers are shared with %xmm registers.578    xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;579  } else if (IsMPX(reg_index)) {580    // MPX registers map to two XSAVE features.581    xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;582  }583}584 585Status NativeRegisterContextLinux_x86_64::WriteRegister(586    const RegisterInfo *reg_info, const RegisterValue &reg_value) {587  assert(reg_info && "reg_info is null");588 589  const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];590  if (reg_index == LLDB_INVALID_REGNUM)591    return Status::FromErrorStringWithFormat(592        "no lldb regnum for %s",593        reg_info && reg_info->name ? reg_info->name : "<unknown register>");594 595  UpdateXSTATEforWrite(reg_index);596 597  if (IsGPR(reg_index) || IsDR(reg_index))598    return WriteRegisterRaw(reg_index, reg_value);599 600  if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {601    if (reg_info->encoding == lldb::eEncodingVector) {602      if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)603        ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,604                 reg_value.GetBytes(), reg_value.GetByteSize());605 606      if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)607        ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,608                 reg_value.GetBytes(), reg_value.GetByteSize());609 610      if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)611        ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,612                 reg_value.GetBytes(), reg_value.GetByteSize());613 614      if (reg_index >= m_reg_info.first_ymm &&615          reg_index <= m_reg_info.last_ymm) {616        // Store ymm register content, and split into the register halves in617        // xmm.bytes and ymmh.bytes618        ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,619                 reg_value.GetBytes(), reg_value.GetByteSize());620        if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))621          return Status::FromErrorString("CopyYMMtoXSTATE() failed");622      }623 624      if (reg_index >= m_reg_info.first_mpxr &&625          reg_index <= m_reg_info.last_mpxr) {626        ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,627                 reg_value.GetBytes(), reg_value.GetByteSize());628        if (!CopyMPXtoXSTATE(reg_index))629          return Status::FromErrorString("CopyMPXtoXSTATE() failed");630      }631 632      if (reg_index >= m_reg_info.first_mpxc &&633          reg_index <= m_reg_info.last_mpxc) {634        ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,635                 reg_value.GetBytes(), reg_value.GetByteSize());636        if (!CopyMPXtoXSTATE(reg_index))637          return Status::FromErrorString("CopyMPXtoXSTATE() failed");638      }639    } else {640      // Get pointer to m_xstate->fxsave variable and set the data to it.641 642      // Byte offsets of all registers are calculated wrt 'UserArea' structure.643      // However, WriteFPR() takes m_fpr (of type FPR structure) and writes644      // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu645      // registers should be written in m_fpr at byte offsets calculated wrt646      // FPR structure.647 648      // Since, FPR structure is also one of the member of UserArea structure.649      // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -650      // byte_offset(fctrl wrt UserArea)651      assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <652             sizeof(FPR));653      uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset -654                     m_fctrl_offset_in_userarea;655 656      if (dst == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag))657        m_xstate->fxsave.ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());658      else {659        switch (reg_info->byte_size) {660        case 1:661          *(uint8_t *)dst = reg_value.GetAsUInt8();662          break;663        case 2:664          *(uint16_t *)dst = reg_value.GetAsUInt16();665          break;666        case 4:667          *(uint32_t *)dst = reg_value.GetAsUInt32();668          break;669        case 8:670          *(uint64_t *)dst = reg_value.GetAsUInt64();671          break;672        default:673          assert(false && "Unhandled data size.");674          return Status::FromErrorStringWithFormat(675              "unhandled register data size %" PRIu32, reg_info->byte_size);676        }677      }678    }679 680    Status error = WriteFPR();681    if (error.Fail())682      return error;683 684    if (IsAVX(reg_index)) {685      if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))686        return Status::FromErrorString("CopyYMMtoXSTATE() failed");687    }688 689    if (IsMPX(reg_index)) {690      if (!CopyMPXtoXSTATE(reg_index))691        return Status::FromErrorString("CopyMPXtoXSTATE() failed");692    }693    return Status();694  }695  return Status::FromErrorString(696      "failed - register wasn't recognized to be a GPR or an FPR, "697      "write strategy unknown");698}699 700Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(701    lldb::WritableDataBufferSP &data_sp) {702  Status error;703 704  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));705  error = ReadGPR();706  if (error.Fail())707    return error;708 709  error = ReadFPR();710  if (error.Fail())711    return error;712 713  uint8_t *dst = data_sp->GetBytes();714  ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());715  dst += GetRegisterInfoInterface().GetGPRSize();716  if (m_xstate_type == XStateType::FXSAVE)717    ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave));718  else if (m_xstate_type == XStateType::XSAVE) {719    lldb::ByteOrder byte_order = GetByteOrder();720 721    if (IsCPUFeatureAvailable(RegSet::avx)) {722      // Assemble the YMM register content from the register halves.723      for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;724           ++reg) {725        if (!CopyXSTATEtoYMM(reg, byte_order)) {726          error = Status::FromErrorStringWithFormat(727              "NativeRegisterContextLinux_x86_64::%s "728              "CopyXSTATEtoYMM() failed for reg num "729              "%" PRIu32,730              __FUNCTION__, reg);731          return error;732        }733      }734    }735 736    if (IsCPUFeatureAvailable(RegSet::mpx)) {737      for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;738           ++reg) {739        if (!CopyXSTATEtoMPX(reg)) {740          error = Status::FromErrorStringWithFormat(741              "NativeRegisterContextLinux_x86_64::%s "742              "CopyXSTATEtoMPX() failed for reg num "743              "%" PRIu32,744              __FUNCTION__, reg);745          return error;746        }747      }748    }749    // Copy the extended register state including the assembled ymm registers.750    ::memcpy(dst, m_xstate.get(), sizeof(FPR));751  } else {752    assert(false && "how do we save the floating point registers?");753    error = Status::FromErrorString(754        "unsure how to save the floating point registers");755  }756  /** The following code is specific to Linux x86 based architectures,757   *  where the register orig_eax (32 bit)/orig_rax (64 bit) is set to758   *  -1 to solve the bug 23659, such a setting prevents the automatic759   *  decrement of the instruction pointer which was causing the SIGILL760   *  exception.761   * **/762 763  RegisterValue value((uint64_t)-1);764  const RegisterInfo &info = GetRegisterInfo().GetOrigAxInfo();765  return DoWriteRegisterValue(info.byte_offset, info.name, value);766 767  return error;768}769 770Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(771    const lldb::DataBufferSP &data_sp) {772  Status error;773 774  if (!data_sp) {775    error = Status::FromErrorStringWithFormat(776        "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",777        __FUNCTION__);778    return error;779  }780 781  if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {782    error = Status::FromErrorStringWithFormatv(783        "data_sp contained mismatched data size, expected {0}, actual {1}",784        REG_CONTEXT_SIZE, data_sp->GetByteSize());785    return error;786  }787 788  const uint8_t *src = data_sp->GetBytes();789  if (src == nullptr) {790    error = Status::FromErrorStringWithFormat(791        "NativeRegisterContextLinux_x86_64::%s "792        "DataBuffer::GetBytes() returned a null "793        "pointer",794        __FUNCTION__);795    return error;796  }797  ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());798 799  error = WriteGPR();800  if (error.Fail())801    return error;802 803  src += GetRegisterInfoInterface().GetGPRSize();804  if (m_xstate_type == XStateType::FXSAVE)805    ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave));806  else if (m_xstate_type == XStateType::XSAVE)807    ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave));808 809  error = WriteFPR();810  if (error.Fail())811    return error;812 813  if (m_xstate_type == XStateType::XSAVE) {814    lldb::ByteOrder byte_order = GetByteOrder();815 816    if (IsCPUFeatureAvailable(RegSet::avx)) {817      // Parse the YMM register content from the register halves.818      for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;819           ++reg) {820        if (!CopyYMMtoXSTATE(reg, byte_order)) {821          error = Status::FromErrorStringWithFormat(822              "NativeRegisterContextLinux_x86_64::%s "823              "CopyYMMtoXSTATE() failed for reg num "824              "%" PRIu32,825              __FUNCTION__, reg);826          return error;827        }828      }829    }830 831    if (IsCPUFeatureAvailable(RegSet::mpx)) {832      for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;833           ++reg) {834        if (!CopyMPXtoXSTATE(reg)) {835          error = Status::FromErrorStringWithFormat(836              "NativeRegisterContextLinux_x86_64::%s "837              "CopyMPXtoXSTATE() failed for reg num "838              "%" PRIu32,839              __FUNCTION__, reg);840          return error;841        }842      }843    }844  }845 846  return error;847}848 849bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(850    RegSet feature_code) const {851  if (m_xstate_type == XStateType::Invalid) {852    if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)->ReadFPR().Fail())853      return false;854  }855  switch (feature_code) {856  case RegSet::gpr:857  case RegSet::fpu:858    return true;859  case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by860                    // reading in the XCR0 area of XSAVE.861    if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)862      return true;863     break;864  case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by865                    // reading in the XCR0 area of XSAVE.866    if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)867      return true;868    break;869  }870  return false;871}872 873bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(874    uint32_t set_index) const {875  uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;876 877  switch (static_cast<RegSet>(set_index)) {878  case RegSet::gpr:879  case RegSet::fpu:880    return (set_index < num_sets);881  case RegSet::avx:882    return IsCPUFeatureAvailable(RegSet::avx);883  case RegSet::mpx:884    return IsCPUFeatureAvailable(RegSet::mpx);885  }886  return false;887}888 889bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {890  // GPRs come first.891  return reg_index <= m_reg_info.last_gpr;892}893 894bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {895  return (m_reg_info.first_fpr <= reg_index &&896          reg_index <= m_reg_info.last_fpr);897}898 899bool NativeRegisterContextLinux_x86_64::IsDR(uint32_t reg_index) const {900  return (m_reg_info.first_dr <= reg_index &&901          reg_index <= m_reg_info.last_dr);902}903 904Status NativeRegisterContextLinux_x86_64::WriteFPR() {905  switch (m_xstate_type) {906  case XStateType::FXSAVE:907    return WriteRegisterSet(908        &m_iovec, sizeof(m_xstate->fxsave),909        fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));910  case XStateType::XSAVE:911    return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);912  default:913    return Status::FromErrorString("Unrecognized FPR type.");914  }915}916 917bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const {918  if (!IsCPUFeatureAvailable(RegSet::avx))919    return false;920  return (m_reg_info.first_ymm <= reg_index &&921          reg_index <= m_reg_info.last_ymm);922}923 924bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(925    uint32_t reg_index, lldb::ByteOrder byte_order) {926  if (!IsAVX(reg_index))927    return false;928 929  if (byte_order == lldb::eByteOrderLittle) {930    uint32_t reg_no = reg_index - m_reg_info.first_ymm;931    m_ymm_set.ymm[reg_no] = XStateToYMM(932        m_xstate->fxsave.xmm[reg_no].bytes,933        m_xstate->xsave.ymmh[reg_no].bytes);934    return true;935  }936 937  return false; // unsupported or invalid byte order938}939 940bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(941    uint32_t reg, lldb::ByteOrder byte_order) {942  if (!IsAVX(reg))943    return false;944 945  if (byte_order == lldb::eByteOrderLittle) {946    uint32_t reg_no = reg - m_reg_info.first_ymm;947    YMMToXState(m_ymm_set.ymm[reg_no],948        m_xstate->fxsave.xmm[reg_no].bytes,949        m_xstate->xsave.ymmh[reg_no].bytes);950    return true;951  }952 953  return false; // unsupported or invalid byte order954}955 956void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {957  switch (m_xstate_type) {958  case XStateType::FXSAVE:959    return &m_xstate->fxsave;960  case XStateType::XSAVE:961    return &m_iovec;962  default:963    return nullptr;964  }965}966 967size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {968  switch (m_xstate_type) {969  case XStateType::FXSAVE:970    return sizeof(m_xstate->fxsave);971  case XStateType::XSAVE:972    return sizeof(m_iovec);973  default:974    return 0;975  }976}977 978Status NativeRegisterContextLinux_x86_64::ReadFPR() {979  Status error;980 981  // Probe XSAVE and if it is not supported fall back to FXSAVE.982  if (m_xstate_type != XStateType::FXSAVE) {983    error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);984    if (!error.Fail()) {985      m_xstate_type = XStateType::XSAVE;986      return error;987    }988  }989  error = ReadRegisterSet(990      &m_iovec, sizeof(m_xstate->xsave),991      fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));992  if (!error.Fail()) {993    m_xstate_type = XStateType::FXSAVE;994    return error;995  }996  return Status::FromErrorString("Unrecognized FPR type.");997}998 999bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const {1000  if (!IsCPUFeatureAvailable(RegSet::mpx))1001    return false;1002  return (m_reg_info.first_mpxr <= reg_index &&1003          reg_index <= m_reg_info.last_mpxc);1004}1005 1006bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {1007  if (!IsMPX(reg))1008    return false;1009 1010  if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {1011    ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,1012             m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,1013             sizeof(MPXReg));1014  } else {1015    ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,1016             m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,1017             sizeof(MPXCsr));1018  }1019  return true;1020}1021 1022bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {1023  if (!IsMPX(reg))1024    return false;1025 1026  if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {1027    ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,1028             m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));1029  } else {1030    ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,1031             m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));1032  }1033  return true;1034}1035 1036uint32_t1037NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) {1038  // If register is MPX, remove extra factor from gdb offset1039  return GetRegisterInfoAtIndex(reg_index)->byte_offset -1040         (IsMPX(reg_index) ? 128 : 0);1041}1042 1043std::optional<NativeRegisterContextLinux::SyscallData>1044NativeRegisterContextLinux_x86_64::GetSyscallData() {1045  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {1046  case llvm::Triple::x86: {1047    static const uint8_t Int80[] = {0xcd, 0x80};1048    static const uint32_t Args[] = {lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386,1049                                    lldb_edx_i386, lldb_esi_i386, lldb_edi_i386,1050                                    lldb_ebp_i386};1051    return SyscallData{Int80, Args, lldb_eax_i386};1052  }1053  case llvm::Triple::x86_64: {1054    static const uint8_t Syscall[] = {0x0f, 0x05};1055    static const uint32_t Args[] = {1056        x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rdx,1057        x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r8,  x86_64_with_base::lldb_r9};1058    return SyscallData{Syscall, Args, x86_64_with_base::lldb_rax};1059  }1060  default:1061    llvm_unreachable("Unhandled architecture!");1062  }1063}1064 1065std::optional<NativeRegisterContextLinux::MmapData>1066NativeRegisterContextLinux_x86_64::GetMmapData() {1067  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {1068  case llvm::Triple::x86:1069    return MmapData{192, 91};1070  case llvm::Triple::x86_64:1071    return MmapData{9, 11};1072  default:1073    llvm_unreachable("Unhandled architecture!");1074  }1075}1076 1077const RegisterInfo *NativeRegisterContextLinux_x86_64::GetDR(int num) const {1078  assert(num >= 0 && num <= 7);1079  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {1080  case llvm::Triple::x86:1081    return GetRegisterInfoAtIndex(lldb_dr0_i386 + num);1082  case llvm::Triple::x86_64:1083    return GetRegisterInfoAtIndex(x86_64_with_base::lldb_dr0 + num);1084  default:1085    llvm_unreachable("Unhandled target architecture.");1086  }1087}1088 1089#endif // defined(__i386__) || defined(__x86_64__)1090