New options --sb / --isb for binary signature dump (#24375)
authorTomáš Rylek <trylek@microsoft.com>
Fri, 3 May 2019 21:15:25 +0000 (23:15 +0200)
committerGitHub <noreply@github.com>
Fri, 3 May 2019 21:15:25 +0000 (23:15 +0200)
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
src/tools/r2rdump/R2RReader.cs
src/tools/r2rdump/R2RSignature.cs

index cb5310b..ccc7ce2 100644 (file)
@@ -26,6 +26,8 @@ namespace R2RDump
         public bool GC;
         public bool SectionContents;
         public bool EntryPoints;
+        public bool SignatureBinary;
+        public bool InlineSignatureBinary;
 
         public IReadOnlyList<string> ReferenceAssemblies = Array.Empty<string>();
         public IReadOnlyList<string> ReferencePaths = Array.Empty<string>();
@@ -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)
index 2574f4d..9f88f38 100644 (file)
@@ -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;
index 95be668..6501999 100644 (file)
@@ -35,10 +35,10 @@ namespace R2RDump
         /// <param name="metadataReader">Metadata reader corresponding to the handle</param>
         /// <param name="handle">Metadata handle to parse</param>
         /// <param name="namespaceQualified">Include namespace in type names</param>
-        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.
         /// </summary>
         /// <param name="methodToken">ECMA token to provide string representation for</param>
-        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.
         /// </summary>
         /// <param name="methodSpecHandle">Method specification handle</param>
-        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<string>(), Array.Empty<string>());
-            return EmitHandleName(methodSpec.Method, namespaceQualified: true, owningTypeOverride: owningTypeOverride)
+            return EmitHandleName(methodSpec.Method, namespaceQualified: true, owningTypeOverride: owningTypeOverride, signaturePrefix: signaturePrefix)
                 + methodSpec.DecodeSignature<string, DisassemblingGenericContext>(this, genericContext);
         }
 
@@ -98,7 +98,7 @@ namespace R2RDump
         /// Emit a method reference.
         /// </summary>
         /// <param name="memberRefHandle">Member reference handle</param>
-        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<string, DisassemblingGenericContext>(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<String> methodSig = memberRef.DecodeMethodSignature<string, DisassemblingGenericContext>(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.
         /// </summary>
         /// <param name="methodSpecHandle">Method definition handle</param>
-        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<string>(), Array.Empty<string>());
@@ -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
         /// </summary>
         /// <param name="memberRef">Member reference to format</param>
         /// <param name="owningTypeOverride">Optional override for the owning type, null = MemberReference.Parent</param>
-        private string EmitContainingTypeAndMemberName(MemberReference memberRef, string owningTypeOverride)
+        /// <param name="signaturePrefix">Optional member signature prefix</param>
+        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);
         }
 
         /// <summary>
@@ -217,7 +219,8 @@ namespace R2RDump
         /// </summary>
         /// <param name="typeRefHandle">Type reference handle</param>
         /// <param name="namespaceQualified">When set to true, include namespace information</param>
-        private string EmitTypeReferenceName(TypeReferenceHandle typeRefHandle, bool namespaceQualified)
+        /// <param name="signaturePrefix">Optional type name signature prefix</param>
+        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;
         }
 
         /// <summary>
@@ -243,11 +246,12 @@ namespace R2RDump
         /// </summary>
         /// <param name="typeDefHandle">Type definition handle</param>
         /// <param name="namespaceQualified">true = prefix type name with namespace information</param>
+        /// <param name="signaturePrefix">Optional type name signature prefix</param>
         /// <returns></returns>
-        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
         /// </summary>
         /// <param name="typeSpecHandle">Type specification handle</param>
         /// <param name="namespaceQualified">When set to true, include namespace information</param>
-        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<string>(), Array.Empty<string>());
@@ -288,8 +292,9 @@ namespace R2RDump
         /// <param name="fieldDefHandle">Field definition handle to format</param>
         /// <param name="namespaceQualified">True = display namespace information for the owning type</param>
         /// <param name="owningTypeOverride">Owning type override when non-null</param>
+        /// <param name="signaturePrefix">Optional field name signature prefix</param>
         /// <returns>Textual representation of the field declaration</returns>
-        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<string>(), Array.Empty<string>());
@@ -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("]");
+            }
+        }
+
         /// <summary>
         /// Parse the signature into a given output string builder.
         /// </summary>
@@ -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()));
         }
 
         /// <summary>
@@ -970,7 +1053,7 @@ namespace R2RDump
         /// <param name="builder">Output string builder to receive the textual signature representation</param>
         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
         /// <param name="builder">Output string builder</param>
         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()));
         }
 
         /// <summary>
@@ -1040,8 +1129,14 @@ namespace R2RDump
         /// <param name="owningTypeOverride">Explicit owning type override</param>
         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()));
         }
 
         /// <summary>
@@ -1050,7 +1145,7 @@ namespace R2RDump
         /// <param name="builder">Output string builder</param>
         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()));
         }
 
         /// <summary>
@@ -1076,7 +1177,7 @@ namespace R2RDump
         /// <returns></returns>
         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
         /// <returns></returns>
         private void ParseStringHandle(StringBuilder builder)
         {
-            uint rid = ReadUInt();
+            uint rid = ReadUIntAndEmitInlineSignatureBinary(builder);
             UserStringHandle stringHandle = MetadataTokens.UserStringHandle((int)rid);
             builder.Append(_ecmaReader.MetadataReader.GetUserString(stringHandle));
         }