internal Internal.TypeSystem.Ecma.EcmaModule ResolveEcmaModule(EcmaModuleInfo module) { if (_ecmaModules == null) { _ecmaModules = new ModuleToEcmaModuleHashtable(this); } return(_ecmaModules.GetOrCreateValue(module)); }
partial void BindEcmaByteArray(byte[] rawAssembly, byte[] rawSymbolStore, ref AssemblyBindResult bindResult, ref Exception exception, ref bool?result) { // 1. Load byte[] into immutable array for use by PEReader/MetadataReader ImmutableArray <byte> assemblyData = ImmutableArray.Create(rawAssembly); PEReader pe = new PEReader(assemblyData); MetadataReader reader = pe.GetMetadataReader(); // 2. Create AssemblyName from MetadataReader RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader); AssemblyName asmName = new AssemblyName(); runtimeAssemblyName.CopyToAssemblyName(asmName); lock (s_ecmaLoadedAssemblies) { // 3. Attempt to bind to already loaded assembly if (Bind(asmName, out bindResult, out exception)) { result = true; return; } exception = null; // 4. If that fails, then add newly created metareader to global cache of byte array loaded modules PEInfo peinfo = new PEInfo(asmName, reader, pe); s_ecmaLoadedAssemblies.Add(peinfo); ModuleList moduleList = ModuleList.Instance; ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader); moduleList.RegisterModule(newModuleInfo); // 5. Then try to load by name again. This load should always succeed if (Bind(asmName, out bindResult, out exception)) { result = true; return; } result = false; Debug.Assert(exception != null); // We must have an error on load. At this time this could happen due to ambiguous name matching } }
internal TypeDesc GetTypeDescFromQHandle(QTypeDefinition qTypeDefinition) { #if ECMA_METADATA_SUPPORT if (qTypeDefinition.IsNativeFormatMetadataBased) #endif { MetadataReader nativeFormatMetadataReader = qTypeDefinition.NativeFormatReader; TypeDefinitionHandle typeDefinitionHandle = qTypeDefinition.NativeFormatHandle; NativeFormatModuleInfo module = ModuleList.Instance.GetModuleInfoForMetadataReader(nativeFormatMetadataReader); NativeFormatMetadataUnit metadataUnit = ResolveMetadataUnit(module); NativeFormatType nativeFormatType = (NativeFormatType)metadataUnit.GetType(typeDefinitionHandle); return(nativeFormatType); } #if ECMA_METADATA_SUPPORT else if (qTypeDefinition.IsEcmaFormatMetadataBased) { EcmaModuleInfo module = ModuleList.Instance.GetModuleInfoForMetadataReader(qTypeDefinition.EcmaFormatReader); Ecma.EcmaModule ecmaModule = ResolveEcmaModule(module); Ecma.EcmaType ecmaType = (Ecma.EcmaType)ecmaModule.GetType(qTypeDefinition.EcmaFormatHandle); return(ecmaType); } #endif return(null); }
private void BindEcma(PEReader pe, MemoryMappedViewAccessor?memoryMappedView, out AssemblyBindResult bindResult, out Exception?exception, out bool?result) { MetadataReader reader = pe.GetMetadataReader(); // 1. Create AssemblyName from MetadataReader RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader); lock (s_ecmaLoadedAssemblies) { // 2. Attempt to bind to already loaded assembly if (Bind(runtimeAssemblyName, cacheMissedLookups: false, out bindResult, out exception)) { result = true; return; } exception = null; // 3. If that fails, then add newly created metareader to global cache of loaded modules PEInfo peinfo = new PEInfo(runtimeAssemblyName, reader, pe, memoryMappedView); s_ecmaLoadedAssemblies.Add(peinfo); ModuleList moduleList = ModuleList.Instance; ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader); moduleList.RegisterModule(newModuleInfo); // 4. Then try to load by name again. This load should always succeed if (Bind(runtimeAssemblyName, cacheMissedLookups: true, out bindResult, out exception)) { result = true; return; } result = false; Debug.Assert(exception != null); // We must have an error on load. At this time this could happen due to ambiguous name matching } }
public void SetRuntimeModuleInfoUNSAFE(EcmaModuleInfo moduleInfo) { RuntimeModuleInfo = moduleInfo; }
partial void BindEcmaAssemblyName(RuntimeAssemblyName refName, bool cacheMissedLookups, ref AssemblyBindResult result, ref Exception exception, ref Exception preferredException, ref bool foundMatch) { lock (s_ecmaLoadedAssemblies) { for (int i = 0; i < s_ecmaLoadedAssemblies.Count; i++) { PEInfo info = s_ecmaLoadedAssemblies[i]; if (AssemblyNameMatches(refName, info.Name, ref preferredException)) { if (foundMatch) { exception = new AmbiguousMatchException(); return; } result.EcmaMetadataReader = info.Reader; foundMatch = result.EcmaMetadataReader != null; // For failed matches, we will never be able to succeed, so return now if (!foundMatch) { return; } } } if (!foundMatch) { try { // Not found in already loaded list, attempt to source assembly from disk foreach (string filePath in FilePathsForAssembly(refName)) { FileStream ownedFileStream = null; PEReader ownedPEReader = null; try { if (!RuntimeAugments.FileExists(filePath)) { continue; } try { ownedFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); } catch (System.IO.IOException) { // Failure to open a file is not fundamentally an assembly load error, but it does indicate this file cannot be used continue; } ownedPEReader = new PEReader(ownedFileStream); // FileStream ownership transferred to ownedPEReader ownedFileStream = null; if (!ownedPEReader.HasMetadata) { continue; } MetadataReader reader = ownedPEReader.GetMetadataReader(); // Create AssemblyName from MetadataReader RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader).CanonicalizePublicKeyToken(); // If assembly name doesn't match, it isn't the one we're looking for. Continue to look for more assemblies if (!AssemblyNameMatches(refName, runtimeAssemblyName, ref preferredException)) { continue; } // This is the one we are looking for, add it to the list of loaded assemblies PEInfo peinfo = new PEInfo(runtimeAssemblyName, reader, ownedPEReader); s_ecmaLoadedAssemblies.Add(peinfo); // At this point the PE reader is no longer owned by this code, but is owned by the s_ecmaLoadedAssemblies list PEReader pe = ownedPEReader; ownedPEReader = null; ModuleList moduleList = ModuleList.Instance; ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader); moduleList.RegisterModule(newModuleInfo); foundMatch = true; result.EcmaMetadataReader = peinfo.Reader; break; } finally { if (ownedFileStream != null) { ownedFileStream.Dispose(); } if (ownedPEReader != null) { ownedPEReader.Dispose(); } } } } catch (System.IO.IOException) { } catch (System.ArgumentException) { } catch (System.BadImageFormatException badImageFormat) { exception = badImageFormat; } // Cache missed lookups if (cacheMissedLookups && !foundMatch) { PEInfo peinfo = new PEInfo(refName, null, null); s_ecmaLoadedAssemblies.Add(peinfo); } } } }