@@ -199,6 +199,24 @@ uint64_t DNBArchMachARM64::GetSP(uint64_t failValue) {
199199 return failValue;
200200}
201201
202+ static void log_signed_registers (arm_thread_state64_t *gpr, const char *desc) {
203+ if (DNBLogEnabledForAny (LOG_THREAD)) {
204+ const char *log_str = " %s signed regs "
205+ " \n fp=%16.16llx"
206+ " \n lr=%16.16llx"
207+ " \n sp=%16.16llx"
208+ " \n pc=%16.16llx" ;
209+ #if defined(DEBUGSERVER_IS_ARM64E)
210+ DNBLogThreaded (log_str, desc, reinterpret_cast <uint64_t >(gpr->__opaque_fp ),
211+ reinterpret_cast <uint64_t >(gpr->__opaque_lr ),
212+ reinterpret_cast <uint64_t >(gpr->__opaque_sp ),
213+ reinterpret_cast <uint64_t >(gpr->__opaque_pc ));
214+ #else
215+ DNBLogThreaded (log_str, desc, gpr->__fp , gpr->__lr , gpr->__sp , gpr->__pc );
216+ #endif
217+ }
218+ }
219+
202220kern_return_t DNBArchMachARM64::GetGPRState (bool force) {
203221 int set = e_regSetGPR;
204222 // Check if we have valid cached registers
@@ -210,25 +228,29 @@ kern_return_t DNBArchMachARM64::GetGPRState(bool force) {
210228 kern_return_t kret =
211229 ::thread_get_state (m_thread->MachPortNumber (), ARM_THREAD_STATE64,
212230 (thread_state_t )&m_state.context.gpr, &count);
213- if (DNBLogEnabledForAny(LOG_THREAD)) {
214- uint64_t *x = &m_state.context .gpr .__x [0 ];
231+ log_signed_registers (&m_state.context.gpr, " Values from thread_get_state" );
215232
216- const char *log_str = " thread_get_state signed regs "
217- " \n fp=%16.16llx"
218- " \n lr=%16.16llx"
219- " \n sp=%16.16llx"
220- " \n pc=%16.16llx" ;
221- #if defined(DEBUGSERVER_IS_ARM64E)
222- DNBLogThreaded (log_str,
223- reinterpret_cast <uint64_t >(m_state.context .gpr .__opaque_fp ),
224- reinterpret_cast <uint64_t >(m_state.context .gpr .__opaque_lr ),
225- reinterpret_cast <uint64_t >(m_state.context .gpr .__opaque_sp ),
226- reinterpret_cast <uint64_t >(m_state.context .gpr .__opaque_pc ));
227- #else
228- DNBLogThreaded (log_str, m_state.context .gpr .__fp , m_state.context .gpr .__lr ,
229- m_state.context .gpr .__sp , m_state.context .gpr .__pc );
230- #endif
233+ #if defined(THREAD_CONVERT_THREAD_STATE_TO_SELF) && defined(__LP64__)
234+ if (kret == KERN_SUCCESS) {
235+ mach_msg_type_number_t newcount = ARM_THREAD_STATE64_COUNT;
236+ arm_thread_state64_t new_gpr;
237+ kern_return_t convert_kret = thread_convert_thread_state (
238+ m_thread->MachPortNumber (), THREAD_CONVERT_THREAD_STATE_TO_SELF,
239+ ARM_THREAD_STATE64, (thread_state_t )&m_state.context .gpr , count,
240+ (thread_state_t )&new_gpr, &newcount);
241+ DNBLogThreadedIf (
242+ LOG_THREAD,
243+ " converted register values "
244+ " to debugserver's keys, return value %d, old count %d new count %d" ,
245+ convert_kret, count, newcount);
246+ if (convert_kret == KERN_SUCCESS)
247+ memcpy (&m_state.context .gpr , &new_gpr, count * 4 );
248+ log_signed_registers (&m_state.context .gpr ,
249+ " Values after thread_convert_thread_state" );
250+ }
251+ #endif // THREAD_CONVERT_THREAD_STATE_TO_SELF
231252
253+ if (DNBLogEnabledForAny(LOG_THREAD)) {
232254#if defined(DEBUGSERVER_IS_ARM64E)
233255 uint64_t log_fp = clear_pac_bits (
234256 reinterpret_cast <uint64_t >(m_state.context .gpr .__opaque_fp ));
@@ -244,6 +266,7 @@ kern_return_t DNBArchMachARM64::GetGPRState(bool force) {
244266 uint64_t log_sp = m_state.context .gpr .__sp ;
245267 uint64_t log_pc = m_state.context .gpr .__pc ;
246268#endif
269+ uint64_t *x = &m_state.context .gpr .__x [0 ];
247270 DNBLogThreaded (
248271 " thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = %u) regs"
249272 " \n x0=%16.16llx"
@@ -567,10 +590,28 @@ kern_return_t DNBArchMachARM64::GetSMEState(bool force) {
567590}
568591
569592kern_return_t DNBArchMachARM64::SetGPRState () {
593+ arm_thread_state64_t *state_to_set = &m_state.context .gpr ;
594+ #if defined(THREAD_CONVERT_THREAD_STATE_FROM_SELF) && defined(__LP64__)
595+ mach_msg_type_number_t count = ARM_THREAD_STATE64_COUNT;
596+ mach_msg_type_number_t new_count = ARM_THREAD_STATE64_COUNT;
597+ arm_thread_state64_t new_gpr;
598+ memcpy (&new_gpr, &m_state.context .gpr , count * 4 );
599+ kern_return_t convert_kret = thread_convert_thread_state (
600+ m_thread->MachPortNumber (), THREAD_CONVERT_THREAD_STATE_FROM_SELF,
601+ ARM_THREAD_STATE64, (thread_state_t )&m_state.context .gpr , count,
602+ (thread_state_t )&new_gpr, &new_count);
603+ if (convert_kret == KERN_SUCCESS)
604+ state_to_set = &new_gpr;
605+ DNBLogThreadedIf (LOG_THREAD,
606+ " converted register values "
607+ " to inferior's keys, return value %d, count %d" ,
608+ convert_kret, new_count);
609+ #endif // THREAD_CONVERT_THREAD_STATE_TO_SELF
610+
570611 int set = e_regSetGPR;
571- kern_return_t kret = :: thread_set_state (
572- m_thread->MachPortNumber (), ARM_THREAD_STATE64,
573- (thread_state_t )&m_state. context . gpr , e_regSetGPRCount);
612+ kern_return_t kret =
613+ ::thread_set_state ( m_thread->MachPortNumber (), ARM_THREAD_STATE64,
614+ (thread_state_t )state_to_set , e_regSetGPRCount);
574615 m_state.SetError(set, Write,
575616 kret); // Set the current write error for this register set
576617 m_state.InvalidateRegisterSetState (set); // Invalidate the current register
0 commit comments