diff options
Diffstat (limited to 'src/vm/arm64/stubs.cpp')
-rw-r--r-- | src/vm/arm64/stubs.cpp | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/src/vm/arm64/stubs.cpp b/src/vm/arm64/stubs.cpp index b25dc4d531..6061654fdc 100644 --- a/src/vm/arm64/stubs.cpp +++ b/src/vm/arm64/stubs.cpp @@ -612,11 +612,33 @@ void StubPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) m_pMethodDesc = (TADDR)pMD; } +void RelativeStubPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) +{ + WRAPPER_NO_CONTRACT; + + int n = 0; + + m_rgCode[n++] = 0x100000C9; // adr x9, #24 + m_rgCode[n++] = 0xA940312A; // ldp x10,x12,[x9] + m_rgCode[n++] = 0x8B09018C; // add x12,x12,x9 + m_rgCode[n++] = 0x8B09014A; // add x10,x10,x9 + m_rgCode[n++] = 0xD61F0140; // br x10 + + _ASSERTE(n+1 == _countof(m_rgCode)); + + m_pTargetOffset = GetPreStubEntryPoint() - (TADDR)this - RelativeStubPrecode::GetTargetOffset(); + m_pMethodDescOffset = (TADDR)pMD - (TADDR)this - RelativeStubPrecode::GetTargetOffset(); +} + #ifdef FEATURE_NATIVE_IMAGE_GENERATION void StubPrecode::Fixup(DataImage *image) { WRAPPER_NO_CONTRACT; +#ifdef HAS_RELATIVE_STUB_PRECODE + // StubPrecode is not saved to image in this case + _ASSERTE(!"StubPrecode is not saved to NGENed image, RelativeStubPrecode is instead"); +#else // HAS_RELATIVE_STUB_PRECODE image->FixupFieldToNode(this, offsetof(StubPrecode, m_pTarget), image->GetHelperThunk(CORINFO_HELP_EE_PRESTUB), 0, @@ -626,6 +648,24 @@ void StubPrecode::Fixup(DataImage *image) (void*)GetMethodDesc(), 0, IMAGE_REL_BASED_PTR); +#endif // HAS_RELATIVE_STUB_PRECODE +} + +void RelativeStubPrecode::Fixup(DataImage *image) +{ + WRAPPER_NO_CONTRACT; + + image->FixupFieldToNode(this, + offsetof(RelativeStubPrecode, m_pTargetOffset), + image->GetHelperThunk(CORINFO_HELP_EE_PRESTUB), + offsetof(RelativeStubPrecode, m_pTargetOffset) - RelativeStubPrecode::GetTargetOffset(), + IMAGE_REL_BASED_RELPTR); + + image->FixupField(this, + offsetof(RelativeStubPrecode, m_pMethodDescOffset), + (void*)GetMethodDesc(), + offsetof(RelativeStubPrecode, m_pMethodDescOffset) - RelativeStubPrecode::GetTargetOffset(), + IMAGE_REL_BASED_RELPTR); } #endif // FEATURE_NATIVE_IMAGE_GENERATION @@ -886,9 +926,7 @@ BOOL DoesSlotCallPrestub(PCODE pCode) #endif // HAS_RELATIVE_FIXUP_PRECODE // StubPrecode - if (pInstr[0] == 0x10000089 && // adr x9, #16 - pInstr[1] == 0xA940312A && // ldp x10,x12,[x9] - pInstr[2] == 0xD61F0140) // br x10 + if (StubPrecode::IsStubPrecodeByASM(pCode)) { PCODE pTarget = dac_cast<PTR_StubPrecode>(pInstr)->m_pTarget; @@ -900,6 +938,21 @@ BOOL DoesSlotCallPrestub(PCODE pCode) return pTarget == GetPreStubEntryPoint(); } + // RelativeStubPrecode +#if defined(HAS_RELATIVE_STUB_PRECODE) + if (RelativeStubPrecode::IsRelativeStubPrecodeByASM(pCode)) + { + PCODE pTarget = dac_cast<PTR_RelativeStubPrecode>(pInstr)->GetTarget(); + + if (isJump(pTarget)) + { + pTarget = decodeJump(pTarget); + } + + return pTarget == GetPreStubEntryPoint(); + } +#endif // HAS_RELATIVE_STUB_PRECODE + return FALSE; } |