Skip to content

Commit 7cc45f1

Browse files
committed
[lldb][debugserver] Save and restore the SVE/SME register state
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
1 parent 749c20b commit 7cc45f1

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2953,7 +2953,14 @@ kern_return_t DNBArchMachARM64::SetRegisterState(int set) {
29532953

29542954
switch (set) {
29552955
case e_regSetALL:
2956-
return SetGPRState() | SetVFPState() | SetEXCState() | SetDBGState(false);
2956+
{
2957+
kern_return_t ret = SetGPRState() | SetVFPState() | SetEXCState() | SetDBGState(false);
2958+
if (CPUHasSME()) {
2959+
ret |= SetSVEState();
2960+
ret |= SetSMEState();
2961+
}
2962+
return ret;
2963+
}
29572964
case e_regSetGPR:
29582965
return SetGPRState();
29592966
case e_regSetVFP:
@@ -3122,6 +3129,15 @@ uint32_t DNBArchMachARM64::SaveRegisterState() {
31223129
DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::SaveRegisterState () "
31233130
"error: %s regs failed to read: %u",
31243131
"VFP", kret);
3132+
} else if (CPUHasSME() && (kret = SetSVEState() != KERN_SUCCESS)) {
3133+
DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::SaveRegisterState () "
3134+
"error: %s regs failed to read: %u",
3135+
"SVE", kret);
3136+
}
3137+
else if (CPUHasSME() && (kret = SetSMEState() != KERN_SUCCESS)) {
3138+
DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::SaveRegisterState () "
3139+
"error: %s regs failed to read: %u",
3140+
"SME", kret);
31253141
} else {
31263142
const uint32_t save_id = GetNextRegisterStateSaveID();
31273143
m_saved_register_states[save_id] = m_state.context;
@@ -3149,6 +3165,18 @@ bool DNBArchMachARM64::RestoreRegisterState(uint32_t save_id) {
31493165
"write: %u",
31503166
save_id, "VFP", kret);
31513167
success = false;
3168+
} else if ((kret = SetSVEState()) != KERN_SUCCESS) {
3169+
DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::RestoreRegisterState "
3170+
"(save_id = %u) error: %s regs failed to "
3171+
"write: %u",
3172+
save_id, "SVE", kret);
3173+
success = false;
3174+
} else if ((kret = SetSMEState()) != KERN_SUCCESS) {
3175+
DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM64::RestoreRegisterState "
3176+
"(save_id = %u) error: %s regs failed to "
3177+
"write: %u",
3178+
save_id, "SME", kret);
3179+
success = false;
31523180
}
31533181
m_saved_register_states.erase(pos);
31543182
return success;

0 commit comments

Comments
 (0)