Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2016-01-07 03:36:16 +0300
committerJan Kotas <jkotas@microsoft.com>2016-01-07 03:36:16 +0300
commit69e69b7acd28f30de630c6269b066433ad24bbf4 (patch)
tree7414eb908d922d828e0a617e3b41c18848f633d1 /src/Native
parentff6fb1968ce5dbdaec33b22733b7c55fc07b9846 (diff)
Native part of previous commit
[tfs-changeset: 1561881]
Diffstat (limited to 'src/Native')
-rw-r--r--src/Native/Runtime/EHHelpers.cpp83
-rw-r--r--src/Native/Runtime/StackFrameIterator.cpp150
-rw-r--r--src/Native/Runtime/amd64/ExceptionHandling.asm76
-rw-r--r--src/Native/Runtime/arm/ExceptionHandling.asm54
-rw-r--r--src/Native/Runtime/i386/ExceptionHandling.asm31
-rw-r--r--src/Native/Runtime/thread.cpp22
-rw-r--r--src/Native/Runtime/thread.h2
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
//