summaryrefslogtreecommitdiff
path: root/packaging/0001-Improve-UMEntryThunkCode-Poison-method.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/0001-Improve-UMEntryThunkCode-Poison-method.patch')
-rw-r--r--packaging/0001-Improve-UMEntryThunkCode-Poison-method.patch175
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
+