From 8207a0e56fa7f3bfce85448b069791ca3b606a1a Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Sat, 11 Mar 2017 08:58:01 +0100 Subject: [PATCH] lldb-netbsd: Implement unwinding of code that caused interruption Changes: - porting NativeRegisters on x86 64-bit - fix code reading memory from tracee's address space Trace of the following program: int main(int argc, char **argv) { printf("Hello world!\n"); __asm__ __volatile__("int3;\n"); return 0; } $ lldb (lldb) process connect connect://localhost:1234 Process 21323 stopped * thread #1, stop reason = The signal Stopped (signal) was caught frame #0: 0x00007f7f3c800740 -> 0x7f7f3c800740: subq $0x10, %rsp 0x7f7f3c800744: movq %rsp, %r12 0x7f7f3c800747: pushq %rbx 0x7f7f3c800748: andq $-0x10, %rsp (lldb) c Process 21323 resuming Hello world! Process 21323 stopped * thread #1, stop reason = signal SIGTRAP frame #0: 0x000000000040088a -> 0x40088a: movl $0x0, %eax 0x40088f: leave 0x400890: retq 0x400891: addb %al, (%rax) (lldb) c Process 21323 resuming Process 21323 exited with status = 0 (0x00000000) (lldb) Sponsored by --- lldb-netbsd/distinfo | 10 +- ...ins_Process_NetBSD_NativeProcessNetBSD.cpp | 4 +- ...ess_NetBSD_NativeRegisterContextNetBSD.cpp | 7 +- ...ocess_NetBSD_NativeRegisterContextNetBSD.h | 6 +- ...D_NativeRegisterContextNetBSD__x86__64.cpp | 778 +++--------------- ...BSD_NativeRegisterContextNetBSD__x86__64.h | 83 +- 6 files changed, 143 insertions(+), 745 deletions(-) diff --git a/lldb-netbsd/distinfo b/lldb-netbsd/distinfo index 01387315df0..39e7190a1be 100644 --- a/lldb-netbsd/distinfo +++ b/lldb-netbsd/distinfo @@ -23,12 +23,12 @@ SHA1 (patch-source_Host_netbsd_ThisThread.cpp) = f0d32c81bc1b8fe9aeb86519ea46ba2 SHA1 (patch-source_Initialization_SystemInitializerCommon.cpp) = dc270227e68c655753ef5f5168e3fa9a8dab3696 SHA1 (patch-source_Plugins_Process_CMakeLists.txt) = c689ff4ec455234f8d506dc9eb8e0ed7f750d426 SHA1 (patch-source_Plugins_Process_NetBSD_CMakeLists.txt) = a77f397020ab752875813a7a93b53ccd3a130e6f -SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp) = 64ad94ee859712090bebd1e9dbf79d4add4de448 +SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp) = 533e215f48d9d5569771082611be3fee059744ec SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h) = c48bb2dd45682164ab904b8b3f7664b91ac35d5b -SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp) = d3ba093e776ce3af1a6d6f5f5263e5535f8cdec9 -SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h) = c9bd447b3a5e70475d1b857c5441a59c7b2a54ba -SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp) = e937316bee978570c9fe27caa859ba5d35763761 -SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h) = 58803697f65411d1ad62e45c6af68c9271633bac +SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp) = c503ae3b197da1c9555e314d17cb88b4ce2b4ba9 +SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h) = 8c0e41f16445e894a18eee6cae8d3d31ba7c8dd9 +SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp) = 196f33520950262d2ca59f1dc6a019e0ba2e3e7c +SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h) = fa3980158bfe07b476c883b2354329dac9eb0c22 SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp) = cb8757705327e62273bfe9a84dbdbf9cb9b0751a SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h) = c675af8495a75f99bb60cb4ab3fa36223f1cb6f4 SHA1 (patch-source_Plugins_Process_gdb-remote_GDBRemoteCommunicationServerCommon.cpp) = 76e3f6a3e0a24a28a2f5a30e8812906f8a2b2649 diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp index 837c948071b..3374a9b7d1a 100644 --- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp +++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp @@ -1,6 +1,6 @@ $NetBSD$ ---- source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp.orig 2017-03-03 15:35:02.252988829 +0000 +--- source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp.orig 2017-03-11 07:50:19.309994898 +0000 +++ source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -0,0 +1,1307 @@ +//===-- NativeProcessNetBSD.cpp -------------------------------- -*- C++ -*-===// @@ -1126,7 +1126,7 @@ + + do { + io.piod_offs = (void *)(addr + bytes_read); -+ io.piod_offs = dst + bytes_read; ++ io.piod_addr = dst + bytes_read; + + Error error = NativeProcessNetBSD::PtraceWrapper( + PT_IO, GetID(), &io); diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp index f93567d9c4c..25e9e0f70be 100644 --- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp +++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp @@ -1,8 +1,8 @@ $NetBSD$ ---- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp.orig 2017-03-03 15:35:02.265865750 +0000 +--- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp.orig 2017-03-11 07:50:19.322535530 +0000 +++ source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp -@@ -0,0 +1,111 @@ +@@ -0,0 +1,112 @@ +//===-- NativeRegisterContextNetBSD.cpp --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure @@ -31,7 +31,8 @@ + NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *reg_info_interface_p) + : NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx, -+ reg_info_interface_p) {} ++ reg_info_interface_p) { ++} + +lldb::ByteOrder NativeRegisterContextNetBSD::GetByteOrder() const { + // Get the target process whose privileged thread was used for the register diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h index f75aed8ed35..a212799e42b 100644 --- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h +++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h @@ -1,8 +1,8 @@ $NetBSD$ ---- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h.orig 2017-03-03 15:35:02.272170791 +0000 +--- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h.orig 2017-03-11 07:50:19.328597210 +0000 +++ source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h -@@ -0,0 +1,76 @@ +@@ -0,0 +1,78 @@ +//===-- NativeRegisterContextNetBSD.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure @@ -60,6 +60,8 @@ + + virtual void *GetFPRBuffer() { return nullptr; } + ++ virtual void *GetDBRBuffer() { return nullptr; } ++ + virtual size_t GetFPRSize() { return 0; } + + virtual Error DoReadGPR(void *buf); diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp index a7f394d74e8..6282f5f8c46 100644 --- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp +++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp @@ -1,8 +1,8 @@ $NetBSD$ ---- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp.orig 2017-03-03 15:35:02.278989585 +0000 +--- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp.orig 2017-03-11 07:50:19.335169838 +0000 +++ source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp -@@ -0,0 +1,996 @@ +@@ -0,0 +1,434 @@ +//===-- NativeRegisterContextNetBSD_x86_64.cpp ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure @@ -12,7 +12,7 @@ +// +//===----------------------------------------------------------------------===// + -+#if defined(__i386__) || defined(__x86_64__) ++#if defined(__x86_64__) + +#include "NativeRegisterContextNetBSD_x86_64.h" + @@ -22,7 +22,6 @@ +#include "lldb/Host/HostInfo.h" +#include "lldb/Utility/Error.h" + -+//#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h" +#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" + +#include @@ -35,63 +34,6 @@ +// ---------------------------------------------------------------------------- + +namespace { -+// x86 32-bit general purpose registers. -+const uint32_t g_gpr_regnums_i386[] = { -+ lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386, -+ lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386, -+ lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386, -+ lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386, -+ lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386, -+ lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386, -+ lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386, -+ lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386, -+ LLDB_INVALID_REGNUM // register sets need to end with this flag -+}; -+static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - -+ 1 == -+ k_num_gpr_registers_i386, -+ "g_gpr_regnums_i386 has wrong number of register infos"); -+ -+// x86 32-bit floating point registers. -+const uint32_t g_fpu_regnums_i386[] = { -+ lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386, -+ lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386, -+ lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386, -+ lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386, -+ lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386, -+ lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386, -+ lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386, -+ lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386, -+ lldb_xmm6_i386, lldb_xmm7_i386, -+ LLDB_INVALID_REGNUM // register sets need to end with this flag -+}; -+static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - -+ 1 == -+ k_num_fpr_registers_i386, -+ "g_fpu_regnums_i386 has wrong number of register infos"); -+ -+// x86 32-bit AVX registers. -+const uint32_t g_avx_regnums_i386[] = { -+ lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386, -+ lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386, -+ LLDB_INVALID_REGNUM // register sets need to end with this flag -+}; -+static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - -+ 1 == -+ k_num_avx_registers_i386, -+ " g_avx_regnums_i386 has wrong number of register infos"); -+ -+// x64 32-bit MPX registers. -+static const uint32_t g_mpx_regnums_i386[] = { -+ lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386, lldb_bnd3_i386, -+ lldb_bndcfgu_i386, lldb_bndstatus_i386, -+ LLDB_INVALID_REGNUM // register sets need to end with this flag -+}; -+static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) - -+ 1 == -+ k_num_mpx_registers_i386, -+ "g_mpx_regnums_x86_64 has wrong number of register infos"); -+ +// x86 64-bit general purpose registers. +static const uint32_t g_gpr_regnums_x86_64[] = { + lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64, @@ -188,17 +130,6 @@ +// Number of register sets provided by this context. +enum { k_num_extended_register_sets = 2, k_num_register_sets = 4 }; + -+// Register sets for x86 32-bit. -+static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { -+ {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, -+ g_gpr_regnums_i386}, -+ {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, -+ g_fpu_regnums_i386}, -+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386, -+ g_avx_regnums_i386}, -+ { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386, -+ g_mpx_regnums_i386}}; -+ +// Register sets for x86 64-bit. +static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, @@ -247,75 +178,7 @@ + uint32_t concrete_frame_idx) + : NativeRegisterContextNetBSD(native_thread, concrete_frame_idx, + CreateRegisterInfoInterface(target_arch)), -+ m_xstate_type(XStateType::Invalid), m_fpr(), m_iovec(), m_ymm_set(), -+ m_mpx_set(), m_reg_info(), m_gpr_x86_64() { -+ // Set up data about ranges of valid registers. -+ switch (target_arch.GetMachine()) { -+ case llvm::Triple::x86: -+ 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.num_mpx_registers = k_num_mpx_registers_i386; -+ m_reg_info.last_gpr = k_last_gpr_i386; -+ m_reg_info.first_fpr = k_first_fpr_i386; -+ m_reg_info.last_fpr = k_last_fpr_i386; -+ m_reg_info.first_st = lldb_st0_i386; -+ m_reg_info.last_st = lldb_st7_i386; -+ m_reg_info.first_mm = lldb_mm0_i386; -+ m_reg_info.last_mm = lldb_mm7_i386; -+ m_reg_info.first_xmm = lldb_xmm0_i386; -+ m_reg_info.last_xmm = lldb_xmm7_i386; -+ m_reg_info.first_ymm = lldb_ymm0_i386; -+ m_reg_info.last_ymm = lldb_ymm7_i386; -+ m_reg_info.first_mpxr = lldb_bnd0_i386; -+ m_reg_info.last_mpxr = lldb_bnd3_i386; -+ m_reg_info.first_mpxc = lldb_bndcfgu_i386; -+ m_reg_info.last_mpxc = lldb_bndstatus_i386; -+ m_reg_info.first_dr = lldb_dr0_i386; -+ m_reg_info.gpr_flags = lldb_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.num_mpx_registers = k_num_mpx_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 = lldb_st0_x86_64; -+ m_reg_info.last_st = lldb_st7_x86_64; -+ m_reg_info.first_mm = lldb_mm0_x86_64; -+ m_reg_info.last_mm = lldb_mm7_x86_64; -+ m_reg_info.first_xmm = lldb_xmm0_x86_64; -+ m_reg_info.last_xmm = lldb_xmm15_x86_64; -+ m_reg_info.first_ymm = lldb_ymm0_x86_64; -+ m_reg_info.last_ymm = lldb_ymm15_x86_64; -+ m_reg_info.first_mpxr = lldb_bnd0_x86_64; -+ m_reg_info.last_mpxr = lldb_bnd3_x86_64; -+ m_reg_info.first_mpxc = lldb_bndcfgu_x86_64; -+ m_reg_info.last_mpxc = lldb_bndstatus_x86_64; -+ m_reg_info.first_dr = lldb_dr0_x86_64; -+ m_reg_info.gpr_flags = lldb_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)); -+ -+ // Store byte offset of fctrl (i.e. first register of FPR) -+ const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl"); -+ m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset; ++ m_gpr_x86_64(), m_fpr_x86_64(), m_dr_x86_64() { +} + +// CONSIDER after local and llgs debugging are merged, register set support can @@ -323,31 +186,15 @@ +uint32_t NativeRegisterContextNetBSD_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; ++ ++sets; + } + + return sets; +} + -+uint32_t NativeRegisterContextNetBSD_x86_64::GetUserRegisterCount() const { -+ uint32_t count = 0; -+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { -+ const RegisterSet *set = GetRegisterSet(set_index); -+ if (set) -+ count += set->num_registers; -+ } -+ return count; -+} -+ +const RegisterSet * +NativeRegisterContextNetBSD_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: @@ -358,6 +205,27 @@ + return nullptr; +} + ++int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(int reg_num) const { ++ if (reg_num < lldb_fctrl_x86_64) ++ return GPRegSet; ++ else ++ return FPRegSet; ++} ++ ++int NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set, bool force) { ++ switch (set) { ++ case GPRegSet: ++ ReadGPR(); ++ return 0; ++ case FPRegSet: ++ ReadFPR(); ++ return 0; ++ default: ++ break; ++ } ++ return -1; ++} ++ +Error NativeRegisterContextNetBSD_x86_64::ReadRegister( + const RegisterInfo *reg_info, RegisterValue ®_value) { + Error error; @@ -377,127 +245,95 @@ + return error; + } + -+ if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) { -+ error = ReadFPR(); -+ if (error.Fail()) -+ return error; -+ } else { -+ uint32_t full_reg = reg; -+ bool is_subreg = reg_info->invalidate_regs && -+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); -+ -+ if (is_subreg) { -+ // Read the full aligned 64-bit register. -+ full_reg = reg_info->invalidate_regs[0]; -+ } -+ -+#if 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); -+ } ++ int set = GetSetForNativeRegNum(reg); ++ if (set == -1) { ++ // This is likely an internal register for lldb use only and should not be ++ // directly queried. ++ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", ++ reg_info->name); + return error; -+#endif + } + -+ 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 (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 >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { -+ if (CopyXSTATEtoMPX(reg)) -+ reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, -+ reg_info->byte_size, byte_order); -+ else { -+ error.SetErrorString("failed to copy mpx register value"); -+ return error; -+ } -+ } -+ if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) { -+ if (CopyXSTATEtoMPX(reg)) -+ reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, -+ reg_info->byte_size, byte_order); -+ else { -+ error.SetErrorString("failed to copy mpx 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"); ++ if (ReadRegisterSet(set, false) != 0) { ++ // This is likely an internal register for lldb use only and should not be ++ // directly queried. ++ error.SetErrorStringWithFormat("reading register set for register \"%s\" failed", ++ reg_info->name); + return error; + } + -+ // Get pointer to m_fpr.xstate.fxsave variable and set the data from it. -+ -+ // Byte offsets of all registers are calculated wrt 'UserArea' structure. -+ // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)} -+ // and stores them in 'm_fpr' (of type FPR structure). To extract values of -+ // fpu -+ // registers, m_fpr should be read at byte offsets calculated wrt to FPR -+ // structure. -+ -+ // Since, FPR structure is also one of the member of UserArea structure. -+ // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - -+ // byte_offset(fctrl wrt UserArea) -+ assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr)); -+ uint8_t *src = -+ (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea; -+ switch (reg_info->byte_size) { -+ case 1: -+ reg_value.SetUInt8(*(uint8_t *)src); ++ switch (reg) { ++ case lldb_rax_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RAX]; + break; -+ case 2: -+ reg_value.SetUInt16(*(uint16_t *)src); ++ case lldb_rbx_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBX]; + break; -+ case 4: -+ reg_value.SetUInt32(*(uint32_t *)src); ++ case lldb_rcx_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RCX]; + break; -+ case 8: -+ reg_value.SetUInt64(*(uint64_t *)src); ++ case lldb_rdx_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDX]; + break; -+ default: -+ assert(false && "Unhandled data size."); -+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32, -+ reg_info->byte_size); ++ case lldb_rdi_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDI]; ++ break; ++ case lldb_rsi_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSI]; ++ break; ++ case lldb_rbp_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBP]; ++ break; ++ case lldb_rsp_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSP]; ++ break; ++ case lldb_r8_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R8]; ++ break; ++ case lldb_r9_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R9]; ++ break; ++ case lldb_r10_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R10]; ++ break; ++ case lldb_r11_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R11]; ++ break; ++ case lldb_r12_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R12]; ++ break; ++ case lldb_r13_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R13]; ++ break; ++ case lldb_r14_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R14]; ++ break; ++ case lldb_r15_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R15]; ++ break; ++ case lldb_rip_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RIP]; ++ break; ++ case lldb_rflags_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RFLAGS]; ++ break; ++ case lldb_cs_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_CS]; ++ break; ++ case lldb_fs_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_FS]; ++ break; ++ case lldb_gs_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_GS]; ++ break; ++ case lldb_ss_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_SS]; ++ break; ++ case lldb_ds_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_DS]; ++ break; ++ case lldb_es_x86_64: ++ reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_ES]; + break; + } + @@ -514,105 +350,6 @@ + ? reg_info->name + : ""); + -+#if 0 -+ if (IsGPR(reg_index)) -+ return WriteRegisterRaw(reg_index, reg_value); -+#endif -+ -+ if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) { -+ if (reg_info->encoding == lldb::eEncodingVector) { -+ if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st) -+ ::memcpy( -+ m_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) { -+ // 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"); -+ } -+ -+ if (reg_index >= m_reg_info.first_mpxr && -+ reg_index <= m_reg_info.last_mpxr) { -+ ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes, -+ reg_value.GetBytes(), reg_value.GetByteSize()); -+ if (!CopyMPXtoXSTATE(reg_index)) -+ return Error("CopyMPXtoXSTATE() failed"); -+ } -+ -+ if (reg_index >= m_reg_info.first_mpxc && -+ reg_index <= m_reg_info.last_mpxc) { -+ ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes, -+ reg_value.GetBytes(), reg_value.GetByteSize()); -+ if (!CopyMPXtoXSTATE(reg_index)) -+ return Error("CopyMPXtoXSTATE() failed"); -+ } -+ } else { -+ // Get pointer to m_fpr.xstate.fxsave variable and set the data to it. -+ -+ // Byte offsets of all registers are calculated wrt 'UserArea' structure. -+ // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only -+ // fpu -+ // registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu registers -+ // should -+ // be written in m_fpr at byte offsets calculated wrt FPR structure. -+ -+ // Since, FPR structure is also one of the member of UserArea structure. -+ // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - -+ // byte_offset(fctrl wrt UserArea) -+ assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < -+ sizeof(m_fpr)); -+ uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - -+ m_fctrl_offset_in_userarea; -+ switch (reg_info->byte_size) { -+ case 1: -+ *(uint8_t *)dst = reg_value.GetAsUInt8(); -+ break; -+ case 2: -+ *(uint16_t *)dst = reg_value.GetAsUInt16(); -+ break; -+ case 4: -+ *(uint32_t *)dst = reg_value.GetAsUInt32(); -+ break; -+ case 8: -+ *(uint64_t *)dst = reg_value.GetAsUInt64(); -+ break; -+ default: -+ assert(false && "Unhandled data size."); -+ return Error("unhandled register data size %" PRIu32, -+ reg_info->byte_size); -+ } -+ } -+ -+ Error error = WriteFPR(); -+ if (error.Fail()) -+ return error; -+ -+ if (IsAVX(reg_index)) { -+ if (!CopyYMMtoXSTATE(reg_index, GetByteOrder())) -+ return Error("CopyYMMtoXSTATE() failed"); -+ } -+ -+ if (IsMPX(reg_index)) { -+ if (!CopyMPXtoXSTATE(reg_index)) -+ return Error("CopyMPXtoXSTATE() failed"); -+ } -+ return Error(); -+ } + return Error("failed - register wasn't recognized to be a GPR or an FPR, " + "write strategy unknown"); +} @@ -647,63 +384,13 @@ + + ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize()); + dst += GetRegisterInfoInterface().GetGPRSize(); -+ if (m_xstate_type == XStateType::FXSAVE) -+ ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave)); -+ else if (m_xstate_type == XStateType::XSAVE) { -+ lldb::ByteOrder byte_order = GetByteOrder(); -+ -+ if (IsCPUFeatureAvailable(RegSet::avx)) { -+ // Assemble the YMM register content from the register halves. -+ for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; -+ ++reg) { -+ if (!CopyXSTATEtoYMM(reg, byte_order)) { -+ error.SetErrorStringWithFormat( -+ "NativeRegisterContextNetBSD_x86_64::%s " -+ "CopyXSTATEtoYMM() failed for reg num " -+ "%" PRIu32, -+ __FUNCTION__, reg); -+ return error; -+ } -+ } -+ } -+ -+ if (IsCPUFeatureAvailable(RegSet::mpx)) { -+ for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc; -+ ++reg) { -+ if (!CopyXSTATEtoMPX(reg)) { -+ error.SetErrorStringWithFormat( -+ "NativeRegisterContextNetBSD_x86_64::%s " -+ "CopyXSTATEtoMPX() 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"); -+ } -+ /** The following code is specific to NetBSD x86 based architectures, -+ * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to -+ * -1 to solve the bug 23659, such a setting prevents the automatic -+ * decrement of the instruction pointer which was causing the SIGILL -+ * exception. -+ * **/ -+ -+ RegisterValue value((uint64_t)-1); ++ ++ RegisterValue value((uint64_t)-1); + const RegisterInfo *reg_info = + GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax"); + if (reg_info == nullptr) + reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax"); + -+#if 0 -+ if (reg_info != nullptr) -+ return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value); -+#endif -+ + return error; +} + @@ -741,261 +428,12 @@ + return error; + + src += GetRegisterInfoInterface().GetGPRSize(); -+ if (m_xstate_type == XStateType::FXSAVE) -+ ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave)); -+ else if (m_xstate_type == XStateType::XSAVE) -+ ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave)); + + error = WriteFPR(); + if (error.Fail()) + return error; + -+ if (m_xstate_type == XStateType::XSAVE) { -+ lldb::ByteOrder byte_order = GetByteOrder(); -+ -+ if (IsCPUFeatureAvailable(RegSet::avx)) { -+ // Parse the YMM register content from the register halves. -+ for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; -+ ++reg) { -+ if (!CopyYMMtoXSTATE(reg, byte_order)) { -+ error.SetErrorStringWithFormat( -+ "NativeRegisterContextNetBSD_x86_64::%s " -+ "CopyYMMtoXSTATE() failed for reg num " -+ "%" PRIu32, -+ __FUNCTION__, reg); -+ return error; -+ } -+ } -+ } -+ -+ if (IsCPUFeatureAvailable(RegSet::mpx)) { -+ for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc; -+ ++reg) { -+ if (!CopyMPXtoXSTATE(reg)) { -+ error.SetErrorStringWithFormat( -+ "NativeRegisterContextNetBSD_x86_64::%s " -+ "CopyMPXtoXSTATE() failed for reg num " -+ "%" PRIu32, -+ __FUNCTION__, reg); -+ return error; -+ } -+ } -+ } -+ } -+ + return error; +} + -+bool NativeRegisterContextNetBSD_x86_64::IsCPUFeatureAvailable( -+ RegSet feature_code) const { -+ if (m_xstate_type == XStateType::Invalid) { -+ if (const_cast(this)->ReadFPR().Fail()) -+ return false; -+ } -+ switch (feature_code) { -+ case RegSet::gpr: -+ case RegSet::fpu: -+ return true; -+ case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by -+ // reading in the XCR0 area of XSAVE. -+ if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX) -+ return true; -+ break; -+ case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by -+ // reading in the XCR0 area of XSAVE. -+ if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX) -+ return true; -+ break; -+ } -+ return false; -+} -+ -+bool NativeRegisterContextNetBSD_x86_64::IsRegisterSetAvailable( -+ uint32_t set_index) const { -+ uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets; -+ -+ switch (static_cast(set_index)) { -+ case RegSet::gpr: -+ case RegSet::fpu: -+ return (set_index < num_sets); -+ case RegSet::avx: -+ return IsCPUFeatureAvailable(RegSet::avx); -+ case RegSet::mpx: -+ return IsCPUFeatureAvailable(RegSet::mpx); -+ } -+ return false; -+} -+ -+bool NativeRegisterContextNetBSD_x86_64::IsGPR(uint32_t reg_index) const { -+ // GPRs come first. -+ return reg_index <= m_reg_info.last_gpr; -+} -+ -+bool NativeRegisterContextNetBSD_x86_64::IsFPR(uint32_t reg_index) const { -+ return (m_reg_info.first_fpr <= reg_index && -+ reg_index <= m_reg_info.last_fpr); -+} -+ -+Error NativeRegisterContextNetBSD_x86_64::WriteFPR() { -+ switch (m_xstate_type) { -+#if 0 -+ case XStateType::FXSAVE: -+ return WriteRegisterSet( -+ &m_iovec, sizeof(m_fpr.xstate.xsave), -+ fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture())); -+ case XStateType::XSAVE: -+ return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), -+ NT_X86_XSTATE); -+#endif -+ default: -+ return Error("Unrecognized FPR type."); -+ } -+} -+ -+bool NativeRegisterContextNetBSD_x86_64::IsAVX(uint32_t reg_index) const { -+ if (!IsCPUFeatureAvailable(RegSet::avx)) -+ return false; -+ return (m_reg_info.first_ymm <= reg_index && -+ reg_index <= m_reg_info.last_ymm); -+} -+ -+bool NativeRegisterContextNetBSD_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 NativeRegisterContextNetBSD_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 -+} -+ -+void *NativeRegisterContextNetBSD_x86_64::GetFPRBuffer() { -+ switch (m_xstate_type) { -+ case XStateType::FXSAVE: -+ return &m_fpr.xstate.fxsave; -+ case XStateType::XSAVE: -+ return &m_iovec; -+ default: -+ return nullptr; -+ } -+} -+ -+size_t NativeRegisterContextNetBSD_x86_64::GetFPRSize() { -+ switch (m_xstate_type) { -+ case XStateType::FXSAVE: -+ return sizeof(m_fpr.xstate.fxsave); -+ case XStateType::XSAVE: -+ return sizeof(m_iovec); -+ default: -+ return 0; -+ } -+} -+ -+Error NativeRegisterContextNetBSD_x86_64::ReadFPR() { -+ Error error; -+ -+ // Probe XSAVE and if it is not supported fall back to FXSAVE. -+ if (m_xstate_type != XStateType::FXSAVE) { -+#if 0 -+ error = -+ ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE); -+ if (!error.Fail()) { -+ m_xstate_type = XStateType::XSAVE; -+ return error; -+ } -+#endif -+ } -+#if 0 -+ error = ReadRegisterSet( -+ &m_iovec, sizeof(m_fpr.xstate.xsave), -+ fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture())); -+ if (!error.Fail()) { -+ m_xstate_type = XStateType::FXSAVE; -+ return error; -+ } -+#endif -+ return Error("Unrecognized FPR type."); -+} -+ -+bool NativeRegisterContextNetBSD_x86_64::IsMPX(uint32_t reg_index) const { -+ if (!IsCPUFeatureAvailable(RegSet::mpx)) -+ return false; -+ return (m_reg_info.first_mpxr <= reg_index && -+ reg_index <= m_reg_info.last_mpxc); -+} -+ -+bool NativeRegisterContextNetBSD_x86_64::CopyXSTATEtoMPX(uint32_t reg) { -+ if (!IsMPX(reg)) -+ return false; -+ -+ if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { -+ ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, -+ m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, -+ sizeof(MPXReg)); -+ } else { -+ ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, -+ m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, -+ sizeof(MPXCsr)); -+ } -+ return true; -+} -+ -+bool NativeRegisterContextNetBSD_x86_64::CopyMPXtoXSTATE(uint32_t reg) { -+ if (!IsMPX(reg)) -+ return false; -+ -+ if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { -+ ::memcpy(m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, -+ m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg)); -+ } else { -+ ::memcpy(m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, -+ m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr)); -+ } -+ return true; -+} -+ -+#endif // defined(__i386__) || defined(__x86_64__) ++#endif // defined(__x86_64__) diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h index 8627a386d69..738a4f3cfd7 100644 --- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h +++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h @@ -1,8 +1,8 @@ $NetBSD$ ---- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h.orig 2017-03-01 11:04:51.743978339 +0000 +--- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h.orig 2017-03-11 07:50:19.341693363 +0000 +++ source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h -@@ -0,0 +1,125 @@ +@@ -0,0 +1,82 @@ +//===-- NativeRegisterContextNetBSD_x86_64.h ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure @@ -12,11 +12,15 @@ +// +//===----------------------------------------------------------------------===// + -+#if defined(__i386__) || defined(__x86_64__) ++#if defined(__x86_64__) + +#ifndef lldb_NativeRegisterContextNetBSD_x86_64_h +#define lldb_NativeRegisterContextNetBSD_x86_64_h + ++#include ++#include ++#include ++ +#include "Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h" +#include "Plugins/Process/Utility/RegisterContext_x86.h" +#include "Plugins/Process/Utility/lldb-x86-register-enums.h" @@ -36,8 +40,6 @@ + + const RegisterSet *GetRegisterSet(uint32_t set_index) const override; + -+ uint32_t GetUserRegisterCount() const override; -+ + Error ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + @@ -51,75 +53,30 @@ +protected: + void *GetGPRBuffer() override { return &m_gpr_x86_64; } + -+ void *GetFPRBuffer() override; ++ void *GetFPRBuffer() override { return &m_fpr_x86_64; } ++ ++ void *GetDBRBuffer() override { return &m_dr_x86_64; } + -+ size_t GetFPRSize() override; ++ size_t GetFPRSize() override { return 0; } + -+ Error ReadFPR() override; ++ Error ReadFPR() override { return Error(); } + -+ Error WriteFPR() override; ++ Error WriteFPR() override { return Error(); } + +private: + // Private member types. -+ enum class XStateType { Invalid, FXSAVE, XSAVE }; + enum class RegSet { gpr, fpu, avx, mpx }; + -+ // 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 num_mpx_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_mpxr; -+ uint32_t last_mpxr; -+ uint32_t first_mpxc; -+ uint32_t last_mpxc; -+ uint32_t first_dr; -+ uint32_t gpr_flags; -+ }; -+ + // Private member variables. -+ mutable XStateType m_xstate_type; -+ FPR m_fpr; // Extended States Area, named FPR for historical reasons. -+ IOVEC m_iovec; -+ YMM m_ymm_set; -+ MPX m_mpx_set; -+ RegInfo m_reg_info; -+ uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64]; -+ uint32_t m_fctrl_offset_in_userarea; -+ -+ // Private member methods. -+ bool IsCPUFeatureAvailable(RegSet feature_code) const; -+ -+ bool IsRegisterSetAvailable(uint32_t set_index) const; -+ -+ bool IsGPR(uint32_t reg_index) const; -+ -+ bool IsFPR(uint32_t reg_index) 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; ++ struct reg m_gpr_x86_64; ++ struct fpreg m_fpr_x86_64; ++ struct dbreg m_dr_x86_64; + -+ bool CopyXSTATEtoMPX(uint32_t reg); ++ int GetSetForNativeRegNum(int reg_num) const; + -+ bool CopyMPXtoXSTATE(uint32_t reg); ++ enum { GPRegSet = 4, FPRegSet = 5, DBRegSet = 6 }; + -+ bool IsMPX(uint32_t reg_index) const; ++ int ReadRegisterSet(uint32_t set, bool force); +}; + +} // namespace process_netbsd @@ -127,4 +84,4 @@ + +#endif // #ifndef lldb_NativeRegisterContextNetBSD_x86_64_h + -+#endif // defined(__i386__) || defined(__x86_64__) ++#endif // defined(__x86_64__)