Skip to content

Commit 00977b1

Browse files
authored
Improve handling bad metadata in EE (#76878)
1 parent a8a7c6d commit 00977b1

40 files changed

+501
-409
lines changed

Roslyn.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Expr
205205
EndProject
206206
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.CodeAnalysis.VisualBasic.ResultProvider.UnitTests", "src\ExpressionEvaluator\VisualBasic\Test\ResultProvider\Microsoft.CodeAnalysis.VisualBasic.ResultProvider.UnitTests.vbproj", "{ACE53515-482C-4C6A-E2D2-4242A687DFEE}"
207207
EndProject
208-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.ExpressionCompiler.Utilities", "src\ExpressionEvaluator\Core\Test\ExpressionCompiler\Microsoft.CodeAnalysis.ExpressionCompiler.Utilities.csproj", "{21B80A31-8FF9-4E3A-8403-AABD635AEED9}"
208+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.ExpressionCompiler.Test.Utilities", "src\ExpressionEvaluator\Core\Test\ExpressionCompiler\Microsoft.CodeAnalysis.ExpressionCompiler.Test.Utilities.csproj", "{21B80A31-8FF9-4E3A-8403-AABD635AEED9}"
209209
EndProject
210210
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.ResultProvider.Utilities", "src\ExpressionEvaluator\Core\Test\ResultProvider\Microsoft.CodeAnalysis.ResultProvider.Utilities.csproj", "{ABDBAC1E-350E-4DC3-BB45-3504404545EE}"
211211
EndProject

src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CSharpExpressionCompiler.cs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,27 +33,29 @@ internal override DkmCompilerId CompilerId
3333
internal delegate MetadataContext<CSharpMetadataContext> GetMetadataContextDelegate<TAppDomain>(TAppDomain appDomain);
3434
internal delegate void SetMetadataContextDelegate<TAppDomain>(TAppDomain appDomain, MetadataContext<CSharpMetadataContext> metadataContext, bool report);
3535

36+
/// <exception cref="BadMetadataModuleException">Module wasn't included in the compilation due to bad metadata.</exception>
3637
internal override EvaluationContextBase CreateTypeContext(
3738
DkmClrAppDomain appDomain,
3839
ImmutableArray<MetadataBlock> metadataBlocks,
39-
Guid moduleVersionId,
40+
ModuleId moduleId,
4041
int typeToken,
4142
bool useReferencedModulesOnly)
4243
{
4344
return CreateTypeContext(
4445
appDomain,
4546
ad => ad.GetMetadataContext<CSharpMetadataContext>(),
4647
metadataBlocks,
47-
moduleVersionId,
48+
moduleId,
4849
typeToken,
4950
GetMakeAssemblyReferencesKind(useReferencedModulesOnly));
5051
}
5152

53+
/// <exception cref="BadMetadataModuleException">Module wasn't included in the compilation due to bad metadata.</exception>
5254
internal static EvaluationContext CreateTypeContext<TAppDomain>(
5355
TAppDomain appDomain,
5456
GetMetadataContextDelegate<TAppDomain> getMetadataContext,
5557
ImmutableArray<MetadataBlock> metadataBlocks,
56-
Guid moduleVersionId,
58+
ModuleId moduleId,
5759
int typeToken,
5860
MakeAssemblyReferencesKind kind)
5961
{
@@ -63,14 +65,14 @@ internal static EvaluationContext CreateTypeContext<TAppDomain>(
6365
{
6466
// Avoid using the cache for referenced assemblies only
6567
// since this should be the exceptional case.
66-
compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleVersionId);
68+
compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleId);
6769
return EvaluationContext.CreateTypeContext(
6870
compilation,
69-
moduleVersionId,
71+
moduleId,
7072
typeToken);
7173
}
7274

73-
var contextId = MetadataContextId.GetContextId(moduleVersionId, kind);
75+
var contextId = MetadataContextId.GetContextId(moduleId, kind);
7476
var previous = getMetadataContext(appDomain);
7577
CSharpMetadataContext previousMetadataContext = default;
7678
if (previous.Matches(metadataBlocks))
@@ -80,11 +82,11 @@ internal static EvaluationContext CreateTypeContext<TAppDomain>(
8082

8183
// Re-use the previous compilation if possible.
8284
compilation = previousMetadataContext.Compilation;
83-
compilation ??= metadataBlocks.ToCompilation(moduleVersionId, kind);
85+
compilation ??= metadataBlocks.ToCompilation(moduleId, kind);
8486

8587
var context = EvaluationContext.CreateTypeContext(
8688
compilation,
87-
moduleVersionId,
89+
moduleId,
8890
typeToken);
8991

9092
// New type context is not attached to the AppDomain since it is less
@@ -101,7 +103,7 @@ internal override EvaluationContextBase CreateMethodContext(
101103
ImmutableArray<MetadataBlock> metadataBlocks,
102104
Lazy<ImmutableArray<AssemblyReaders>> unusedLazyAssemblyReaders,
103105
object? symReader,
104-
Guid moduleVersionId,
106+
ModuleId moduleId,
105107
int methodToken,
106108
int methodVersion,
107109
uint ilOffset,
@@ -114,7 +116,7 @@ internal override EvaluationContextBase CreateMethodContext(
114116
(ad, mc, report) => ad.SetMetadataContext<CSharpMetadataContext>(mc, report),
115117
metadataBlocks,
116118
symReader,
117-
moduleVersionId,
119+
moduleId,
118120
methodToken,
119121
methodVersion,
120122
ilOffset,
@@ -128,7 +130,7 @@ internal static EvaluationContext CreateMethodContext<TAppDomain>(
128130
SetMetadataContextDelegate<TAppDomain> setMetadataContext,
129131
ImmutableArray<MetadataBlock> metadataBlocks,
130132
object? symReader,
131-
Guid moduleVersionId,
133+
ModuleId moduleId,
132134
int methodToken,
133135
int methodVersion,
134136
uint ilOffset,
@@ -142,18 +144,18 @@ internal static EvaluationContext CreateMethodContext<TAppDomain>(
142144
{
143145
// Avoid using the cache for referenced assemblies only
144146
// since this should be the exceptional case.
145-
compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleVersionId);
147+
compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleId);
146148
return EvaluationContext.CreateMethodContext(
147149
compilation,
148150
symReader,
149-
moduleVersionId,
151+
moduleId,
150152
methodToken,
151153
methodVersion,
152154
offset,
153155
localSignatureToken);
154156
}
155157

156-
var contextId = MetadataContextId.GetContextId(moduleVersionId, kind);
158+
var contextId = MetadataContextId.GetContextId(moduleId, kind);
157159
var previous = getMetadataContext(appDomain);
158160
var assemblyContexts = previous.Matches(metadataBlocks) ? previous.AssemblyContexts : ImmutableDictionary<MetadataContextId, CSharpMetadataContext>.Empty;
159161
CSharpMetadataContext previousMetadataContext;
@@ -167,20 +169,20 @@ internal static EvaluationContext CreateMethodContext<TAppDomain>(
167169
var previousContext = previousMetadataContext.EvaluationContext;
168170
if (previousContext != null &&
169171
previousContext.MethodContextReuseConstraints.HasValue &&
170-
previousContext.MethodContextReuseConstraints.GetValueOrDefault().AreSatisfied(moduleVersionId, methodToken, methodVersion, offset))
172+
previousContext.MethodContextReuseConstraints.GetValueOrDefault().AreSatisfied(moduleId, methodToken, methodVersion, offset))
171173
{
172174
return previousContext;
173175
}
174176
}
175177
else
176178
{
177-
compilation = metadataBlocks.ToCompilation(moduleVersionId, kind);
179+
compilation = metadataBlocks.ToCompilation(moduleId, kind);
178180
}
179181

180182
var context = EvaluationContext.CreateMethodContext(
181183
compilation,
182184
symReader,
183-
moduleVersionId,
185+
moduleId,
184186
methodToken,
185187
methodVersion,
186188
offset,

src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CSharpInstructionDecoder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,20 +151,20 @@ internal override ImmutableArray<TypeParameterSymbol> GetAllTypeParameters(Metho
151151
internal override CSharpCompilation GetCompilation(DkmClrModuleInstance moduleInstance)
152152
{
153153
var appDomain = moduleInstance.AppDomain;
154-
var moduleVersionId = moduleInstance.Mvid;
154+
var moduleId = moduleInstance.GetModuleId();
155155
var previous = appDomain.GetMetadataContext<CSharpMetadataContext>();
156156
var metadataBlocks = moduleInstance.RuntimeInstance.GetMetadataBlocks(appDomain, previous.MetadataBlocks);
157157

158158
var kind = GetMakeAssemblyReferencesKind();
159-
var contextId = MetadataContextId.GetContextId(moduleVersionId, kind);
159+
var contextId = MetadataContextId.GetContextId(moduleId, kind);
160160
var assemblyContexts = previous.Matches(metadataBlocks) ? previous.AssemblyContexts : ImmutableDictionary<MetadataContextId, CSharpMetadataContext>.Empty;
161161
CSharpMetadataContext previousContext;
162162
assemblyContexts.TryGetValue(contextId, out previousContext);
163163

164164
var compilation = previousContext.Compilation;
165165
if (compilation == null)
166166
{
167-
compilation = metadataBlocks.ToCompilation(moduleVersionId, kind);
167+
compilation = metadataBlocks.ToCompilation(moduleId, kind);
168168
appDomain.SetMetadataContext(
169169
new MetadataContext<CSharpMetadataContext>(
170170
metadataBlocks,
@@ -178,7 +178,7 @@ internal override CSharpCompilation GetCompilation(DkmClrModuleInstance moduleIn
178178
internal override MethodSymbol GetMethod(CSharpCompilation compilation, DkmClrInstructionAddress instructionAddress)
179179
{
180180
var methodHandle = (MethodDefinitionHandle)MetadataTokens.Handle(instructionAddress.MethodId.Token);
181-
return compilation.GetSourceMethod(instructionAddress.ModuleInstance.Mvid, methodHandle);
181+
return compilation.GetSourceMethod(instructionAddress.ModuleInstance.GetModuleId(), methodHandle);
182182
}
183183

184184
internal override TypeNameDecoder<PEModuleSymbol, TypeSymbol> GetTypeNameDecoder(CSharpCompilation compilation, MethodSymbol method)

src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ private static PENamedTypeSymbol GetType(PEModuleSymbol module, TypeDefinitionHa
2424
return (PENamedTypeSymbol)metadataDecoder.GetTypeOfToken(typeHandle);
2525
}
2626

27-
internal static PENamedTypeSymbol GetType(this CSharpCompilation compilation, Guid moduleVersionId, int typeToken)
27+
/// <exception cref="BadMetadataModuleException">Module wasn't included in the compilation due to bad metadata.</exception>
28+
internal static PENamedTypeSymbol GetType(this CSharpCompilation compilation, ModuleId moduleId, int typeToken)
2829
{
29-
return GetType(compilation.GetModule(moduleVersionId), (TypeDefinitionHandle)MetadataTokens.Handle(typeToken));
30+
return GetType(compilation.GetModule(moduleId), (TypeDefinitionHandle)MetadataTokens.Handle(typeToken));
3031
}
3132

32-
internal static PEMethodSymbol GetSourceMethod(this CSharpCompilation compilation, Guid moduleVersionId, MethodDefinitionHandle methodHandle)
33+
internal static PEMethodSymbol GetSourceMethod(this CSharpCompilation compilation, ModuleId moduleId, MethodDefinitionHandle methodHandle)
3334
{
34-
var method = GetMethod(compilation, moduleVersionId, methodHandle);
35+
var method = GetMethod(compilation, moduleId, methodHandle);
3536
var metadataDecoder = new MetadataDecoder((PEModuleSymbol)method.ContainingModule);
3637
var containingType = method.ContainingType;
3738
if (GeneratedNameParser.TryParseSourceMethodNameFromGeneratedName(containingType.Name, GeneratedNameKind.StateMachineType, out var sourceMethodName))
@@ -49,17 +50,19 @@ internal static PEMethodSymbol GetSourceMethod(this CSharpCompilation compilatio
4950
return method;
5051
}
5152

52-
internal static PEMethodSymbol GetMethod(this CSharpCompilation compilation, Guid moduleVersionId, MethodDefinitionHandle methodHandle)
53+
/// <exception cref="BadMetadataModuleException">Module wasn't included in the compilation due to bad metadata.</exception>
54+
internal static PEMethodSymbol GetMethod(this CSharpCompilation compilation, ModuleId moduleId, MethodDefinitionHandle methodHandle)
5355
{
54-
var module = compilation.GetModule(moduleVersionId);
56+
var module = compilation.GetModule(moduleId);
5557
var reader = module.Module.MetadataReader;
5658
var typeHandle = reader.GetMethodDefinition(methodHandle).GetDeclaringType();
5759
var type = GetType(module, typeHandle);
5860
var method = (PEMethodSymbol)new MetadataDecoder(module, type).GetMethodSymbolForMethodDefOrMemberRef(methodHandle, type);
5961
return method;
6062
}
6163

62-
internal static PEModuleSymbol GetModule(this CSharpCompilation compilation, Guid moduleVersionId)
64+
/// <exception cref="BadMetadataModuleException">Module wasn't included in the compilation due to bad metadata.</exception>
65+
internal static PEModuleSymbol GetModule(this CSharpCompilation compilation, ModuleId moduleId)
6366
{
6467
foreach (var pair in compilation.GetBoundReferenceManager().GetReferencedAssemblies())
6568
{
@@ -68,24 +71,24 @@ internal static PEModuleSymbol GetModule(this CSharpCompilation compilation, Gui
6871
{
6972
var m = (PEModuleSymbol)module;
7073
var id = m.Module.GetModuleVersionIdOrThrow();
71-
if (id == moduleVersionId)
74+
if (id == moduleId.Id)
7275
{
7376
return m;
7477
}
7578
}
7679
}
7780

78-
throw new ArgumentException($"No module found with MVID '{moduleVersionId}'", nameof(moduleVersionId));
81+
throw new BadMetadataModuleException(moduleId);
7982
}
8083

81-
internal static CSharpCompilation ToCompilationReferencedModulesOnly(this ImmutableArray<MetadataBlock> metadataBlocks, Guid moduleVersionId)
84+
internal static CSharpCompilation ToCompilationReferencedModulesOnly(this ImmutableArray<MetadataBlock> metadataBlocks, ModuleId moduleId)
8285
{
83-
return ToCompilation(metadataBlocks, moduleVersionId, kind: MakeAssemblyReferencesKind.DirectReferencesOnly);
86+
return ToCompilation(metadataBlocks, moduleId, kind: MakeAssemblyReferencesKind.DirectReferencesOnly);
8487
}
8588

86-
internal static CSharpCompilation ToCompilation(this ImmutableArray<MetadataBlock> metadataBlocks, Guid moduleVersionId, MakeAssemblyReferencesKind kind)
89+
internal static CSharpCompilation ToCompilation(this ImmutableArray<MetadataBlock> metadataBlocks, ModuleId moduleId, MakeAssemblyReferencesKind kind)
8790
{
88-
var references = metadataBlocks.MakeAssemblyReferences(moduleVersionId, IdentityComparer, kind, out var referencesBySimpleName);
91+
var references = metadataBlocks.MakeAssemblyReferences(moduleId, IdentityComparer, kind, out var referencesBySimpleName);
8992
var options = s_compilationOptions;
9093
if (referencesBySimpleName != null)
9194
{

0 commit comments

Comments
 (0)