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

Reply via email to