private bool TryGetDebuggableMethod(int methodToken, out PortablePdbReader pdbReader, out MethodDebugInformationHandle handle) { if (!MetadataUtilities.IsMethodToken(methodToken)) { pdbReader = null; handle = default(MethodDebugInformationHandle); return(false); } var methodId = MethodId.FromToken(methodToken); if (Version == 1) { pdbReader = GetReader(version: 1); if (pdbReader.TryGetMethodHandle(methodId, out handle)) { return(pdbReader.HasDebugInfo(handle)); } } else { var methodMap = GetMethodMap(); if (methodMap.IsValidMethodRowId(methodId.Value)) { var info = methodMap.GetInfo(methodId); pdbReader = GetReader(info.Version); handle = info.Handle; return(pdbReader.HasDebugInfo(handle)); } } pdbReader = null; handle = default(MethodDebugInformationHandle); return(false); }
private AsyncMethodData ReadAsyncMethodData() { var reader = MetadataReader; var body = reader.GetMethodDebugInformation(DebugHandle); var kickoffMethod = body.GetStateMachineKickoffMethod(); if (kickoffMethod.IsNil) { return(AsyncMethodData.None); } var value = reader.GetCustomDebugInformation(DefinitionHandle, MetadataUtilities.MethodSteppingInformationBlobId); if (value.IsNil) { return(AsyncMethodData.None); } var blobReader = reader.GetBlobReader(value); long catchHandlerOffset = blobReader.ReadUInt32(); if (catchHandlerOffset > (uint)int.MaxValue + 1) { throw new BadImageFormatException(); } var yieldOffsets = ImmutableArray.CreateBuilder <int>(); var resultOffsets = ImmutableArray.CreateBuilder <int>(); var resumeMethods = ImmutableArray.CreateBuilder <int>(); while (blobReader.RemainingBytes > 0) { uint yieldOffset = blobReader.ReadUInt32(); if (yieldOffset > int.MaxValue) { throw new BadImageFormatException(); } uint resultOffset = blobReader.ReadUInt32(); if (resultOffset > int.MaxValue) { throw new BadImageFormatException(); } yieldOffsets.Add((int)yieldOffset); resultOffsets.Add((int)resultOffset); resumeMethods.Add(MetadataUtilities.MethodDefToken(blobReader.ReadCompressedInteger())); } return(new AsyncMethodData( kickoffMethod, (int)(catchHandlerOffset - 1), yieldOffsets.ToImmutable(), resultOffsets.ToImmutable(), resumeMethods.ToImmutable())); }
public unsafe int GetSourceServerData(out byte *data, out int size) { var reader = GetReader(version: 1).MetadataReader; BlobHandle handle = MetadataUtilities.GetCustomDebugInformation(reader, EntityHandle.ModuleDefinition, MetadataUtilities.SourceLinkId); if (!handle.IsNil) { var blobReader = reader.GetBlobReader(handle); data = blobReader.StartPointer; size = blobReader.Length; return(HResult.S_OK); } data = null; size = 0; return(HResult.S_FALSE); }
/// <summary> /// Get a particular version of a method with specified token. /// </summary> public int GetMethodByVersion( int methodToken, int version, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedMethod method) { if (!IsValidVersion(version)) { method = null; return(HResult.E_INVALIDARG); } if (!MetadataUtilities.IsMethodToken(methodToken)) { method = null; return(HResult.E_INVALIDARG); } var pdbReader = GetReader(version); if (!pdbReader.TryGetMethodHandle(MethodId.FromToken(methodToken), out var methodDebugHandle)) { method = null; return(HResult.E_FAIL); } var debugInfo = pdbReader.MetadataReader.GetMethodDebugInformation(methodDebugHandle); if (debugInfo.SequencePointsBlob.IsNil) { // no debug info for the method method = null; return(HResult.E_FAIL); } method = new SymMethod(pdbReader, methodDebugHandle); return(HResult.S_OK); }
public static (object? Value, byte[] Signature) GetConstantValueAndSignature(MetadataReader mdReader, LocalConstantHandle handle, Func<EntityHandle, string?> getQualifiedTypeName) { var constant = mdReader.GetLocalConstant(handle); var sigReader = mdReader.GetBlobReader(constant.Signature); var sigWriter = new BlobWriter(sigReader.Length); // custom modifiers: int rawTypeCode; while (true) { rawTypeCode = sigReader.ReadCompressedInteger(); if (rawTypeCode == (int)SignatureTypeCode.OptionalModifier || rawTypeCode == (int)SignatureTypeCode.RequiredModifier) { sigReader.ReadCompressedInteger(); } else { break; } } int customModifiersLength = sigReader.Offset - 1; if (customModifiersLength > 0) { sigWriter.Write(mdReader.GetBlobBytes(constant.Signature), 0, customModifiersLength); } object? translatedValue; if (rawTypeCode == (int)MetadataUtilities.SignatureTypeCode_ValueType || rawTypeCode == (int)MetadataUtilities.SignatureTypeCode_Class) { var typeHandle = sigReader.ReadTypeHandle(); string? qualifiedName = getQualifiedTypeName(typeHandle); if (qualifiedName == "System.Decimal") { translatedValue = sigReader.ReadDecimal(); } else if (qualifiedName == "System.DateTime") { translatedValue = BitConverter.Int64BitsToDouble(sigReader.ReadDateTime().Ticks); } else if (sigReader.RemainingBytes == 0) { // null reference is returned as a boxed integer 0: translatedValue = s_nullReferenceValue; } else { // unknown (not produced by C# or VB) translatedValue = null; } sigWriter.Write((byte)rawTypeCode); sigWriter.WriteCompressedInteger(MetadataUtilities.GetTypeDefOrRefOrSpecCodedIndex(typeHandle)); } else { bool isEnumTypeCode; translatedValue = ReadAndTranslateValue(ref sigReader, (SignatureTypeCode)rawTypeCode, out isEnumTypeCode); if (sigReader.RemainingBytes == 0) { // primitive type code: sigWriter.Write((byte)rawTypeCode); } else if (isEnumTypeCode) { var enumTypeHandle = sigReader.ReadTypeHandle(); // enum type signature: sigWriter.Write((byte)MetadataUtilities.SignatureTypeCode_ValueType); sigWriter.WriteCompressedInteger(MetadataUtilities.GetTypeDefOrRefOrSpecCodedIndex(enumTypeHandle)); } if (sigReader.RemainingBytes > 0) { throw new BadImageFormatException(); } } return (translatedValue, sigWriter.ToArray()); }
internal bool IsValidMethodToken(int token) => MetadataUtilities.IsMethodToken(token) && IsValidMethodRowId(MetadataUtilities.GetRowId(token));
public static MethodId FromToken(int methodToken) => new MethodId(MetadataUtilities.GetRowId(methodToken));