summaryrefslogtreecommitdiff
path: root/src/vm/i386/umthunkstub.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/i386/umthunkstub.S')
-rw-r--r--src/vm/i386/umthunkstub.S177
1 files changed, 177 insertions, 0 deletions
diff --git a/src/vm/i386/umthunkstub.S b/src/vm/i386/umthunkstub.S
new file mode 100644
index 0000000000..728964bdb6
--- /dev/null
+++ b/src/vm/i386/umthunkstub.S
@@ -0,0 +1,177 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+//
+// eax = UMEntryThunk*
+//
+NESTED_ENTRY TheUMEntryPrestub, _TEXT, UnhandledExceptionHandlerUnix
+ // Preserve argument registers
+ push ecx
+ push edx
+
+ push eax // UMEntryThunk*
+ call C_FUNC(TheUMEntryPrestubWorker)
+ pop edx
+ // eax = PCODE
+
+ // Restore argument registers
+ pop edx
+ pop ecx
+
+ jmp eax // Tail Jmp
+NESTED_END TheUMEntryPrestub, _TEXT
+
+//
+// eax: UMEntryThunk*
+//
+NESTED_ENTRY UMThunkStub, _TEXT, UnhandledExceptionHandlerUnix
+
+#define UMThunkStub_SAVEDREG (3*4) // ebx, esi, edi
+#define UMThunkStub_LOCALVARS (2*4) // UMEntryThunk*, Thread*
+#define UMThunkStub_INT_ARG_SPILL (2*4) // for save ecx, edx
+#define UMThunkStub_UMENTRYTHUNK_OFFSET (UMThunkStub_SAVEDREG+4)
+#define UMThunkStub_THREAD_OFFSET (UMThunkStub_UMENTRYTHUNK_OFFSET+4)
+#define UMThunkStub_INT_ARG_OFFSET (UMThunkStub_THREAD_OFFSET+4)
+#define UMThunkStub_FIXEDALLOCSIZE (UMThunkStub_LOCALVARS+UMThunkStub_INT_ARG_SPILL)
+
+// return address <-- entry ESP
+// saved ebp <-- EBP
+// saved ebx
+// saved esi
+// saved edi
+// UMEntryThunk*
+// Thread*
+// save ecx
+// save edx
+// {optional stack args passed to callee} <-- new esp
+
+ PROLOG_BEG
+ PROLOG_PUSH ebx
+ PROLOG_PUSH esi
+ PROLOG_PUSH edi
+ PROLOG_END
+ sub esp, UMThunkStub_FIXEDALLOCSIZE
+
+ mov dword ptr [ebp - UMThunkStub_INT_ARG_OFFSET], ecx
+ mov dword ptr [ebp - UMThunkStub_INT_ARG_OFFSET - 0x04], edx
+
+ mov dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET], eax
+
+ call C_FUNC(GetThread)
+ test eax, eax
+ jz LOCAL_LABEL(DoThreadSetup)
+
+LOCAL_LABEL(HaveThread):
+
+ mov dword ptr [ebp - UMThunkStub_THREAD_OFFSET], eax
+
+ // FailFast if a native callable method is invoked via ldftn and calli.
+ cmp dword ptr [eax + Thread_m_fPreemptiveGCDisabled], 1
+ jz LOCAL_LABEL(InvalidTransition)
+
+ // disable preemptive GC
+ mov dword ptr [eax + Thread_m_fPreemptiveGCDisabled], 1
+
+ // catch returning thread here if a GC is in progress
+ PREPARE_EXTERNAL_VAR g_TrapReturningThreads, eax
+ cmp eax, 0
+ jnz LOCAL_LABEL(DoTrapReturningThreadsTHROW)
+
+LOCAL_LABEL(InCooperativeMode):
+
+#if _DEBUG
+ mov eax, dword ptr [ebp - UMThunkStub_THREAD_OFFSET]
+ mov eax, dword ptr [eax + Thread__m_pDomain]
+ mov esi, dword ptr [eax + AppDomain__m_dwId]
+
+ mov eax, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ mov edi, dword ptr [eax + UMEntryThunk__m_dwDomainId]
+
+ cmp esi, edi
+ jne LOCAL_LABEL(WrongAppDomain)
+#endif
+
+ mov eax, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ mov ebx, dword ptr [eax + UMEntryThunk__m_pUMThunkMarshInfo]
+ mov eax, dword ptr [ebx + UMThunkMarshInfo__m_cbActualArgSize]
+ test eax, eax
+ jnz LOCAL_LABEL(UMThunkStub_CopyStackArgs)
+
+LOCAL_LABEL(UMThunkStub_ArgumentsSetup):
+
+ mov ecx, dword ptr [ebp - UMThunkStub_INT_ARG_OFFSET]
+ mov edx, dword ptr [ebp - UMThunkStub_INT_ARG_OFFSET - 0x04]
+
+ mov eax, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ mov ebx, dword ptr [eax + UMEntryThunk__m_pUMThunkMarshInfo]
+ mov ebx, dword ptr [ebx + UMThunkMarshInfo__m_pILStub]
+
+ call ebx
+
+LOCAL_LABEL(PostCall):
+
+ mov ebx, dword ptr [ebp - UMThunkStub_THREAD_OFFSET]
+ mov dword ptr [ebx + Thread_m_fPreemptiveGCDisabled], 0
+
+ lea esp, [ebp - UMThunkStub_SAVEDREG] // deallocate arguments
+ EPILOG_BEG
+ EPILOG_POP edi
+ EPILOG_POP esi
+ EPILOG_POP ebx
+ EPILOG_END
+ ret
+
+LOCAL_LABEL(DoThreadSetup):
+
+ call C_FUNC(CreateThreadBlockThrow)
+ jmp LOCAL_LABEL(HaveThread)
+
+LOCAL_LABEL(InvalidTransition):
+
+ //No arguments to setup , ReversePInvokeBadTransition will failfast
+ call C_FUNC(ReversePInvokeBadTransition)
+
+LOCAL_LABEL(DoTrapReturningThreadsTHROW):
+
+ // extern "C" VOID STDCALL UMThunkStubRareDisableWorker(Thread *pThread, UMEntryThunk *pUMEntryThunk)
+ mov eax, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ push eax
+ mov eax, dword ptr [ebp - UMThunkStub_THREAD_OFFSET]
+ push eax
+ call C_FUNC(UMThunkStubRareDisableWorker)
+
+ jmp LOCAL_LABEL(InCooperativeMode)
+
+LOCAL_LABEL(UMThunkStub_CopyStackArgs):
+
+ // eax = m_cbActualArgSize
+ sub esp, eax
+ and esp, -16 // align with 16 byte
+ lea esi, [ebp + 0x08]
+ lea edi, [esp]
+
+LOCAL_LABEL(CopyLoop):
+
+ // eax = number of bytes
+ // esi = src
+ // edi = dest
+ // edx = sratch
+
+ add eax, -4
+ mov edx, dword ptr [esi + eax]
+ mov dword ptr [edi + eax], edx
+ jnz LOCAL_LABEL(CopyLoop)
+
+ jmp LOCAL_LABEL(UMThunkStub_ArgumentsSetup)
+
+#if _DEBUG
+LOCAL_LABEL(WrongAppDomain):
+ int3
+#endif
+
+NESTED_END UMThunkStub, _TEXT