summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
authorTomáš Rylek <trylek@microsoft.com>2018-12-18 22:26:54 +0100
committerGitHub <noreply@github.com>2018-12-18 22:26:54 +0100
commitb7b1aa016ac4eb13a54e49c1f9e137b9dab01a66 (patch)
tree8b112c2331ff5c01d13afc299aeecdd8c3c86ae4 /src/tools
parent12a8870119b3e8023d68868792b29c28991168b3 (diff)
downloadcoreclr-b7b1aa016ac4eb13a54e49c1f9e137b9dab01a66.tar.gz
coreclr-b7b1aa016ac4eb13a54e49c1f9e137b9dab01a66.tar.bz2
coreclr-b7b1aa016ac4eb13a54e49c1f9e137b9dab01a66.zip
Add support for parsing field signatures (#21573)
This change adds basic field signature parsing support to R2RDump and it improves parsing of two fixup types (FIELD_ADDRESS and CCTOR_TRIGGER). Thanks Tomas
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/r2rdump/R2RSignature.cs78
1 files changed, 62 insertions, 16 deletions
diff --git a/src/tools/r2rdump/R2RSignature.cs b/src/tools/r2rdump/R2RSignature.cs
index 852521ae24..a714383cf0 100644
--- a/src/tools/r2rdump/R2RSignature.cs
+++ b/src/tools/r2rdump/R2RSignature.cs
@@ -97,14 +97,34 @@ namespace R2RDump
/// <param name="memberRefHandle">Member reference handle</param>
private string EmitMemberReferenceName(MemberReferenceHandle memberRefHandle, string owningTypeOverride)
{
- MemberReference methodRef = _metadataReader.GetMemberReference(memberRefHandle);
+ MemberReference memberRef = _metadataReader.GetMemberReference(memberRefHandle);
StringBuilder builder = new StringBuilder();
DisassemblingGenericContext genericContext = new DisassemblingGenericContext(Array.Empty<string>(), Array.Empty<string>());
- MethodSignature<String> methodSig = methodRef.DecodeMethodSignature<string, DisassemblingGenericContext>(this, genericContext);
- builder.Append(methodSig.ReturnType);
- builder.Append(" ");
- builder.Append(EmitContainingTypeAndMethodName(methodRef, owningTypeOverride));
- builder.Append(EmitMethodSignature(methodSig));
+ switch (memberRef.GetKind())
+ {
+ case MemberReferenceKind.Field:
+ {
+ string fieldSig = memberRef.DecodeFieldSignature<string, DisassemblingGenericContext>(this, genericContext);
+ builder.Append(fieldSig);
+ builder.Append(" ");
+ builder.Append(EmitContainingTypeAndMemberName(memberRef, owningTypeOverride));
+ break;
+ }
+
+ case MemberReferenceKind.Method:
+ {
+ MethodSignature<String> methodSig = memberRef.DecodeMethodSignature<string, DisassemblingGenericContext>(this, genericContext);
+ builder.Append(methodSig.ReturnType);
+ builder.Append(" ");
+ builder.Append(EmitContainingTypeAndMemberName(memberRef, owningTypeOverride));
+ builder.Append(EmitMethodSignature(methodSig));
+ break;
+ }
+
+ default:
+ throw new NotImplementedException(memberRef.GetKind().ToString());
+ }
+
return builder.ToString();
}
@@ -176,17 +196,17 @@ namespace R2RDump
}
/// <summary>
- /// Emit containing type and method name and extract the method signature from a method reference.
+ /// Emit containing type and member name.
/// </summary>
- /// <param name="methodRef">Method reference to format</param>
- /// <param name="methodSignature">Output method signature</param>
- private string EmitContainingTypeAndMethodName(MemberReference methodRef, string owningTypeOverride)
+ /// <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)
{
if (owningTypeOverride == null)
{
- owningTypeOverride = EmitHandleName(methodRef.Parent, namespaceQualified: true, owningTypeOverride: null);
+ owningTypeOverride = EmitHandleName(memberRef.Parent, namespaceQualified: true, owningTypeOverride: null);
}
- return owningTypeOverride + "." + EmitString(methodRef.Name);
+ return owningTypeOverride + "." + EmitString(memberRef.Name);
}
/// <summary>
@@ -550,13 +570,13 @@ namespace R2RDump
case ReadyToRunFixupKind.READYTORUN_FIXUP_FieldAddress:
- builder.Append("FIELD_ADDRESS");
- // TODO
+ ParseField(builder);
+ builder.Append(" (FIELD_ADDRESS)");
break;
case ReadyToRunFixupKind.READYTORUN_FIXUP_CctorTrigger:
- builder.Append("CCTOR_TRIGGER");
- // TODO
+ ParseType(builder);
+ builder.Append(" (CCTOR_TRIGGER)");
break;
@@ -936,6 +956,32 @@ namespace R2RDump
}
/// <summary>
+ /// Parse field signature and output its textual representation into the given string builder.
+ /// </summary>
+ /// <param name="builder">Output string builder</param>
+ private void ParseField(StringBuilder builder)
+ {
+ uint flags = ReadUInt();
+ string owningTypeOverride = null;
+ if ((flags & (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_OwnerType) != 0)
+ {
+ StringBuilder owningTypeBuilder = new StringBuilder();
+ ParseType(owningTypeBuilder);
+ owningTypeOverride = owningTypeBuilder.ToString();
+ }
+ uint fieldToken;
+ if ((flags & (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_MemberRefToken) != 0)
+ {
+ fieldToken = ReadUInt() | (uint)CorTokenType.mdtMemberRef;
+ }
+ else
+ {
+ fieldToken = ReadUInt() | (uint)CorTokenType.mdtFieldDef;
+ }
+ builder.Append(MetadataNameFormatter.FormatHandle(_metadataReader, MetadataTokens.Handle((int)fieldToken), namespaceQualified: false, owningTypeOverride: owningTypeOverride));
+ }
+
+ /// <summary>
/// Read R2R helper signature.
/// </summary>
/// <returns></returns>