From 988df2aafd4d6af1bd80166f9df5bd289a0d5396 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Fri, 3 May 2019 23:15:25 +0200 Subject: [PATCH] New options --sb / --isb for binary signature dump (#24375) Based on JanV's suggestion I have added two new options to R2RDump: "--sb" (SignatureBinary) appends the binary signature representation at the end of the parsed textual signature; "--isb" (InlineSignatureBinary) inlines the signature bytes into the parsed textual signature and makes it (somewhat) easy to correlate the binary bytes with individual parts of the signature. Thanks Tomas --- src/tools/r2rdump/R2RDump.cs | 4 + src/tools/r2rdump/R2RReader.cs | 6 +- src/tools/r2rdump/R2RSignature.cs | 207 ++++++++++++++++++++++++++++---------- 3 files changed, 161 insertions(+), 56 deletions(-) diff --git a/src/tools/r2rdump/R2RDump.cs b/src/tools/r2rdump/R2RDump.cs index cb5310b..ccc7ce2 100644 --- a/src/tools/r2rdump/R2RDump.cs +++ b/src/tools/r2rdump/R2RDump.cs @@ -26,6 +26,8 @@ namespace R2RDump public bool GC; public bool SectionContents; public bool EntryPoints; + public bool SignatureBinary; + public bool InlineSignatureBinary; public IReadOnlyList ReferenceAssemblies = Array.Empty(); public IReadOnlyList ReferencePaths = Array.Empty(); @@ -186,6 +188,8 @@ namespace R2RDump syntax.DefineOption("ignoreSensitive", ref _ignoreSensitive, "Ignores sensitive properties in xml dump to avoid failing tests"); syntax.DefineOptionList("r|reference", ref _options.ReferenceAssemblies, "Explicit reference assembly files"); syntax.DefineOptionList("rp|referencepath", ref _options.ReferencePaths, "Search paths for reference assemblies"); + syntax.DefineOption("isb|inlineSignatureBinary", ref _options.InlineSignatureBinary, "Embed binary signature into its textual description"); + syntax.DefineOption("sb|signatureBinary", ref _options.SignatureBinary, "Append signature binary to its textual description"); }); if (verbose) diff --git a/src/tools/r2rdump/R2RReader.cs b/src/tools/r2rdump/R2RReader.cs index 2574f4d..9f88f38 100644 --- a/src/tools/r2rdump/R2RReader.cs +++ b/src/tools/r2rdump/R2RReader.cs @@ -474,7 +474,7 @@ namespace R2RDump uint methodFlags = decoder.ReadUInt(); if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { - owningType = decoder.ReadTypeSignature(); + owningType = decoder.ReadTypeSignatureNoEmit(); } if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_SlotInsteadOfToken) != 0) { @@ -497,14 +497,14 @@ namespace R2RDump methodTypeArgs = new string[typeArgCount]; for (int typeArgIndex = 0; typeArgIndex < typeArgCount; typeArgIndex++) { - methodTypeArgs[typeArgIndex] = decoder.ReadTypeSignature(); + methodTypeArgs[typeArgIndex] = decoder.ReadTypeSignatureNoEmit(); } } string constrainedType = null; if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained) != 0) { - constrainedType = decoder.ReadTypeSignature(); + constrainedType = decoder.ReadTypeSignatureNoEmit(); } int runtimeFunctionId; diff --git a/src/tools/r2rdump/R2RSignature.cs b/src/tools/r2rdump/R2RSignature.cs index 95be668..6501999 100644 --- a/src/tools/r2rdump/R2RSignature.cs +++ b/src/tools/r2rdump/R2RSignature.cs @@ -35,10 +35,10 @@ namespace R2RDump /// Metadata reader corresponding to the handle /// Metadata handle to parse /// Include namespace in type names - public static string FormatHandle(MetadataReader metadataReader, Handle handle, bool namespaceQualified = true, string owningTypeOverride = null) + public static string FormatHandle(MetadataReader metadataReader, Handle handle, bool namespaceQualified = true, string owningTypeOverride = null, string signaturePrefix = "") { MetadataNameFormatter formatter = new MetadataNameFormatter(metadataReader); - return formatter.EmitHandleName(handle, namespaceQualified, owningTypeOverride); + return formatter.EmitHandleName(handle, namespaceQualified, owningTypeOverride, signaturePrefix); } public static string FormatSignature(DumpOptions options, EcmaMetadataReader ecmaReader, int imageOffset) @@ -52,30 +52,30 @@ namespace R2RDump /// Emit a given token to a specified string builder. /// /// ECMA token to provide string representation for - private string EmitHandleName(Handle handle, bool namespaceQualified, string owningTypeOverride) + private string EmitHandleName(Handle handle, bool namespaceQualified, string owningTypeOverride, string signaturePrefix = "") { switch (handle.Kind) { case HandleKind.MemberReference: - return EmitMemberReferenceName((MemberReferenceHandle)handle, owningTypeOverride); + return EmitMemberReferenceName((MemberReferenceHandle)handle, owningTypeOverride, signaturePrefix); case HandleKind.MethodSpecification: - return EmitMethodSpecificationName((MethodSpecificationHandle)handle, owningTypeOverride); + return EmitMethodSpecificationName((MethodSpecificationHandle)handle, owningTypeOverride, signaturePrefix); case HandleKind.MethodDefinition: - return EmitMethodDefinitionName((MethodDefinitionHandle)handle, owningTypeOverride); + return EmitMethodDefinitionName((MethodDefinitionHandle)handle, owningTypeOverride, signaturePrefix); case HandleKind.TypeReference: - return EmitTypeReferenceName((TypeReferenceHandle)handle, namespaceQualified); + return EmitTypeReferenceName((TypeReferenceHandle)handle, namespaceQualified, signaturePrefix); case HandleKind.TypeSpecification: - return EmitTypeSpecificationName((TypeSpecificationHandle)handle, namespaceQualified); + return EmitTypeSpecificationName((TypeSpecificationHandle)handle, namespaceQualified, signaturePrefix); case HandleKind.TypeDefinition: - return EmitTypeDefinitionName((TypeDefinitionHandle)handle, namespaceQualified); + return EmitTypeDefinitionName((TypeDefinitionHandle)handle, namespaceQualified, signaturePrefix); case HandleKind.FieldDefinition: - return EmitFieldDefinitionName((FieldDefinitionHandle)handle, namespaceQualified, owningTypeOverride); + return EmitFieldDefinitionName((FieldDefinitionHandle)handle, namespaceQualified, owningTypeOverride, signaturePrefix); default: throw new NotImplementedException(); @@ -86,11 +86,11 @@ namespace R2RDump /// Emit a method specification. /// /// Method specification handle - private string EmitMethodSpecificationName(MethodSpecificationHandle methodSpecHandle, string owningTypeOverride) + private string EmitMethodSpecificationName(MethodSpecificationHandle methodSpecHandle, string owningTypeOverride, string signaturePrefix) { MethodSpecification methodSpec = _metadataReader.GetMethodSpecification(methodSpecHandle); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty(), Array.Empty()); - return EmitHandleName(methodSpec.Method, namespaceQualified: true, owningTypeOverride: owningTypeOverride) + return EmitHandleName(methodSpec.Method, namespaceQualified: true, owningTypeOverride: owningTypeOverride, signaturePrefix: signaturePrefix) + methodSpec.DecodeSignature(this, genericContext); } @@ -98,7 +98,7 @@ namespace R2RDump /// Emit a method reference. /// /// Member reference handle - private string EmitMemberReferenceName(MemberReferenceHandle memberRefHandle, string owningTypeOverride) + private string EmitMemberReferenceName(MemberReferenceHandle memberRefHandle, string owningTypeOverride, string signaturePrefix) { MemberReference memberRef = _metadataReader.GetMemberReference(memberRefHandle); StringBuilder builder = new StringBuilder(); @@ -110,7 +110,7 @@ namespace R2RDump string fieldSig = memberRef.DecodeFieldSignature(this, genericContext); builder.Append(fieldSig); builder.Append(" "); - builder.Append(EmitContainingTypeAndMemberName(memberRef, owningTypeOverride)); + builder.Append(EmitContainingTypeAndMemberName(memberRef, owningTypeOverride, signaturePrefix)); break; } @@ -119,7 +119,7 @@ namespace R2RDump MethodSignature methodSig = memberRef.DecodeMethodSignature(this, genericContext); builder.Append(methodSig.ReturnType); builder.Append(" "); - builder.Append(EmitContainingTypeAndMemberName(memberRef, owningTypeOverride)); + builder.Append(EmitContainingTypeAndMemberName(memberRef, owningTypeOverride, signaturePrefix)); builder.Append(EmitMethodSignature(methodSig)); break; } @@ -135,7 +135,7 @@ namespace R2RDump /// Emit a method definition. /// /// Method definition handle - private string EmitMethodDefinitionName(MethodDefinitionHandle methodDefinitionHandle, string owningTypeOverride) + private string EmitMethodDefinitionName(MethodDefinitionHandle methodDefinitionHandle, string owningTypeOverride, string signaturePrefix) { MethodDefinition methodDef = _metadataReader.GetMethodDefinition(methodDefinitionHandle); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty(), Array.Empty()); @@ -149,6 +149,7 @@ namespace R2RDump } builder.Append(owningTypeOverride); builder.Append("."); + builder.Append(signaturePrefix); builder.Append(EmitString(methodDef.Name)); builder.Append(EmitMethodSignature(methodSig)); return builder.ToString(); @@ -203,13 +204,14 @@ namespace R2RDump /// /// Member reference to format /// Optional override for the owning type, null = MemberReference.Parent - private string EmitContainingTypeAndMemberName(MemberReference memberRef, string owningTypeOverride) + /// Optional member signature prefix + private string EmitContainingTypeAndMemberName(MemberReference memberRef, string owningTypeOverride, string signaturePrefix) { if (owningTypeOverride == null) { owningTypeOverride = EmitHandleName(memberRef.Parent, namespaceQualified: true, owningTypeOverride: null); } - return owningTypeOverride + "." + EmitString(memberRef.Name); + return owningTypeOverride + "." + signaturePrefix + EmitString(memberRef.Name); } /// @@ -217,7 +219,8 @@ namespace R2RDump /// /// Type reference handle /// When set to true, include namespace information - private string EmitTypeReferenceName(TypeReferenceHandle typeRefHandle, bool namespaceQualified) + /// Optional type name signature prefix + private string EmitTypeReferenceName(TypeReferenceHandle typeRefHandle, bool namespaceQualified, string signaturePrefix) { TypeReference typeRef = _metadataReader.GetTypeReference(typeRefHandle); string typeName = EmitString(typeRef.Name); @@ -235,7 +238,7 @@ namespace R2RDump output += "."; } } - return output + typeName; + return output + signaturePrefix + typeName; } /// @@ -243,11 +246,12 @@ namespace R2RDump /// /// Type definition handle /// true = prefix type name with namespace information + /// Optional type name signature prefix /// - private string EmitTypeDefinitionName(TypeDefinitionHandle typeDefHandle, bool namespaceQualified) + private string EmitTypeDefinitionName(TypeDefinitionHandle typeDefHandle, bool namespaceQualified, string signaturePrefix) { TypeDefinition typeDef = _metadataReader.GetTypeDefinition(typeDefHandle); - string typeName = EmitString(typeDef.Name); + string typeName = signaturePrefix + EmitString(typeDef.Name); if (typeDef.IsNested) { // Nested type @@ -275,7 +279,7 @@ namespace R2RDump /// /// Type specification handle /// When set to true, include namespace information - private string EmitTypeSpecificationName(TypeSpecificationHandle typeSpecHandle, bool namespaceQualified) + private string EmitTypeSpecificationName(TypeSpecificationHandle typeSpecHandle, bool namespaceQualified, string signaturePrefix) { TypeSpecification typeSpec = _metadataReader.GetTypeSpecification(typeSpecHandle); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty(), Array.Empty()); @@ -288,8 +292,9 @@ namespace R2RDump /// Field definition handle to format /// True = display namespace information for the owning type /// Owning type override when non-null + /// Optional field name signature prefix /// Textual representation of the field declaration - private string EmitFieldDefinitionName(FieldDefinitionHandle fieldDefHandle, bool namespaceQualified, string owningTypeOverride) + private string EmitFieldDefinitionName(FieldDefinitionHandle fieldDefHandle, bool namespaceQualified, string owningTypeOverride, string signaturePrefix) { FieldDefinition fieldDef = _metadataReader.GetFieldDefinition(fieldDefHandle); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty(), Array.Empty()); @@ -298,6 +303,7 @@ namespace R2RDump output.Append(' '); output.Append(EmitHandleName(fieldDef.GetDeclaringType(), namespaceQualified, owningTypeOverride)); output.Append('.'); + output.Append(signaturePrefix); output.Append(_metadataReader.GetString(fieldDef.Name)); return output.ToString(); } @@ -476,24 +482,91 @@ namespace R2RDump public string ReadR2RSignature() { StringBuilder builder = new StringBuilder(); + int startOffset = _offset; ParseSignature(builder); + EmitSignatureBinaryFrom(builder, startOffset); return builder.ToString(); } - public string ReadMethodSignature() + public string ReadTypeSignature() { StringBuilder builder = new StringBuilder(); - ParseMethod(builder); + int startOffset = _offset; + ParseType(builder); + EmitSignatureBinaryFrom(builder, startOffset); return builder.ToString(); } - public string ReadTypeSignature() + public string ReadTypeSignatureNoEmit() { StringBuilder builder = new StringBuilder(); ParseType(builder); return builder.ToString(); } + private void EmitInlineSignatureBinaryFrom(StringBuilder builder, int startOffset) + { + EmitInlineSignatureBinaryBytes(builder, _offset - startOffset); + } + + private void EmitInlineSignatureBinaryBytes(StringBuilder builder, int count) + { + if (_options.InlineSignatureBinary) + { + if (builder.Length > 0 && Char.IsDigit(builder[builder.Length - 1])) + { + builder.Append('-'); + } + + for (int index = 0; index < count; index++) + { + if (index != 0) + { + builder.Append('-'); + } + builder.Append(_image[_offset - count + index].ToString("x2")); + } + builder.Append("-"); + } + } + + private uint ReadUIntAndEmitInlineSignatureBinary(StringBuilder builder) + { + int startOffset = _offset; + uint value = ReadUInt(); + EmitInlineSignatureBinaryFrom(builder, startOffset); + return value; + } + + private int ReadIntAndEmitInlineSignatureBinary(StringBuilder builder) + { + int startOffset = _offset; + int value = ReadInt(); + EmitInlineSignatureBinaryFrom(builder, startOffset); + return value; + } + + private uint ReadTokenAndEmitInlineSignatureBinary(StringBuilder builder) + { + int startOffset = _offset; + uint value = ReadToken(); + EmitInlineSignatureBinaryFrom(builder, startOffset); + return value; + } + + private void EmitSignatureBinaryFrom(StringBuilder builder, int startOffset) + { + if (_options.SignatureBinary) + { + for (int offset = startOffset; offset < _offset; offset++) + { + builder.Append(offset == startOffset ? " [" : "-"); + builder.Append(_image[offset].ToString("x2")); + } + builder.Append("]"); + } + } + /// /// Parse the signature into a given output string builder. /// @@ -501,6 +574,7 @@ namespace R2RDump private void ParseSignature(StringBuilder builder) { uint fixupType = ReadByte(); + EmitInlineSignatureBinaryBytes(builder, 1); bool moduleOverride = (fixupType & (byte)CORCOMPILE_FIXUP_BLOB_KIND.ENCODE_MODULE_OVERRIDE) != 0; SignatureDecoder moduleDecoder = this; @@ -508,7 +582,7 @@ namespace R2RDump if (moduleOverride) { fixupType &= ~(uint)CORCOMPILE_FIXUP_BLOB_KIND.ENCODE_MODULE_OVERRIDE; - int moduleIndex = (int)ReadUInt(); + int moduleIndex = (int)ReadUIntAndEmitInlineSignatureBinary(builder); EcmaMetadataReader refAsmEcmaReader = _contextReader.OpenReferenceAssembly(moduleIndex); moduleDecoder = new SignatureDecoder(_options, refAsmEcmaReader, _image, _offset, _contextReader); } @@ -596,7 +670,7 @@ namespace R2RDump case ReadyToRunFixupKind.READYTORUN_FIXUP_VirtualEntry_Slot: { - uint slot = ReadUInt(); + uint slot = ReadUIntAndEmitInlineSignatureBinary(builder); ParseType(builder); builder.Append($@" #{slot} (VIRTUAL_ENTRY_SLOT)"); @@ -733,6 +807,7 @@ namespace R2RDump private void ParseType(StringBuilder builder) { CorElementType corElemType = ReadElementType(); + EmitInlineSignatureBinaryBytes(builder, 1); switch (corElemType) { case CorElementType.ELEMENT_TYPE_VOID: @@ -806,28 +881,30 @@ namespace R2RDump break; case CorElementType.ELEMENT_TYPE_VAR: + uint varIndex = ReadUIntAndEmitInlineSignatureBinary(builder); builder.Append("var #"); - builder.Append(ReadUInt()); + builder.Append(varIndex); break; case CorElementType.ELEMENT_TYPE_ARRAY: ParseType(builder); { builder.Append('['); - uint rank = ReadUInt(); + int startOffset = _offset; + uint rank = ReadUIntAndEmitInlineSignatureBinary(builder); if (rank != 0) { - uint sizeCount = ReadUInt(); // number of sizes + uint sizeCount = ReadUIntAndEmitInlineSignatureBinary(builder); // number of sizes uint[] sizes = new uint[sizeCount]; for (uint sizeIndex = 0; sizeIndex < sizeCount; sizeIndex++) { - sizes[sizeIndex] = ReadUInt(); + sizes[sizeIndex] = ReadUIntAndEmitInlineSignatureBinary(builder); } - uint lowerBoundCount = ReadUInt(); // number of lower bounds + uint lowerBoundCount = ReadUIntAndEmitInlineSignatureBinary(builder); // number of lower bounds int[] lowerBounds = new int[sizeCount]; for (uint lowerBoundIndex = 0; lowerBoundIndex < lowerBoundCount; lowerBoundIndex++) { - lowerBounds[lowerBoundIndex] = ReadInt(); + lowerBounds[lowerBoundIndex] = ReadIntAndEmitInlineSignatureBinary(builder); } for (int index = 0; index < rank; index++) { @@ -888,8 +965,9 @@ namespace R2RDump break; case CorElementType.ELEMENT_TYPE_MVAR: + uint mvarIndex = ReadUIntAndEmitInlineSignatureBinary(builder); builder.Append("mvar #"); - builder.Append(ReadUInt()); + builder.Append(mvarIndex); break; case CorElementType.ELEMENT_TYPE_CMOD_REQD: @@ -930,7 +1008,7 @@ namespace R2RDump case CorElementType.ELEMENT_TYPE_MODULE_ZAPSIG: { - int moduleIndex = (int)ReadUInt(); + int moduleIndex = (int)ReadUIntAndEmitInlineSignatureBinary(builder); EcmaMetadataReader refAsmReader = _contextReader.OpenReferenceAssembly(moduleIndex); SignatureDecoder refAsmDecoder = new SignatureDecoder(_options, refAsmReader, _image, _offset, _contextReader); refAsmDecoder.ParseType(builder); @@ -945,7 +1023,7 @@ namespace R2RDump private void ParseGenericTypeInstance(StringBuilder builder) { ParseType(builder); - uint typeArgCount = ReadUInt(); + uint typeArgCount = ReadUIntAndEmitInlineSignatureBinary(builder); builder.Append("<"); for (uint paramIndex = 0; paramIndex < typeArgCount; paramIndex++) { @@ -960,8 +1038,13 @@ namespace R2RDump private void ParseTypeToken(StringBuilder builder) { - uint token = ReadToken(); - builder.Append(MetadataNameFormatter.FormatHandle(_ecmaReader.MetadataReader, MetadataTokens.Handle((int)token))); + StringBuilder signaturePrefixBuilder = new StringBuilder(); + uint token = ReadTokenAndEmitInlineSignatureBinary(signaturePrefixBuilder); + builder.Append(MetadataNameFormatter.FormatHandle( + _ecmaReader.MetadataReader, + MetadataTokens.Handle((int)token), + owningTypeOverride: null, + signaturePrefix: signaturePrefixBuilder.ToString())); } /// @@ -970,7 +1053,7 @@ namespace R2RDump /// Output string builder to receive the textual signature representation private void ParseMethod(StringBuilder builder) { - uint methodFlags = ReadUInt(); + uint methodFlags = ReadUIntAndEmitInlineSignatureBinary(builder); if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_UnboxingStub) != 0) { @@ -985,7 +1068,7 @@ namespace R2RDump if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { SignatureDecoder owningTypeDecoder = new SignatureDecoder(_options, _ecmaReader, _image, _offset, _contextReader); - owningTypeOverride = owningTypeDecoder.ReadTypeSignature(); + owningTypeOverride = owningTypeDecoder.ReadTypeSignatureNoEmit(); _offset = owningTypeDecoder._offset; } if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_SlotInsteadOfToken) != 0) @@ -1003,7 +1086,7 @@ namespace R2RDump if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0) { - uint typeArgCount = ReadUInt(); + uint typeArgCount = ReadUIntAndEmitInlineSignatureBinary(builder); builder.Append("<"); for (int typeArgIndex = 0; typeArgIndex < typeArgCount; typeArgIndex++) { @@ -1029,8 +1112,14 @@ namespace R2RDump /// Output string builder private void ParseMethodDefToken(StringBuilder builder, string owningTypeOverride) { - uint methodDefToken = ReadUInt() | (uint)CorTokenType.mdtMethodDef; - builder.Append(MetadataNameFormatter.FormatHandle(_ecmaReader.MetadataReader, MetadataTokens.Handle((int)methodDefToken), namespaceQualified: true, owningTypeOverride: owningTypeOverride)); + StringBuilder signaturePrefixBuilder = new StringBuilder(); + uint methodDefToken = ReadUIntAndEmitInlineSignatureBinary(signaturePrefixBuilder) | (uint)CorTokenType.mdtMethodDef; + builder.Append(MetadataNameFormatter.FormatHandle( + _ecmaReader.MetadataReader, + MetadataTokens.Handle((int)methodDefToken), + namespaceQualified: true, + owningTypeOverride: owningTypeOverride, + signaturePrefix: signaturePrefixBuilder.ToString())); } /// @@ -1040,8 +1129,14 @@ namespace R2RDump /// Explicit owning type override private void ParseMethodRefToken(StringBuilder builder, string owningTypeOverride) { - uint methodRefToken = ReadUInt() | (uint)CorTokenType.mdtMemberRef; - builder.Append(MetadataNameFormatter.FormatHandle(_ecmaReader.MetadataReader, MetadataTokens.Handle((int)methodRefToken), namespaceQualified: false, owningTypeOverride: owningTypeOverride)); + StringBuilder signaturePrefixBuilder = new StringBuilder(); + uint methodRefToken = ReadUIntAndEmitInlineSignatureBinary(signaturePrefixBuilder) | (uint)CorTokenType.mdtMemberRef; + builder.Append(MetadataNameFormatter.FormatHandle( + _ecmaReader.MetadataReader, + MetadataTokens.Handle((int)methodRefToken), + namespaceQualified: false, + owningTypeOverride: owningTypeOverride, + signaturePrefix: signaturePrefixBuilder.ToString())); } /// @@ -1050,7 +1145,7 @@ namespace R2RDump /// Output string builder private void ParseField(StringBuilder builder) { - uint flags = ReadUInt(); + uint flags = ReadUIntAndEmitInlineSignatureBinary(builder); string owningTypeOverride = null; if ((flags & (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_OwnerType) != 0) { @@ -1058,16 +1153,22 @@ namespace R2RDump ParseType(owningTypeBuilder); owningTypeOverride = owningTypeBuilder.ToString(); } + StringBuilder signaturePrefixBuilder = new StringBuilder(); uint fieldToken; if ((flags & (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_MemberRefToken) != 0) { - fieldToken = ReadUInt() | (uint)CorTokenType.mdtMemberRef; + fieldToken = ReadUIntAndEmitInlineSignatureBinary(signaturePrefixBuilder) | (uint)CorTokenType.mdtMemberRef; } else { - fieldToken = ReadUInt() | (uint)CorTokenType.mdtFieldDef; + fieldToken = ReadUIntAndEmitInlineSignatureBinary(signaturePrefixBuilder) | (uint)CorTokenType.mdtFieldDef; } - builder.Append(MetadataNameFormatter.FormatHandle(_ecmaReader.MetadataReader, MetadataTokens.Handle((int)fieldToken), namespaceQualified: false, owningTypeOverride: owningTypeOverride)); + builder.Append(MetadataNameFormatter.FormatHandle( + _ecmaReader.MetadataReader, + MetadataTokens.Handle((int)fieldToken), + namespaceQualified: false, + owningTypeOverride: owningTypeOverride, + signaturePrefix: signaturePrefixBuilder.ToString())); } /// @@ -1076,7 +1177,7 @@ namespace R2RDump /// private void ParseHelper(StringBuilder builder) { - uint helperType = ReadUInt(); + uint helperType = ReadUIntAndEmitInlineSignatureBinary(builder); if ((helperType & (uint)ReadyToRunHelper.READYTORUN_HELPER_FLAG_VSD) != 0) { builder.Append("VSD_"); @@ -1455,7 +1556,7 @@ namespace R2RDump /// private void ParseStringHandle(StringBuilder builder) { - uint rid = ReadUInt(); + uint rid = ReadUIntAndEmitInlineSignatureBinary(builder); UserStringHandle stringHandle = MetadataTokens.UserStringHandle((int)rid); builder.Append(_ecmaReader.MetadataReader.GetUserString(stringHandle)); } -- 2.7.4