Author: Jason Molenda Date: 2025-04-02T20:37:07-07:00 New Revision: 4e40c7c4bd66d98f529a807dbf410dc46444f4ca
URL: https://github.com/llvm/llvm-project/commit/4e40c7c4bd66d98f529a807dbf410dc46444f4ca DIFF: https://github.com/llvm/llvm-project/commit/4e40c7c4bd66d98f529a807dbf410dc46444f4ca.diff LOG: [lldb][debugserver] Save and restore the SVE/SME register state (#134184) debugserver isn't saving and restoring the SVE/SME register state around inferior function calls. Making arbitrary function calls while in Streaming SVE mode is generally a poor idea because a NEON instruction can be hit and crash the expression execution, which is how I missed this, but they should be handled correctly if the user knows it is safe to do. rdar://146886210 Added: Modified: lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp Removed: ################################################################################ diff --git a/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp b/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp index 34a4ee21f8502..d32a63daa5672 100644 --- a/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp @@ -2952,8 +2952,15 @@ kern_return_t DNBArchMachARM64::SetRegisterState(int set) { return err; switch (set) { - case e_regSetALL: - return SetGPRState() | SetVFPState() | SetEXCState() | SetDBGState(false); + case e_regSetALL: { + kern_return_t ret = + SetGPRState() | SetVFPState() | SetEXCState() | SetDBGState(false); + if (CPUHasSME()) { + ret |= SetSVEState(); + ret |= SetSMEState(); + } + return ret; + } case e_regSetGPR: return SetGPRState(); case e_regSetVFP: @@ -3119,9 +3126,20 @@ uint32_t DNBArchMachARM64::SaveRegisterState() { "error: GPR regs failed to read: %u ", kret); } else if ((kret = GetVFPState(force)) != KERN_SUCCESS) { - DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::SaveRegisterState () " - "error: %s regs failed to read: %u", + DNBLogThreadedIf(LOG_THREAD, + "DNBArchMachARM64::SaveRegisterState () " + "error: %s regs failed to read: %u", "VFP", kret); + } else if (CPUHasSME() && (kret = SetSVEState() != KERN_SUCCESS)) { + DNBLogThreadedIf(LOG_THREAD, + "DNBArchMachARM64::SaveRegisterState () " + "error: %s regs failed to read: %u", + "SVE", kret); + } else if (CPUHasSME() && (kret = SetSMEState() != KERN_SUCCESS)) { + DNBLogThreadedIf(LOG_THREAD, + "DNBArchMachARM64::SaveRegisterState () " + "error: %s regs failed to read: %u", + "SME", kret); } else { const uint32_t save_id = GetNextRegisterStateSaveID(); m_saved_register_states[save_id] = m_state.context; @@ -3144,11 +3162,26 @@ bool DNBArchMachARM64::RestoreRegisterState(uint32_t save_id) { save_id, kret); success = false; } else if ((kret = SetVFPState()) != KERN_SUCCESS) { - DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::RestoreRegisterState " - "(save_id = %u) error: %s regs failed to " - "write: %u", + DNBLogThreadedIf(LOG_THREAD, + "DNBArchMachARM64::RestoreRegisterState " + "(save_id = %u) error: %s regs failed to " + "write: %u", save_id, "VFP", kret); success = false; + } else if ((kret = SetSVEState()) != KERN_SUCCESS) { + DNBLogThreadedIf(LOG_THREAD, + "DNBArchMachARM64::RestoreRegisterState " + "(save_id = %u) error: %s regs failed to " + "write: %u", + save_id, "SVE", kret); + success = false; + } else if ((kret = SetSMEState()) != KERN_SUCCESS) { + DNBLogThreadedIf(LOG_THREAD, + "DNBArchMachARM64::RestoreRegisterState " + "(save_id = %u) error: %s regs failed to " + "write: %u", + save_id, "SME", kret); + success = false; } m_saved_register_states.erase(pos); return success; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits