Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/register_command/TestRegisters.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/register_command/TestRegisters.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/register_command/TestRegisters.py @@ -272,14 +272,18 @@ target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) - lldbutil.run_break_set_by_symbol( - self, "main", num_expected_locations=-1) - - # Launch the process, and do not stop at the entry point. - process = target.LaunchSimple( - None, None, self.get_process_working_directory()) + # Launch the process, stop at the entry point. + error = lldb.SBError() + process = target.Launch( + lldb.SBListener(), + None, None, # argv, envp + None, None, None, # stdin/out/err + self.get_process_working_directory(), + 0, # launch flags + True, # stop at entry + error) + self.assertTrue(error.Success(), "Launch succeeds. Error is :" + str(error)) - process = target.GetProcess() self.assertTrue( process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h @@ -136,6 +136,8 @@ bool CopyMPXtoXSTATE(uint32_t reg); bool IsMPX(uint32_t reg_index) const; + + void UpdateXSTATEforWrite(uint32_t reg_index); }; } // namespace process_linux Index: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp @@ -528,6 +528,22 @@ return error; } +void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite( + uint32_t reg_index) { + XSAVE_HDR::XFeature &xstate_bv = m_fpr.xstate.xsave.header.xstate_bv; + if (IsFPR(reg_index)) { + // IsFPR considers both %st and %xmm registers as floating point, but these + // map to two features. Set both flags, just in case. + xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE; + } else if (IsAVX(reg_index)) { + // Lower bytes of some %ymm registers are shared with %xmm registers. + xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE; + } else if (IsMPX(reg_index)) { + // MPX registers map to two XSAVE features. + xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR; + } +} + Status NativeRegisterContextLinux_x86_64::WriteRegister( const RegisterInfo *reg_info, const RegisterValue ®_value) { assert(reg_info && "reg_info is null"); @@ -538,6 +554,8 @@ ? reg_info->name : ""); + UpdateXSTATEforWrite(reg_index); + if (IsGPR(reg_index)) return WriteRegisterRaw(reg_index, reg_value); Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -149,9 +149,10 @@ RegInfo m_reg_info; FPRType m_fpr_type; // determines the type of data stored by union FPR, if any. - FPR m_fpr; // floating-point registers including extended register sets. - IOVEC m_iovec; // wrapper for xsave. - YMM m_ymm_set; // copy of ymmh and xmm register halves. + lldb_private::FPR m_fpr; // floating-point registers including extended + // register sets. + lldb_private::IOVEC m_iovec; // wrapper for xsave. + lldb_private::YMM m_ymm_set; // copy of ymmh and xmm register halves. std::unique_ptr m_register_info_ap; // Register Info Interface (FreeBSD or Linux) Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContext_x86.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterContext_x86.h +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -13,8 +13,10 @@ #include #include +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/Support/Compiler.h" +namespace lldb_private { //--------------------------------------------------------------------------- // i386 ehframe, dwarf regnums //--------------------------------------------------------------------------- @@ -313,13 +315,28 @@ LLVM_PACKED_START struct XSAVE_HDR { - uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states + enum class XFeature : uint64_t { + FP = 1, + SSE = FP << 1, + YMM = SSE << 1, + BNDREGS = YMM << 1, + BNDCSR = BNDREGS << 1, + OPMASK = BNDCSR << 1, + ZMM_Hi256 = OPMASK << 1, + Hi16_ZMM = ZMM_Hi256 << 1, + PT = Hi16_ZMM << 1, + PKRU = PT << 1, + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ PKRU) + }; + + XFeature xstate_bv; // OS enabled xstate mask to determine the extended states // supported by the processor - uint64_t xcomp_bv; // Mask to indicate the format of the XSAVE area and of + XFeature xcomp_bv; // Mask to indicate the format of the XSAVE area and of // the XRSTOR instruction uint64_t reserved1[1]; uint64_t reserved2[5]; }; +static_assert(sizeof(XSAVE_HDR) == 64, "XSAVE_HDR layout incorrect"); LLVM_PACKED_END // x86 extensions to FXSAVE (i.e. for AVX and MPX processors) @@ -355,4 +372,8 @@ size_t iov_len; // sizeof(XSAVE) }; +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +} // namespace lldb_private + #endif