Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define lldb_NativeRegisterContextLinux_x86_64_h

#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
#include "Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h"
#include "Plugins/Process/Utility/RegisterContext_x86.h"
#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
#include <sys/uio.h>
Expand All @@ -21,7 +22,9 @@ namespace process_linux {

class NativeProcessLinux;

class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
class NativeRegisterContextLinux_x86_64
: public NativeRegisterContextLinux,
public NativeRegisterContextWatchpoint_x86 {
public:
NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
NativeThreadProtocol &native_thread);
Expand All @@ -42,28 +45,6 @@ class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {

Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;

Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;

Status GetWatchpointHitIndex(uint32_t &wp_index,
lldb::addr_t trap_addr) override;

Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;

bool ClearHardwareWatchpoint(uint32_t wp_index) override;

Status ClearAllHardwareWatchpoints() override;

Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
uint32_t watch_flags,
uint32_t wp_index);

uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
uint32_t watch_flags) override;

lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;

uint32_t NumSupportedHardwareWatchpoints() override;

llvm::Optional<SyscallData> GetSyscallData() override;

llvm::Optional<MmapData> GetMmapData() override;
Expand Down Expand Up @@ -109,6 +90,7 @@ class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
uint32_t first_mpxc;
uint32_t last_mpxc;
uint32_t first_dr;
uint32_t last_dr;
uint32_t gpr_flags;
};

Expand All @@ -132,6 +114,8 @@ class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {

bool IsFPR(uint32_t reg_index) const;

bool IsDR(uint32_t reg_index) const;

bool CopyXSTATEtoYMM(uint32_t reg_index, lldb::ByteOrder byte_order);

bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,8 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
return error;
}

uint64_t new_xstate_bv = XCR0_X87; // the most common case

switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
case llvm::Triple::x86_64:
break;
Expand Down Expand Up @@ -918,9 +920,11 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
break;
case lldb_mxcsr_x86_64:
m_xstate.xs_fxsave.fx_mxcsr = reg_value.GetAsUInt32();
new_xstate_bv = XCR0_SSE;
break;
case lldb_mxcsrmask_x86_64:
m_xstate.xs_fxsave.fx_mxcsr_mask = reg_value.GetAsUInt32();
new_xstate_bv = XCR0_SSE;
break;
case lldb_st0_x86_64:
case lldb_st1_x86_64:
Expand Down Expand Up @@ -966,6 +970,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
} else {
::memcpy(&m_xstate.xs_fxsave.fx_xmm[reg - lldb_xmm0_x86_64],
reg_value.GetBytes(), reg_value.GetByteSize());
new_xstate_bv = XCR0_SSE;
}
break;
case lldb_ymm0_x86_64:
Expand Down Expand Up @@ -994,6 +999,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
YMMToXState(ymm, m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
new_xstate_bv = XCR0_SSE | XCR0_YMM_Hi128;
}
break;
case lldb_dr0_x86_64:
Expand All @@ -1010,6 +1016,9 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
llvm_unreachable("Reading unknown/unsupported register");
}

if (set == XStateRegSet)
m_xstate.xs_xstate_bv |= new_xstate_bv;

return WriteRegisterSet(set);
}

Expand Down
2 changes: 1 addition & 1 deletion lldb/test/Shell/Register/Inputs/x86-64-write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ union alignas(16) xmm_t {

int main() {
constexpr xmm_t xmm_fill = {
.as_uint64 = { 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F }
.as_uint64 = { 0, 0 }
};

uint64_t r64[8];
Expand Down
2 changes: 1 addition & 1 deletion lldb/test/Shell/Register/Inputs/x86-mm-xmm-write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ union alignas(16) xmm_t {

int main() {
constexpr xmm_t xmm_fill = {
.as_uint64 = { 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F }
.as_uint64 = { 0, 0 }
};

uint64_t mm[8];
Expand Down
3 changes: 1 addition & 2 deletions lldb/test/Shell/Register/Inputs/x86-ymm-write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ union alignas(32) ymm_t {

int main() {
constexpr ymm_t ymm_fill = {
.as_uint64 = { 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F,
0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F }
.as_uint64 = { 0, 0, 0, 0 }
};

ymm_t ymm[16];
Expand Down
5 changes: 1 addition & 4 deletions lldb/test/Shell/Register/Inputs/x86-zmm-write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ union alignas(64) zmm_t {

int main() {
constexpr zmm_t zmm_fill = {
.as_uint64 = { 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F,
0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F,
0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F,
0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F }
.as_uint64 = { 0, 0, 0, 0, 0, 0, 0, 0 }
};

zmm_t zmm[32];
Expand Down