private string?TryGetSourceLinkUrl(DocumentHandle handle) { var document = _pdbReader.GetDocument(handle); if (document.Name.IsNil) { return(null); } var documentName = _pdbReader.GetString(document.Name); if (documentName is null) { return(null); } foreach (var cdiHandle in _pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition)) { var cdi = _pdbReader.GetCustomDebugInformation(cdiHandle); if (_pdbReader.GetGuid(cdi.Kind) == PortableCustomDebugInfoKinds.SourceLink && !cdi.Value.IsNil) { var blobReader = _pdbReader.GetBlobReader(cdi.Value); var sourceLinkJson = blobReader.ReadUTF8(blobReader.Length); var map = SourceLinkMap.Parse(sourceLinkJson); if (map.TryGetUri(documentName, out var uri)) { return(uri); } } } return(null); }
private string GetAttributeArgument(CustomAttribute attribute, MetadataReader metadataReader) { var signature = metadataReader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature; var signatureReader = metadataReader.GetBlobReader(signature); var valueReader = metadataReader.GetBlobReader(attribute.Value); valueReader.ReadUInt16(); // Skip prolog signatureReader.ReadSignatureHeader(); // Skip header int parameterCount; signatureReader.TryReadCompressedInteger(out parameterCount); signatureReader.ReadSignatureTypeCode(); // Skip return type for (int i = 0; i < parameterCount; i++) { var signatureTypeCode = signatureReader.ReadSignatureTypeCode(); if (signatureTypeCode == SignatureTypeCode.String) { return(valueReader.ReadSerializedString()); } } return(string.Empty); }
/// <exception cref="BadImageFormatException">Invalid data format.</exception> private static void ReadMethodCustomDebugInformation( MetadataReader reader, MethodDefinitionHandle methodHandle, out ImmutableArray <HoistedLocalScopeRecord> hoistedLocalScopes, out string defaultNamespace ) { hoistedLocalScopes = TryGetCustomDebugInformation( reader, methodHandle, PortableCustomDebugInfoKinds.StateMachineHoistedLocalScopes, out var info ) ? DecodeHoistedLocalScopes(reader.GetBlobReader(info.Value)) : ImmutableArray <HoistedLocalScopeRecord> .Empty; // TODO: consider looking this up once per module (not for every method) defaultNamespace = TryGetCustomDebugInformation( reader, EntityHandle.ModuleDefinition, PortableCustomDebugInfoKinds.DefaultNamespace, out info ) ? DecodeDefaultNamespace(reader.GetBlobReader(info.Value)) : ""; }
private Object ResolveMethodSpecification(MethodSpecificationHandle handle) { MethodSpecification methodSpecification = _metadataReader.GetMethodSpecification(handle); object resolvedMethod = GetObject(methodSpecification.Method, NotFoundBehavior.ReturnResolutionFailure); if (resolvedMethod is ResolutionFailure) { return(resolvedMethod); } MethodDesc methodDef = resolvedMethod as MethodDesc; if (methodDef == null) { ThrowHelper.ThrowBadImageFormatException($"method expected for handle {handle.ToString()}"); } BlobReader signatureReader = _metadataReader.GetBlobReader(methodSpecification.Signature); EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader, NotFoundBehavior.ReturnResolutionFailure); TypeDesc[] instantiation = parser.ParseMethodSpecSignature(); if (instantiation == null) { return(parser.ResolutionFailure); } return(Context.GetInstantiatedMethod(methodDef, new Instantiation(instantiation))); }
private void LookupMetadataDefinitions( TypeDefinition typeDefinition, OrderPreservingMultiDictionary <string, MetadataDefinition> definitionMap) { // Only bother looking for extension methods in static types. if ((typeDefinition.Attributes & TypeAttributes.Abstract) != 0 && (typeDefinition.Attributes & TypeAttributes.Sealed) != 0) { foreach (var child in typeDefinition.GetMethods()) { var method = _metadataReader.GetMethodDefinition(child); if ((method.Attributes & MethodAttributes.SpecialName) != 0 || (method.Attributes & MethodAttributes.RTSpecialName) != 0) { continue; } // SymbolTreeInfo is only searched for types and extension methods. // So we don't want to pull in all methods here. As a simple approximation // we just pull in methods that have attributes on them. if ((method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public && (method.Attributes & MethodAttributes.Static) != 0 && method.GetParameters().Count > 0 && method.GetCustomAttributes().Count > 0) { // Decode method signature to get the target type name (i.e. type name for the first parameter) var blob = _metadataReader.GetBlobReader(method.Signature); var decoder = new SignatureDecoder <ParameterTypeInfo, object>(ParameterTypeInfoProvider.Instance, _metadataReader, genericContext: null); var signature = decoder.DecodeMethodSignature(ref blob); // It'd be good if we don't need to go through all parameters and make unnecessary allocations. // However, this is not possible with meatadata reader API right now (although it's possible by copying code from meatadata reader implementaion) if (signature.ParameterTypes.Length > 0) { _containsExtensionsMethod = true; var firstParameterTypeInfo = signature.ParameterTypes[0]; var definition = new MetadataDefinition(MetadataDefinitionKind.Member, _metadataReader.GetString(method.Name), firstParameterTypeInfo); definitionMap.Add(definition.Name, definition); } } } } foreach (var child in typeDefinition.GetNestedTypes()) { var type = _metadataReader.GetTypeDefinition(child); // We don't include internals from metadata assemblies. It's less likely that // a project would have IVT to it and so it helps us save on memory. It also // means we can avoid loading lots and lots of obfuscated code in the case the // dll was obfuscated. if (IsPublic(type.Attributes)) { var definition = MetadataDefinition.Create(_metadataReader, type); definitionMap.Add(definition.Name, definition); _allTypeDefinitions.Add(definition); } } }
// Enabling this for MONO, because it's required by GetFrameworkName. // More details are in the comment for that method #if !FEATURE_ASSEMBLY_LOADFROM || MONO // This method copied from DNX source: https://github.com/aspnet/dnx/blob/e0726f769aead073af2d8cd9db47b89e1745d574/src/Microsoft.Dnx.Tooling/Utils/LockFileUtils.cs#L385 // System.Reflection.Metadata 1.1 is expected to have an API that helps with this. /// <summary> /// Gets the fixed (required) string arguments of a custom attribute. /// Only attributes that have only fixed string arguments. /// </summary> private static List <string> GetFixedStringArguments(MetadataReader reader, CustomAttribute attribute) { // TODO: Nick Guerrera ([email protected]) hacked this method for temporary use. // There is a blob decoder feature in progress but it won't ship in time for our milestone. // Replace this method with the blob decoder feature when later it is availale. var signature = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature; var signatureReader = reader.GetBlobReader(signature); var valueReader = reader.GetBlobReader(attribute.Value); var arguments = new List <string>(); var prolog = valueReader.ReadUInt16(); if (prolog != 1) { // Invalid custom attribute prolog return(arguments); } var header = signatureReader.ReadSignatureHeader(); if (header.Kind != SignatureKind.Method || header.IsGeneric) { // Invalid custom attribute constructor signature return(arguments); } int parameterCount; if (!signatureReader.TryReadCompressedInteger(out parameterCount)) { // Invalid custom attribute constructor signature return(arguments); } var returnType = signatureReader.ReadSignatureTypeCode(); if (returnType != SignatureTypeCode.Void) { // Invalid custom attribute constructor signature return(arguments); } for (int i = 0; i < parameterCount; i++) { var signatureTypeCode = signatureReader.ReadSignatureTypeCode(); if (signatureTypeCode == SignatureTypeCode.String) { // Custom attribute constructor must take only strings arguments.Add(valueReader.ReadSerializedString()); } } return(arguments); }
private static string DumpRec(this MetadataReader reader, EntityHandle handle) { switch (handle.Kind) { case HandleKind.AssemblyReference: return(reader.GetString(reader.GetAssemblyReference((AssemblyReferenceHandle)handle).Name)); case HandleKind.TypeDefinition: { TypeDefinition type = reader.GetTypeDefinition((TypeDefinitionHandle)handle); return(getQualifiedName(type.Namespace, type.Name)); } case HandleKind.MethodDefinition: { MethodDefinition method = reader.GetMethodDefinition((MethodDefinitionHandle)handle); var blob = reader.GetBlobReader(method.Signature); var decoder = new SignatureDecoder <string, object>(ConstantSignatureVisualizer.Instance, reader, genericContext: null); var signature = decoder.DecodeMethodSignature(ref blob); var parameters = signature.ParameterTypes.Join(", "); return($"{signature.ReturnType} {DumpRec(reader, method.GetDeclaringType())}.{reader.GetString(method.Name)}({parameters})"); } case HandleKind.MemberReference: { MemberReference member = reader.GetMemberReference((MemberReferenceHandle)handle); var blob = reader.GetBlobReader(member.Signature); var decoder = new SignatureDecoder <string, object>(ConstantSignatureVisualizer.Instance, reader, genericContext: null); var signature = decoder.DecodeMethodSignature(ref blob); var parameters = signature.ParameterTypes.Join(", "); return($"{signature.ReturnType} {DumpRec(reader, member.Parent)}.{reader.GetString(member.Name)}({parameters})"); } case HandleKind.TypeReference: { TypeReference type = reader.GetTypeReference((TypeReferenceHandle)handle); return(getQualifiedName(type.Namespace, type.Name)); } default: return(null); } string getQualifiedName(StringHandle leftHandle, StringHandle rightHandle) { string name = reader.GetString(rightHandle); if (!leftHandle.IsNil) { name = reader.GetString(leftHandle) + "." + name; } return(name); } }
private Object ResolveMethodSpecification(MethodSpecificationHandle handle) { MethodSpecification methodSpecification = _metadataReader.GetMethodSpecification(handle); MethodDesc methodDef = GetMethod(methodSpecification.Method); BlobReader signatureReader = _metadataReader.GetBlobReader(methodSpecification.Signature); EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader); TypeDesc[] instantiation = parser.ParseMethodSpecSignature(); return(Context.GetInstantiatedMethod(methodDef, new Instantiation(instantiation))); }
public CustomAttributeValue <TType> DecodeValue(EntityHandle constructor, BlobHandle value) { BlobHandle signature; switch (constructor.Kind) { case HandleKind.MethodDefinition: MethodDefinition definition = _reader.GetMethodDefinition((MethodDefinitionHandle)constructor); signature = definition.Signature; break; case HandleKind.MemberReference: MemberReference reference = _reader.GetMemberReference((MemberReferenceHandle)constructor); signature = reference.Signature; break; default: throw new BadImageFormatException(); } BlobReader signatureReader = _reader.GetBlobReader(signature); BlobReader valueReader = _reader.GetBlobReader(value); ushort prolog = valueReader.ReadUInt16(); if (prolog != 1) { throw new BadImageFormatException(); } SignatureHeader header = signatureReader.ReadSignatureHeader(); if (header.Kind != SignatureKind.Method || header.IsGeneric) { throw new BadImageFormatException(); } int parameterCount = signatureReader.ReadCompressedInteger(); SignatureTypeCode returnType = signatureReader.ReadSignatureTypeCode(); if (returnType != SignatureTypeCode.Void) { throw new BadImageFormatException(); } ImmutableArray <CustomAttributeTypedArgument <TType> > fixedArguments = DecodeFixedArguments(ref signatureReader, ref valueReader, parameterCount); ImmutableArray <CustomAttributeNamedArgument <TType> > namedArguments = DecodeNamedArguments(ref valueReader); return(new CustomAttributeValue <TType>(fixedArguments, namedArguments)); }
//<SnippetReadPdb> static string ReadDocumentPath(MetadataReader reader, Document doc) { BlobReader blob = reader.GetBlobReader(doc.Name); // Read path separator character var separator = (char)blob.ReadByte(); var sb = new StringBuilder(blob.Length * 2); // Read path segments while (true) { BlobHandle bh = blob.ReadBlobHandle(); if (!bh.IsNil) { byte[] nameBytes = reader.GetBlobBytes(bh); sb.Append(Encoding.UTF8.GetString(nameBytes)); } if (blob.Offset >= blob.Length) { break; } sb.Append(separator); } return(sb.ToString()); }
void ParseEnum(TypeDefinition enumTypeDef) { // TODO: verify that int32 is the enums storage type for constant read below InspectorEnum ienum = new InspectorEnum(); ienum.Name = metaReader.GetString(enumTypeDef.Name); InspectorEnums [ienum.Name] = ienum; var fields = enumTypeDef.GetFields(); foreach (var fieldHandle in fields) { var inspectorField = new InspectorField(); var fieldDef = metaReader.GetFieldDefinition(fieldHandle); if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0) { var constantHandle = fieldDef.GetDefaultValue(); var constant = metaReader.GetConstant(constantHandle); BlobReader constantReader = metaReader.GetBlobReader(constant.Value); ienum.Values [metaReader.GetString(fieldDef.Name)] = constantReader.ReadInt32(); } } return; }
public ImmutableDictionary <string, string> GetCompilationOptions() { using var _ = PooledDictionary <string, string> .GetInstance(out var result); foreach (var handle in _pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition)) { var customDebugInformation = _pdbReader.GetCustomDebugInformation(handle); if (_pdbReader.GetGuid(customDebugInformation.Kind) == PortableCustomDebugInfoKinds.CompilationOptions) { var blobReader = _pdbReader.GetBlobReader(customDebugInformation.Value); // Compiler flag bytes are UTF-8 null-terminated key-value pairs var nullIndex = blobReader.IndexOf(0); while (nullIndex >= 0) { var key = blobReader.ReadUTF8(nullIndex); // Skip the null terminator blobReader.ReadByte(); nullIndex = blobReader.IndexOf(0); var value = blobReader.ReadUTF8(nullIndex); result.Add(key, value); // Skip the null terminator blobReader.ReadByte(); nullIndex = blobReader.IndexOf(0); } } } return(result.ToImmutableDictionary()); }
private ulong HandleConstant(EcmaModule module, ConstantHandle constantHandle) { MetadataReader reader = module.MetadataReader; Constant constant = reader.GetConstant(constantHandle); BlobReader blob = reader.GetBlobReader(constant.Value); switch (constant.TypeCode) { case ConstantTypeCode.Byte: return((ulong)blob.ReadByte()); case ConstantTypeCode.Int16: return((ulong)blob.ReadInt16()); case ConstantTypeCode.Int32: return((ulong)blob.ReadInt32()); case ConstantTypeCode.Int64: return((ulong)blob.ReadInt64()); case ConstantTypeCode.SByte: return((ulong)blob.ReadSByte()); case ConstantTypeCode.UInt16: return((ulong)blob.ReadUInt16()); case ConstantTypeCode.UInt32: return((ulong)blob.ReadUInt32()); case ConstantTypeCode.UInt64: return((ulong)blob.ReadUInt64()); } System.Diagnostics.Debug.Assert(false); return(0); }
private void AddNamespaceParts( StringHandle namespaceHandle, List <string> simpleNames) { var blobReader = _metadataReader.GetBlobReader(namespaceHandle); while (true) { int dotIndex = blobReader.IndexOf((byte)'.'); unsafe { // Note: we won't get any string sharing as we're just using the // default string decoded. However, that's ok. We only produce // these strings when we first read metadata. Then we create and // persist our own index. In the future when we read in that index // there's no way for us to share strings between us and the // compiler at that point. if (dotIndex == -1) { simpleNames.Add(MetadataStringDecoder.DefaultUTF8.GetString( blobReader.CurrentPointer, blobReader.RemainingBytes)); return; } else { simpleNames.Add(MetadataStringDecoder.DefaultUTF8.GetString( blobReader.CurrentPointer, dotIndex)); blobReader.Offset += dotIndex + 1; } } } }
/// <summary> /// Extracts the method signature from the metadata by rid /// </summary> public R2RMethod(byte[] image, MetadataReader mdReader, uint rid, int entryPointId, GenericElementTypes[] instanceArgs, uint[] tok) { Token = _mdtMethodDef | rid; EntryPointRuntimeFunctionId = entryPointId; _mdReader = mdReader; RuntimeFunctions = new List <RuntimeFunction>(); // get the method signature from the MethodDefhandle MethodDefinitionHandle methodDefHandle = MetadataTokens.MethodDefinitionHandle((int)rid); _methodDef = mdReader.GetMethodDefinition(methodDefHandle); Name = mdReader.GetString(_methodDef.Name); BlobReader signatureReader = mdReader.GetBlobReader(_methodDef.Signature); TypeDefinitionHandle declaringTypeHandle = _methodDef.GetDeclaringType(); TypeDefinition declaringTypeDef; while (!declaringTypeHandle.IsNil) { declaringTypeDef = mdReader.GetTypeDefinition(declaringTypeHandle); DeclaringType = mdReader.GetString(declaringTypeDef.Name) + "." + DeclaringType; declaringTypeHandle = declaringTypeDef.GetDeclaringType(); } NamespaceDefinitionHandle namespaceHandle = declaringTypeDef.NamespaceDefinition; while (!namespaceHandle.IsNil) { NamespaceDefinition namespaceDef = mdReader.GetNamespaceDefinition(namespaceHandle); DeclaringType = mdReader.GetString(namespaceDef.Name) + "." + DeclaringType; namespaceHandle = namespaceDef.Parent; } SignatureHeader signatureHeader = signatureReader.ReadSignatureHeader(); IsGeneric = signatureHeader.IsGeneric; GenericParameterHandleCollection genericParams = _methodDef.GetGenericParameters(); _genericParamInstanceMap = new Dictionary <string, GenericInstance>(); int argCount = signatureReader.ReadCompressedInteger(); if (IsGeneric) { argCount = signatureReader.ReadCompressedInteger(); } ReturnType = new SignatureType(ref signatureReader, mdReader, genericParams); ArgTypes = new SignatureType[argCount]; for (int i = 0; i < argCount; i++) { ArgTypes[i] = new SignatureType(ref signatureReader, mdReader, genericParams); } if (IsGeneric && instanceArgs != null && tok != null) { InitGenericInstances(genericParams, instanceArgs, tok); } }
internal unsafe SharpLangType ResolveTypeHandle(ISharpLangGenericContext context, Handle handle) { switch (handle.Kind) { case HandleKind.TypeDefinition: return(ResolveTypeDef(null, (TypeDefinitionHandle)handle)); case HandleKind.TypeReference: { var typeReference = MetadataReader.GetTypeReference((TypeReferenceHandle)handle); var module = ResolveModule(typeReference.ResolutionScope); if (module == null) { throw new InvalidOperationException("Could not resolve module"); } return(module.ResolveType(MetadataReader.GetString(typeReference.Namespace), MetadataReader.GetString(typeReference.Name))); } case HandleKind.TypeSpecification: { var typeSpecification = MetadataReader.GetTypeSpecification((TypeSpecificationHandle)handle); var signatureReader = MetadataReader.GetBlobReader(typeSpecification.Signature); return(ReadSignature(context, signatureReader)); } case HandleKind.GenericParameter: default: throw new NotImplementedException(); } }
public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader, out PrimitiveTypeCode underlyingType) { underlyingType = 0; EntityHandle baseType = typeDefinition.GetBaseTypeOrNil(); if (baseType.IsNil) { return(false); } if (!baseType.IsKnownType(reader, KnownTypeCode.Enum)) { return(false); } foreach (var handle in typeDefinition.GetFields()) { var field = reader.GetFieldDefinition(handle); if ((field.Attributes & FieldAttributes.Static) != 0) { continue; } var blob = reader.GetBlobReader(field.Signature); if (blob.ReadSignatureHeader().Kind != SignatureKind.Field) { return(false); } underlyingType = (PrimitiveTypeCode)blob.ReadByte(); return(true); } return(false); }
public static BlobReader GetSingleBlob(Guid infoGuid, MetadataReader pdbReader) { return((from cdiHandle in pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition) let cdi = pdbReader.GetCustomDebugInformation(cdiHandle) where pdbReader.GetGuid(cdi.Kind) == infoGuid select pdbReader.GetBlobReader(cdi.Value)).Single()); }
// TODO: this needs to be made more robust. // We currently rely on the fact that all attributes defined by the Q# compiler // have a single constructor taking a single string argument. private static (string, string)? GetAttribute(MetadataReader metadataReader, CustomAttribute attribute) { var attrType = GetAttributeType(metadataReader, attribute); QsCompilerError.Verify(attrType.HasValue, "the type of the custom attribute could not be determined"); var(ns, name) = attrType.Value; var attrNS = metadataReader.GetString(ns); if (attrNS.StartsWith("Microsoft.Quantum", StringComparison.InvariantCulture)) { var attrReader = metadataReader.GetBlobReader(attribute.Value); _ = attrReader.ReadUInt16(); // All custom attributes start with 0x0001, so read that now and discard it. try { var serialization = attrReader.ReadSerializedString(); // FIXME: this needs to be made more robust return(metadataReader.GetString(name), serialization); } catch { return(null); } } return(null); }
public static string SignatureWithHeaderToString(this MetadataReader reader, BlobHandle srcHandle) { var blobReader = reader.GetBlobReader(srcHandle); var stringBuilder = new StringBuilder(); var header = blobReader.ReadSignatureHeader(); stringBuilder.Append($"{header.Kind} "); switch (header.Kind) { case SignatureKind.Method: case SignatureKind.Property: MethodSignatureToString(reader, header, ref blobReader, stringBuilder); break; case SignatureKind.Field: FieldSignatureToString(reader, ref blobReader, stringBuilder); break; case SignatureKind.LocalVariables: LocalSignatureToString(reader, ref blobReader, stringBuilder); break; case SignatureKind.MethodSpecification: MethodSpecSignatureToString(reader, ref blobReader, stringBuilder); break; default: throw new BadImageFormatException(); } return(stringBuilder.ToString()); }
/// <summary> /// Get the strong name of a reference assembly represented by the 'metadataReader' /// </summary> private static string GetAssemblyStrongName(MetadataReader metadataReader) { AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition(); string asmName = metadataReader.GetString(assemblyDefinition.Name); string asmVersion = assemblyDefinition.Version.ToString(); string asmCulture = metadataReader.GetString(assemblyDefinition.Culture); asmCulture = (asmCulture == string.Empty) ? "neutral" : asmCulture; AssemblyHashAlgorithm hashAlgorithm = assemblyDefinition.HashAlgorithm; BlobHandle blobHandle = assemblyDefinition.PublicKey; BlobReader blobReader = metadataReader.GetBlobReader(blobHandle); byte[] publickey = blobReader.ReadBytes(blobReader.Length); HashAlgorithm hashImpl = null; switch (hashAlgorithm) { case AssemblyHashAlgorithm.Sha1: hashImpl = SHA1.Create(); break; case AssemblyHashAlgorithm.MD5: hashImpl = MD5.Create(); break; case AssemblyHashAlgorithm.Sha256: hashImpl = SHA256.Create(); break; case AssemblyHashAlgorithm.Sha384: hashImpl = SHA384.Create(); break; case AssemblyHashAlgorithm.Sha512: hashImpl = SHA512.Create(); break; default: throw new NotSupportedException(); } byte[] publicKeyHash = hashImpl.ComputeHash(publickey); byte[] publicKeyTokenBytes = new byte[8]; // Note that, the low 8 bytes of the hash of public key in reverse order is the public key tokens. for (int i = 1; i <= 8; i++) { publicKeyTokenBytes[i - 1] = publicKeyHash[publicKeyHash.Length - i]; } // Convert bytes to hex format strings in lower case. string publicKeyTokenString = BitConverter.ToString(publicKeyTokenBytes).Replace("-", string.Empty).ToLowerInvariant(); string strongAssemblyName = string.Format(CultureInfo.InvariantCulture, "{0}, Version={1}, Culture={2}, PublicKeyToken={3}", asmName, asmVersion, asmCulture, publicKeyTokenString); return(strongAssemblyName); }
public static string TypeSignatureToString(this MetadataReader reader, BlobHandle srcHandle) { var blobReader = reader.GetBlobReader(srcHandle); var stringBuilder = new StringBuilder(); TypeSignatureToString(reader, ref blobReader, stringBuilder); return(stringBuilder.ToString()); }
private static ImmutableArray <bool> ReadDynamicCustomDebugInformation(MetadataReader reader, EntityHandle variableOrConstantHandle) { if (TryGetCustomDebugInformation(reader, variableOrConstantHandle, PortableCustomDebugInfoKinds.DynamicLocalVariables, out var info)) { return(DecodeDynamicFlags(reader.GetBlobReader(info.Value))); } return(default);
public static IEnumerable <string> GetLinkWithLibraryNames(this MetadataReader reader) { foreach (var attrHandle in reader.GetAssemblyDefinition().GetCustomAttributes()) { var attr = reader.GetCustomAttribute(attrHandle); if (attr.Constructor.Kind != HandleKind.MemberReference) { continue; } var ctor = reader.GetMemberReference((MemberReferenceHandle)attr.Constructor); var typeReference = reader.GetTypeReference((TypeReferenceHandle)ctor.Parent); if (reader.GetString(typeReference.Namespace) != "ObjCRuntime" || reader.GetString(typeReference.Name) != "LinkWithAttribute") { continue; } // Unfortunately SRM does not yet have a number of facilities made public, // such as the *.Decoding namespace. Below we verify the raw signature of the // attribute, ensuring `void ObjCRuntime.LinkWithAttribute::.ctor(string)`. // See Decoding/MethodSignature.cs.cs in SRM. // // (header)(generic-type-param-count?)(param-count)(return-type)(param-types...) var sigReader = reader.GetBlobReader(ctor.Signature); if (sigReader.ReadSignatureHeader().IsGeneric || // (skip generics) sigReader.ReadCompressedInteger() != 1 || // (param-count) sigReader.ReadCompressedInteger() != (int)SignatureTypeCode.Void || // (return-type) sigReader.ReadCompressedInteger() != (int)SignatureTypeCode.String) // (first param-type) { continue; } // I could not actually find any uses of ReadSerializedString in SRM code, // but § II.23.3 Custom attributes of ECMA 335 indicates that we should expect // an LE unsigned int16 prolog of 0x0001 immediately followed by the fixed // argument value list, the format of which is defined by the ctor signature // itself as verified above, and is not repeated in the value blob. var valReader = reader.GetBlobReader(attr.Value); if (valReader.ReadUInt16() == 0x0001) { yield return(valReader.ReadSerializedString()); } } }
private uint LookupIbcMethodToken(MetadataType methodMetadataType, uint ibcToken, Dictionary <IBCBlobKey, BlobEntry> blobs) { var methodEntry = (BlobEntry.ExternalMethodEntry)blobs[new IBCBlobKey(ibcToken, BlobType.ExternalMethodDef)]; var signatureEntry = (BlobEntry.ExternalSignatureEntry)blobs[new IBCBlobKey(methodEntry.SignatureToken, BlobType.ExternalSignatureDef)]; string methodName = Encoding.UTF8.GetString(methodEntry.Name); var ecmaType = (EcmaType)methodMetadataType.GetTypeDefinition(); EcmaModule ecmaModule = ecmaType.EcmaModule; var lookupClassTokenTypeDef = (int)LookupIbcTypeToken(ref ecmaModule, methodEntry.ClassToken, blobs); if (lookupClassTokenTypeDef != ecmaType.MetadataReader.GetToken(ecmaType.Handle)) { throw new Exception($"Ibc MethodToken {ibcToken:x} incosistent classToken '{ibcToken:x}' with specified exact type '{ecmaType}'"); } foreach (MethodDesc method in ecmaType.GetMethods()) { if (method.Name == methodName) { EcmaMethod ecmaCandidateMethod = method as EcmaMethod; if (method == null) { continue; } MetadataReader metadataReader = ecmaCandidateMethod.MetadataReader; BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetMethodDefinition(ecmaCandidateMethod.Handle).Signature); // Compare for equality if (signatureReader.RemainingBytes != signatureEntry.Signature.Length) { continue; } for (int i = 0; i < signatureEntry.Signature.Length; i++) { if (signatureReader.ReadByte() != signatureEntry.Signature[i]) { continue; } } // TODO, consider implementing the fuzzy matching that CrossGen implements // It will be necessary for handling version tolerant ibc parsing of generics // Exact match return((uint)MetadataTokens.GetToken(ecmaCandidateMethod.Handle)); } } if (_logger.IsVerbose) { _logger.Writer.WriteLine("Warning: Unable to find exact match for candidate external method"); } return(0); }
/// <exception cref="BadImageFormatException">Invalid data format.</exception> private static void ReadMethodCustomDebugInformation( MetadataReader reader, MethodDefinitionHandle methodHandle, out ImmutableArray <HoistedLocalScopeRecord> hoistedLocalScopes, out string defaultNamespace) { hoistedLocalScopes = ImmutableArray <HoistedLocalScopeRecord> .Empty; foreach (var infoHandle in reader.GetCustomDebugInformation(methodHandle)) { var info = reader.GetCustomDebugInformation(infoHandle); var id = reader.GetGuid(info.Kind); if (id == PortableCustomDebugInfoKinds.StateMachineHoistedLocalScopes) { // only single CDIof this kind is allowed on a method: if (!hoistedLocalScopes.IsEmpty) { throw new BadImageFormatException(); } hoistedLocalScopes = DecodeHoistedLocalScopes(reader.GetBlobReader(info.Value)); } } // TODO: consider looking this up once per module (not for every method) defaultNamespace = null; foreach (var infoHandle in reader.GetCustomDebugInformation(EntityHandle.ModuleDefinition)) { var info = reader.GetCustomDebugInformation(infoHandle); var id = reader.GetGuid(info.Kind); if (id == PortableCustomDebugInfoKinds.DefaultNamespace) { // only single CDI of this kind is allowed on the module: if (defaultNamespace != null) { throw new BadImageFormatException(); } var valueReader = reader.GetBlobReader(info.Value); defaultNamespace = valueReader.ReadUTF8(valueReader.Length); } } defaultNamespace = defaultNamespace ?? ""; }
public EntityHandle GetTypeFromSpecification(MetadataReader reader, TypeSpecificationHandle handle) { // Create a decoder to process the type specification (which happens with // instantiated generics). It will call back into us to get the first handle // for the type def or type ref that the specification starts with. var sigReader = reader.GetBlobReader(reader.GetTypeSpecification(handle).Signature); return(new SignatureDecoder <EntityHandle, object>(this, reader, genericContext: null).DecodeType(ref sigReader)); }
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 static EntityHandle GetGenericType(this MetadataReader reader, TypeSpecification typeSpec) { var blobReader = reader.GetBlobReader(typeSpec.Signature); var typeCode = blobReader.ReadCompressedInteger(); if (typeCode != (int)SignatureTypeCode.GenericTypeInstance) { return(default);
private static string GetFileName(MetadataReader reader, DocumentHandle documentHandle) { var document = reader.GetDocument(documentHandle); if (document.Name.IsNil) { return(null); } var nameReader = reader.GetBlobReader(document.Name); int separator = nameReader.ReadByte(); if (!FileNameUtilities.IsDirectorySeparator((char)separator)) { return(FileNameUtilities.GetFileName(reader.GetString(document.Name))); } // find the last part handle: BlobHandle partHandle = default(BlobHandle); while (nameReader.RemainingBytes > 0) { partHandle = nameReader.ReadBlobHandle(); } if (partHandle.IsNil) { return(string.Empty); } var partReader = reader.GetBlobReader(partHandle); var part = partReader.ReadUTF8(partReader.Length); if (part.IndexOf('\0') >= 0) { // bad metadata return(null); } // it is valid to encode document name so that the parts contain directory separators: return(FileNameUtilities.GetFileName(part)); }