diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2018-07-27 02:18:02 +0300 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2018-07-27 02:18:02 +0300 |
commit | d23b7f190431b216c45eed3444012a6565b45668 (patch) | |
tree | e60356fdca1c26dbde5fe09922bb26c2116d69ac /src/Native | |
parent | 907e75814f72cb4ebf5ec172def064ff1b9959c8 (diff) |
[tfs-changeset: 1708860]
Diffstat (limited to 'src/Native')
-rw-r--r-- | src/Native/Runtime/RHCodeMan.cpp | 22 | ||||
-rw-r--r-- | src/Native/Runtime/thread.cpp | 14 |
2 files changed, 19 insertions, 17 deletions
diff --git a/src/Native/Runtime/RHCodeMan.cpp b/src/Native/Runtime/RHCodeMan.cpp index 082b32d79..8fbaea299 100644 --- a/src/Native/Runtime/RHCodeMan.cpp +++ b/src/Native/Runtime/RHCodeMan.cpp @@ -1064,10 +1064,9 @@ bool EECodeManager::UnwindStackFrame(GCInfoHeader * pInfoHeader, // The compiler enforces that by placing an 8-byte padding between those areas if needed. // Account for that padding and ensure that the unwound SP is 16-byte aligned. RSP = dac_cast<PTR_UIntNative>((dac_cast<TADDR>(RSP) + 0xf) & ~0xf); -#else - -#error NYI - For this arch +#else +#error Unexpected target architecture #endif pContext->SetSP((UIntNative) dac_cast<TADDR>(RSP)); @@ -1135,7 +1134,7 @@ UIntNative EECodeManager::GetConservativeUpperBoundForOutgoingArgs(GCInfoHeader upperBound = pContext->GetFP() - pInfoHeader->GetFramePointerOffset(); #else -#error NYI - For this arch +#error Unexpected target architecture #endif } else @@ -1145,21 +1144,15 @@ UIntNative EECodeManager::GetConservativeUpperBoundForOutgoingArgs(GCInfoHeader // Adding the frame size to the SP is guaranteed to yield an address above all outgoing // arguments. // - // If this frame contains one or more callee-saved register (guaranteed on ARM since at + // If this frame contains one or more callee-saved register (guaranteed on ARM/ARM64 since at // least LR is saved in all functions that contain callsites), then the computed address // will point at the lowest callee-saved register (or possibly above it in the x86 case // where registers are saved at the bottom of the frame). // - // If the frame contains no callee-saved registers (impossible on ARM), then the computed + // If the frame contains no callee-saved registers (impossible on ARM/ARM64), then the computed // address will point to the pushed return address. upperBound = pContext->GetSP() + pInfoHeader->GetFrameSize(); - -#if defined(_TARGET_ARM_) - ASSERT(pInfoHeader->GetSavedRegs() != 0); -#elif defined(_TARGET_ARM64_) - PORTABILITY_ASSERT("@TODO: FIXME:ARM64"); -#endif } } @@ -1331,6 +1324,10 @@ bool EECodeManager::GetEpilogOffset( #ifndef DACCESS_COMPILE +// ARM64 epilogs have a window between loading the hijackable return address into LR and the RET instruction. +// We cannot hijack or unhijack a thread while it is suspended in that window unless we implement hijacking +// via LR register modification. +#ifndef _ARM64_ void ** EECodeManager::GetReturnAddressLocationFromEpilog(GCInfoHeader * pInfoHeader, REGDISPLAY * pContext, UInt32 epilogOffset, UInt32 epilogSize) { @@ -1743,6 +1740,7 @@ void ** EECodeManager::GetReturnAddressLocationFromEpilog(GCInfoHeader * pInfoHe #endif } +#endif // _ARM64_ #ifdef _DEBUG diff --git a/src/Native/Runtime/thread.cpp b/src/Native/Runtime/thread.cpp index 77cfc1904..cb6c3990c 100644 --- a/src/Native/Runtime/thread.cpp +++ b/src/Native/Runtime/thread.cpp @@ -728,8 +728,6 @@ bool Thread::InternalHijack(PAL_LIMITED_CONTEXT * pSuspendCtx, void * pvHijackTa if (frameIterator.IsValid()) { - CrossThreadUnhijack(); - frameIterator.CalculateCurrentMethodState(); frameIterator.GetCodeManager()->UnsynchronizedHijackMethodLoops(frameIterator.GetMethodInfo()); @@ -738,10 +736,16 @@ bool Thread::InternalHijack(PAL_LIMITED_CONTEXT * pSuspendCtx, void * pvHijackTa GCRefKind retValueKind; if (frameIterator.GetCodeManager()->GetReturnAddressHijackInfo(frameIterator.GetMethodInfo(), - frameIterator.GetRegisterSet(), - &ppvRetAddrLocation, - &retValueKind)) + frameIterator.GetRegisterSet(), + &ppvRetAddrLocation, + &retValueKind)) { + // ARM64 epilogs have a window between loading the hijackable return address into LR and the RET instruction. + // We cannot hijack or unhijack a thread while it is suspended in that window unless we implement hijacking + // via LR register modification. Therefore it is important to check our ability to hijack the thread before + // unhijacking it. + CrossThreadUnhijack(); + void* pvRetAddr = *ppvRetAddrLocation; ASSERT(ppvRetAddrLocation != NULL); ASSERT(pvRetAddr != NULL); |