Fix module override effect on method instantiating signature
authorJan Vorlicek <janvorli@microsoft.com>
Wed, 1 May 2019 01:22:03 +0000 (03:22 +0200)
committerJan Vorlicek <janvorli@microsoft.com>
Wed, 1 May 2019 01:22:03 +0000 (03:22 +0200)
When a module override is placed on a fixup blob top level, it also
affects types in the method instantiating signature. This can cause
tokens in the signature to be resolved in a wrong module.

This change fixes it by adding module zapsig elements before each
argument of the method's instantiating signature.

Commit migrated from https://github.com/dotnet/coreclr/commit/4b603baf496544a6a6d67c4ef43ee1b3a200acfc

src/coreclr/src/vm/zapsig.cpp

index cfccdea..8feb7be 100644 (file)
@@ -1315,7 +1315,7 @@ BOOL ZapSig::EncodeMethod(
         }
         else
         {
-            _ASSERTE(pInfoModule = pMethod->GetModule());
+            _ASSERTE(pInfoModule == pMethod->GetModule());
         }
 
         if (!ownerType.HasInstantiation())
@@ -1366,10 +1366,40 @@ BOOL ZapSig::EncodeMethod(
         {
             _ASSERTE(pResolvedToken->cbMethodSpec > 1);
 
-            if (*(BYTE*)pResolvedToken->pMethodSpec != (BYTE)IMAGE_CEE_CS_CALLCONV_GENERICINST)
+            // Copy the pResolvedToken->pMethodSpec, inserting ELEMENT_TYPE_MODULE_ZAPSIG in front of each type parameter in needed
+            SigParser sigParser(pResolvedToken->pMethodSpec);
+            BYTE callingConvention;
+            IfFailThrow(sigParser.GetByte(&callingConvention));
+            if (callingConvention != (BYTE)IMAGE_CEE_CS_CALLCONV_GENERICINST)
+            {
                 ThrowHR(COR_E_BADIMAGEFORMAT);
+            }
+
+            ULONG numGenArgs;
+            IfFailThrow(sigParser.GetData(&numGenArgs));
+            pSigBuilder->AppendData(numGenArgs);
+
+            DWORD moduleIndex;
+            bool addModuleZapSig = (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope);
+            if (addModuleZapSig)
+            {
+                moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope);
+            }
 
-            pSigBuilder->AppendBlob((PVOID)(((BYTE*)pResolvedToken->pMethodSpec) + 1), pResolvedToken->cbMethodSpec - 1);
+            while (numGenArgs != 0)
+            {
+                if (addModuleZapSig)
+                {
+                    pSigBuilder->AppendElementType((CorElementType)ELEMENT_TYPE_MODULE_ZAPSIG);
+                    pSigBuilder->AppendData(moduleIndex);
+                }
+
+                PCCOR_SIGNATURE typeSigStart = sigParser.GetPtr();
+                IfFailThrow(sigParser.SkipExactlyOne());
+                PCCOR_SIGNATURE typeSigEnd = sigParser.GetPtr();
+                pSigBuilder->AppendBlob((PVOID)typeSigStart, typeSigEnd - typeSigStart);
+                numGenArgs--;
+            }
         }
         else
         {