public void PinnedAndUnpinnedLocals() { using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(PinnedAndUnpinnedLocalsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new DisassemblingTypeProvider(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(reader, typeof(PinnedAndUnpinnedLocalsToDecode)); TypeDefinition typeDef = reader.GetTypeDefinition(typeDefHandle); MethodDefinition methodDef = reader.GetMethodDefinition(typeDef.GetMethods().First()); Assert.Equal("DoSomething", reader.GetString(methodDef.Name)); MethodBodyBlock body = peReader.GetMethodBody(methodDef.RelativeVirtualAddress); StandaloneSignature localSignature = reader.GetStandaloneSignature(body.LocalSignature); ImmutableArray <string> localTypes = localSignature.DecodeLocalSignature(provider, genericContext: null); // Compiler can generate temporaries or re-order so just check the ones we expect are there. // (They could get optimized away too. If that happens in practice, change this test to use hard-coded signatures.) Assert.Contains("uint8[] pinned", localTypes); Assert.Contains("uint8[]", localTypes); } }
public void WrongSignatureType() { using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(VarArgsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new DisassemblingTypeProvider(); var decoder = new SignatureDecoder <string, DisassemblingGenericContext>(provider, reader, genericContext: null); BlobReader fieldSignature = reader.GetBlobReader(reader.GetFieldDefinition(MetadataTokens.FieldDefinitionHandle(1)).Signature); BlobReader methodSignature = reader.GetBlobReader(reader.GetMethodDefinition(MetadataTokens.MethodDefinitionHandle(1)).Signature); BlobReader propertySignature = reader.GetBlobReader(reader.GetPropertyDefinition(MetadataTokens.PropertyDefinitionHandle(1)).Signature); Assert.Throws <BadImageFormatException>(() => decoder.DecodeMethodSignature(ref fieldSignature)); Assert.Throws <BadImageFormatException>(() => decoder.DecodeFieldSignature(ref methodSignature)); Assert.Throws <BadImageFormatException>(() => decoder.DecodeLocalSignature(ref propertySignature)); } }
public void SimpleSignatureProviderCoverage() { using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(SignaturesToDecode <>).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new DisassemblingTypeProvider(); TypeDefinitionHandle typeHandle = TestMetadataResolver.FindTestType(reader, typeof(SignaturesToDecode <>)); Assert.Equal("System.Reflection.Metadata.Decoding.Tests.SignatureDecoderTests/SignaturesToDecode`1", provider.GetTypeFromHandle(reader, genericContext: null, handle: typeHandle)); TypeDefinition type = reader.GetTypeDefinition(typeHandle); Dictionary <string, string> expectedFields = GetExpectedFieldSignatures(); ImmutableArray <string> genericTypeParameters = type.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray(); var genericTypeContext = new DisassemblingGenericContext(genericTypeParameters, ImmutableArray <string> .Empty); foreach (var fieldHandle in type.GetFields()) { FieldDefinition field = reader.GetFieldDefinition(fieldHandle); string fieldName = reader.GetString(field.Name); string expected; Assert.True(expectedFields.TryGetValue(fieldName, out expected), "Unexpected field: " + fieldName); Assert.Equal(expected, field.DecodeSignature(provider, genericTypeContext)); } Dictionary <string, string> expectedMethods = GetExpectedMethodSignatures(); foreach (var methodHandle in type.GetMethods()) { MethodDefinition method = reader.GetMethodDefinition(methodHandle); ImmutableArray <string> genericMethodParameters = method.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray(); var genericMethodContext = new DisassemblingGenericContext(genericTypeParameters, genericMethodParameters); string methodName = reader.GetString(method.Name); string expected; Assert.True(expectedMethods.TryGetValue(methodName, out expected), "Unexpected method: " + methodName); MethodSignature <string> signature = method.DecodeSignature(provider, genericMethodContext); Assert.True(signature.Header.Kind == SignatureKind.Method); if (methodName.StartsWith("Generic")) { Assert.Equal(1, signature.GenericParameterCount); } else { Assert.Equal(0, signature.GenericParameterCount); } Assert.True(signature.GenericParameterCount <= 1 && (methodName != "GenericMethodParameter" || signature.GenericParameterCount == 1)); Assert.Equal(expected, provider.GetFunctionPointerType(signature)); } Dictionary <string, string> expectedProperties = GetExpectedPropertySignatures(); foreach (var propertyHandle in type.GetProperties()) { PropertyDefinition property = reader.GetPropertyDefinition(propertyHandle); string propertyName = reader.GetString(property.Name); string expected; Assert.True(expectedProperties.TryGetValue(propertyName, out expected), "Unexpected property: " + propertyName); MethodSignature <string> signature = property.DecodeSignature(provider, genericTypeContext); Assert.True(signature.Header.Kind == SignatureKind.Property); Assert.Equal(expected, provider.GetFunctionPointerType(signature)); } Dictionary <string, string> expectedEvents = GetExpectedEventSignatures(); foreach (var eventHandle in type.GetEvents()) { EventDefinition @event = reader.GetEventDefinition(eventHandle); string eventName = reader.GetString(@event.Name); string expected; Assert.True(expectedEvents.TryGetValue(eventName, out expected), "Unexpected event: " + eventName); Assert.Equal(expected, provider.GetTypeFromHandle(reader, genericTypeContext, @event.Type)); } Assert.Equal($"[{CollectionsAssemblyName}]System.Collections.Generic.List`1<!T>", provider.GetTypeFromHandle(reader, genericTypeContext, handle: type.BaseType)); } }