diff options
Diffstat (limited to 'packaging/0001-Improve-UMEntryThunkCode-Poison-method.patch')
-rw-r--r-- | packaging/0001-Improve-UMEntryThunkCode-Poison-method.patch | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/packaging/0001-Improve-UMEntryThunkCode-Poison-method.patch b/packaging/0001-Improve-UMEntryThunkCode-Poison-method.patch new file mode 100644 index 0000000000..49525b0b59 --- /dev/null +++ b/packaging/0001-Improve-UMEntryThunkCode-Poison-method.patch @@ -0,0 +1,175 @@ +From ce9c04e177ad80997aa0824aaa112ef51f9d0a3b Mon Sep 17 00:00:00 2001 +From: Konstantin Baladurin <k.baladurin@partner.samsung.com> +Date: Wed, 10 Jan 2018 18:26:01 +0300 +Subject: [PATCH 01/47] Improve UMEntryThunkCode::Poison method. + +Improve UMEntryThunkCode::Poison to produce diagnostic message +when collected delegate was called. +--- + src/vm/amd64/cgenamd64.cpp | 13 ++++++++++++- + src/vm/arm/stubs.cpp | 14 ++++++++++++-- + src/vm/arm64/stubs.cpp | 9 +++++++++ + src/vm/dllimportcallback.cpp | 36 ++++++++++++++++++++++++++++++++++++ + src/vm/dllimportcallback.h | 2 ++ + src/vm/i386/cgenx86.cpp | 7 ++++++- + 6 files changed, 77 insertions(+), 4 deletions(-) + +diff --git a/src/vm/amd64/cgenamd64.cpp b/src/vm/amd64/cgenamd64.cpp +index 20dca22..1b20b32 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 70cc900..a52f0c8 100644 +--- a/src/vm/arm/stubs.cpp ++++ b/src/vm/arm/stubs.cpp +@@ -2523,12 +2523,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 df2124d..a0d90de 100644 +--- a/src/vm/arm64/stubs.cpp ++++ b/src/vm/arm64/stubs.cpp +@@ -1244,11 +1244,20 @@ void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) + FlushInstructionCache(GetCurrentProcess(),&m_code,sizeof(m_code)); + } + ++#ifndef DACCESS_COMPILE ++ + void UMEntryThunkCode::Poison() + { ++ m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; ++ ++ // ldp x16, x0, [x12] ++ m_code[1] = 0xa9400190; + ++ 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 b4277db..8db4073 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) +-- +2.7.4 + |