Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Fix dotnet/corefx#29266 #17734

Merged
merged 1 commit into from
Apr 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/vm/amd64/PInvokeStubs.asm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ LEAF_ENTRY GenericPInvokeCalliHelper, _TEXT
test rax, rax
jz GenericPInvokeCalliGenILStub

;
; We need to distinguish between a MethodDesc* and an unmanaged target.
; The way we do this is to shift the managed target to the left by one bit and then set the
; least significant bit to 1. This works because MethodDesc* are always 8-byte aligned.
;
shl PINVOKE_CALLI_TARGET_REGISTER, 1
or PINVOKE_CALLI_TARGET_REGISTER, 1

;
; jump to existing IL stub
;
Expand Down
8 changes: 8 additions & 0 deletions src/vm/amd64/pinvokestubs.S
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ LEAF_ENTRY GenericPInvokeCalliHelper, _TEXT
test rax, rax
jz C_FUNC(GenericPInvokeCalliGenILStub)

//
// We need to distinguish between a MethodDesc* and an unmanaged target.
// The way we do this is to shift the managed target to the left by one bit and then set the
// least significant bit to 1. This works because MethodDesc* are always 8-byte aligned.
//
shl PINVOKE_CALLI_TARGET_REGISTER, 1
or PINVOKE_CALLI_TARGET_REGISTER, 1

//
// jump to existing IL stub
//
Expand Down
9 changes: 9 additions & 0 deletions src/vm/arm64/PInvokeStubs.asm
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ __PInvokeGenStubFuncName SETS "$__PInvokeGenStubFuncName":CC:"_RetBuffArg"
; if null goto stub generation
cbz x9, %0

IF "$FuncPrefix" == "GenericPInvokeCalli"
;
; We need to distinguish between a MethodDesc* and an unmanaged target.
; The way we do this is to shift the managed target to the left by one bit and then set the
; least significant bit to 1. This works because MethodDesc* are always 8-byte aligned.
;
lsl x9, x9, #1
orr x9, x9, #1
ENDIF

EPILOG_BRANCH_REG x9

Expand Down
14 changes: 12 additions & 2 deletions src/vm/arm64/pinvokestubs.S
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// $VASigCookieReg : register which contains the VASigCookie
// $SaveFPArgs : "Yes" or "No" . For varidic functions FP Args are not present in FP regs
// So need not save FP Args registers for vararg Pinvoke
.macro PINVOKE_STUB __PInvokeStubFuncName,__PInvokeGenStubFuncName,__PInvokeStubWorkerName,VASigCookieReg,HiddenArg,SaveFPArgs
.macro PINVOKE_STUB __PInvokeStubFuncName,__PInvokeGenStubFuncName,__PInvokeStubWorkerName,VASigCookieReg,HiddenArg,SaveFPArgs,ShiftLeftAndOrSecret=0


NESTED_ENTRY \__PInvokeStubFuncName, _TEXT, NoHandler
Expand All @@ -32,6 +32,16 @@
// if null goto stub generation
cbz x9, LOCAL_LABEL(\__PInvokeStubFuncName\()_0)

.if (\ShiftLeftAndOrSecret == 1)
//
// We need to distinguish between a MethodDesc* and an unmanaged target.
// The way we do this is to shift the managed target to the left by one bit and then set the
// least significant bit to 1. This works because MethodDesc* are always 8-byte aligned.
//
lsl x9, x9, #1
orr x9, x9, #1
.endif

EPILOG_BRANCH_REG x9

LOCAL_LABEL(\__PInvokeStubFuncName\()_0):
Expand Down Expand Up @@ -97,7 +107,7 @@ PINVOKE_STUB VarargPInvokeStub, VarargPInvokeGenILStub, VarargPInvokeStubWorker,
// x15 = VASigCookie*
// x12 = Unmanaged target
//
PINVOKE_STUB GenericPInvokeCalliHelper, GenericPInvokeCalliGenILStub, GenericPInvokeCalliStubWorker, x15, x12, 1
PINVOKE_STUB GenericPInvokeCalliHelper, GenericPInvokeCalliGenILStub, GenericPInvokeCalliStubWorker, x15, x12, 1, 1

// ------------------------------------------------------------------
// VarargPInvokeStub_RetBuffArg & VarargPInvokeGenILStub_RetBuffArg
Expand Down
5 changes: 5 additions & 0 deletions src/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2256,6 +2256,11 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth
// for managed-to-unmanaged CALLI that requires marshaling, the target is passed
// as the secret argument to the stub by GenericPInvokeCalliHelper (asmhelpers.asm)
EmitLoadStubContext(pcsEmit, dwStubFlags);
#ifdef _WIN64
// the secret arg has been shifted to left and ORed with 1 (see code:GenericPInvokeCalliHelper)
pcsEmit->EmitLDC(1);
pcsEmit->EmitSHR_UN();
#endif
}
else
#ifdef FEATURE_COMINTEROP
Expand Down
1 change: 1 addition & 0 deletions src/vm/frames.h
Original file line number Diff line number Diff line change
Expand Up @@ -2957,6 +2957,7 @@ class InlinedCallFrame : public Frame
WRAPPER_NO_CONTRACT;

#ifdef _WIN64
// See code:GenericPInvokeCalliHelper
return ((m_Datum != NULL) && !(dac_cast<TADDR>(m_Datum) & 0x1));
#else // _WIN64
return ((dac_cast<TADDR>(m_Datum) & ~0xffff) != 0);
Expand Down
1 change: 1 addition & 0 deletions src/vm/stubhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,7 @@ FCIMPL2(void*, StubHelpers::GetDelegateTarget, DelegateObject *pThisUNSAFE, UINT
#if defined(_WIN64)
UINT_PTR target = (UINT_PTR)orefThis->GetMethodPtrAux();

// See code:GenericPInvokeCalliHelper
// The lowest bit is used to distinguish between MD and target on 64-bit.
target = (target << 1) | 1;

Expand Down