IAssemblyMetadata IAssemblyResolver.FindAssembly(string simpleName, string parentFile) { using var triggerErrors = new ModuleLoadLogger.LoadFailuresAsErrors(); EcmaAssembly ecmaAssembly = (EcmaAssembly)this.GetModuleForSimpleName(simpleName, false); return(new StandaloneAssemblyMetadata(ecmaAssembly.PEReader)); }
/// <summary> /// Determines whether the assembly was compiled without optimizations using the DebuggableAttribute /// </summary> public static bool HasOptimizationsDisabled(this EcmaAssembly assembly) { bool result = false; MetadataReader reader = assembly.MetadataReader; var attributeHandles = assembly.AssemblyDefinition.GetCustomAttributes(); CustomAttributeHandle attributeHandle = reader.GetCustomAttributeHandle(attributeHandles, "System.Diagnostics", "DebuggableAttribute"); if (!attributeHandle.IsNil) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <TypeDesc> decoded = attribute.DecodeValue(new CustomAttributeTypeProvider(assembly)); if (decoded.FixedArguments.Length == 1) { // DebuggableAttribute( DebuggableAttribute.DebuggingModes modes ) if (!(decoded.FixedArguments[0].Value is int)) { ThrowHelper.ThrowBadImageFormatException(); } DebuggableAttribute.DebuggingModes modes = (DebuggableAttribute.DebuggingModes)decoded.FixedArguments[0].Value; result = modes.HasFlag(DebuggableAttribute.DebuggingModes.DisableOptimizations) && modes.HasFlag(DebuggableAttribute.DebuggingModes.Default); } else if (decoded.FixedArguments.Length == 2) { // DebuggableAttribute( bool isJITTrackingEnabled, bool isJITOptimizerDisabled ) if (!(decoded.FixedArguments[0].Value is bool) || !(decoded.FixedArguments[1].Value is bool)) { ThrowHelper.ThrowBadImageFormatException(); } result = ((bool)decoded.FixedArguments[1].Value); } } return(result); }
IAssemblyMetadata IAssemblyResolver.FindAssembly(MetadataReader metadataReader, AssemblyReferenceHandle assemblyReferenceHandle, string parentFile) { using var triggerErrors = new ModuleLoadLogger.LoadFailuresAsErrors(); EcmaAssembly ecmaAssembly = (EcmaAssembly)this.GetModuleForSimpleName(metadataReader.GetString(metadataReader.GetAssemblyReference(assemblyReferenceHandle).Name), false); return(new StandaloneAssemblyMetadata(ecmaAssembly.PEReader)); }
private RoAssembly LoadFromStreamCore(Stream peStream) { PEReader peReader = new PEReader(peStream); PEReader peReaderToDispose = peReader; // Ensure peReader is disposed immediately if we throw an exception before we're done. try { if (!peReader.HasMetadata) { throw new BadImageFormatException(SR.NoMetadataInPeImage); } string location = (peStream is FileStream fs) ? (fs.Name ?? string.Empty) : string.Empty; MetadataReader reader = peReader.GetMetadataReader(); RoAssembly newAssembly = new EcmaAssembly(this, peReader, reader, location); AssemblyNameData defNameData = newAssembly.GetAssemblyNameDataNoCopy(); byte[] pkt = defNameData.PublicKeyToken ?? Array.Empty <byte>(); if (pkt.Length == 0 && defNameData.PublicKey != null && defNameData.PublicKey.Length != 0) { pkt = defNameData.PublicKey.ComputePublicKeyToken(); } RoAssemblyName defName = new RoAssemblyName(defNameData.Name, defNameData.Version, defNameData.CultureName, pkt); Guid mvid = newAssembly.ManifestModule.ModuleVersionId; LoadedAssemblyEntry candidate = new LoadedAssemblyEntry(newAssembly, mvid); LoadedAssemblyEntry winner = _loadedAssemblies.GetOrAdd(defName, candidate); if (winner.Assembly == newAssembly) { // We won the race. RegisterForDisposal(peReader); peReaderToDispose = null; return(_binds.GetOrAdd(defName, winner.Assembly)); // What if we lost the race to bind the defName in the _binds list? Should we ignore it and return the newly created assembly // (like Assembly.LoadModule()) does or return the prior assembly (like we do if we lose the race to commit into _loadedAssemblies?) // There's no perfect answer here. Fundamentally, the dilemma comes about because our apis don't lets apps properly separate // the act of creating an Assembly object from the act of committing the TypeLoader to bind to it. // // We will choose to return the prior winner so that the api is consistent with itself. This is how other LoadFrom() // apis work and they're used a lot more than LoadModule(). } else { // We lost the race but check for a MVID mismatch. if (mvid != winner.Mvid) { throw new FileLoadException(SR.Format(SR.FileLoadDuplicateAssemblies, defName)); } } return(winner.Assembly); } finally { peReaderToDispose?.Dispose(); } }
// // returns the DebugInfoBlob containing the method token to virtual method slot mapping // .mdinfo format // offset 0, 4 bytes: version number // offset 4, 4 bytes: count of assemblies // // for each assembly // offset 0, 4 bytes: count of methods with a virtual method slot // // for each method // offset 0, 4 bytes: method def token (as they are in the input assembly) // offset 4, 2 bytes: length of the per method information [ currently always 4 ] // offset 6, 4 bytes: virtual slot number // methods are sorted by their method def token internal DebugInfoBlob GetDebugMethodInfoMap(NodeFactory factory) { Dictionary <EcmaAssembly, uint> originalAssemblyOrder = new Dictionary <EcmaAssembly, uint>(); List <SortedDictionary <uint, int> > moduleMethods = new List <SortedDictionary <uint, int> >(); // re-construct orginal assembly input order foreach (MergedAssemblyRecord mergedAssembly in _mergedAssemblies.MergedAssemblies) { uint assemblyIndex = AdjustIndex(mergedAssembly.AssemblyIndex, _mergedAssemblies.CorLibIndex); originalAssemblyOrder.Add(mergedAssembly.Assembly, assemblyIndex); moduleMethods.Add(new SortedDictionary <uint, int>()); } foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes()) { // skip if sealed if (type.IsSealed()) { continue; } // no generic support yet if (type is EcmaType) { EcmaType ecmaType = (EcmaType)type; EcmaAssembly ecmaAssembly = (EcmaAssembly)ecmaType.EcmaModule; int assemblyIndex = (int)originalAssemblyOrder[ecmaAssembly]; SortedDictionary <uint, int> methodList = moduleMethods[assemblyIndex]; foreach (MethodDesc md in type.GetAllMethods()) { // skip non-virtual and final methods if (!md.IsVirtual || md.IsFinal) { continue; } // skip generic if (md.HasInstantiation) { continue; } // method token. EntityHandle methodHandle = ((EcmaMethod)md).Handle; uint methodToken = (uint)MetadataTokens.GetToken(methodHandle); // find virtual method slot. MethodDesc declaringMethodForSlot = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(md.GetTypicalMethodDefinition()); int slot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, declaringMethodForSlot, type); if (slot != -1 && !methodList.ContainsKey(methodToken)) { methodList.Add(methodToken, slot); } } } } return(ConvertToDebugInfoBlob(moduleMethods)); }
private RoAssembly LoadFromStreamCore(Stream peStream) { PEReader peReader = new PEReader(peStream); PEReader?peReaderToDispose = peReader; // Ensure peReader is disposed immediately if we throw an exception before we're done. try { if (!peReader.HasMetadata) { throw new BadImageFormatException(SR.NoMetadataInPeImage); } string location = (peStream is FileStream fs) ? (fs.Name ?? string.Empty) : string.Empty; MetadataReader reader = peReader.GetMetadataReader(); RoAssembly candidate = new EcmaAssembly(this, peReader, reader, location); AssemblyNameData defNameData = candidate.GetAssemblyNameDataNoCopy(); byte[] pkt = defNameData.PublicKeyToken ?? Array.Empty <byte>(); if (pkt.Length == 0 && defNameData.PublicKey != null && defNameData.PublicKey.Length != 0) { pkt = defNameData.PublicKey.ComputePublicKeyToken() !; } RoAssemblyName defName = new RoAssemblyName(defNameData.Name, defNameData.Version, defNameData.CultureName, pkt, defNameData.Flags); RoAssembly winner = _loadedAssemblies.GetOrAdd(defName, candidate); if (winner == candidate) { // We won the race. RegisterForDisposal(peReader); peReaderToDispose = null; // We do not add to the _binds list because the binding list is only for assemblies that have been resolved through // the Resolve method. This allows the resolver to have complete control over selecting the appropriate assembly // based on Version, CultureName and PublicKeyToken. return(winner); } else { // We lost the race but check for a Mvid mismatch. if (candidate.ManifestModule.ModuleVersionId != winner.ManifestModule.ModuleVersionId) { throw new FileLoadException(SR.Format(SR.FileLoadDuplicateAssemblies, defName)); } } return(winner); } finally { peReaderToDispose?.Dispose(); } }
private string ComputeMangledModuleName(EcmaAssembly module) { // Do not prepend the module prefix when building pntestcl because the prefix is unknown // when building an app against pntestcl. if (!BuildingClassLib) { int index; if (_inputModuleIndices.TryGetValue(module, out index)) { return("$" + index); } } return(SanitizeName(module.GetName().Name)); }
private AssemblyReferenceHandle MakeAssemblyReferenceHandle(EcmaAssembly assemblyRef) { AssemblyReferenceHandle handle; if (!_assemblyRefHandles.TryGetValue(assemblyRef, out handle)) { AssemblyName assemblyName = assemblyRef.GetName(); handle = _metadataBuilder.AddAssemblyReference( _metadataBuilder.GetOrAddString(assemblyName.Name), assemblyName.Version, default(StringHandle), _metadataBuilder.GetOrAddBlob(ImmutableArray.Create <byte>(assemblyName.GetPublicKeyToken())), default(AssemblyFlags), default(BlobHandle)); _assemblyRefHandles[assemblyRef] = handle; } return(handle); }
public MergedAssemblyRecord(EcmaAssembly assembly, string name, uint assemblyIndex, uint timestamp, bool hasPDB, byte[] publicKey, byte[] versionInfo) { Assembly = assembly; Name = name; AssemblyIndex = assemblyIndex; Timestamp = timestamp; HasPDB = hasPDB; PublicKey = publicKey; VersionInfo = versionInfo; if (versionInfo.Length < sizeof(ushort)) { throw new ArgumentException("versionInfo"); } int versionInfoLength = VersionInfoLength; if (versionInfoLength == 0) { VersionInfo = BitConverter.GetBytes((ushort)sizeof(ushort)); Debug.Assert(VersionInfoLength == sizeof(ushort)); } else { // Validate that a non-empty version info contains a VS_VERSION_INFO structure string vsVersionInfoString = "VS_VERSION_INFO"; if (VersionInfoLength < (6 + vsVersionInfoString.Length * sizeof(char))) { throw new ArgumentException("versionInfo"); } string encodedString = Encoding.Unicode.GetString(versionInfo, 6, vsVersionInfoString.Length * sizeof(char)); if (encodedString != vsVersionInfoString) { throw new ArgumentException("versionInfo"); } } }
public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaAssembly assembly) { AssemblyDefinition asmDef = assembly.MetadataReader.GetAssemblyDefinition(); AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, asmDef.GetCustomAttributes()); ModuleDefinition moduleDef = assembly.MetadataReader.GetModuleDefinition(); AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, moduleDef.GetCustomAttributes()); }
public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaAssembly assembly) { AssemblyDefinition asmDef = assembly.MetadataReader.GetAssemblyDefinition(); AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, asmDef.GetCustomAttributes()); // This is rather awkward because ModuleDefinition doesn't offer means to get to the custom attributes CustomAttributeHandleCollection moduleAttributes = assembly.MetadataReader.GetCustomAttributes(System.Reflection.Metadata.Ecma335.MetadataTokens.EntityHandle(0x1)); AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, moduleAttributes); }
IAssemblyMetadata IAssemblyResolver.FindAssembly(string simpleName, string parentFile) { EcmaAssembly ecmaAssembly = (EcmaAssembly)this.GetModuleForSimpleName(simpleName, false); return(new StandaloneAssemblyMetadata(ecmaAssembly.PEReader)); }
IAssemblyMetadata IAssemblyResolver.FindAssembly(MetadataReader metadataReader, AssemblyReferenceHandle assemblyReferenceHandle, string parentFile) { EcmaAssembly ecmaAssembly = (EcmaAssembly)this.GetModuleForSimpleName(metadataReader.GetString(metadataReader.GetAssemblyReference(assemblyReferenceHandle).Name), false); return(new StandaloneAssemblyMetadata(ecmaAssembly.PEReader)); }