GenericPInvokeCalli shift left then or 1 (dotnet/coreclr#17734)
authorSteve MacLean <sdmaclea.qdt@qualcommdatacenter.com>
Tue, 24 Apr 2018 01:39:24 +0000 (21:39 -0400)
committerJan Kotas <jkotas@microsoft.com>
Tue, 24 Apr 2018 01:39:24 +0000 (18:39 -0700)
When _WIN64 is defined vm relies on the secret arg being
shifted left and orred with dotnet/coreclr#1.

Revert part of changes from dotnet/coreclr#17659 to fix dotnet/corefxdotnet/coreclr#29266

Fix arm64 to match amd64

Simplify dllimport.cpp

Commit migrated from https://github.com/dotnet/coreclr/commit/5ebaadf50f99050591a6a987888ef9077cf2050b

src/coreclr/src/vm/amd64/PInvokeStubs.asm
src/coreclr/src/vm/amd64/pinvokestubs.S
src/coreclr/src/vm/arm64/PInvokeStubs.asm
src/coreclr/src/vm/arm64/pinvokestubs.S
src/coreclr/src/vm/dllimport.cpp
src/coreclr/src/vm/frames.h
src/coreclr/src/vm/stubhelpers.cpp

index 7255fa2ebf94c4b83fc5a48233d74bd4afea54ab..82e33ac03d045fcd16d152e514b73a7d6eac837f 100644 (file)
@@ -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
         ;
index dad668af23fd61b1a0e948725c88d2bdbd9ae8fc..19521642ae69256841c7024d58f0521c0938759f 100644 (file)
@@ -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
         //
index e21151e179bcb26bbc6280cdf89a48a68174fb38..69d8a91e1ecf206311f2737a27688ae9620df84e 100644 (file)
@@ -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 
 
index f13d2da72ecbb38cba0b141acaccba925e8e6bbd..38f4665713fa07052d6755b9b4827ba1f72509e0 100644 (file)
@@ -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
         // 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):
@@ -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
index c0f7d1fa247dc48fef68887015f129813c5a4d07..dc5ae06bf256bb593605e7ab1dcd8f228ecd5ff5 100644 (file)
@@ -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
index 66520a849ca6c129e18b2329d60613d4281df9b7..09803788bc6c8db3d3c03c695b79ea6342e44279 100644 (file)
@@ -2957,6 +2957,7 @@ public:
         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);
index 071c87966edce9d75561ae49019c5b64e8fcabeb..d43c065362cc05726ae8e5d77371860601275a1c 100644 (file)
@@ -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;