Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ILVerifyTypeSystemContext.cs « src « ILVerification « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 96aaa3fd90c3030f810c53b4979ac241243016a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using Internal.IL;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;

namespace ILVerify
{
    class ILVerifyTypeSystemContext : MetadataTypeSystemContext
    {
        internal readonly IResolver _resolver;

        private RuntimeInterfacesAlgorithm _arrayOfTRuntimeInterfacesAlgorithm;
        private MetadataRuntimeInterfacesAlgorithm _metadataRuntimeInterfacesAlgorithm = new MetadataRuntimeInterfacesAlgorithm();

        private readonly Dictionary<PEReader, EcmaModule> _modulesCache = new Dictionary<PEReader, EcmaModule>();

        public ILVerifyTypeSystemContext(IResolver resolver)
        {
            _resolver = resolver;
        }

        public override ModuleDesc ResolveAssembly(AssemblyName name, bool throwIfNotFound = true)
        {
            // Note: we use simple names instead of full names to resolve, because we can't get a full name from an assembly without reading it
            string simpleName = name.Name;
            return ResolveAssemblyOrNetmodule(simpleName, simpleName, throwIfNotFound);
        }

        internal override ModuleDesc ResolveModule(ModuleDesc referencingModule, string fileName, bool throwIfNotFound = true)
        {
            // Referenced modules are stored without their extension (see CommandLineHelpers.cs), so we have to drop
            // the extension here as well to find a match.
            string simpleName = Path.GetFileNameWithoutExtension(fileName);
            // The referencing module is not getting verified currently.
            // However, netmodules are resolved in the context of assembly, not in the global context.
            EcmaModule module = ResolveAssemblyOrNetmodule(simpleName, fileName, throwIfNotFound);
            if (module.MetadataReader.IsAssembly)
            {
                throw new VerifierException($"The module '{fileName}' is not expected to be an assembly");
            }
            return module;
        }

        private EcmaModule ResolveAssemblyOrNetmodule(string simpleName, string verificationName, bool throwIfNotFound)
        {
            PEReader peReader = _resolver.Resolve(simpleName);
            if (peReader == null && throwIfNotFound)
            {
                throw new VerifierException("Assembly or module not found: " + simpleName);
            }
            var module = GetModule(peReader);
            VerifyModuleName(verificationName, module);
            return module;
        }

        private static void VerifyModuleName(string simpleName, EcmaModule module)
        {
            MetadataReader metadataReader = module.MetadataReader;
            StringHandle nameHandle = metadataReader.IsAssembly
                ? metadataReader.GetAssemblyDefinition().Name
                : metadataReader.GetModuleDefinition().Name;

            string actualSimpleName = metadataReader.GetString(nameHandle);
            if (!actualSimpleName.Equals(simpleName, StringComparison.OrdinalIgnoreCase))
            {
                throw new VerifierException($"Actual PE name '{actualSimpleName}' does not match provided name '{simpleName}'");
            }
        }

        protected override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForNonPointerArrayType(ArrayType type)
        {
            if (_arrayOfTRuntimeInterfacesAlgorithm == null)
            {
                _arrayOfTRuntimeInterfacesAlgorithm = new SimpleArrayOfTRuntimeInterfacesAlgorithm(SystemModule);
            }
            return _arrayOfTRuntimeInterfacesAlgorithm;
        }

        protected override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForDefType(DefType type)
        {
            return _metadataRuntimeInterfacesAlgorithm;
        }

        internal EcmaModule GetModule(PEReader peReader)
        {
            if (peReader == null)
            {
                return null;
            }

            if (_modulesCache.TryGetValue(peReader, out EcmaModule existingModule))
            {
                return existingModule;
            }

            EcmaModule module = EcmaModule.Create(this, peReader);
            _modulesCache.Add(peReader, module);
            return module;
        }
    }
}