summaryrefslogtreecommitdiff
path: root/src/vm/amd64/remotingamd64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/amd64/remotingamd64.cpp')
-rw-r--r--src/vm/amd64/remotingamd64.cpp672
1 files changed, 0 insertions, 672 deletions
diff --git a/src/vm/amd64/remotingamd64.cpp b/src/vm/amd64/remotingamd64.cpp
deleted file mode 100644
index 587afae124..0000000000
--- a/src/vm/amd64/remotingamd64.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-// 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.
-/*===========================================================================
-**
-** File: RemotingCpu.cpp
-**
-**
-**
-** Purpose: Defines various remoting related functions for the AMD64 architecture
-**
-**
-** See code:EEStartup#TableOfContents for EE overview
-**
-=============================================================================*/
-
-#include "common.h"
-
-#ifdef FEATURE_REMOTING
-
-#include "excep.h"
-#include "comdelegate.h"
-#include "remoting.h"
-#include "field.h"
-#include "siginfo.hpp"
-#include "stackbuildersink.h"
-#include "threads.h"
-#include "method.hpp"
-
-#include "asmconstants.h"
-
-// External variables
-extern DWORD g_dwNonVirtualThunkRemotingLabelOffset;
-extern DWORD g_dwNonVirtualThunkReCheckLabelOffset;
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::CheckForContextMatch public
-//
-// Synopsis: This code generates a check to see if the current context and
-// the context of the proxy match.
-//
-//+----------------------------------------------------------------------------
-//
-// returns zero if contexts match
-// returns non-zero if contexts don't match
-//
-extern "C" UINT_PTR __stdcall CRemotingServices__CheckForContextMatch(Object* pStubData)
-{
- // This method cannot have a contract because CreateStubForNonVirtualMethod assumes
- // it won't trash XMM registers. The code generated for contracts by recent compilers
- // is trashing XMM registers.
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_COOPERATIVE; // due to the Object parameter
- STATIC_CONTRACT_SO_TOLERANT;
-
- UINT_PTR contextID = *(UINT_PTR*)pStubData->UnBox();
- UINT_PTR contextCur = (UINT_PTR)GetThread()->m_Context;
- return (contextCur != contextID); // chosen to match x86 convention
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CreateThunkForVirtualMethod private
-//
-// Synopsis: Creates the thunk that pushes the supplied slot number and jumps
-// to TP Stub
-//
-//+----------------------------------------------------------------------------
-PCODE CTPMethodTable::CreateThunkForVirtualMethod(DWORD dwSlot, BYTE* pbCode)
-{
- LIMITED_METHOD_CONTRACT;
-
- BYTE *pbCodeStart = pbCode;
-
- // NOTE: if you change the code generated here, update
- // CVirtualThunkMgr::IsThunkByASM, CVirtualThunkMgr::GetMethodDescByASM
-
- //
- // mov r10, <dwSlot>
- // mov rax, TransparentProxyStub
- // jmp rax
- //
- *pbCode++ = 0x49;
- *pbCode++ = 0xc7;
- *pbCode++ = 0xc2;
- *((DWORD*)pbCode) = dwSlot;
- pbCode += sizeof(DWORD);
- *pbCode++ = 0x48;
- *pbCode++ = 0xB8;
- *((UINT64*)pbCode) = (UINT64)(TransparentProxyStub);
- pbCode += sizeof(UINT64);
- *pbCode++ = 0xFF;
- *pbCode++ = 0xE0;
-
- _ASSERTE(pbCode - pbCodeStart == ConstVirtualThunkSize);
- _ASSERTE(CVirtualThunkMgr::IsThunkByASM((PCODE)pbCodeStart));
-
- return (PCODE)pbCodeStart;
-}
-
-
-#ifdef HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::ActivatePrecodeRemotingThunk private
-//
-// Synopsis: Patch the precode remoting thunk to begin interception
-//
-//+----------------------------------------------------------------------------
-void CTPMethodTable::ActivatePrecodeRemotingThunk()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- PORTABILITY_WARNING("CTPMethodTable::ActivatePrecodeRemotingThunk");
-}
-
-#else // HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CreateStubForNonVirtualMethod public
-//
-// Synopsis: Create a stub for a non virtual method
-//
-//+----------------------------------------------------------------------------
-Stub* CTPMethodTable::CreateStubForNonVirtualMethod(MethodDesc* pMD, CPUSTUBLINKER* psl,
- LPVOID pvAddrOfCode, Stub* pInnerStub)
-{
- STANDARD_VM_CONTRACT;
-
- // Sanity check
-
- Stub *pStub = NULL;
-
- // we need a hash table only for virtual methods
- _ASSERTE(!pMD->IsVirtual());
-
- // Ensure the TP MethodTable's fields have been initialized.
- EnsureFieldsInitialized();
-
- /*
- NonVirtualMethodStub<thisReg, pvAddrOfCode, pTPMethodTable, pvTPStub>
- {
- ;; thisReg: this
-
- sub rsp, 0x28
-
- test thisReg, thisReg
- je JmpAddrLabel
-
- mov rax, [thisReg]
- mov r10, <pTPMethodTable>
- cmp rax, r10
- jne JmpAddrLabel
-
- mov [rsp+0x30], rcx ;|
- mov [rsp+0x38], rdx ;|
- mov [rsp+0x40], r8 ;|
- mov [rsp+0x48], r9 ;|
- ;|
- mov rax, [thisReg + TransparentProxyObject___stubData] ;|
- call [thisReg + TransparentProxyObject___stub] ;| EmitCallToStub<pCtxMismatch>
- ;|
- mov rcx, [rsp+0x30] ;|
- mov rdx, [rsp+0x38] ;|
- mov r8, [rsp+0x40] ;|
- mov r9, [rsp+0x48] ;|
- ;|
- test rax, rax ;|
- jnz RemotingLabel ;|
-
- JmpAddrLabel:
- mov rax, <pvAddrOfCode>
- add rsp, 0x28
- jmp rax
-
- RemotingLabel:
- mov r10, <pMD>
- mov rax, <pvTPStub>
- add rsp, 0x20
- jmp rax
- }
- */
-
- X86Reg thisReg = kRCX;
- void* pvTPStub = TransparentProxyStub_CrossContext;
-
- // Generate label where a null reference exception will be thrown
- CodeLabel *pJmpAddrLabel = psl->NewCodeLabel();
- // Generate label where remoting code will execute
- CodeLabel *pRemotingLabel = psl->NewCodeLabel();
-
- // NOTE: if you change any of this code, you must update
- // CNonVirtualThunkMgr::IsThunkByASM.
-
- // Allocate callee scratch area
- // sub rsp, 0x28
- psl->X86EmitSubEsp(0x28);
-
- // test thisReg, thisReg
- psl->X86EmitR2ROp(0x85, thisReg, thisReg);
- // je JmpAddrLabel
- psl->X86EmitCondJump(pJmpAddrLabel, X86CondCode::kJE);
-
- // Emit a label here for the debugger. A breakpoint will
- // be set at the next instruction and the debugger will
- // call CNonVirtualThunkMgr::TraceManager when the
- // breakpoint is hit with the thread's context.
- CodeLabel *pRecheckLabel = psl->NewCodeLabel();
- psl->EmitLabel(pRecheckLabel);
-
- // mov rax, [thisReg]
- psl->X86EmitIndexRegLoad(kRAX, thisReg, 0);
-
- // mov r10, CTPMethodTable::GetMethodTable()
- psl->X86EmitRegLoad(kR10, (UINT_PTR)CTPMethodTable::GetMethodTable());
- // cmp rax, r10
- psl->X86EmitR2ROp(0x3B, kRAX, kR10);
-
- // jne JmpAddrLabel
- psl->X86EmitCondJump(pJmpAddrLabel, X86CondCode::kJNE);
-
- // CONSIDER: write all possible stubs in asm to ensure param registers are not trashed
-
- // mov [rsp+0x30], rcx
- // mov [rsp+0x38], rdx
- // mov [rsp+0x40], r8
- // mov [rsp+0x48], r9
- psl->X86EmitRegSave(kRCX, 0x30);
- psl->X86EmitRegSave(kRDX, 0x38);
- psl->X86EmitRegSave(kR8, 0x40);
- psl->X86EmitRegSave(kR9, 0x48);
-
- // mov rax, [thisReg + TransparentProxyObject___stub]
- psl->X86EmitIndexRegLoad(kRAX, thisReg, TransparentProxyObject___stub);
-
- // mov rcx, [thisReg + TransparentProxyObject___stubData]
- psl->X86EmitIndexRegLoad(kRCX, thisReg, TransparentProxyObject___stubData);
-
- // call rax
- psl->Emit16(0xd0ff);
-
- // mov rcx, [rsp+0x30]
- // mov rdx, [rsp+0x38]
- // mov r8, [rsp+0x40]
- // mov r9, [rsp+0x48]
- psl->X86EmitEspOffset(0x8b, kRCX, 0x30);
- psl->X86EmitEspOffset(0x8b, kRDX, 0x38);
- psl->X86EmitEspOffset(0x8b, kR8, 0x40);
- psl->X86EmitEspOffset(0x8b, kR9, 0x48);
-
- // test rax, rax
- psl->X86EmitR2ROp(0x85, kRAX, kRAX);
- // jnz RemotingLabel
- psl->X86EmitCondJump(pRemotingLabel, X86CondCode::kJNZ);
-
-// pJmpAddrLabel:
- psl->EmitLabel(pJmpAddrLabel);
-
- // Make sure that the actual code does not require MethodDesc in r10
- _ASSERTE(!pMD->RequiresMethodDescCallingConvention());
-
- // mov rax, <pvAddrOfCode>
- // add rsp, 0x28
- // REX.W jmp rax
- psl->X86EmitTailcallWithESPAdjust(psl->NewExternalCodeLabel(pvAddrOfCode), 0x28);
-
-// pRemotingLabel:
- psl->EmitLabel(pRemotingLabel);
-
- // mov r10, <pMD>
- psl->X86EmitRegLoad(kR10, (UINT_PTR)pMD);
-
- // mov rax, <pvTPStub>
- // add rsp, 0x28
- // REX.W jmp rax
- psl->X86EmitTailcallWithESPAdjust(psl->NewExternalCodeLabel(pvTPStub), 0x28);
-
- // Link and produce the stub
- pStub = psl->LinkInterceptor(pMD->GetLoaderAllocator()->GetStubHeap(),
- pInnerStub, pvAddrOfCode);
-
- return pStub;
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Synopsis: Find an existing thunk or create a new one for the given
-// method descriptor. NOTE: This is used for the methods that do
-// not go through the vtable such as constructors, private and
-// final methods.
-//
-//+----------------------------------------------------------------------------
-PCODE CTPMethodTable::CreateNonVirtualThunkForVirtualMethod(MethodDesc* pMD)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pMD));
- }
- CONTRACTL_END;
-
- CPUSTUBLINKER sl;
- CPUSTUBLINKER* psl = &sl;
-
- Stub *pStub = NULL;
-
- // The thunk has not been created yet. Go ahead and create it.
- // Compute the address of the slot
- LPVOID pvEntryPoint = (LPVOID)pMD->GetMethodEntryPoint();
-
- X86Reg thisReg = kRCX;
- void* pvStub = CRemotingServices__DispatchInterfaceCall;
-
- // Generate label where a null reference exception will be thrown
- CodeLabel *pExceptionLabel = psl->NewCodeLabel();
-
- // !!! WARNING WARNING WARNING WARNING WARNING !!!
- //
- // DO NOT CHANGE this code without changing the thunk recognition
- // code in CNonVirtualThunkMgr::IsThunkByASM
- // & CNonVirtualThunkMgr::GetMethodDescByASM
- //
- // !!! WARNING WARNING WARNING WARNING WARNING !!!
-
- // NOTE: constant mov's should use an extended register to force a REX
- // prefix and the full 64-bit immediate value, so that
- // g_dwNonVirtualThunkRemotingLabelOffset and
- // g_dwNonVirtualThunkReCheckLabelOffset are the same for all
- // generated code.
-
- // if this == NULL throw NullReferenceException
- // test rcx, rcx
- psl->X86EmitR2ROp(0x85, thisReg, thisReg);
-
- // je ExceptionLabel
- psl->X86EmitCondJump(pExceptionLabel, X86CondCode::kJE);
-
- // Generate label where remoting code will execute
- CodeLabel *pRemotingLabel = psl->NewCodeLabel();
-
- // Emit a label here for the debugger. A breakpoint will
- // be set at the next instruction and the debugger will
- // call CNonVirtualThunkMgr::TraceManager when the
- // breakpoint is hit with the thread's context.
- CodeLabel *pRecheckLabel = psl->NewCodeLabel();
- psl->EmitLabel(pRecheckLabel);
-
- // If this.MethodTable == TPMethodTable then do RemotingCall
- // mov rax, [thisReg]
- psl->X86EmitIndexRegLoad(kRAX, thisReg, 0);
- // mov r10, CTPMethodTable::GetMethodTable()
- psl->X86EmitRegLoad(kR10, (UINT_PTR)CTPMethodTable::GetMethodTable());
- // cmp rax, r10
- psl->X86EmitR2ROp(0x3B, kRAX, kR10);
- // je RemotingLabel
- psl->X86EmitCondJump(pRemotingLabel, X86CondCode::kJE);
-
- // Exception handling and non-remoting share the
- // same codepath
- psl->EmitLabel(pExceptionLabel);
-
- // Non-RemotingCode
- // Jump to the vtable slot of the method
- // mov rax, pvEntryPoint
- // Encoded the mov manually so that it always uses the 64-bit form.
- //psl->X86EmitRegLoad(kRAX, (UINT_PTR)pvEntryPoint);
- psl->Emit8(REX_PREFIX_BASE | REX_OPERAND_SIZE_64BIT);
- psl->Emit8(0xb8);
- psl->EmitBytes((BYTE*)&pvEntryPoint, 8);
- // jmp rax
- psl->Emit8(0xff);
- psl->Emit8(0xe0);
-
- // Remoting code. Note: CNonVirtualThunkMgr::TraceManager
- // relies on this label being right after the jmp pvEntryPoint
- // instruction above. If you move this label, update
- // CNonVirtualThunkMgr::DoTraceStub.
- psl->EmitLabel(pRemotingLabel);
-
- // Save the MethodDesc and goto TPStub
- // push MethodDesc
- psl->X86EmitRegLoad(kR10, (UINT_PTR)pMD);
-
- // jmp TPStub
- psl->X86EmitNearJump(psl->NewExternalCodeLabel(pvStub));
-
- // Link and produce the stub
- // FUTURE: Do we have to provide the loader heap ?
- pStub = psl->Link(SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap());
-
- // Grab the offset of the RemotingLabel and RecheckLabel
- // for use in CNonVirtualThunkMgr::DoTraceStub and
- // TraceManager.
- DWORD dwOffset;
-
- dwOffset = psl->GetLabelOffset(pRemotingLabel);
- ASSERT(!g_dwNonVirtualThunkRemotingLabelOffset || g_dwNonVirtualThunkRemotingLabelOffset == dwOffset);
- g_dwNonVirtualThunkRemotingLabelOffset = dwOffset;
-
- dwOffset = psl->GetLabelOffset(pRecheckLabel);
- ASSERT(!g_dwNonVirtualThunkReCheckLabelOffset || g_dwNonVirtualThunkReCheckLabelOffset == dwOffset);
- g_dwNonVirtualThunkReCheckLabelOffset = dwOffset;
-
- return (pStub->GetEntryPoint());
-}
-
-#endif // HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::DoTraceStub public
-//
-// Synopsis: Traces the stub given the starting address
-//
-//+----------------------------------------------------------------------------
-BOOL CVirtualThunkMgr::DoTraceStub(PCODE stubStartAddress, TraceDestination *trace)
-{
- LIMITED_METHOD_CONTRACT;
-
- // <TODO> implement this </TODO>
- return FALSE;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::IsThunkByASM public
-//
-// Synopsis: Check assembly to see if this one of our thunks
-//
-//+----------------------------------------------------------------------------
-BOOL CVirtualThunkMgr::IsThunkByASM(PCODE startaddr)
-{
- LIMITED_METHOD_CONTRACT;
-
- PTR_BYTE pbCode = PTR_BYTE(startaddr);
-
- // NOTE: this depends on the code generated by
- // CTPMethodTable::CreateThunkForVirtualMethod.
-
- // mov r10, <dwSlot>
- return 0x49 == pbCode[0]
- && 0xc7 == pbCode[1]
- && 0xc2 == pbCode[2]
- // mov rax, TransparentProxyStub
- && 0x48 == pbCode[7]
- && 0xb8 == pbCode[8]
- && (TADDR)TransparentProxyStub == *PTR_TADDR(pbCode+9)
- // jmp rax
- && 0xff == pbCode[17]
- && 0xe0 == pbCode[18];
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::GetMethodDescByASM public
-//
-// Synopsis: Parses MethodDesc out of assembly code
-//
-//+----------------------------------------------------------------------------
-MethodDesc *CVirtualThunkMgr::GetMethodDescByASM(PCODE pbThunkCode, MethodTable *pMT)
-{
- LIMITED_METHOD_CONTRACT;
-
- // NOTE: this depends on the code generated by
- // CTPMethodTable::CreateThunkForVirtualMethod.
-
- return pMT->GetMethodDescForSlot(*((DWORD *) (pbThunkCode + 3)));
-}
-
-
-#ifndef HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::TraceManager public
-//
-// Synopsis: Traces the stub given the current context
-//
-//+----------------------------------------------------------------------------
-BOOL CNonVirtualThunkMgr::TraceManager(Thread* thread,
- TraceDestination* trace,
- CONTEXT* pContext,
- BYTE** pRetAddr)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(thread, NULL_OK));
- PRECONDITION(CheckPointer(trace));
- PRECONDITION(CheckPointer(pContext));
- PRECONDITION(CheckPointer(pRetAddr));
- }
- CONTRACTL_END;
-
- BOOL bRet = FALSE;
-
- MethodDesc * pMD = GetMethodDescByASM(GetIP(pContext) - g_dwNonVirtualThunkReCheckLabelOffset);
-
- LPBYTE pThis = (LPBYTE)pContext->Rcx;
-
- if ((pThis != NULL) &&
- (*(LPBYTE*)(SIZE_T)pThis == (LPBYTE)(SIZE_T)CTPMethodTable::GetMethodTable()))
- {
- // <TODO>We know that we've got a proxy
- // in the way. If the proxy is to a remote call, with no
- // managed code in between, then the debugger doesn't care and
- // we should just be able to return FALSE.
- //
- // </TODO>
- bRet = FALSE;
- }
- else
- {
- // No proxy in the way, so figure out where we're really going
- // to and let the stub manager try to pickup the trace from
- // there.
- LPBYTE stubStartAddress = (LPBYTE)GetIP(pContext) -
- g_dwNonVirtualThunkReCheckLabelOffset;
-
- // Extract the address of the destination
- BYTE* pbAddr = (BYTE *)(SIZE_T)(stubStartAddress +
- g_dwNonVirtualThunkRemotingLabelOffset - 2 - sizeof(void *));
-
- SIZE_T destAddress = *(SIZE_T *)pbAddr;
-
- // Ask the stub manager to trace the destination address
- bRet = StubManager::TraceStub((PCODE)(BYTE *)(size_t)destAddress, trace);
- }
-
- // While we may have made it this far, further tracing may reveal
- // that the debugger can't continue on. Therefore, since there is
- // no frame currently pushed, we need to tell the debugger where
- // we're returning to just in case it hits such a situtation. We
- // know that the return address is on the top of the thread's
- // stack.
- (*pRetAddr) = *((BYTE**)(size_t)(GetSP(pContext)));
-
- return bRet;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::DoTraceStub public
-//
-// Synopsis: Traces the stub given the starting address
-//
-//+----------------------------------------------------------------------------
-BOOL CNonVirtualThunkMgr::DoTraceStub(PCODE stubStartAddress,
- TraceDestination* trace)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(stubStartAddress != NULL);
- PRECONDITION(CheckPointer(trace));
- }
- CONTRACTL_END;
-
- BOOL bRet = FALSE;
-
- if (!IsThunkByASM(stubStartAddress))
- return FALSE;
-
- CNonVirtualThunk* pThunk = FindThunk((const BYTE *)stubStartAddress);
-
- if(NULL != pThunk)
- {
- // We can either jump to
- // (1) a slot in the transparent proxy table (UNMANAGED)
- // (2) a slot in the non virtual part of the vtable
- // ... so, we need to return TRACE_MGR_PUSH with the address
- // at which we want to be called back with the thread's context
- // so we can figure out which way we're gonna go.
- if((const BYTE *)stubStartAddress == pThunk->GetThunkCode())
- {
- trace->InitForManagerPush(
- (PCODE) (stubStartAddress + g_dwNonVirtualThunkReCheckLabelOffset),
- this);
- bRet = TRUE;
- }
- }
-
- return bRet;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::IsThunkByASM public
-//
-// Synopsis: Check assembly to see if this one of our thunks
-//
-//+----------------------------------------------------------------------------
-BOOL CNonVirtualThunkMgr::IsThunkByASM(PCODE startaddr)
-{
- LIMITED_METHOD_CONTRACT;
-
- PTR_BYTE pbCode = PTR_BYTE(startaddr);
-
- // test rcx, rcx ; 3 bytes
- return 0x48 == pbCode[0]
- && 0x85 == pbCode[1]
- && 0xc9 == pbCode[2]
- // je ... ; 2 bytes
- && 0x74 == pbCode[3]
- // mov rax, [rcx] ; 3 bytes
- // mov r10, CTPMethodTable::GetMethodTable() ; 2 bytes + MethodTable*
- && (TADDR)CTPMethodTable::GetMethodTable() == *PTR_TADDR(pbCode + 10);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::GetMethodDescByASM public
-//
-// Synopsis: Parses MethodDesc out of assembly code
-//
-//+----------------------------------------------------------------------------
-MethodDesc* CNonVirtualThunkMgr::GetMethodDescByASM(PCODE pbThunkCode)
-{
- LIMITED_METHOD_CONTRACT;
-
- return *((MethodDesc **) (pbThunkCode + g_dwNonVirtualThunkRemotingLabelOffset + 2));
-}
-
-#endif // HAS_REMOTING_PRECODE
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::GenericCheckForContextMatch private
-//
-// Synopsis: Calls the stub in the TP & returns TRUE if the contexts
-// match, FALSE otherwise.
-//
-// Note: 1. Called during FieldSet/Get, used for proxy extensibility
-//
-//+----------------------------------------------------------------------------
-BOOL __stdcall CTPMethodTable__GenericCheckForContextMatch(Object* orTP)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE; // due to the Object parameter
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- Object *StubData = OBJECTREFToObject(((TransparentProxyObject*)orTP)->GetStubData());
- CTPMethodTable::CheckContextCrossingProc *pfnCheckContextCrossing =
- (CTPMethodTable::CheckContextCrossingProc*)(((TransparentProxyObject*)orTP)->GetStub());
- return pfnCheckContextCrossing(StubData) == 0;
-}
-
-#endif // FEATURE_REMOTING
-
-