summaryrefslogtreecommitdiff
path: root/src/vm/arm64/stubs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/arm64/stubs.cpp')
-rw-r--r--src/vm/arm64/stubs.cpp59
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;
}