summaryrefslogtreecommitdiff
path: root/src/vm/arm64/cgencpu.h
diff options
context:
space:
mode:
authorGleb Balykov <g.balykov@samsung.com>2020-09-14 13:30:50 +0300
committerAlexander Soldatov/Platform Lab /SRR/Staff Engineer/Samsung Electronics <soldatov.a@samsung.com>2020-09-21 20:04:27 +0300
commit676b3e46459a5138d05ac31bb697a54a8a8f685c (patch)
tree9a5d32deb41da42d98bf125b6a1ec9dee8359ce8 /src/vm/arm64/cgencpu.h
parent7a0186fe2611e00cd8019adced7af3a269e2e7f4 (diff)
downloadcoreclr-607f973f7c01fd87302259fcd534bddebcb7e902.tar.gz
coreclr-607f973f7c01fd87302259fcd534bddebcb7e902.tar.bz2
coreclr-607f973f7c01fd87302259fcd534bddebcb7e902.zip
[Tizen] Add RelativeFixupPrecode for arm64, which replaces FixupPrecode in FNV imagessubmit/tizen/20200921.230336accepted/tizen/unified/20200922.034817
Diffstat (limited to 'src/vm/arm64/cgencpu.h')
-rw-r--r--src/vm/arm64/cgencpu.h120
1 files changed, 119 insertions, 1 deletions
diff --git a/src/vm/arm64/cgencpu.h b/src/vm/arm64/cgencpu.h
index b30d5026f3..7d01f9d6ff 100644
--- a/src/vm/arm64/cgencpu.h
+++ b/src/vm/arm64/cgencpu.h
@@ -44,6 +44,10 @@ extern PCODE GetPreStubEntryPoint();
#define HAS_FIXUP_PRECODE 1
#define HAS_FIXUP_PRECODE_CHUNKS 1
+#if defined(HAS_FIXUP_PRECODE) && defined(HAS_FIXUP_PRECODE_CHUNKS)
+#define HAS_RELATIVE_FIXUP_PRECODE 1
+#endif
+
// ThisPtrRetBufPrecode one is necessary for closed delegates over static methods with return buffer
#define HAS_THISPTR_RETBUF_PRECODE 1
@@ -561,6 +565,7 @@ struct HijackArgs
};
EXTERN_C VOID STDCALL PrecodeFixupThunk();
+EXTERN_C VOID STDCALL PrecodeRelativeFixupThunk();
// Invalid precode type
struct InvalidPrecode {
@@ -677,9 +682,9 @@ struct FixupPrecode {
// adr x12, #0
// ldr x11, [pc, #12] ; =m_pTarget
// br x11
+ // 2 byte padding
// dcb m_MethodDescChunkIndex
// dcb m_PrecodeChunkIndex
- // 2 byte padding
// dcd m_pTarget
@@ -771,6 +776,119 @@ struct FixupPrecode {
typedef DPTR(FixupPrecode) PTR_FixupPrecode;
+struct RelativeFixupPrecode {
+
+ static const int Type = 0x0B;
+
+ // adr x11, #0 ; registers x11 and x12 are reversed to differentiate from FixupPrecode
+ // ldr x12, #20 ; =m_pTargetOffset, which is relative to "adr x11, #0"
+ // add x12, x11, x12
+ // br x12
+ // dcb m_MethodDescChunkIndex
+ // dcb m_PrecodeChunkIndex
+ // 6 byte padding
+ // dcd m_pTargetOffset
+
+
+ UINT32 m_rgCode[4];
+ BYTE m_MethodDescChunkIndex;
+ BYTE m_PrecodeChunkIndex;
+ BYTE padding[6];
+ TADDR m_pTargetOffset;
+
+ void Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int iMethodDescChunkIndex = 0, int iPrecodeChunkIndex = 0);
+ void InitCommon()
+ {
+ WRAPPER_NO_CONTRACT;
+ int n = 0;
+
+ m_rgCode[n++] = 0x1000000B; // adr x11, #0
+ m_rgCode[n++] = 0x580000AC; // ldr x12, #20 ; =m_pTargetOffset, which is relative to "adr x11, #0"
+ m_rgCode[n++] = 0x8B0C016C; // add x12, x11, x12
+
+ _ASSERTE((UINT32*)&m_pTargetOffset == &m_rgCode[n + 3]);
+
+ m_rgCode[n++] = 0xD61F0180; // br x12
+
+ _ASSERTE(n == _countof(m_rgCode));
+ }
+
+ TADDR GetBase()
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ return dac_cast<TADDR>(this) + (m_PrecodeChunkIndex + 1) * sizeof(RelativeFixupPrecode);
+ }
+
+ TADDR GetMethodDesc();
+
+ static TADDR GetTargetOffset()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return 0;
+ }
+
+ PCODE GetTarget()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return dac_cast<TADDR>(this) + GetTargetOffset() + m_pTargetOffset;
+ }
+
+ void ResetTargetInterlocked()
+ {
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ EnsureWritableExecutablePages(&m_pTargetOffset);
+ TADDR addr = (TADDR)GetEEFuncEntryPoint(PrecodeRelativeFixupThunk) - (TADDR)(this) - GetTargetOffset();
+ InterlockedExchange64((LONGLONG*)&m_pTargetOffset, addr);
+ }
+
+ BOOL SetTargetInterlocked(TADDR target, TADDR expected)
+ {
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ EnsureWritableExecutablePages(&m_pTargetOffset);
+ TADDR addrExpected = expected - (TADDR)(this) - GetTargetOffset();
+ TADDR addrTarget = target - (TADDR)(this) - GetTargetOffset();
+ return (TADDR)InterlockedCompareExchange64(
+ (LONGLONG*)&m_pTargetOffset, addrTarget, addrExpected) == addrExpected;
+ }
+
+ static BOOL IsRelativeFixupPrecodeByASM(PCODE addr)
+ {
+ PTR_DWORD pInstr = dac_cast<PTR_DWORD>(PCODEToPINSTR(addr));
+ return
+ (pInstr[0] == 0x1000000B) &&
+ (pInstr[1] == 0x580000AC) &&
+ (pInstr[2] == 0x8B0C016C) &&
+ (pInstr[3] == 0xD61F0180);
+ }
+
+#ifdef FEATURE_PREJIT
+ // Partial initialization. Used to save regrouped chunks.
+ void InitForSave(int iPrecodeChunkIndex);
+
+ void Fixup(DataImage *image, MethodDesc * pMD);
+#endif
+
+#ifdef DACCESS_COMPILE
+ void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+#endif
+};
+typedef DPTR(RelativeFixupPrecode) PTR_RelativeFixupPrecode;
+
+
// Precode to shuffle this and retbuf for closed delegates over static methods with return buffer
struct ThisPtrRetBufPrecode {