/// <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)
/// 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();
/// 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);
}
/// 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();
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;
}
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;
}
/// 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>());
}
builder.Append(owningTypeOverride);
builder.Append(".");
+ builder.Append(signaturePrefix);
builder.Append(EmitString(methodDef.Name));
builder.Append(EmitMethodSignature(methodSig));
return builder.ToString();
/// </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>
/// </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);
output += ".";
}
}
- return output + typeName;
+ return output + signaturePrefix + typeName;
}
/// <summary>
/// </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
/// </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>());
/// <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>());
output.Append(' ');
output.Append(EmitHandleName(fieldDef.GetDeclaringType(), namespaceQualified, owningTypeOverride));
output.Append('.');
+ output.Append(signaturePrefix);
output.Append(_metadataReader.GetString(fieldDef.Name));
return output.ToString();
}
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>
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;
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);
}
case ReadyToRunFixupKind.READYTORUN_FIXUP_VirtualEntry_Slot:
{
- uint slot = ReadUInt();
+ uint slot = ReadUIntAndEmitInlineSignatureBinary(builder);
ParseType(builder);
builder.Append($@" #{slot} (VIRTUAL_ENTRY_SLOT)");
private void ParseType(StringBuilder builder)
{
CorElementType corElemType = ReadElementType();
+ EmitInlineSignatureBinaryBytes(builder, 1);
switch (corElemType)
{
case CorElementType.ELEMENT_TYPE_VOID:
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++)
{
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:
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);
private void ParseGenericTypeInstance(StringBuilder builder)
{
ParseType(builder);
- uint typeArgCount = ReadUInt();
+ uint typeArgCount = ReadUIntAndEmitInlineSignatureBinary(builder);
builder.Append("<");
for (uint paramIndex = 0; paramIndex < typeArgCount; paramIndex++)
{
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>
/// <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)
{
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)
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++)
{
/// <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>
/// <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>
/// <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)
{
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>
/// <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_");
/// <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));
}