diff options
author | Gleb Balykov <g.balykov@samsung.com> | 2020-09-14 13:30:50 +0300 |
---|---|---|
committer | Alexander Soldatov/Platform Lab /SRR/Staff Engineer/Samsung Electronics <soldatov.a@samsung.com> | 2020-09-21 20:04:27 +0300 |
commit | 676b3e46459a5138d05ac31bb697a54a8a8f685c (patch) | |
tree | 9a5d32deb41da42d98bf125b6a1ec9dee8359ce8 /src/vm/arm64/cgencpu.h | |
parent | 7a0186fe2611e00cd8019adced7af3a269e2e7f4 (diff) | |
download | coreclr-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.h | 120 |
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 { |