diff options
-rw-r--r-- | src/vm/amd64/cgenamd64.cpp | 13 | ||||
-rw-r--r-- | src/vm/arm/stubs.cpp | 14 | ||||
-rw-r--r-- | src/vm/arm64/stubs.cpp | 12 | ||||
-rw-r--r-- | src/vm/dllimportcallback.cpp | 36 | ||||
-rw-r--r-- | src/vm/dllimportcallback.h | 2 | ||||
-rw-r--r-- | src/vm/i386/cgenx86.cpp | 7 |
6 files changed, 78 insertions, 6 deletions
diff --git a/src/vm/amd64/cgenamd64.cpp b/src/vm/amd64/cgenamd64.cpp index 4e1f38ad12..6075134943 100644 --- a/src/vm/amd64/cgenamd64.cpp +++ b/src/vm/amd64/cgenamd64.cpp @@ -680,7 +680,18 @@ void UMEntryThunkCode::Poison() } CONTRACTL_END; - m_movR10[0] = X86_INSTR_INT3; + m_execstub = (BYTE *)UMEntryThunk::ReportViolation; + + m_movR10[0] = REX_PREFIX_BASE | REX_OPERAND_SIZE_64BIT; +#ifdef _WIN32 + // mov rcx, pUMEntryThunk // 48 b9 xx xx xx xx xx xx xx xx + m_movR10[1] = 0xB9; +#else + // mov rdi, pUMEntryThunk // 48 bf xx xx xx xx xx xx xx xx + m_movR10[1] = 0xBF; +#endif + + ClrFlushInstructionCache(&m_movR10[0], &m_jmpRAX[3]-&m_movR10[0]); } UMEntryThunk* UMEntryThunk::Decode(LPVOID pCallback) diff --git a/src/vm/arm/stubs.cpp b/src/vm/arm/stubs.cpp index f2500c302e..7e5b58c54b 100644 --- a/src/vm/arm/stubs.cpp +++ b/src/vm/arm/stubs.cpp @@ -2483,12 +2483,22 @@ void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) FlushInstructionCache(GetCurrentProcess(),&m_code,sizeof(m_code)); } +#ifndef DACCESS_COMPILE + void UMEntryThunkCode::Poison() { - // Insert 'udf 0xff' at the entry point - m_code[0] = 0xdeff; + m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; + + // ldr r0, [pc + 8] + m_code[0] = 0x4802; + // nop + m_code[1] = 0xbf00; + + ClrFlushInstructionCache(&m_code,sizeof(m_code)); } +#endif // DACCESS_COMPILE + ///////////////////////////// UNIMPLEMENTED ////////////////////////////////// #ifndef DACCESS_COMPILE diff --git a/src/vm/arm64/stubs.cpp b/src/vm/arm64/stubs.cpp index 3c56c382ea..3d4213bea1 100644 --- a/src/vm/arm64/stubs.cpp +++ b/src/vm/arm64/stubs.cpp @@ -1268,12 +1268,20 @@ void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) FlushInstructionCache(GetCurrentProcess(),&m_code,sizeof(m_code)); } +#ifndef DACCESS_COMPILE + void UMEntryThunkCode::Poison() { - // Insert 'brk 0xbe' at the entry point - m_code[0] = 0xd42017c0; + m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; + + // ldp x16, x0, [x12] + m_code[1] = 0xd42017c0; + + ClrFlushInstructionCache(&m_code,sizeof(m_code)); } +#endif // DACCESS_COMPILE + #ifdef PROFILING_SUPPORTED #include "proftoeeinterfaceimpl.h" diff --git a/src/vm/dllimportcallback.cpp b/src/vm/dllimportcallback.cpp index 8684c12167..c3e6a4e62d 100644 --- a/src/vm/dllimportcallback.cpp +++ b/src/vm/dllimportcallback.cpp @@ -1167,6 +1167,42 @@ VOID UMEntryThunk::FreeUMEntryThunk(UMEntryThunk* p) #endif // CROSSGEN_COMPILE +//------------------------------------------------------------------------- +// This function is used to report error when we call collected delegate. +// But memory that was allocated for thunk can be reused, due to it this +// function will not be called in all cases of the collected delegate call, +// also it may crash while trying to report the problem. +//------------------------------------------------------------------------- +VOID __fastcall UMEntryThunk::ReportViolation(UMEntryThunk* pEntryThunk) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(CheckPointer(pEntryThunk)); + } + CONTRACTL_END; + + MethodDesc* pMethodDesc = pEntryThunk->GetMethod(); + + SString namespaceOrClassName; + SString methodName; + SString moduleName; + + pMethodDesc->GetMethodInfoNoSig(namespaceOrClassName, methodName); + moduleName.SetUTF8(pMethodDesc->GetModule()->GetSimpleName()); + + SString message; + + message.Printf(W("A callback was made on a garbage collected delegate of type '%s!%s::%s'."), + moduleName.GetUnicode(), + namespaceOrClassName.GetUnicode(), + methodName.GetUnicode()); + + EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_FAILFAST, message.GetUnicode()); +} + UMThunkMarshInfo::~UMThunkMarshInfo() { CONTRACTL diff --git a/src/vm/dllimportcallback.h b/src/vm/dllimportcallback.h index e79c5f03ef..5838e49566 100644 --- a/src/vm/dllimportcallback.h +++ b/src/vm/dllimportcallback.h @@ -511,6 +511,8 @@ public: } #endif + static VOID __fastcall ReportViolation(UMEntryThunk* p); + private: // The start of the managed code. // if m_pObjectHandle is non-NULL, this field is still set to help with diagnostic of call on collected delegate crashes diff --git a/src/vm/i386/cgenx86.cpp b/src/vm/i386/cgenx86.cpp index 19d7bbeea3..7071d27928 100644 --- a/src/vm/i386/cgenx86.cpp +++ b/src/vm/i386/cgenx86.cpp @@ -1614,7 +1614,12 @@ void UMEntryThunkCode::Poison() { LIMITED_METHOD_CONTRACT; - m_movEAX = X86_INSTR_INT3; + m_execstub = (BYTE*) ((BYTE*)UMEntryThunk::ReportViolation - (4+((BYTE*)&m_execstub))); + + // mov ecx, imm32 + m_movEAX = 0xb9; + + ClrFlushInstructionCache(GetEntryPoint(),sizeof(UMEntryThunkCode)); } UMEntryThunk* UMEntryThunk::Decode(LPVOID pCallback) |