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;
}
}
}
|