summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/Utility')
-rw-r--r--lldb/source/Plugins/Process/Utility/CMakeLists.txt2
-rw-r--r--lldb/source/Plugins/Process/Utility/LinuxSignals.cpp79
-rw-r--r--lldb/source/Plugins/Process/Utility/LinuxSignals.h35
-rw-r--r--lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.cpp1040
-rw-r--r--lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.h135
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp14
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h8
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp15
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h8
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp67
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h12
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp15
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h8
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp66
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h12
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h14
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h292
17 files changed, 1755 insertions, 67 deletions
diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
index 7089f8485e3..880b8758ef8 100644
--- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
@@ -8,6 +8,8 @@ add_lldb_library(lldbPluginProcessUtility
HistoryThread.cpp
HistoryUnwind.cpp
InferiorCallPOSIX.cpp
+ LinuxSignals.cpp
+ NativeRegisterContextLinux_x86_64.cpp
RegisterContextDarwin_arm.cpp
RegisterContextDarwin_arm64.cpp
RegisterContextDarwin_i386.cpp
diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
new file mode 100644
index 00000000000..f0affb7b68b
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
@@ -0,0 +1,79 @@
+//===-- LinuxSignals.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <signal.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "LinuxSignals.h"
+
+using namespace process_linux;
+
+LinuxSignals::LinuxSignals()
+ : UnixSignals()
+{
+ Reset();
+}
+
+void
+LinuxSignals::Reset()
+{
+ m_signals.clear();
+
+ // FIXME we now need *Signals classes on systems that are different OSes (e.g. LinuxSignals
+ // needed on MacOSX to debug Linux from MacOSX, and similar scenarios, used by ProcessGDBRemote). These must be defined
+ // not based on OS includes and defines.
+
+#define ADDSIGNAL(S, SUPPRESS, STOP, NOTIFY, DESCRIPTION) \
+ AddSignal(SIG ## S, "SIG" #S, #S, SUPPRESS, STOP, NOTIFY, DESCRIPTION)
+
+ ADDSIGNAL(HUP, false, true, true, "hangup");
+ ADDSIGNAL(INT, true, true, true, "interrupt");
+ ADDSIGNAL(QUIT, false, true, true, "quit");
+ ADDSIGNAL(ILL, false, true, true, "illegal instruction");
+ ADDSIGNAL(TRAP, true, true, true, "trace trap (not reset when caught)");
+ ADDSIGNAL(ABRT, false, true, true, "abort");
+ ADDSIGNAL(IOT, false, true, true, "abort");
+ ADDSIGNAL(BUS, false, true, true, "bus error");
+ ADDSIGNAL(FPE, false, true, true, "floating point exception");
+ ADDSIGNAL(KILL, false, true, true, "kill");
+ ADDSIGNAL(USR1, false, true, true, "user defined signal 1");
+ ADDSIGNAL(SEGV, false, true, true, "segmentation violation");
+ ADDSIGNAL(USR2, false, true, true, "user defined signal 2");
+ ADDSIGNAL(PIPE, false, true, true, "write to pipe with reading end closed");
+ ADDSIGNAL(ALRM, false, false, true, "alarm");
+ ADDSIGNAL(TERM, false, true, true, "termination requested");
+#ifdef SIGSTKFLT
+ ADDSIGNAL(STKFLT, false, true, true, "stack fault");
+#endif
+ ADDSIGNAL(CHLD, false, false, true, "child process exit");
+ ADDSIGNAL(CONT, false, true, true, "process continue");
+ ADDSIGNAL(STOP, true, true, true, "process stop");
+ ADDSIGNAL(TSTP, false, true, true, "tty stop");
+ ADDSIGNAL(TTIN, false, true, true, "background tty read");
+ ADDSIGNAL(TTOU, false, true, true, "background tty write");
+ ADDSIGNAL(URG, false, true, true, "urgent data on socket");
+ ADDSIGNAL(XCPU, false, true, true, "CPU resource exceeded");
+ ADDSIGNAL(XFSZ, false, true, true, "file size limit exceeded");
+ ADDSIGNAL(VTALRM, false, true, true, "virtual alarm");
+ ADDSIGNAL(PROF, false, true, true, "profiling alarm");
+ ADDSIGNAL(WINCH, false, true, true, "window size change");
+#ifdef SIGPOLL
+ ADDSIGNAL(POLL, false, true, true, "pollable event");
+#endif
+ ADDSIGNAL(IO, false, true, true, "input/output ready");
+#ifdef SIGPWR
+ ADDSIGNAL(PWR, false, true, true, "power failure");
+#endif
+ ADDSIGNAL(SYS, false, true, true, "invalid system call");
+
+#undef ADDSIGNAL
+}
diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.h b/lldb/source/Plugins/Process/Utility/LinuxSignals.h
new file mode 100644
index 00000000000..9645b3d8725
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.h
@@ -0,0 +1,35 @@
+//===-- LinuxSignals.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LinuxSignals_H_
+#define liblldb_LinuxSignals_H_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/UnixSignals.h"
+
+namespace process_linux
+{
+
+ /// Linux specific set of Unix signals.
+ class LinuxSignals
+ : public lldb_private::UnixSignals
+ {
+ public:
+ LinuxSignals();
+
+ private:
+ void
+ Reset();
+ };
+}
+
+#endif
diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.cpp
new file mode 100644
index 00000000000..9d7ca9558cd
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.cpp
@@ -0,0 +1,1040 @@
+//===-- NativeRegisterContextLinux_x86_64.cpp ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextLinux_x86_64.h"
+
+#include "lldb/lldb-private-forward.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/RegisterValue.h"
+#include "Host/common/NativeProcessProtocol.h"
+#include "Host/common/NativeThreadProtocol.h"
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+
+using namespace lldb_private;
+
+// ----------------------------------------------------------------------------
+// Private namespace.
+// ----------------------------------------------------------------------------
+
+namespace
+{
+ // x86 32-bit general purpose registers.
+ const uint32_t
+ g_gpr_regnums_i386[] =
+ {
+ gpr_eax_i386,
+ gpr_ebx_i386,
+ gpr_ecx_i386,
+ gpr_edx_i386,
+ gpr_edi_i386,
+ gpr_esi_i386,
+ gpr_ebp_i386,
+ gpr_esp_i386,
+ gpr_eip_i386,
+ gpr_eflags_i386,
+ gpr_cs_i386,
+ gpr_fs_i386,
+ gpr_gs_i386,
+ gpr_ss_i386,
+ gpr_ds_i386,
+ gpr_es_i386,
+ gpr_ax_i386,
+ gpr_bx_i386,
+ gpr_cx_i386,
+ gpr_dx_i386,
+ gpr_di_i386,
+ gpr_si_i386,
+ gpr_bp_i386,
+ gpr_sp_i386,
+ gpr_ah_i386,
+ gpr_bh_i386,
+ gpr_ch_i386,
+ gpr_dh_i386,
+ gpr_al_i386,
+ gpr_bl_i386,
+ gpr_cl_i386,
+ gpr_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.
+ const uint32_t
+ g_fpu_regnums_i386[] =
+ {
+ fpu_fctrl_i386,
+ fpu_fstat_i386,
+ fpu_ftag_i386,
+ fpu_fop_i386,
+ fpu_fiseg_i386,
+ fpu_fioff_i386,
+ fpu_foseg_i386,
+ fpu_fooff_i386,
+ fpu_mxcsr_i386,
+ fpu_mxcsrmask_i386,
+ fpu_st0_i386,
+ fpu_st1_i386,
+ fpu_st2_i386,
+ fpu_st3_i386,
+ fpu_st4_i386,
+ fpu_st5_i386,
+ fpu_st6_i386,
+ fpu_st7_i386,
+ fpu_mm0_i386,
+ fpu_mm1_i386,
+ fpu_mm2_i386,
+ fpu_mm3_i386,
+ fpu_mm4_i386,
+ fpu_mm5_i386,
+ fpu_mm6_i386,
+ fpu_mm7_i386,
+ fpu_xmm0_i386,
+ fpu_xmm1_i386,
+ fpu_xmm2_i386,
+ fpu_xmm3_i386,
+ fpu_xmm4_i386,
+ fpu_xmm5_i386,
+ fpu_xmm6_i386,
+ fpu_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.
+ const uint32_t
+ g_avx_regnums_i386[] =
+ {
+ fpu_ymm0_i386,
+ fpu_ymm1_i386,
+ fpu_ymm2_i386,
+ fpu_ymm3_i386,
+ fpu_ymm4_i386,
+ fpu_ymm5_i386,
+ fpu_ymm6_i386,
+ fpu_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");
+
+ // x86 64-bit general purpose registers.
+ static const
+ uint32_t g_gpr_regnums_x86_64[] =
+ {
+ gpr_rax_x86_64,
+ gpr_rbx_x86_64,
+ gpr_rcx_x86_64,
+ gpr_rdx_x86_64,
+ gpr_rdi_x86_64,
+ gpr_rsi_x86_64,
+ gpr_rbp_x86_64,
+ gpr_rsp_x86_64,
+ gpr_r8_x86_64,
+ gpr_r9_x86_64,
+ gpr_r10_x86_64,
+ gpr_r11_x86_64,
+ gpr_r12_x86_64,
+ gpr_r13_x86_64,
+ gpr_r14_x86_64,
+ gpr_r15_x86_64,
+ gpr_rip_x86_64,
+ gpr_rflags_x86_64,
+ gpr_cs_x86_64,
+ gpr_fs_x86_64,
+ gpr_gs_x86_64,
+ gpr_ss_x86_64,
+ gpr_ds_x86_64,
+ gpr_es_x86_64,
+ gpr_eax_x86_64,
+ gpr_ebx_x86_64,
+ gpr_ecx_x86_64,
+ gpr_edx_x86_64,
+ gpr_edi_x86_64,
+ gpr_esi_x86_64,
+ gpr_ebp_x86_64,
+ gpr_esp_x86_64,
+ gpr_r8d_x86_64, // Low 32 bits or r8
+ gpr_r9d_x86_64, // Low 32 bits or r9
+ gpr_r10d_x86_64, // Low 32 bits or r10
+ gpr_r11d_x86_64, // Low 32 bits or r11
+ gpr_r12d_x86_64, // Low 32 bits or r12
+ gpr_r13d_x86_64, // Low 32 bits or r13
+ gpr_r14d_x86_64, // Low 32 bits or r14
+ gpr_r15d_x86_64, // Low 32 bits or r15
+ gpr_ax_x86_64,
+ gpr_bx_x86_64,
+ gpr_cx_x86_64,
+ gpr_dx_x86_64,
+ gpr_di_x86_64,
+ gpr_si_x86_64,
+ gpr_bp_x86_64,
+ gpr_sp_x86_64,
+ gpr_r8w_x86_64, // Low 16 bits or r8
+ gpr_r9w_x86_64, // Low 16 bits or r9
+ gpr_r10w_x86_64, // Low 16 bits or r10
+ gpr_r11w_x86_64, // Low 16 bits or r11
+ gpr_r12w_x86_64, // Low 16 bits or r12
+ gpr_r13w_x86_64, // Low 16 bits or r13
+ gpr_r14w_x86_64, // Low 16 bits or r14
+ gpr_r15w_x86_64, // Low 16 bits or r15
+ gpr_ah_x86_64,
+ gpr_bh_x86_64,
+ gpr_ch_x86_64,
+ gpr_dh_x86_64,
+ gpr_al_x86_64,
+ gpr_bl_x86_64,
+ gpr_cl_x86_64,
+ gpr_dl_x86_64,
+ gpr_dil_x86_64,
+ gpr_sil_x86_64,
+ gpr_bpl_x86_64,
+ gpr_spl_x86_64,
+ gpr_r8l_x86_64, // Low 8 bits or r8
+ gpr_r9l_x86_64, // Low 8 bits or r9
+ gpr_r10l_x86_64, // Low 8 bits or r10
+ gpr_r11l_x86_64, // Low 8 bits or r11
+ gpr_r12l_x86_64, // Low 8 bits or r12
+ gpr_r13l_x86_64, // Low 8 bits or r13
+ gpr_r14l_x86_64, // Low 8 bits or r14
+ gpr_r15l_x86_64, // 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 == k_num_gpr_registers_x86_64,
+ "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[] =
+ {
+ fpu_fctrl_x86_64,
+ fpu_fstat_x86_64,
+ fpu_ftag_x86_64,
+ fpu_fop_x86_64,
+ fpu_fiseg_x86_64,
+ fpu_fioff_x86_64,
+ fpu_foseg_x86_64,
+ fpu_fooff_x86_64,
+ fpu_mxcsr_x86_64,
+ fpu_mxcsrmask_x86_64,
+ fpu_st0_x86_64,
+ fpu_st1_x86_64,
+ fpu_st2_x86_64,
+ fpu_st3_x86_64,
+ fpu_st4_x86_64,
+ fpu_st5_x86_64,
+ fpu_st6_x86_64,
+ fpu_st7_x86_64,
+ fpu_mm0_x86_64,
+ fpu_mm1_x86_64,
+ fpu_mm2_x86_64,
+ fpu_mm3_x86_64,
+ fpu_mm4_x86_64,
+ fpu_mm5_x86_64,
+ fpu_mm6_x86_64,
+ fpu_mm7_x86_64,
+ fpu_xmm0_x86_64,
+ fpu_xmm1_x86_64,
+ fpu_xmm2_x86_64,
+ fpu_xmm3_x86_64,
+ fpu_xmm4_x86_64,
+ fpu_xmm5_x86_64,
+ fpu_xmm6_x86_64,
+ fpu_xmm7_x86_64,
+ fpu_xmm8_x86_64,
+ fpu_xmm9_x86_64,
+ fpu_xmm10_x86_64,
+ fpu_xmm11_x86_64,
+ fpu_xmm12_x86_64,
+ fpu_xmm13_x86_64,
+ fpu_xmm14_x86_64,
+ fpu_xmm15_x86_64,
+ 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 == k_num_fpr_registers_x86_64,
+ "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[] =
+ {
+ fpu_ymm0_x86_64,
+ fpu_ymm1_x86_64,
+ fpu_ymm2_x86_64,
+ fpu_ymm3_x86_64,
+ fpu_ymm4_x86_64,
+ fpu_ymm5_x86_64,
+ fpu_ymm6_x86_64,
+ fpu_ymm7_x86_64,
+ fpu_ymm8_x86_64,
+ fpu_ymm9_x86_64,
+ fpu_ymm10_x86_64,
+ fpu_ymm11_x86_64,
+ fpu_ymm12_x86_64,
+ fpu_ymm13_x86_64,
+ fpu_ymm14_x86_64,
+ fpu_ymm15_x86_64,
+ 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 == k_num_avx_registers_x86_64,
+ "g_avx_regnums_x86_64 has wrong number of register infos");
+
+ // Number of register sets provided by this context.
+ enum
+ {
+ k_num_extended_register_sets = 1,
+ k_num_register_sets = 3
+ };
+
+ // 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 }
+ };
+
+ // Register sets for x86 64-bit.
+ static const RegisterSet
+ g_reg_sets_x86_64[k_num_register_sets] =
+ {
+ { "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
+ { "Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_fpu_regnums_x86_64 },
+ { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_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
+
+// ----------------------------------------------------------------------------
+// NativeRegisterContextLinux_x86_64 members.
+// ----------------------------------------------------------------------------
+
+NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p) :
+ NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p),
+ m_fpr_type (eFPRTypeNotValid),
+ m_fpr (),
+ m_iovec (),
+ m_ymm_set (),
+ m_reg_info (),
+ m_gpr_x86_64 ()
+{
+ // Set up data about ranges of valid registers.
+ switch (reg_info_interface_p->GetTargetArchitecture ().GetMachine ())
+ {
+ case llvm::Triple::x86:
+ m_reg_info.num_registers = k_num_registers_i386;
+ 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.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 = fpu_st0_i386;
+ m_reg_info.last_st = fpu_st7_i386;
+ m_reg_info.first_mm = fpu_mm0_i386;
+ m_reg_info.last_mm = fpu_mm7_i386;
+ m_reg_info.first_xmm = fpu_xmm0_i386;
+ m_reg_info.last_xmm = fpu_xmm7_i386;
+ m_reg_info.first_ymm = fpu_ymm0_i386;
+ m_reg_info.last_ymm = fpu_ymm7_i386;
+ m_reg_info.first_dr = dr0_i386;
+ m_reg_info.gpr_flags = gpr_eflags_i386;
+ break;
+ case llvm::Triple::x86_64:
+ m_reg_info.num_registers = k_num_registers_x86_64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
+ m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
+ m_reg_info.last_gpr = k_last_gpr_x86_64;
+ m_reg_info.first_fpr = k_first_fpr_x86_64;
+ m_reg_info.last_fpr = k_last_fpr_x86_64;
+ m_reg_info.first_st = fpu_st0_x86_64;
+ m_reg_info.last_st = fpu_st7_x86_64;
+ m_reg_info.first_mm = fpu_mm0_x86_64;
+ m_reg_info.last_mm = fpu_mm7_x86_64;
+ m_reg_info.first_xmm = fpu_xmm0_x86_64;
+ m_reg_info.last_xmm = fpu_xmm15_x86_64;
+ m_reg_info.first_ymm = fpu_ymm0_x86_64;
+ m_reg_info.last_ymm = fpu_ymm15_x86_64;
+ m_reg_info.first_dr = dr0_x86_64;
+ m_reg_info.gpr_flags = gpr_rflags_x86_64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Initialize m_iovec to point to the buffer and buffer size
+ // using the conventions of Berkeley style UIO structures, as required
+ // by PTRACE extensions.
+ m_iovec.iov_base = &m_fpr.xstate.xsave;
+ m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+
+ // Clear out the FPR state.
+ ::memset(&m_fpr, 0, sizeof(FPR));
+}
+
+// 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_64::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;
+}
+
+const lldb_private::RegisterSet *
+NativeRegisterContextLinux_x86_64::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;
+}
+
+lldb_private::Error
+NativeRegisterContextLinux_x86_64::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
+{
+ Error error;
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
+ if (!reg_info)
+ {
+ error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
+ return error;
+ }
+
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+ if (!process_sp)
+ {
+ error.SetErrorString ("NativeProcessProtocol is NULL");
+ return error;
+ }
+
+ NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+ if (!process_p->ReadRegisterValue(m_thread.GetID(),
+ reg_info->byte_offset,
+ reg_info->name,
+ reg_info->byte_size,
+ reg_value))
+ error.SetErrorString ("NativeProcessLinux::ReadRegisterValue() failed");
+
+ return error;
+}
+
+lldb_private::Error
+NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
+{
+ Error error;
+
+ if (!reg_info)
+ {
+ error.SetErrorString ("reg_info NULL");
+ return error;
+ }
+
+ 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.SetErrorStringWithFormat ("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
+ return error;
+ }
+
+ if (IsFPR(reg, GetFPRType()))
+ {
+ if (!ReadFPR())
+ {
+ error.SetErrorString ("failed to read floating point register");
+ 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(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_fpr.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_fpr.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_fpr.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 (GetFPRType() == eFPRTypeXSAVE && 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.SetErrorString ("failed to copy ymm register value");
+ return error;
+ }
+ }
+
+ if (reg_value.GetType() != RegisterValue::eTypeBytes)
+ error.SetErrorString ("write failed - type was expected to be RegisterValue::eTypeBytes");
+
+ return error;
+ }
+
+ error.SetErrorString ("byte order is invalid");
+ return error;
+ }
+
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+ assert (reg_info->byte_offset < sizeof(m_fpr));
+ uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
+ switch (reg_info->byte_size)
+ {
+ 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.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
+ break;
+ }
+
+ return error;
+}
+
+lldb_private::Error
+NativeRegisterContextLinux_x86_64::WriteRegister(const uint32_t reg,
+ const RegisterValue &value)
+{
+ Error error;
+
+ uint32_t reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
+ {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ error = ReadRegister(full_reg_info, full_value);
+ if (error.Fail ())
+ return error;
+
+ lldb::ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
+ dst,
+ sizeof(dst),
+ byte_order,
+ error);
+ if (error.Success() && dest_size)
+ {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size))
+ {
+ // Copy the src bytes to the destination.
+ memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
+ }
+ }
+ }
+
+
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+ if (!process_sp)
+ {
+ error.SetErrorString ("NativeProcessProtocol is NULL");
+ return error;
+ }
+
+ const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
+ assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
+ if (!register_to_write_info_p)
+ {
+ error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
+ return error;
+ }
+
+ NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+ if (!process_p->WriteRegisterValue(m_thread.GetID(),
+ register_to_write_info_p->byte_offset,
+ register_to_write_info_p->name,
+ value_to_write))
+ error.SetErrorString ("NativeProcessLinux::WriteRegisterValue() failed");
+
+ return error;
+}
+
+lldb_private::Error
+NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
+{
+ assert (reg_info && "reg_info is null");
+
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
+
+ if (IsGPR(reg_index))
+ return WriteRegister(reg_index, reg_value);
+
+ if (IsFPR(reg_index, GetFPRType()))
+ {
+ if (reg_info->encoding == lldb::eEncodingVector)
+ {
+ if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
+ ::memcpy (m_fpr.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_fpr.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_fpr.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)
+ {
+ if (GetFPRType() != eFPRTypeXSAVE)
+ return Error ("target processor does not support AVX");
+
+ // 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 Error ("CopyYMMtoXSTATE() failed");
+ }
+ }
+ else
+ {
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+ assert (reg_info->byte_offset < sizeof(m_fpr));
+ uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset;
+ switch (reg_info->byte_size)
+ {
+ 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 Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
+ }
+ }
+
+ if (WriteFPR())
+ {
+ if (IsAVX(reg_index))
+ {
+ if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
+ return Error ("CopyYMMtoXSTATE() failed");
+ }
+ return Error ();
+ }
+ }
+ return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
+}
+
+lldb_private::Error
+NativeRegisterContextLinux_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
+{
+ Error error;
+
+ data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ {
+ error.SetErrorStringWithFormat ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ if (!ReadGPR ())
+ {
+ error.SetErrorString ("ReadGPR() failed");
+ return error;
+ }
+
+ if (!ReadFPR ())
+ {
+ error.SetErrorString ("ReadFPR() failed");
+ return error;
+ }
+
+ uint8_t *dst = data_sp->GetBytes ();
+ if (dst == nullptr)
+ {
+ error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ ::memcpy (dst, &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ());
+ dst += GetRegisterInfoInterface ().GetGPRSize ();
+ if (GetFPRType () == eFPRTypeFXSAVE)
+ ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ else if (GetFPRType () == eFPRTypeXSAVE)
+ {
+ lldb::ByteOrder byte_order = GetByteOrder ();
+
+ // 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.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s CopyXSTATEtoYMM() failed for reg num %" PRIu32, __FUNCTION__, reg);
+ return error;
+ }
+ }
+
+ // Copy the extended register state including the assembled ymm registers.
+ ::memcpy (dst, &m_fpr, sizeof (m_fpr));
+ }
+ else
+ {
+ assert (false && "how do we save the floating point registers?");
+ error.SetErrorString ("unsure how to save the floating point registers");
+ }
+
+ return error;
+}
+
+lldb_private::Error
+NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
+{
+ Error error;
+
+ if (!data_sp)
+ {
+ error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
+ {
+ error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
+ return error;
+ }
+
+
+ uint8_t *src = data_sp->GetBytes ();
+ if (src == nullptr)
+ {
+ error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
+ return error;
+ }
+ ::memcpy (&m_gpr_x86_64, src, GetRegisterInfoInterface ().GetGPRSize ());
+
+ if (!WriteGPR ())
+ {
+ error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__);
+ return error;
+ }
+
+ src += GetRegisterInfoInterface ().GetGPRSize ();
+ if (GetFPRType () == eFPRTypeFXSAVE)
+ ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ else if (GetFPRType () == eFPRTypeXSAVE)
+ ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+
+ if (!WriteFPR ())
+ {
+ error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__);
+ return error;
+ }
+
+ if (GetFPRType() == eFPRTypeXSAVE)
+ {
+ lldb::ByteOrder byte_order = GetByteOrder();
+
+ // 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.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s CopyYMMtoXSTATE() failed for reg num %" PRIu32, __FUNCTION__, reg);
+ return error;
+ }
+ }
+ }
+
+ return error;
+}
+
+bool
+NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable (uint32_t set_index) const
+{
+ // Note: Extended register sets are assumed to be at the end of g_reg_sets.
+ uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
+
+ if (GetFPRType () == eFPRTypeXSAVE)
+ {
+ // AVX is the first extended register set.
+ ++num_sets;
+ }
+ return (set_index < num_sets);
+}
+
+lldb::ByteOrder
+NativeRegisterContextLinux_x86_64::GetByteOrder() const
+{
+ // Get the target process whose privileged thread was used for the register read.
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+ if (!process_sp)
+ return byte_order;
+
+ if (!process_sp->GetByteOrder (byte_order))
+ {
+ // FIXME log here
+ }
+
+ return byte_order;
+}
+
+bool
+NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const
+{
+ // GPRs come first.
+ return reg_index <= m_reg_info.last_gpr;
+}
+
+NativeRegisterContextLinux_x86_64::FPRType
+NativeRegisterContextLinux_x86_64::GetFPRType () const
+{
+ if (m_fpr_type == eFPRTypeNotValid)
+ {
+ // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx.
+
+ // Try and see if AVX register retrieval works.
+ m_fpr_type = eFPRTypeXSAVE;
+ if (!const_cast<NativeRegisterContextLinux_x86_64*> (this)->ReadFPR ())
+ {
+ // Fall back to general floating point with no AVX support.
+ m_fpr_type = eFPRTypeFXSAVE;
+ }
+ }
+
+ return m_fpr_type;
+}
+
+bool
+NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const
+{
+ return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
+}
+
+bool
+NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, FPRType fpr_type) const
+{
+ bool generic_fpr = IsFPR(reg_index);
+
+ if (fpr_type == eFPRTypeXSAVE)
+ return generic_fpr || IsAVX(reg_index);
+ return generic_fpr;
+}
+
+bool
+NativeRegisterContextLinux_x86_64::WriteFPR()
+{
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+ if (!process_sp)
+ return false;
+ NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+
+ if (GetFPRType() == eFPRTypeFXSAVE)
+ return process_p->WriteFPR (m_thread.GetID (), &m_fpr.xstate.fxsave, sizeof (m_fpr.xstate.fxsave));
+
+ if (GetFPRType() == eFPRTypeXSAVE)
+ return process_p->WriteRegisterSet (m_thread.GetID (), &m_iovec, sizeof (m_fpr.xstate.xsave), NT_X86_XSTATE);
+ return false;
+}
+
+bool
+NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const
+{
+ return (m_reg_info.first_ymm <= reg_index && reg_index <= m_reg_info.last_ymm);
+}
+
+bool
+NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order)
+{
+ if (!IsAVX (reg_index))
+ return false;
+
+ if (byte_order == lldb::eByteOrderLittle)
+ {
+ ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof (XMMReg));
+ ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof (XMMReg),
+ m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof (YMMHReg));
+ return true;
+ }
+
+ if (byte_order == lldb::eByteOrderBig)
+ {
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof (XMMReg),
+ m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof (XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof (YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
+
+}
+
+bool
+NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
+{
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == lldb::eByteOrderLittle)
+ {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == lldb::eByteOrderBig)
+ {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
+}
+
+bool
+NativeRegisterContextLinux_x86_64::ReadFPR ()
+{
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+ if (!process_sp)
+ return false;
+ NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+
+ const FPRType fpr_type = GetFPRType ();
+ switch (fpr_type)
+ {
+ case FPRType::eFPRTypeFXSAVE:
+ return process_p->ReadFPR (m_thread.GetID (), &m_fpr.xstate.fxsave, sizeof (m_fpr.xstate.fxsave));
+
+ case FPRType::eFPRTypeXSAVE:
+ return process_p->ReadRegisterSet (m_thread.GetID (), &m_iovec, sizeof (m_fpr.xstate.xsave), NT_X86_XSTATE);
+
+ default:
+ return false;
+ }
+}
+
+bool
+NativeRegisterContextLinux_x86_64::ReadGPR()
+{
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+ if (!process_sp)
+ return false;
+ NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+
+ return process_p->ReadGPR (m_thread.GetID (), &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ());
+}
+
+bool
+NativeRegisterContextLinux_x86_64::WriteGPR()
+{
+ NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+ if (!process_sp)
+ return false;
+ NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+
+ return process_p->WriteGPR (m_thread.GetID (), &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ());
+}
+
diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.h
new file mode 100644
index 00000000000..d7353c08ef4
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextLinux_x86_64.h
@@ -0,0 +1,135 @@
+//===-- NativeRegisterContextLinux_x86_64.h ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef lldb_NativeRegisterContextLinux_x86_64_h
+#define lldb_NativeRegisterContextLinux_x86_64_h
+
+#include "lldb/Target/NativeRegisterContextRegisterInfo.h"
+#include "RegisterContext_x86.h"
+#include "lldb-x86-register-enums.h"
+
+namespace lldb_private
+{
+ class NativeProcessLinux;
+
+ class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextRegisterInfo
+ {
+ public:
+ NativeRegisterContextLinux_x86_64 (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p);
+
+ uint32_t
+ GetRegisterSetCount () const override;
+
+ const RegisterSet *
+ GetRegisterSet (uint32_t set_index) const override;
+
+ Error
+ ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+
+ Error
+ WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+
+ Error
+ ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+
+ Error
+ WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+
+ private:
+
+ // Private member types.
+ enum FPRType
+ {
+ eFPRTypeNotValid = 0,
+ eFPRTypeFXSAVE,
+ eFPRTypeXSAVE
+ };
+
+ // Info about register ranges.
+ struct RegInfo
+ {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+ uint32_t num_avx_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
+ uint32_t first_st;
+ uint32_t last_st;
+ uint32_t first_mm;
+ uint32_t last_mm;
+ uint32_t first_xmm;
+ uint32_t last_xmm;
+ uint32_t first_ymm;
+ uint32_t last_ymm;
+
+ uint32_t first_dr;
+ uint32_t gpr_flags;
+ };
+
+ // Private member variables.
+ mutable FPRType m_fpr_type;
+ FPR m_fpr;
+ IOVEC m_iovec;
+ YMM m_ymm_set;
+ RegInfo m_reg_info;
+ uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64];
+
+ // Private member methods.
+ lldb_private::Error
+ WriteRegister(const uint32_t reg, const RegisterValue &value);
+
+ bool IsRegisterSetAvailable (uint32_t set_index) const;
+
+ lldb::ByteOrder
+ GetByteOrder() const;
+
+ bool
+ IsGPR(uint32_t reg_index) const;
+
+ FPRType
+ GetFPRType () const;
+
+ bool
+ IsFPR(uint32_t reg_index) const;
+
+ bool
+ WriteFPR();
+
+ bool IsFPR(uint32_t reg_index, FPRType fpr_type) const;
+
+ bool
+ CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order);
+
+ bool
+ CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
+
+ bool
+ IsAVX (uint32_t reg_index) const;
+
+ bool
+ ReadFPR ();
+
+ lldb_private::Error
+ ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value);
+
+ bool
+ ReadGPR();
+
+ bool
+ WriteGPR();
+ };
+}
+
+#endif // #ifndef lldb_NativeRegisterContextLinux_x86_64_h
+
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
index af9445fd4be..185ba26944f 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
@@ -62,18 +62,14 @@ RegisterContextFreeBSD_i386::RegisterContextFreeBSD_i386(const ArchSpec &target_
{
}
-RegisterContextFreeBSD_i386::~RegisterContextFreeBSD_i386()
-{
-}
-
size_t
-RegisterContextFreeBSD_i386::GetGPRSize()
+RegisterContextFreeBSD_i386::GetGPRSize() const
{
return sizeof(GPR);
}
const RegisterInfo *
-RegisterContextFreeBSD_i386::GetRegisterInfo()
+RegisterContextFreeBSD_i386::GetRegisterInfo() const
{
switch (m_target_arch.GetMachine())
{
@@ -84,3 +80,9 @@ RegisterContextFreeBSD_i386::GetRegisterInfo()
return NULL;
}
}
+
+uint32_t
+RegisterContextFreeBSD_i386::GetRegisterCount () const
+{
+ return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
index 8dc6a9159f1..62792c02e2b 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
@@ -17,13 +17,15 @@ class RegisterContextFreeBSD_i386
{
public:
RegisterContextFreeBSD_i386(const lldb_private::ArchSpec &target_arch);
- virtual ~RegisterContextFreeBSD_i386();
size_t
- GetGPRSize();
+ GetGPRSize() const override;
const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ GetRegisterInfo() const override;
+
+ uint32_t
+ GetRegisterCount () const override;
};
#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
index 4714251fd2d..c31b0ee7de5 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
@@ -71,20 +71,23 @@ RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64(const ArchSpec &tar
{
}
-RegisterContextFreeBSD_mips64::~RegisterContextFreeBSD_mips64()
-{
-}
-
size_t
-RegisterContextFreeBSD_mips64::GetGPRSize()
+RegisterContextFreeBSD_mips64::GetGPRSize() const
{
return sizeof(GPR);
}
const RegisterInfo *
-RegisterContextFreeBSD_mips64::GetRegisterInfo()
+RegisterContextFreeBSD_mips64::GetRegisterInfo() const
{
assert (m_target_arch.GetCore() == ArchSpec::eCore_mips64);
return g_register_infos_mips64;
}
+uint32_t
+RegisterContextFreeBSD_mips64::GetRegisterCount () const
+{
+ return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
+}
+
+
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
index 493750c4dd6..f9a3ce09c5b 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
@@ -17,13 +17,15 @@ class RegisterContextFreeBSD_mips64:
{
public:
RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch);
- virtual ~RegisterContextFreeBSD_mips64();
size_t
- GetGPRSize();
+ GetGPRSize() const override;
const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ GetRegisterInfo() const override;
+
+ uint32_t
+ GetRegisterCount () const override;
};
#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
index 0b5c4f02cee..257de719859 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
@@ -67,10 +67,17 @@ struct dbreg {
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
+static std::vector<lldb_private::RegisterInfo>&
+GetSharedRegisterInfoVector ()
+{
+ static std::vector<lldb_private::RegisterInfo> register_infos;
+ return register_infos;
+}
+
static const RegisterInfo *
GetRegisterInfo_i386(const lldb_private::ArchSpec& arch)
{
- static std::vector<lldb_private::RegisterInfo> g_register_infos;
+ static std::vector<lldb_private::RegisterInfo> g_register_infos (GetSharedRegisterInfoVector ());
// Allocate RegisterInfo only once
if (g_register_infos.empty())
@@ -92,33 +99,61 @@ GetRegisterInfo_i386(const lldb_private::ArchSpec& arch)
return &g_register_infos[0];
}
-RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(const ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch)
+static const RegisterInfo *
+PrivateGetRegisterInfoPtr (const lldb_private::ArchSpec& target_arch)
{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86:
+ return GetRegisterInfo_i386 (target_arch);
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
-RegisterContextFreeBSD_x86_64::~RegisterContextFreeBSD_x86_64()
+static uint32_t
+PrivateGetRegisterCount (const lldb_private::ArchSpec& target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86:
+ // This vector should have already been filled.
+ assert (!GetSharedRegisterInfoVector ().empty () && "i386 register info vector not filled.");
+ return static_cast<uint32_t> (GetSharedRegisterInfoVector().size ());
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(const ArchSpec &target_arch) :
+ lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p (PrivateGetRegisterInfoPtr (target_arch)),
+ m_register_count (PrivateGetRegisterCount (target_arch))
{
}
size_t
-RegisterContextFreeBSD_x86_64::GetGPRSize()
+RegisterContextFreeBSD_x86_64::GetGPRSize() const
{
return sizeof(GPR);
}
const RegisterInfo *
-RegisterContextFreeBSD_x86_64::GetRegisterInfo()
+RegisterContextFreeBSD_x86_64::GetRegisterInfo() const
{
- switch (m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return GetRegisterInfo_i386 (m_target_arch);
- case llvm::Triple::x86_64:
- return g_register_infos_x86_64;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+ return m_register_info_p;
}
+uint32_t
+RegisterContextFreeBSD_x86_64::GetRegisterCount () const
+{
+ return m_register_count;
+}
+
+
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
index 818da7264a4..21fbdb4681b 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
@@ -17,13 +17,19 @@ class RegisterContextFreeBSD_x86_64:
{
public:
RegisterContextFreeBSD_x86_64(const lldb_private::ArchSpec &target_arch);
- virtual ~RegisterContextFreeBSD_x86_64();
size_t
- GetGPRSize();
+ GetGPRSize() const override;
const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ GetRegisterInfo() const override;
+
+ uint32_t
+ GetRegisterCount () const override;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ const uint32_t m_register_count;
};
#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
index e6ef1fb8acf..b9b9dca07be 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
@@ -100,18 +100,14 @@ RegisterContextLinux_i386::RegisterContextLinux_i386(const ArchSpec &target_arch
{
}
-RegisterContextLinux_i386::~RegisterContextLinux_i386()
-{
-}
-
size_t
-RegisterContextLinux_i386::GetGPRSize()
+RegisterContextLinux_i386::GetGPRSize() const
{
return sizeof(GPR);
}
const RegisterInfo *
-RegisterContextLinux_i386::GetRegisterInfo()
+RegisterContextLinux_i386::GetRegisterInfo() const
{
switch (m_target_arch.GetMachine())
{
@@ -122,3 +118,10 @@ RegisterContextLinux_i386::GetRegisterInfo()
return NULL;
}
}
+
+uint32_t
+RegisterContextLinux_i386::GetRegisterCount () const
+{
+ return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
+}
+
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
index 870b1cdee8f..f8b21fc8e87 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
@@ -17,13 +17,15 @@ class RegisterContextLinux_i386
{
public:
RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch);
- virtual ~RegisterContextLinux_i386();
size_t
- GetGPRSize();
+ GetGPRSize() const override;
const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ GetRegisterInfo() const override;
+
+ uint32_t
+ GetRegisterCount () const override;
};
#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
index e291519bba3..9cfc1c410dc 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
@@ -80,10 +80,17 @@ struct UserArea
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
+static std::vector<lldb_private::RegisterInfo>&
+GetPrivateRegisterInfoVector ()
+{
+ static std::vector<lldb_private::RegisterInfo> g_register_infos;
+ return g_register_infos;
+}
+
static const RegisterInfo *
GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
{
- static std::vector<lldb_private::RegisterInfo> g_register_infos;
+ static std::vector<lldb_private::RegisterInfo> g_register_infos (GetPrivateRegisterInfoVector ());
// Allocate RegisterInfo only once
if (g_register_infos.empty())
@@ -105,33 +112,60 @@ GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
return &g_register_infos[0];
}
-RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch)
+static const RegisterInfo *
+GetRegisterInfoPtr (const ArchSpec &target_arch)
{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86:
+ return GetRegisterInfo_i386 (target_arch);
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
-RegisterContextLinux_x86_64::~RegisterContextLinux_x86_64()
+static uint32_t
+GetRegisterInfoCount (const ArchSpec &target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86:
+ {
+ assert (!GetPrivateRegisterInfoVector ().empty () && "i386 register info not yet filled.");
+ return static_cast<uint32_t> (GetPrivateRegisterInfoVector ().size ());
+ }
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
+ lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p (GetRegisterInfoPtr (target_arch)),
+ m_register_info_count (GetRegisterInfoCount (target_arch))
{
}
size_t
-RegisterContextLinux_x86_64::GetGPRSize()
+RegisterContextLinux_x86_64::GetGPRSize() const
{
return sizeof(GPR);
}
const RegisterInfo *
-RegisterContextLinux_x86_64::GetRegisterInfo()
+RegisterContextLinux_x86_64::GetRegisterInfo() const
{
- switch (m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return GetRegisterInfo_i386 (m_target_arch);
- case llvm::Triple::x86_64:
- return g_register_infos_x86_64;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+ return m_register_info_p;
}
+uint32_t
+RegisterContextLinux_x86_64::GetRegisterCount () const
+{
+ return m_register_info_count;
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
index 2ef094b5cb2..7b6828661c1 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
@@ -17,13 +17,19 @@ class RegisterContextLinux_x86_64
{
public:
RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch);
- virtual ~RegisterContextLinux_x86_64();
size_t
- GetGPRSize();
+ GetGPRSize() const override;
const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ GetRegisterInfo() const override;
+
+ uint32_t
+ GetRegisterCount () const override;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
};
#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
index bcce128f07a..382475f4523 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -10,6 +10,8 @@
#ifndef lldb_RegisterInfoInterface_h
#define lldb_RegisterInfoInterface_h
+#include "lldb/Core/ArchSpec.h"
+
namespace lldb_private
{
@@ -25,12 +27,20 @@ namespace lldb_private
virtual ~RegisterInfoInterface () {}
virtual size_t
- GetGPRSize () = 0;
+ GetGPRSize () const = 0;
virtual const lldb_private::RegisterInfo *
- GetRegisterInfo () = 0;
+ GetRegisterInfo () const = 0;
+
+ virtual uint32_t
+ GetRegisterCount () const = 0;
+
+ const lldb_private::ArchSpec&
+ GetTargetArchitecture() const
+ { return m_target_arch; }
public:
+ // FIXME make private.
lldb_private::ArchSpec m_target_arch;
};
diff --git a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
new file mode 100644
index 00000000000..c4706d567b7
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -0,0 +1,292 @@
+//===-- lldb-x86-register-enums.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_x86_register_enums_h
+#define lldb_x86_register_enums_h
+
+namespace lldb_private
+{
+
+ //---------------------------------------------------------------------------
+ // Internal codes for all i386 registers.
+ //---------------------------------------------------------------------------
+ enum
+ {
+ k_first_gpr_i386,
+ gpr_eax_i386 = k_first_gpr_i386,
+ gpr_ebx_i386,
+ gpr_ecx_i386,
+ gpr_edx_i386,
+ gpr_edi_i386,
+ gpr_esi_i386,
+ gpr_ebp_i386,
+ gpr_esp_i386,
+ gpr_eip_i386,
+ gpr_eflags_i386,
+ gpr_cs_i386,
+ gpr_fs_i386,
+ gpr_gs_i386,
+ gpr_ss_i386,
+ gpr_ds_i386,
+ gpr_es_i386,
+
+ k_first_alias_i386,
+ gpr_ax_i386 = k_first_alias_i386,
+ gpr_bx_i386,
+ gpr_cx_i386,
+ gpr_dx_i386,
+ gpr_di_i386,
+ gpr_si_i386,
+ gpr_bp_i386,
+ gpr_sp_i386,
+ gpr_ah_i386,
+ gpr_bh_i386,
+ gpr_ch_i386,
+ gpr_dh_i386,
+ gpr_al_i386,
+ gpr_bl_i386,
+ gpr_cl_i386,
+ gpr_dl_i386,
+ k_last_alias_i386 = gpr_dl_i386,
+
+ k_last_gpr_i386 = k_last_alias_i386,
+
+ k_first_fpr_i386,
+ fpu_fctrl_i386 = k_first_fpr_i386,
+ fpu_fstat_i386,
+ fpu_ftag_i386,
+ fpu_fop_i386,
+ fpu_fiseg_i386,
+ fpu_fioff_i386,
+ fpu_foseg_i386,
+ fpu_fooff_i386,
+ fpu_mxcsr_i386,
+ fpu_mxcsrmask_i386,
+ fpu_st0_i386,
+ fpu_st1_i386,
+ fpu_st2_i386,
+ fpu_st3_i386,
+ fpu_st4_i386,
+ fpu_st5_i386,
+ fpu_st6_i386,
+ fpu_st7_i386,
+ fpu_mm0_i386,
+ fpu_mm1_i386,
+ fpu_mm2_i386,
+ fpu_mm3_i386,
+ fpu_mm4_i386,
+ fpu_mm5_i386,
+ fpu_mm6_i386,
+ fpu_mm7_i386,
+ fpu_xmm0_i386,
+ fpu_xmm1_i386,
+ fpu_xmm2_i386,
+ fpu_xmm3_i386,
+ fpu_xmm4_i386,
+ fpu_xmm5_i386,
+ fpu_xmm6_i386,
+ fpu_xmm7_i386,
+ k_last_fpr_i386 = fpu_xmm7_i386,
+
+ k_first_avx_i386,
+ fpu_ymm0_i386 = k_first_avx_i386,
+ fpu_ymm1_i386,
+ fpu_ymm2_i386,
+ fpu_ymm3_i386,
+ fpu_ymm4_i386,
+ fpu_ymm5_i386,
+ fpu_ymm6_i386,
+ fpu_ymm7_i386,
+ k_last_avx_i386 = fpu_ymm7_i386,
+
+ dr0_i386,
+ dr1_i386,
+ dr2_i386,
+ dr3_i386,
+ dr4_i386,
+ dr5_i386,
+ dr6_i386,
+ dr7_i386,
+
+ k_num_registers_i386,
+ k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
+ k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
+ k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1
+ };
+
+ //---------------------------------------------------------------------------
+ // Internal codes for all x86_64 registers.
+ //---------------------------------------------------------------------------
+ enum
+ {
+ k_first_gpr_x86_64,
+ gpr_rax_x86_64 = k_first_gpr_x86_64,
+ gpr_rbx_x86_64,
+ gpr_rcx_x86_64,
+ gpr_rdx_x86_64,
+ gpr_rdi_x86_64,
+ gpr_rsi_x86_64,
+ gpr_rbp_x86_64,
+ gpr_rsp_x86_64,
+ gpr_r8_x86_64,
+ gpr_r9_x86_64,
+ gpr_r10_x86_64,
+ gpr_r11_x86_64,
+ gpr_r12_x86_64,
+ gpr_r13_x86_64,
+ gpr_r14_x86_64,
+ gpr_r15_x86_64,
+ gpr_rip_x86_64,
+ gpr_rflags_x86_64,
+ gpr_cs_x86_64,
+ gpr_fs_x86_64,
+ gpr_gs_x86_64,
+ gpr_ss_x86_64,
+ gpr_ds_x86_64,
+ gpr_es_x86_64,
+
+ k_first_alias_x86_64,
+ gpr_eax_x86_64 = k_first_alias_x86_64,
+ gpr_ebx_x86_64,
+ gpr_ecx_x86_64,
+ gpr_edx_x86_64,
+ gpr_edi_x86_64,
+ gpr_esi_x86_64,
+ gpr_ebp_x86_64,
+ gpr_esp_x86_64,
+ gpr_r8d_x86_64, // Low 32 bits of r8
+ gpr_r9d_x86_64, // Low 32 bits of r9
+ gpr_r10d_x86_64, // Low 32 bits of r10
+ gpr_r11d_x86_64, // Low 32 bits of r11
+ gpr_r12d_x86_64, // Low 32 bits of r12
+ gpr_r13d_x86_64, // Low 32 bits of r13
+ gpr_r14d_x86_64, // Low 32 bits of r14
+ gpr_r15d_x86_64, // Low 32 bits of r15
+ gpr_ax_x86_64,
+ gpr_bx_x86_64,
+ gpr_cx_x86_64,
+ gpr_dx_x86_64,
+ gpr_di_x86_64,
+ gpr_si_x86_64,
+ gpr_bp_x86_64,
+ gpr_sp_x86_64,
+ gpr_r8w_x86_64, // Low 16 bits of r8
+ gpr_r9w_x86_64, // Low 16 bits of r9
+ gpr_r10w_x86_64, // Low 16 bits of r10
+ gpr_r11w_x86_64, // Low 16 bits of r11
+ gpr_r12w_x86_64, // Low 16 bits of r12
+ gpr_r13w_x86_64, // Low 16 bits of r13
+ gpr_r14w_x86_64, // Low 16 bits of r14
+ gpr_r15w_x86_64, // Low 16 bits of r15
+ gpr_ah_x86_64,
+ gpr_bh_x86_64,
+ gpr_ch_x86_64,
+ gpr_dh_x86_64,
+ gpr_al_x86_64,
+ gpr_bl_x86_64,
+ gpr_cl_x86_64,
+ gpr_dl_x86_64,
+ gpr_dil_x86_64,
+ gpr_sil_x86_64,
+ gpr_bpl_x86_64,
+ gpr_spl_x86_64,
+ gpr_r8l_x86_64, // Low 8 bits of r8
+ gpr_r9l_x86_64, // Low 8 bits of r9
+ gpr_r10l_x86_64, // Low 8 bits of r10
+ gpr_r11l_x86_64, // Low 8 bits of r11
+ gpr_r12l_x86_64, // Low 8 bits of r12
+ gpr_r13l_x86_64, // Low 8 bits of r13
+ gpr_r14l_x86_64, // Low 8 bits of r14
+ gpr_r15l_x86_64, // Low 8 bits of r15
+ k_last_alias_x86_64 = gpr_r15l_x86_64,
+
+ k_last_gpr_x86_64 = k_last_alias_x86_64,
+
+ k_first_fpr_x86_64,
+ fpu_fctrl_x86_64 = k_first_fpr_x86_64,
+ fpu_fstat_x86_64,
+ fpu_ftag_x86_64,
+ fpu_fop_x86_64,
+ fpu_fiseg_x86_64,
+ fpu_fioff_x86_64,
+ fpu_foseg_x86_64,
+ fpu_fooff_x86_64,
+ fpu_mxcsr_x86_64,
+ fpu_mxcsrmask_x86_64,
+ fpu_st0_x86_64,
+ fpu_st1_x86_64,
+ fpu_st2_x86_64,
+ fpu_st3_x86_64,
+ fpu_st4_x86_64,
+ fpu_st5_x86_64,
+ fpu_st6_x86_64,
+ fpu_st7_x86_64,
+ fpu_mm0_x86_64,
+ fpu_mm1_x86_64,
+ fpu_mm2_x86_64,
+ fpu_mm3_x86_64,
+ fpu_mm4_x86_64,
+ fpu_mm5_x86_64,
+ fpu_mm6_x86_64,
+ fpu_mm7_x86_64,
+ fpu_xmm0_x86_64,
+ fpu_xmm1_x86_64,
+ fpu_xmm2_x86_64,
+ fpu_xmm3_x86_64,
+ fpu_xmm4_x86_64,
+ fpu_xmm5_x86_64,
+ fpu_xmm6_x86_64,
+ fpu_xmm7_x86_64,
+ fpu_xmm8_x86_64,
+ fpu_xmm9_x86_64,
+ fpu_xmm10_x86_64,
+ fpu_xmm11_x86_64,
+ fpu_xmm12_x86_64,
+ fpu_xmm13_x86_64,
+ fpu_xmm14_x86_64,
+ fpu_xmm15_x86_64,
+ k_last_fpr_x86_64 = fpu_xmm15_x86_64,
+
+ k_first_avx_x86_64,
+ fpu_ymm0_x86_64 = k_first_avx_x86_64,
+ fpu_ymm1_x86_64,
+ fpu_ymm2_x86_64,
+ fpu_ymm3_x86_64,
+ fpu_ymm4_x86_64,
+ fpu_ymm5_x86_64,
+ fpu_ymm6_x86_64,
+ fpu_ymm7_x86_64,
+ fpu_ymm8_x86_64,
+ fpu_ymm9_x86_64,
+ fpu_ymm10_x86_64,
+ fpu_ymm11_x86_64,
+ fpu_ymm12_x86_64,
+ fpu_ymm13_x86_64,
+ fpu_ymm14_x86_64,
+ fpu_ymm15_x86_64,
+ k_last_avx_x86_64 = fpu_ymm15_x86_64,
+
+ dr0_x86_64,
+ dr1_x86_64,
+ dr2_x86_64,
+ dr3_x86_64,
+ dr4_x86_64,
+ dr5_x86_64,
+ dr6_x86_64,
+ dr7_x86_64,
+
+ k_num_registers_x86_64,
+ k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
+ k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
+ k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1
+ };
+
+}
+
+#endif // #ifndef lldb_x86_register_enums_h
OpenPOWER on IntegriCloud