Skip to content

Commit

Permalink
Expose the parsed signature in structured format (dotnet#36190)
Browse files Browse the repository at this point in the history
  • Loading branch information
cshung authored May 11, 2020
1 parent 2cda903 commit cf1f24b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public sealed class ReadyToRunReader
// ImportSections
private List<ReadyToRunImportSection> _importSections;
private Dictionary<int, string> _importCellNames;
private Dictionary<int, ReadyToRunSignature> _importSignatures;

// AvailableType
private Dictionary<ReadyToRunSection, List<string>> _availableTypes;
Expand Down Expand Up @@ -308,6 +309,19 @@ public IReadOnlyDictionary<int, string> ImportCellNames

}

/// <summary>
/// Map from import cell addresses to their symbolic names.
/// </summary>
public IReadOnlyDictionary<int, ReadyToRunSignature> ImportSignatures
{
get
{
EnsureImportSections();
return _importSignatures;
}

}

internal Dictionary<int, DebugInfo> RuntimeFunctionToDebugInfo
{
get
Expand Down Expand Up @@ -945,6 +959,7 @@ private void EnsureImportSections()
}
_importSections = new List<ReadyToRunImportSection>();
_importCellNames = new Dictionary<int, string>();
_importSignatures = new Dictionary<int, ReadyToRunSignature>();
if (!ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.ImportSections, out ReadyToRunSection importSectionsSection))
{
return;
Expand Down Expand Up @@ -997,9 +1012,11 @@ private void EnsureImportSections()
long section = NativeReader.ReadInt64(Image, ref sectionOffset);
uint sigRva = NativeReader.ReadUInt32(Image, ref signatureOffset);
int sigOffset = GetOffset((int)sigRva);
string cellName = MetadataNameFormatter.FormatSignature(_assemblyResolver, this, sigOffset);
ReadyToRunSignature signature;
string cellName = MetadataNameFormatter.FormatSignature(_assemblyResolver, this, sigOffset, out signature);
entries.Add(new ReadyToRunImportSection.ImportSectionEntry(entries.Count, entryOffset, entryOffset + rva, section, sigRva, cellName));
_importCellNames.Add(rva + entrySize * i, cellName);
_importSignatures.Add(rva + entrySize * i, signature);
}

