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));
        }
示例#2
0
        /// <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));
        }
示例#4
0
        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();
            }
        }
示例#5
0
        //
        // 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();
            }
        }
示例#7
0
        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));
        }
示例#8
0
        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);
        }
示例#9
0
        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);
        }
示例#12
0
        IAssemblyMetadata IAssemblyResolver.FindAssembly(string simpleName, string parentFile)
        {
            EcmaAssembly ecmaAssembly = (EcmaAssembly)this.GetModuleForSimpleName(simpleName, false);

            return(new StandaloneAssemblyMetadata(ecmaAssembly.PEReader));
        }
示例#13
0
        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));
        }