From bbe126746c59e27d7dea03f86b0dcff734f355e9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Tue, 18 Dec 2018 22:26:54 +0100 Subject: [PATCH] Add support for parsing field signatures (dotnet/coreclr#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 Commit migrated from https://github.com/dotnet/coreclr/commit/b7b1aa016ac4eb13a54e49c1f9e137b9dab01a66 --- src/coreclr/src/tools/r2rdump/R2RSignature.cs | 78 +++++++++++++++++++++------ 1 file changed, 62 insertions(+), 16 deletions(-) diff --git a/src/coreclr/src/tools/r2rdump/R2RSignature.cs b/src/coreclr/src/tools/r2rdump/R2RSignature.cs index 852521a..a714383 100644 --- a/src/coreclr/src/tools/r2rdump/R2RSignature.cs +++ b/src/coreclr/src/tools/r2rdump/R2RSignature.cs @@ -97,14 +97,34 @@ namespace R2RDump /// Member reference handle 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(), Array.Empty()); - MethodSignature methodSig = methodRef.DecodeMethodSignature(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(this, genericContext); + builder.Append(fieldSig); + builder.Append(" "); + builder.Append(EmitContainingTypeAndMemberName(memberRef, owningTypeOverride)); + break; + } + + case MemberReferenceKind.Method: + { + MethodSignature methodSig = memberRef.DecodeMethodSignature(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 } /// - /// Emit containing type and method name and extract the method signature from a method reference. + /// Emit containing type and member name. /// - /// Method reference to format - /// Output method signature - private string EmitContainingTypeAndMethodName(MemberReference methodRef, string owningTypeOverride) + /// Member reference to format + /// Optional override for the owning type, null = MemberReference.Parent + 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); } /// @@ -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 } /// + /// Parse field signature and output its textual representation into the given string builder. + /// + /// Output string builder + 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)); + } + + /// /// Read R2R helper signature. /// /// -- 2.7.4