diff options
author | Jan Kotas <jkotas@microsoft.com> | 2016-01-07 03:36:16 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2016-01-07 03:36:16 +0300 |
commit | 69e69b7acd28f30de630c6269b066433ad24bbf4 (patch) | |
tree | 7414eb908d922d828e0a617e3b41c18848f633d1 /src/Native | |
parent | ff6fb1968ce5dbdaec33b22733b7c55fc07b9846 (diff) |
Native part of previous commit
[tfs-changeset: 1561881]
Diffstat (limited to 'src/Native')
-rw-r--r-- | src/Native/Runtime/EHHelpers.cpp | 83 | ||||
-rw-r--r-- | src/Native/Runtime/StackFrameIterator.cpp | 150 | ||||
-rw-r--r-- | src/Native/Runtime/amd64/ExceptionHandling.asm | 76 | ||||
-rw-r--r-- | src/Native/Runtime/arm/ExceptionHandling.asm | 54 | ||||
-rw-r--r-- | src/Native/Runtime/i386/ExceptionHandling.asm | 31 | ||||
-rw-r--r-- | src/Native/Runtime/thread.cpp | 22 | ||||
-rw-r--r-- | src/Native/Runtime/thread.h | 2 |
7 files changed, 158 insertions, 260 deletions
diff --git a/src/Native/Runtime/EHHelpers.cpp b/src/Native/Runtime/EHHelpers.cpp index a2fb1c297..bab2d116b 100644 --- a/src/Native/Runtime/EHHelpers.cpp +++ b/src/Native/Runtime/EHHelpers.cpp @@ -25,50 +25,39 @@ #include "thread.h" #include "stressLog.h" -// Find the module containing the given address, which is a return address from a managed function. The +// Find the module containing the given address, which might be a return address from a managed function. The // address may be to another managed function, or it may be to an unmanaged function, or it may be to a GC // hijack. The address may also refer to an EEType if we've been called from RhpGetClasslibFunction. If it is // a GC hijack, we will recgonize that and use the real return address, updating the address passed in. -static Module * FindModuleRespectingReturnAddressHijacks(void ** pAddress) +static Module * FindModuleRespectingReturnAddressHijacks(void * address) { RuntimeInstance * pRI = GetRuntimeInstance(); - // Try looking up the module assuming the address is for code first. Fall back to a read-only data looukp - // if that fails. If we have data indicating that the data case is more common then we can reverse the - // order of checks. Finally check read/write data: generic EETypes live there since they need to be fixed - // up at runtime to support unification. - Module * pModule = pRI->FindModuleByCodeAddress(*pAddress); + // Try looking up the module assuming the address is for code first. This is expected to be most common. + Module * pModule = pRI->FindModuleByCodeAddress(address); if (pModule == NULL) { - pModule = pRI->FindModuleByReadOnlyDataAddress(*pAddress); - - if (pModule == NULL) - pModule = pRI->FindModuleByDataAddress(*pAddress); - - if (pModule == NULL) + // Less common, we will look for the address in any of the sections of the module. This is slower, but is + // necessary for EEType pointers and jump stubs. + pModule = pRI->FindModuleByAddress(address); + + // Corner-case: The thread might be hijacked -- @TODO: this is a bit brittle because there is no validation that + // the hijacked return address from the thread is actually related to place where the caller got the hijack + // target. + Thread * pCurThread = ThreadStore::GetCurrentThread(); + if ((pModule == NULL) && pCurThread->IsHijacked() && Thread::IsHijackTarget(address)) { - // Hmmm... we didn't find a managed module for the given PC. We have a return address in unmanaged - // code, but it could be because the thread is hijacked for GC suspension. If it is then we should - // get the real return address and try again. - Thread * pCurThread = ThreadStore::GetCurrentThread(); - - if (!pCurThread->IsHijacked()) - { - // The PC isn't in a managed module, and there is no hijack in place, so we have no EH info. - return NULL; - } - - // Update the PC passed in to reflect the correct return address. - *pAddress = pCurThread->GetHijackedReturnAddress(); + pModule = pRI->FindModuleByCodeAddress(pCurThread->GetHijackedReturnAddress()); - pModule = pRI->FindModuleByCodeAddress(*pAddress); + ASSERT_MSG(pModule != NULL, "expected to find the module for a hijacked return address"); } } return pModule; } -COOP_PINVOKE_HELPER(Boolean, RhpEHEnumInitFromStackFrameIterator, (StackFrameIterator* pFrameIter, void ** pMethodStartAddressOut, EHEnum* pEHEnum)) +COOP_PINVOKE_HELPER(Boolean, RhpEHEnumInitFromStackFrameIterator, ( + StackFrameIterator* pFrameIter, void ** pMethodStartAddressOut, EHEnum* pEHEnum)) { ICodeManager * pCodeManager = pFrameIter->GetCodeManager(); pEHEnum->m_pCodeManager = pCodeManager; @@ -81,14 +70,6 @@ COOP_PINVOKE_HELPER(Boolean, RhpEHEnumNext, (EHEnum* pEHEnum, EHClause* pEHClaus return pEHEnum->m_pCodeManager->EHEnumNext(&pEHEnum->m_state, pEHClause); } -// The EH dispatch code needs to know the original return address of a method, even if it has been hijacked. -// We provide this here without modifying the hijack and the EHJump helper will honor the hijack when it -// attempts to dispatch up the stack. -COOP_PINVOKE_HELPER(void*, RhpGetUnhijackedReturnAddress, (void** ppvReturnAddressLocation)) -{ - return ThreadStore::GetCurrentThread()->GetUnhijackedReturnAddress(ppvReturnAddressLocation); -} - //------------------------------------------------------------------------------------------------------------ // @TODO:EXCEPTIONS: the code below is related to throwing exceptions out of Rtm. If we did not have to throw // out of Rtm, then we would note have to have the code below to get a classlib exception object given @@ -117,7 +98,7 @@ COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunction, (void * address, ClasslibFun // Find the module contianing the given address, which is an address into some managed module. It could // be code, or it could be an EEType. No matter what, it's an address into a managed module in some non-Rtm // type system. - Module * pModule = FindModuleRespectingReturnAddressHijacks(&address); + Module * pModule = FindModuleRespectingReturnAddressHijacks(address); // If the address isn't in a managed module then we have no classlib function. if (pModule == NULL) @@ -238,6 +219,14 @@ struct DISPATCHER_CONTEXT // N.B. There is more here (so this struct isn't the right size), but we ignore everything else }; +#ifdef _X86_ +struct EXCEPTION_REGISTRATION_RECORD +{ + UIntNative Next; + UIntNative Handler; +}; +#endif // _X86_ + EXTERN_C void __cdecl RhpFailFastForPInvokeExceptionPreemp(IntNative PInvokeCallsiteReturnAddr, void* pExceptionRecord, void* pContextRecord); EXTERN_C void REDHAWK_CALLCONV RhpFailFastForPInvokeExceptionCoop(IntNative PInvokeCallsiteReturnAddr, @@ -245,10 +234,11 @@ EXTERN_C void REDHAWK_CALLCONV RhpFailFastForPInvokeExceptionCoop(IntNative PInv Int32 __stdcall RhpVectoredExceptionHandler(PEXCEPTION_POINTERS pExPtrs); EXTERN_C Int32 __stdcall RhpPInvokeExceptionGuard(PEXCEPTION_RECORD pExceptionRecord, - UIntNative /*MemoryStackFp*/, + UIntNative EstablisherFrame, PCONTEXT pContextRecord, DISPATCHER_CONTEXT * pDispatcherContext) { + UNREFERENCED_PARAMETER(EstablisherFrame); #ifdef APP_LOCAL_RUNTIME UNREFERENCED_PARAMETER(pDispatcherContext); // @@ -274,16 +264,29 @@ EXTERN_C Int32 __stdcall RhpPInvokeExceptionGuard(PEXCEPTION_RECORD pExcep if (pThread->IsDoNotTriggerGcSet()) RhFailFast(); - IntNative pinvokeCallsiteReturnAddr = (IntNative)pThread->GetCurrentThreadPInvokeReturnAddress(); // We promote exceptions that were not converted to managed exceptions to a FailFast. However, we have to // be careful because we got here via OS SEH infrastructure and, therefore, don't know what GC mode we're // currently in. As a result, since we're calling back into managed code to handle the FailFast, we must // correctly call either a NativeCallable or a RuntimeExport version of the same method. if (pThread->IsCurrentThreadInCooperativeMode()) - RhpFailFastForPInvokeExceptionCoop(pinvokeCallsiteReturnAddr, pExceptionRecord, pContextRecord); + { + // Cooperative mode -- Typically, RhpVectoredExceptionHandler will handle this because the faulting IP will be + // in managed code. But sometimes we AV on a bad call indirect or something similar. In that situation, we can + // use the dispatcher context or exception registration record to find the relevant classlib. +#ifdef _X86_ + IntNative classlibBreadcrumb = ((EXCEPTION_REGISTRATION_RECORD*)EstablisherFrame)->Handler; +#else + IntNative classlibBreadcrumb = pDispatcherContext->ControlPc; +#endif + RhpFailFastForPInvokeExceptionCoop(classlibBreadcrumb, pExceptionRecord, pContextRecord); + } else + { + // Preemptive mode -- the classlib associated with the last pinvoke owns the fail fast behavior. + IntNative pinvokeCallsiteReturnAddr = (IntNative)pThread->GetCurrentThreadPInvokeReturnAddress(); RhpFailFastForPInvokeExceptionPreemp(pinvokeCallsiteReturnAddr, pExceptionRecord, pContextRecord); + } return 0; } diff --git a/src/Native/Runtime/StackFrameIterator.cpp b/src/Native/Runtime/StackFrameIterator.cpp index e424b305c..aa056d42e 100644 --- a/src/Native/Runtime/StackFrameIterator.cpp +++ b/src/Native/Runtime/StackFrameIterator.cpp @@ -494,71 +494,97 @@ bool StackFrameIterator::HandleFuncletInvokeThunk() ); #endif + bool isFilterInvoke = EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallFilterFunclet2); + #ifdef _TARGET_AMD64_ - // Save the preserved regs portion of the REGDISPLAY across the unwind through the C# EH dispatch code. - m_funcletPtrs.pRbp = m_RegDisplay.pRbp; - m_funcletPtrs.pRdi = m_RegDisplay.pRdi; - m_funcletPtrs.pRsi = m_RegDisplay.pRsi; - m_funcletPtrs.pRbx = m_RegDisplay.pRbx; - m_funcletPtrs.pR12 = m_RegDisplay.pR12; - m_funcletPtrs.pR13 = m_RegDisplay.pR13; - m_funcletPtrs.pR14 = m_RegDisplay.pR14; - m_funcletPtrs.pR15 = m_RegDisplay.pR15; - - SP = (PTR_UIntNative)(m_RegDisplay.SP + 0x28); - - m_RegDisplay.pRbp = SP++; - m_RegDisplay.pRdi = SP++; - m_RegDisplay.pRsi = SP++; - m_RegDisplay.pRbx = SP++; - m_RegDisplay.pR12 = SP++; - m_RegDisplay.pR13 = SP++; - m_RegDisplay.pR14 = SP++; - m_RegDisplay.pR15 = SP++; - - // RhpCallCatchFunclet puts a couple of extra things on the stack that aren't put there by the other two - // thunks, but we don't need to know what they are here, so we just skip them. - if (EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallCatchFunclet2)) - SP += 2; + if (isFilterInvoke) + { + SP = (PTR_UIntNative)(m_RegDisplay.SP + 0x20); + m_RegDisplay.pRbp = SP++; + } + else + { + // Save the preserved regs portion of the REGDISPLAY across the unwind through the C# EH dispatch code. + m_funcletPtrs.pRbp = m_RegDisplay.pRbp; + m_funcletPtrs.pRdi = m_RegDisplay.pRdi; + m_funcletPtrs.pRsi = m_RegDisplay.pRsi; + m_funcletPtrs.pRbx = m_RegDisplay.pRbx; + m_funcletPtrs.pR12 = m_RegDisplay.pR12; + m_funcletPtrs.pR13 = m_RegDisplay.pR13; + m_funcletPtrs.pR14 = m_RegDisplay.pR14; + m_funcletPtrs.pR15 = m_RegDisplay.pR15; + + SP = (PTR_UIntNative)(m_RegDisplay.SP + 0x28); + + m_RegDisplay.pRbp = SP++; + m_RegDisplay.pRdi = SP++; + m_RegDisplay.pRsi = SP++; + m_RegDisplay.pRbx = SP++; + m_RegDisplay.pR12 = SP++; + m_RegDisplay.pR13 = SP++; + m_RegDisplay.pR14 = SP++; + m_RegDisplay.pR15 = SP++; + + // RhpCallCatchFunclet puts a couple of extra things on the stack that aren't put there by the other two + // thunks, but we don't need to know what they are here, so we just skip them. + if (EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallCatchFunclet2)) + SP += 2; + } #elif defined(_TARGET_X86_) - // Save the preserved regs portion of the REGDISPLAY across the unwind through the C# EH dispatch code. - m_funcletPtrs.pRbp = m_RegDisplay.pRbp; - m_funcletPtrs.pRdi = m_RegDisplay.pRdi; - m_funcletPtrs.pRsi = m_RegDisplay.pRsi; - m_funcletPtrs.pRbx = m_RegDisplay.pRbx; - - SP = (PTR_UIntNative)(m_RegDisplay.SP + 0x4); - - m_RegDisplay.pRdi = SP++; - m_RegDisplay.pRsi = SP++; - m_RegDisplay.pRbx = SP++; - m_RegDisplay.pRbp = SP++; - + if (isFilterInvoke) + { + SP = (PTR_UIntNative)(m_RegDisplay.SP + 0x4); + m_RegDisplay.pRbp = SP++; + } + else + { + // Save the preserved regs portion of the REGDISPLAY across the unwind through the C# EH dispatch code. + m_funcletPtrs.pRbp = m_RegDisplay.pRbp; + m_funcletPtrs.pRdi = m_RegDisplay.pRdi; + m_funcletPtrs.pRsi = m_RegDisplay.pRsi; + m_funcletPtrs.pRbx = m_RegDisplay.pRbx; + + SP = (PTR_UIntNative)(m_RegDisplay.SP + 0x4); + + m_RegDisplay.pRdi = SP++; + m_RegDisplay.pRsi = SP++; + m_RegDisplay.pRbx = SP++; + m_RegDisplay.pRbp = SP++; + } #elif defined(_TARGET_ARM_) - // RhpCallCatchFunclet puts a couple of extra things on the stack that aren't put there by the other two - // thunks, but we don't need to know what they are here, so we just skip them. - UIntNative uOffsetToR4 = EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallCatchFunclet2) ? 0xC : 0x4; - - // Save the preserved regs portion of the REGDISPLAY across the unwind through the C# EH dispatch code. - m_funcletPtrs.pR4 = m_RegDisplay.pR4; - m_funcletPtrs.pR5 = m_RegDisplay.pR5; - m_funcletPtrs.pR6 = m_RegDisplay.pR6; - m_funcletPtrs.pR7 = m_RegDisplay.pR7; - m_funcletPtrs.pR8 = m_RegDisplay.pR8; - m_funcletPtrs.pR9 = m_RegDisplay.pR9; - m_funcletPtrs.pR10 = m_RegDisplay.pR10; - m_funcletPtrs.pR11 = m_RegDisplay.pR11; - - SP = (PTR_UIntNative)(m_RegDisplay.SP + uOffsetToR4); - - m_RegDisplay.pR4 = SP++; - m_RegDisplay.pR5 = SP++; - m_RegDisplay.pR6 = SP++; - m_RegDisplay.pR7 = SP++; - m_RegDisplay.pR8 = SP++; - m_RegDisplay.pR9 = SP++; - m_RegDisplay.pR10 = SP++; - m_RegDisplay.pR11 = SP++; + if (isFilterInvoke) + { + SP = (PTR_UIntNative)(m_RegDisplay.SP + 0x4); + m_RegDisplay.pR7 = SP++; + m_RegDisplay.pR11 = SP++; + } + else + { + // RhpCallCatchFunclet puts a couple of extra things on the stack that aren't put there by the other two + // thunks, but we don't need to know what they are here, so we just skip them. + UIntNative uOffsetToR4 = EQUALS_CODE_ADDRESS(m_ControlPC, RhpCallCatchFunclet2) ? 0xC : 0x4; + + // Save the preserved regs portion of the REGDISPLAY across the unwind through the C# EH dispatch code. + m_funcletPtrs.pR4 = m_RegDisplay.pR4; + m_funcletPtrs.pR5 = m_RegDisplay.pR5; + m_funcletPtrs.pR6 = m_RegDisplay.pR6; + m_funcletPtrs.pR7 = m_RegDisplay.pR7; + m_funcletPtrs.pR8 = m_RegDisplay.pR8; + m_funcletPtrs.pR9 = m_RegDisplay.pR9; + m_funcletPtrs.pR10 = m_RegDisplay.pR10; + m_funcletPtrs.pR11 = m_RegDisplay.pR11; + + SP = (PTR_UIntNative)(m_RegDisplay.SP + uOffsetToR4); + + m_RegDisplay.pR4 = SP++; + m_RegDisplay.pR5 = SP++; + m_RegDisplay.pR6 = SP++; + m_RegDisplay.pR7 = SP++; + m_RegDisplay.pR8 = SP++; + m_RegDisplay.pR9 = SP++; + m_RegDisplay.pR10 = SP++; + m_RegDisplay.pR11 = SP++; + } #elif defined(_TARGET_ARM64_) PORTABILITY_ASSERT("@TODO: FIXME:ARM64"); diff --git a/src/Native/Runtime/amd64/ExceptionHandling.asm b/src/Native/Runtime/amd64/ExceptionHandling.asm index ad23da576..fdb96b802 100644 --- a/src/Native/Runtime/amd64/ExceptionHandling.asm +++ b/src/Native/Runtime/amd64/ExceptionHandling.asm @@ -595,48 +595,14 @@ NESTED_END RhpCallFinallyFunclet, _TEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NESTED_ENTRY RhpCallFilterFunclet, _TEXT - push_nonvol_reg r15 ;; save preserved regs for OS stackwalker - push_nonvol_reg r14 ;; ... - push_nonvol_reg r13 ;; ... - push_nonvol_reg r12 ;; ... - push_nonvol_reg rbx ;; ... - push_nonvol_reg rsi ;; ... - push_nonvol_reg rdi ;; ... - push_nonvol_reg rbp ;; ... - push_vol_reg r8 ;; save the regdisplay pointer for later + push_nonvol_reg rbp ;; we'll be setting rbp to the funclet's frame pointer alloc_stack 20h ;; outgoing area END_PROLOGUE - mov rax, [r8 + OFFSETOF__REGDISPLAY__pRbx] - mov rbx, [rax] mov rax, [r8 + OFFSETOF__REGDISPLAY__pRbp] mov rbp, [rax] - mov rax, [r8 + OFFSETOF__REGDISPLAY__pRsi] - mov rsi, [rax] - mov rax, [r8 + OFFSETOF__REGDISPLAY__pRdi] - mov rdi, [rax] - mov rax, [r8 + OFFSETOF__REGDISPLAY__pR12] - mov r12, [rax] - mov rax, [r8 + OFFSETOF__REGDISPLAY__pR13] - mov r13, [rax] - mov rax, [r8 + OFFSETOF__REGDISPLAY__pR14] - mov r14, [rax] - mov rax, [r8 + OFFSETOF__REGDISPLAY__pR15] - mov r15, [rax] - - movdqa xmm6, [r8 + OFFSETOF__REGDISPLAY__Xmm + 0*10h] - movdqa xmm7, [r8 + OFFSETOF__REGDISPLAY__Xmm + 1*10h] - movdqa xmm8, [r8 + OFFSETOF__REGDISPLAY__Xmm + 2*10h] - movdqa xmm9, [r8 + OFFSETOF__REGDISPLAY__Xmm + 3*10h] - movdqa xmm10,[r8 + OFFSETOF__REGDISPLAY__Xmm + 4*10h] - - movdqa xmm11,[r8 + OFFSETOF__REGDISPLAY__Xmm + 5*10h] - movdqa xmm12,[r8 + OFFSETOF__REGDISPLAY__Xmm + 6*10h] - movdqa xmm13,[r8 + OFFSETOF__REGDISPLAY__Xmm + 7*10h] - movdqa xmm14,[r8 + OFFSETOF__REGDISPLAY__Xmm + 8*10h] - movdqa xmm15,[r8 + OFFSETOF__REGDISPLAY__Xmm + 9*10h] ;; RCX still contains the exception object call rdx @@ -644,46 +610,8 @@ ALTERNATE_ENTRY RhpCallFilterFunclet2 ;; RAX contains the result of the filter execution - mov r8, [rsp + 20h] ;; reload regdisplay pointer - - mov rdx, [r8 + OFFSETOF__REGDISPLAY__pRbx] - mov [rdx] , rbx - mov rdx, [r8 + OFFSETOF__REGDISPLAY__pRbp] - mov [rdx] , rbp - mov rdx, [r8 + OFFSETOF__REGDISPLAY__pRsi] - mov [rdx] , rsi - mov rdx, [r8 + OFFSETOF__REGDISPLAY__pRdi] - mov [rdx] , rdi - mov rdx, [r8 + OFFSETOF__REGDISPLAY__pR12] - mov [rdx] , r12 - mov rdx, [r8 + OFFSETOF__REGDISPLAY__pR13] - mov [rdx] , r13 - mov rdx, [r8 + OFFSETOF__REGDISPLAY__pR14] - mov [rdx] , r14 - mov rdx, [r8 + OFFSETOF__REGDISPLAY__pR15] - mov [rdx] , r15 - - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 0*10h], xmm6 - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 1*10h], xmm7 - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 2*10h], xmm8 - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 3*10h], xmm9 - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 4*10h], xmm10 - - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 5*10h], xmm11 - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 6*10h], xmm12 - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 7*10h], xmm13 - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 8*10h], xmm14 - movdqa [r8 + OFFSETOF__REGDISPLAY__Xmm + 9*10h], xmm15 - - add rsp, 28h + add rsp, 20h pop rbp - pop rdi - pop rsi - pop rbx - pop r12 - pop r13 - pop r14 - pop r15 ret diff --git a/src/Native/Runtime/arm/ExceptionHandling.asm b/src/Native/Runtime/arm/ExceptionHandling.asm index df1d1ef74..5c2eb3c5b 100644 --- a/src/Native/Runtime/arm/ExceptionHandling.asm +++ b/src/Native/Runtime/arm/ExceptionHandling.asm @@ -514,35 +514,12 @@ SetSuccess ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NESTED_ENTRY RhpCallFilterFunclet - PROLOG_PUSH {r2,r4-r11,lr} ;; r2 is saved so we have the REGDISPLAY later + PROLOG_PUSH {r2,r7,r11,lr} ;; r2 is saved so we have the REGDISPLAY later #undef rsp_offset_r2 #define rsp_offset_r2 0 - ;; - ;; set preserved regs to the values expected by the funclet - ;; - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR4] - ldr r4, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR5] - ldr r5, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR6] - ldr r6, [r12] ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR7] ldr r7, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR8] - ldr r8, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR9] - ldr r9, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR10] - ldr r10, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR11] - ldr r11, [r12] - - ;; - ;; load vfp preserved regs - ;; - add r12, r2, #OFFSETOF__REGDISPLAY__D - vldm r12!, {d8-d15} ;; ;; call the funclet @@ -551,35 +528,8 @@ SetSuccess blx r1 LABELED_RETURN_ADDRESS RhpCallFilterFunclet2 - ldr r2, [sp, #rsp_offset_r2] ;; reload REGDISPLAY pointer - - ;; - ;; save new values of preserved regs into REGDISPLAY - ;; - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR4] - str r4, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR5] - str r5, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR6] - str r6, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR7] - str r7, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR8] - str r8, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR9] - str r9, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR10] - str r10, [r12] - ldr r12, [r2, #OFFSETOF__REGDISPLAY__pR11] - str r11, [r12] - - ;; - ;; store vfp preserved regs - ;; - add r12, r2, #OFFSETOF__REGDISPLAY__D - vstm r12!, {d8-d15} - EPILOG_POP {r1,r4-r11,pc} + EPILOG_POP {r1,r7,r11,pc} NESTED_END RhpCallFilterFunclet diff --git a/src/Native/Runtime/i386/ExceptionHandling.asm b/src/Native/Runtime/i386/ExceptionHandling.asm index 19b3e3c95..6f4679ca1 100644 --- a/src/Native/Runtime/i386/ExceptionHandling.asm +++ b/src/Native/Runtime/i386/ExceptionHandling.asm @@ -416,25 +416,12 @@ FASTCALL_FUNC RhpCallFilterFunclet, 0 push ebp mov ebp, esp - push ebx ;; save preserved registers - push esi ;; - push edi ;; - push edx ;; save filter funclet address ;; ;; load preserved registers for funclet ;; mov edx, [ebp + 8] - mov eax, [edx + OFFSETOF__REGDISPLAY__pRbx] - mov ebx, [eax] - - mov eax, [edx + OFFSETOF__REGDISPLAY__pRsi] - mov esi, [eax] - - mov eax, [edx + OFFSETOF__REGDISPLAY__pRdi] - mov edi, [eax] - mov eax, [edx + OFFSETOF__REGDISPLAY__pRbp] mov eax, [eax] @@ -446,27 +433,9 @@ FASTCALL_FUNC RhpCallFilterFunclet, 0 ALTERNATE_ENTRY RhpCallFilterFunclet2 ;; EAX contains the result of the filter execution - mov ecx, eax - mov edx, [ebp + 8] - ;; - ;; save preserved registers from funclet - ;; - mov eax, [edx + OFFSETOF__REGDISPLAY__pRbx] - mov [eax], ebx - - mov eax, [edx + OFFSETOF__REGDISPLAY__pRsi] - mov [eax], esi - - mov eax, [edx + OFFSETOF__REGDISPLAY__pRdi] - mov [eax], edi - - mov eax, ecx pop ecx ;; pop scratch slot - pop edi - pop esi - pop ebx pop ebp ret diff --git a/src/Native/Runtime/thread.cpp b/src/Native/Runtime/thread.cpp index a814116e1..dcc9ac96e 100644 --- a/src/Native/Runtime/thread.cpp +++ b/src/Native/Runtime/thread.cpp @@ -558,6 +558,24 @@ static void* GcStressHijackTargets[3] = }; #endif // FEATURE_GC_STRESS +// static +bool Thread::IsHijackTarget(void * address) +{ + for (int i = 0; i < 3; i++) + { + if (NormalHijackTargets[i] == address) + return true; + } +#ifdef FEATURE_GC_STRESS + for (int i = 0; i < 3; i++) + { + if (GcStressHijackTargets[i] == address) + return true; + } +#endif // FEATURE_GC_STRESS + return false; +} + bool Thread::Hijack() { ASSERT(ThreadStore::GetCurrentThread() == ThreadStore::GetSuspendingThread()); @@ -689,7 +707,9 @@ bool Thread::InternalHijack(PAL_LIMITED_CONTEXT * pSuspendCtx, void* HijackTarge m_ppvHijackedReturnAddressLocation = ppvRetAddrLocation; m_pvHijackedReturnAddress = pvRetAddr; - *ppvRetAddrLocation = HijackTargets[retValueKind]; + void* pvHijackTarget = HijackTargets[retValueKind]; + ASSERT_MSG(IsHijackTarget(pvHijackTarget), "unexpected method used as hijack target"); + *ppvRetAddrLocation = pvHijackTarget; fSuccess = true; } diff --git a/src/Native/Runtime/thread.h b/src/Native/Runtime/thread.h index 1f9808e7f..9f35fbb78 100644 --- a/src/Native/Runtime/thread.h +++ b/src/Native/Runtime/thread.h @@ -221,6 +221,8 @@ public: PTR_VOID GetTransitionFrameForStackTrace(); void * GetCurrentThreadPInvokeReturnAddress(); + static bool IsHijackTarget(void * address); + // ------------------------------------------------------------------------------------------------------- // LEGACY APIs: do not use except from GC itself // |