Fixes around the GetModuleIfLoaded and related APIs (dotnet/coreclr#26516)
authorFadi Hanna <fadim@microsoft.com>
Thu, 5 Sep 2019 17:35:04 +0000 (10:35 -0700)
committerGitHub <noreply@github.com>
Thu, 5 Sep 2019 17:35:04 +0000 (10:35 -0700)
* Enabling precompiled generics to be loaded from the root entrypoint R2R module.

Include R2RDump tool changes that match the CoreRT cross module signatures in the instantiations table

Commit migrated from https://github.com/dotnet/coreclr/commit/21d651bb4613ca480cd97793fe5d854af36b765c

src/coreclr/src/tools/r2rdump/R2RDump.cs
src/coreclr/src/tools/r2rdump/R2RMethod.cs
src/coreclr/src/tools/r2rdump/R2RReader.cs
src/coreclr/src/tools/r2rdump/R2RSignature.cs
src/coreclr/src/vm/appdomain.cpp
src/coreclr/src/vm/ceeload.cpp
src/coreclr/src/vm/readytoruninfo.cpp

index f871f9f..3a97d5d 100644 (file)
@@ -361,7 +361,7 @@ namespace R2RDump
         {
             int id;
             bool isNum = ArgStringToInt(query, out id);
-            bool idMatch = isNum && (method.Rid == id || MetadataTokens.GetRowNumber(method.R2RReader.MetadataReader, method.MethodHandle) == id);
+            bool idMatch = isNum && (method.Rid == id || MetadataTokens.GetRowNumber(method.MetadataReader, method.MethodHandle) == id);
 
             bool sigMatch = false;
             if (exact)
index e8b4a4d..fe2cb62 100644 (file)
@@ -268,9 +268,9 @@ namespace R2RDump
         private const int _mdtMethodDef = 0x06000000;
 
         /// <summary>
-        /// R2R reader representing the method module.
+        /// MetadataReader representing the method module.
         /// </summary>
-        public R2RReader R2RReader { get; }
+        public MetadataReader MetadataReader { get; private set; }
 
         /// <summary>
         /// An unique index for the method
@@ -327,7 +327,7 @@ namespace R2RDump
         /// </summary>
         public R2RMethod(
             int index, 
-            R2RReader r2rReader, 
+            MetadataReader metadataReader,
             EntityHandle methodHandle, 
             int entryPointId, 
             string owningType, 
@@ -339,7 +339,7 @@ namespace R2RDump
             MethodHandle = methodHandle;
             EntryPointRuntimeFunctionId = entryPointId;
 
-            R2RReader = r2rReader;
+            MetadataReader = metadataReader;
             RuntimeFunctions = new List<RuntimeFunction>();
 
             EntityHandle owningTypeHandle;
@@ -353,8 +353,8 @@ namespace R2RDump
             {
                 case HandleKind.MethodDefinition:
                     {
-                        MethodDefinition methodDef = R2RReader.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle);
-                        Name = R2RReader.MetadataReader.GetString(methodDef.Name);
+                        MethodDefinition methodDef = MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle);
+                        Name = MetadataReader.GetString(methodDef.Name);
                         Signature = methodDef.DecodeSignature<string, DisassemblingGenericContext>(typeProvider, genericContext);
                         owningTypeHandle = methodDef.GetDeclaringType();
                         genericParams = methodDef.GetGenericParameters();
@@ -363,8 +363,8 @@ namespace R2RDump
 
                 case HandleKind.MemberReference:
                     {
-                        MemberReference memberRef = R2RReader.MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle);
-                        Name = R2RReader.MetadataReader.GetString(memberRef.Name);
+                        MemberReference memberRef = MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle);
+                        Name = MetadataReader.GetString(memberRef.Name);
                         Signature = memberRef.DecodeMethodSignature<string, DisassemblingGenericContext>(typeProvider, genericContext);
                         owningTypeHandle = memberRef.Parent;
                     }
@@ -380,7 +380,7 @@ namespace R2RDump
             }
             else
             {
-                DeclaringType = MetadataNameFormatter.FormatHandle(R2RReader.MetadataReader, owningTypeHandle);
+                DeclaringType = MetadataNameFormatter.FormatHandle(MetadataReader, owningTypeHandle);
             }
 
             Fixups = fixups;
