summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>2018-01-10 18:26:01 +0300
committerJan Kotas <jkotas@microsoft.com>2018-01-12 12:40:37 -0800
commit28839fc0b2dcaf89b7217741291c8c3f578f38a0 (patch)
treebbe2e02062a711975fec9c5a0e12dd8d35d4f344 /src/vm
parentf2ef496c87c7ba66f54390d9b5cc08f863183b2f (diff)
downloadcoreclr-28839fc0b2dcaf89b7217741291c8c3f578f38a0.tar.gz
coreclr-28839fc0b2dcaf89b7217741291c8c3f578f38a0.tar.bz2
coreclr-28839fc0b2dcaf89b7217741291c8c3f578f38a0.zip
Improve UMEntryThunkCode::Poison method.
Improve UMEntryThunkCode::Poison to produce diagnostic message when collected delegate was called.
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/amd64/cgenamd64.cpp13
-rw-r--r--src/vm/arm/stubs.cpp14
-rw-r--r--src/vm/arm64/stubs.cpp12
-rw-r--r--src/vm/dllimportcallback.cpp36
-rw-r--r--src/vm/dllimportcallback.h2
-rw-r--r--src/vm/i386/cgenx86.cpp7
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)