From: Konstantin Baladurin Date: Wed, 10 Jan 2018 15:26:01 +0000 (+0300) Subject: Improve UMEntryThunkCode::Poison method. X-Git-Tag: accepted/tizen/base/20180629.140029~154 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=28839fc0b2dcaf89b7217741291c8c3f578f38a0;p=platform%2Fupstream%2Fcoreclr.git Improve UMEntryThunkCode::Poison method. Improve UMEntryThunkCode::Poison to produce diagnostic message when collected delegate was called. --- diff --git a/src/vm/amd64/cgenamd64.cpp b/src/vm/amd64/cgenamd64.cpp index 4e1f38a..6075134 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 f2500c3..7e5b58c 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 3c56c38..3d4213b 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 8684c12..c3e6a4e 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 e79c5f0..5838e49 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 19d7bbe..7071d27 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)