@@ -432,8 +432,8 @@ namespace R2RDump
         {
             writer.WriteLine(SignatureString);
 
-            writer.WriteLine($"Handle: 0x{MetadataTokens.GetToken(R2RReader.MetadataReader, MethodHandle):X8}");
-            writer.WriteLine($"Rid: {MetadataTokens.GetRowNumber(R2RReader.MetadataReader, MethodHandle)}");
+            writer.WriteLine($"Handle: 0x{MetadataTokens.GetToken(MetadataReader, MethodHandle):X8}");
+            writer.WriteLine($"Rid: {MetadataTokens.GetRowNumber(MetadataReader, MethodHandle)}");
             if (!options.Naked)
             {
                 writer.WriteLine($"EntryPointRuntimeFunctionId: {EntryPointRuntimeFunctionId}");
index 99f4674..5e9c2dc 100644 (file)
@@ -438,7 +438,7 @@ namespace R2RDump
                     int runtimeFunctionId;
                     FixupCell[] fixups;
                     GetRuntimeFunctionIndexFromOffset(offset, out runtimeFunctionId, out fixups);
-                    R2RMethod method = new R2RMethod(R2RMethods.Count, this, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixups: fixups);
+                    R2RMethod method = new R2RMethod(R2RMethods.Count, this.MetadataReader, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixups: fixups);
 
                     if (method.EntryPointRuntimeFunctionId < 0 || method.EntryPointRuntimeFunctionId >= isEntryPoint.Length)
                     {
@@ -468,12 +468,14 @@ namespace R2RDump
             while (!curParser.IsNull())
             {
                 SignatureDecoder decoder = new SignatureDecoder(Options, this, (int)curParser.Offset);
+                MetadataReader mdReader = MetadataReader;
 
                 string owningType = null;
 
                 uint methodFlags = decoder.ReadUInt();
                 if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
                 {
+                    mdReader = decoder.GetMetadataReaderFromModuleOverride();
                     owningType = decoder.ReadTypeSignatureNoEmit();
                 }
                 if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_SlotInsteadOfToken) != 0)
@@ -510,7 +512,15 @@ namespace R2RDump
                 int runtimeFunctionId;
                 FixupCell[] fixups;
                 GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixups);
-                R2RMethod method = new R2RMethod(R2RMethods.Count, this, methodHandle, runtimeFunctionId, owningType, constrainedType, methodTypeArgs, fixups);
+                R2RMethod method = new R2RMethod(
+                    R2RMethods.Count, 
+                    mdReader == null ? MetadataReader : mdReader, 
+                    methodHandle, 
+                    runtimeFunctionId, 
+                    owningType, 
+                    constrainedType, 
+                    methodTypeArgs, 
+                    fixups);
                 if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < isEntryPoint.Length)
                 {
                     isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
index 5df119c..a70dca5 100644 (file)
@@ -502,6 +502,11 @@ namespace R2RDump
             return (CorElementType)(ReadByte() & 0x7F);
         }
 
+        public CorElementType PeekElementType()
+        {
+            return (CorElementType)(_image[_offset] & 0x7F);
+        }
+
         /// <summary>
         /// Decode a R2R import signature. The signature starts with the fixup type followed
         /// by custom encoding per fixup type.
@@ -1072,6 +1077,24 @@ namespace R2RDump
                     throw new NotImplementedException();
             }
         }
+
+        public MetadataReader GetMetadataReaderFromModuleOverride()
+        {
+            if (PeekElementType() == CorElementType.ELEMENT_TYPE_MODULE_ZAPSIG)
+            {
+                var currentOffset = _offset;
+
+                ReadElementType();
+                int moduleIndex = (int)ReadUInt();
+                EcmaMetadataReader refAsmReader = _contextReader.OpenReferenceAssembly(moduleIndex);
+
+                _offset = currentOffset;
+
+                return refAsmReader.MetadataReader;
+            }
+            return null;
+        }
+
         private void ParseGenericTypeInstance(StringBuilder builder)
         {
             ParseType(builder);
index 635bba3..8f93123 100644 (file)
@@ -3988,8 +3988,17 @@ DomainAssembly *AppDomain::LoadDomainAssemblyInternal(AssemblySpec* pIdentity,
 
     // Cache result in all cases, since found pFile could be from a different AssemblyRef than pIdentity
     // Do not cache WindowsRuntime assemblies, they are cached in code:CLRPrivTypeCacheWinRT
-    if ((pIdentity != NULL) && (pIdentity->CanUseWithBindingCache()) && (result->CanUseWithBindingCache()))
+    if (pIdentity == NULL)
+    {
+        AssemblySpec spec;
+        spec.InitializeSpec(result->GetFile());
+        if (spec.CanUseWithBindingCache() && result->CanUseWithBindingCache())
+            GetAppDomain()->AddAssemblyToCache(&spec, result);
+    }
+    else if (pIdentity->CanUseWithBindingCache() && result->CanUseWithBindingCache())
+    {
         GetAppDomain()->AddAssemblyToCache(pIdentity, result);
+    }
     
     RETURN result;
 } // AppDomain::LoadDomainAssembly
index 35b89c9..a54c795 100644 (file)
@@ -589,7 +589,17 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName)
 
 #ifdef FEATURE_READYTORUN
     if (!HasNativeImage() && !IsResource())
-        m_pReadyToRunInfo = ReadyToRunInfo::Initialize(this, pamTracker);
+    {
+        if ((m_pReadyToRunInfo = ReadyToRunInfo::Initialize(this, pamTracker)) != NULL)
+        {
+            COUNT_T cMeta = 0;
+            if (GetFile()->GetOpenedILimage()->GetNativeManifestMetadata(&cMeta) != NULL)
+            {
+                // Load the native assembly import
+                GetNativeAssemblyImport(TRUE /* loadAllowed */);
+            }
+        }
+    }
 #endif
 
     // Initialize the instance fields that we need for all non-Resource Modules
index 3136845..19e75f9 100644 (file)
@@ -713,10 +713,7 @@ PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, PrepareCodeConfig* pConfig
             {
                 // Get the updated SigPointer location, so we can calculate the size of the blob,
                 // in order to skip the blob and find the entry point data.
-                PCCOR_SIGNATURE pSigNew;
-                DWORD cbSigNew;
-                sig.GetSignature(&pSigNew, &cbSigNew);
-                offset = entryParser.GetOffset() + (uint)(pSigNew - pBlob);
+                offset = entryParser.GetOffset() + (uint)(sig.GetPtr() - pBlob);
                 break;
             }
         }