@@ -1821,47 +1821,61 @@ PAL_ERROR InjectActivationInternal(CorUnix::CPalThread* pThread)
1821
1821
if (palError == NO_ERROR)
1822
1822
{
1823
1823
mach_port_t thread = pThread->GetMachPortSelf ();
1824
- x86_thread_state64_t ThreadState;
1825
- mach_msg_type_number_t count = sizeof (ThreadState)/sizeof (natural_t );
1824
+ mach_msg_type_number_t count;
1826
1825
kern_return_t MachRet;
1827
1826
1827
+ x86_exception_state64_t ExceptionState;
1828
+ count = x86_EXCEPTION_STATE64_COUNT;
1828
1829
MachRet = thread_get_state (thread,
1829
- x86_THREAD_STATE64 ,
1830
- (thread_state_t )&ThreadState ,
1830
+ x86_EXCEPTION_STATE64 ,
1831
+ (thread_state_t )&ExceptionState ,
1831
1832
&count);
1832
- _ASSERT_MSG (MachRet == KERN_SUCCESS, " thread_get_state\n " );
1833
+ _ASSERT_MSG (MachRet == KERN_SUCCESS, " thread_get_state for x86_EXCEPTION_STATE64 \n " );
1833
1834
1834
- if ((g_safeActivationCheckFunction != NULL ) && g_safeActivationCheckFunction (ThreadState.__rip ))
1835
+ // Inject the activation only if the thread doesn't have a pending hardware exception
1836
+ static const int MaxHardwareExceptionVector = 31 ;
1837
+ if (ExceptionState.__trapno > MaxHardwareExceptionVector)
1835
1838
{
1836
- // TODO: it would be nice to preserve the red zone in case a jitter would want to use it
1837
- // Do we really care about unwinding through the wrapper?
1838
- size_t * sp = (size_t *)ThreadState.__rsp ;
1839
- *(--sp) = ThreadState.__rip ;
1840
- *(--sp) = ThreadState.__rbp ;
1841
- size_t rbpAddress = (size_t )sp;
1842
- size_t contextAddress = (((size_t )sp) - sizeof (CONTEXT)) & ~15 ;
1843
- size_t returnAddressAddress = contextAddress - sizeof (size_t );
1844
- *(size_t *)(returnAddressAddress) = ActivationHandlerReturnOffset + (size_t )ActivationHandlerWrapper;
1845
-
1846
- // Fill in the context in the helper frame with the full context of the suspended thread.
1847
- // The ActivationHandler will use the context to resume the execution of the thread
1848
- // after the activation function returns.
1849
- CONTEXT *pContext = (CONTEXT *)contextAddress;
1850
- pContext->ContextFlags = CONTEXT_FULL | CONTEXT_SEGMENTS;
1851
- MachRet = CONTEXT_GetThreadContextFromPort (thread, pContext);
1852
- _ASSERT_MSG (MachRet == KERN_SUCCESS, " CONTEXT_GetThreadContextFromPort\n " );
1853
-
1854
- // Make the instruction register point to ActivationHandler
1855
- ThreadState.__rip = (size_t )ActivationHandler;
1856
- ThreadState.__rsp = returnAddressAddress;
1857
- ThreadState.__rbp = rbpAddress;
1858
- ThreadState.__rdi = contextAddress;
1859
-
1860
- MachRet = thread_set_state (thread,
1839
+ x86_thread_state64_t ThreadState;
1840
+ count = x86_THREAD_STATE64_COUNT;
1841
+ MachRet = thread_get_state (thread,
1861
1842
x86_THREAD_STATE64,
1862
1843
(thread_state_t )&ThreadState,
1863
- count);
1864
- _ASSERT_MSG (MachRet == KERN_SUCCESS, " thread_set_state\n " );
1844
+ &count);
1845
+ _ASSERT_MSG (MachRet == KERN_SUCCESS, " thread_get_state for x86_THREAD_STATE64\n " );
1846
+
1847
+ if ((g_safeActivationCheckFunction != NULL ) && g_safeActivationCheckFunction (ThreadState.__rip ))
1848
+ {
1849
+ // TODO: it would be nice to preserve the red zone in case a jitter would want to use it
1850
+ // Do we really care about unwinding through the wrapper?
1851
+ size_t * sp = (size_t *)ThreadState.__rsp ;
1852
+ *(--sp) = ThreadState.__rip ;
1853
+ *(--sp) = ThreadState.__rbp ;
1854
+ size_t rbpAddress = (size_t )sp;
1855
+ size_t contextAddress = (((size_t )sp) - sizeof (CONTEXT)) & ~15 ;
1856
+ size_t returnAddressAddress = contextAddress - sizeof (size_t );
1857
+ *(size_t *)(returnAddressAddress) = ActivationHandlerReturnOffset + (size_t )ActivationHandlerWrapper;
1858
+
1859
+ // Fill in the context in the helper frame with the full context of the suspended thread.
1860
+ // The ActivationHandler will use the context to resume the execution of the thread
1861
+ // after the activation function returns.
1862
+ CONTEXT *pContext = (CONTEXT *)contextAddress;
1863
+ pContext->ContextFlags = CONTEXT_FULL | CONTEXT_SEGMENTS;
1864
+ MachRet = CONTEXT_GetThreadContextFromPort (thread, pContext);
1865
+ _ASSERT_MSG (MachRet == KERN_SUCCESS, " CONTEXT_GetThreadContextFromPort\n " );
1866
+
1867
+ // Make the instruction register point to ActivationHandler
1868
+ ThreadState.__rip = (size_t )ActivationHandler;
1869
+ ThreadState.__rsp = returnAddressAddress;
1870
+ ThreadState.__rbp = rbpAddress;
1871
+ ThreadState.__rdi = contextAddress;
1872
+
1873
+ MachRet = thread_set_state (thread,
1874
+ x86_THREAD_STATE64,
1875
+ (thread_state_t )&ThreadState,
1876
+ count);
1877
+ _ASSERT_MSG (MachRet == KERN_SUCCESS, " thread_set_state\n " );
1878
+ }
1865
1879
}
1866
1880
1867
1881
palError = pCurrentThread->suspensionInfo .InternalResumeThreadFromData (
0 commit comments