int auxDataRVA = NativeReader.ReadInt32(Image, ref offset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@

namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// This represents all possible signatures that is
/// </summary>
public class ReadyToRunSignature
{
}

/// <summary>
/// For now, this means the signature is not parsed yet
/// </summary>
public class TodoSignature : ReadyToRunSignature
{
}

public class MethodDefEntrySignature : ReadyToRunSignature
{
public uint MethodDefToken { get; set; }
}

public class MethodRefEntrySignature : ReadyToRunSignature
{
public uint MethodRefToken { get; set; }
}

/// <summary>
/// Helper class for converting metadata tokens into their textual representation.
/// </summary>
Expand Down Expand Up @@ -39,11 +63,11 @@ public static string FormatHandle(MetadataReader metadataReader, Handle handle,
return formatter.EmitHandleName(handle, namespaceQualified, owningTypeOverride, signaturePrefix);
}

public static string FormatSignature(IAssemblyResolver assemblyResolver, ReadyToRunReader r2rReader, int imageOffset)
public static string FormatSignature(IAssemblyResolver assemblyResolver, ReadyToRunReader r2rReader, int imageOffset, out ReadyToRunSignature result)
{
SignatureDecoder decoder = new SignatureDecoder(assemblyResolver, r2rReader.GetGlobalMetadataReader(), r2rReader, imageOffset);
string result = decoder.ReadR2RSignature();
return result;
string answer = decoder.ReadR2RSignature(out result);
return answer;
}

/// <summary>
Expand Down Expand Up @@ -518,13 +542,14 @@ public CorElementType PeekElementType()
/// by custom encoding per fixup type.
/// </summary>
/// <returns></returns>
public string ReadR2RSignature()
public string ReadR2RSignature(out ReadyToRunSignature result)
{
result = null;
StringBuilder builder = new StringBuilder();
int startOffset = _offset;
try
{
ParseSignature(builder);
result = ParseSignature(builder);
EmitSignatureBinaryFrom(builder, startOffset);
}
catch (Exception ex)
Expand Down Expand Up @@ -634,7 +659,7 @@ private void EmitSignatureBinaryFrom(StringBuilder builder, int startOffset)
/// Parse the signature into a given output string builder.
/// </summary>
/// <param name="builder">Output signature builder</param>
private void ParseSignature(StringBuilder builder)
private ReadyToRunSignature ParseSignature(StringBuilder builder)
{
uint fixupType = ReadByte();
EmitInlineSignatureBinaryBytes(builder, 1);
Expand All @@ -650,23 +675,26 @@ private void ParseSignature(StringBuilder builder)
moduleDecoder = new SignatureDecoder(_options, refAsmEcmaReader, _image, _offset, refAsmEcmaReader, _contextReader);
}

moduleDecoder.ParseSignature((ReadyToRunFixupKind)fixupType, builder);
ReadyToRunSignature result = moduleDecoder.ParseSignature((ReadyToRunFixupKind)fixupType, builder);
_offset = moduleDecoder.Offset;
return result;
}

/// <summary>
/// Parse the signature with a given fixup type after module overrides have been resolved.
/// </summary>
/// <param name="fixupType">Fixup type to parse</param>
/// <param name="builder">Output signature builder</param>
private void ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder)
private ReadyToRunSignature ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder)
{
ReadyToRunSignature result = new TodoSignature();
switch (fixupType)
{
case ReadyToRunFixupKind.ThisObjDictionaryLookup:
builder.Append("THISOBJ_DICTIONARY_LOOKUP @ ");
ParseType(builder);
builder.Append(": ");
// It looks like ReadyToRunSignature is potentially a composite pattern
ParseSignature(builder);
break;

Expand Down Expand Up @@ -702,15 +730,17 @@ private void ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder
break;

case ReadyToRunFixupKind.MethodEntry_DefToken:
ParseMethodDefToken(builder, owningTypeOverride: null);
uint methodDefToken = ParseMethodDefToken(builder, owningTypeOverride: null);
builder.Append(" (METHOD_ENTRY");
builder.Append(_options.Naked ? ")" : "_DEF_TOKEN)");
result = new MethodDefEntrySignature { MethodDefToken = methodDefToken };
break;

case ReadyToRunFixupKind.MethodEntry_RefToken:
ParseMethodRefToken(builder, owningTypeOverride: null);
uint methodRefToken = ParseMethodRefToken(builder, owningTypeOverride: null);
builder.Append(" (METHOD_ENTRY");
builder.Append(_options.Naked ? ")" : "_REF_TOKEN)");
result = new MethodRefEntrySignature { MethodRefToken = methodRefToken };
break;


Expand Down Expand Up @@ -909,6 +939,7 @@ private void ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder
builder.Append(string.Format("Unknown fixup type: {0:X2}", fixupType));
break;
}
return result;
}

/// <summary>
Expand Down Expand Up @@ -1235,7 +1266,7 @@ private void ParseMethod(StringBuilder builder)
/// Read a methodDef token from the signature and output the corresponding object to the builder.
/// </summary>
/// <param name="builder">Output string builder</param>
private void ParseMethodDefToken(StringBuilder builder, string owningTypeOverride)
private uint ParseMethodDefToken(StringBuilder builder, string owningTypeOverride)
{
StringBuilder signaturePrefixBuilder = new StringBuilder();
uint methodDefToken = ReadUIntAndEmitInlineSignatureBinary(signaturePrefixBuilder) | (uint)CorTokenType.mdtMethodDef;
Expand All @@ -1245,14 +1276,15 @@ private void ParseMethodDefToken(StringBuilder builder, string owningTypeOverrid
namespaceQualified: true,
owningTypeOverride: owningTypeOverride,
signaturePrefix: signaturePrefixBuilder.ToString()));
return methodDefToken;
}

/// <summary>
/// Read a memberRef token from the signature and output the corresponding object to the builder.
/// </summary>
/// <param name="builder">Output string builder</param>
/// <param name="owningTypeOverride">Explicit owning type override</param>
private void ParseMethodRefToken(StringBuilder builder, string owningTypeOverride)
private uint ParseMethodRefToken(StringBuilder builder, string owningTypeOverride)
{
StringBuilder signaturePrefixBuilder = new StringBuilder();
uint methodRefToken = ReadUIntAndEmitInlineSignatureBinary(signaturePrefixBuilder) | (uint)CorTokenType.mdtMemberRef;
Expand All @@ -1262,6 +1294,7 @@ private void ParseMethodRefToken(StringBuilder builder, string owningTypeOverrid
namespaceQualified: false,
owningTypeOverride: owningTypeOverride,
signaturePrefix: signaturePrefixBuilder.ToString()));
return methodRefToken;
}

/// <summary>
Expand Down

0 comments on commit cf1f24b

Please sign in to comment.