Skip to content

Commit 0fd7a3f

Browse files
authored
R2RDump improvements (#46833)
* Fix handling of module override token in signature parser. When the override is present, a new SignatureDecoder is created and used as the decoder for the final signature with the fixup kind (and module override flag which is stored in the upper bit of the fixup kind byte) already parsed. This causes the remainder of the signature to be parsed as a full R2R signature which is now missing the fixup type. * Instead of creating a new decoder when a module override is present, set up the initial decoder's metadata reader in the constructor by detecting the module override up front. * Fix `TryLocateNativeReadyToRunHeader` to swallow `BadImageFormatException` and return true / false whether the image has a native R2R header (for composite images). * Running R2RDump on IL assemblies with no R2R now emits an error message that the assembly is not R2R instead of an unhelpful error about some RVA offset conversion failing.
1 parent fde73e0 commit 0fd7a3f

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -481,12 +481,21 @@ public IReadOnlyDictionary<TMethod, ReadyToRunMethod> GetCustomMethodToRuntimeFu
481481

482482
private bool TryLocateNativeReadyToRunHeader()
483483
{
484-
PEExportTable exportTable = CompositeReader.GetExportTable();
485-
if (exportTable.TryGetValue("RTR_HEADER", out _readyToRunHeaderRVA))
484+
try
486485
{
487-
_composite = true;
488-
return true;
486+
PEExportTable exportTable = CompositeReader.GetExportTable();
487+
if (exportTable.TryGetValue("RTR_HEADER", out _readyToRunHeaderRVA))
488+
{
489+
_composite = true;
490+
return true;
491+
}
489492
}
493+
catch (BadImageFormatException)
494+
{
495+
// MSIL assemblies with no ready-to-run payload typically have no export table
496+
return false;
497+
}
498+
490499
return false;
491500
}
492501

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,15 @@ protected void UpdateOffset(int offset)
458458
/// <param name="offset">Signature offset within the PE file byte array</param>
459459
public R2RSignatureDecoder(IR2RSignatureTypeProvider<TType, TMethod, TGenericContext> provider, TGenericContext context, MetadataReader metadataReader, ReadyToRunReader r2rReader, int offset)
460460
{
461-
_metadataReader = metadataReader;
462-
_outerReader = metadataReader;
463461
Context = context;
464462
_provider = provider;
465463
_image = r2rReader.Image;
466464
_originalOffset = _offset = offset;
467465
_contextReader = r2rReader;
466+
MetadataReader moduleOverrideMetadataReader = TryGetModuleOverrideMetadataReader();
467+
_metadataReader = moduleOverrideMetadataReader ?? metadataReader;
468+
_outerReader = moduleOverrideMetadataReader ?? metadataReader;
469+
Reset();
468470
}
469471

470472
/// <summary>
@@ -480,11 +482,27 @@ public R2RSignatureDecoder(IR2RSignatureTypeProvider<TType, TMethod, TGenericCon
480482
{
481483
Context = context;
482484
_provider = provider;
483-
_metadataReader = metadataReader;
484485
_image = signature;
485486
_originalOffset = _offset = offset;
486-
_outerReader = outerReader;
487487
_contextReader = contextReader;
488+
MetadataReader moduleOverrideMetadataReader = TryGetModuleOverrideMetadataReader();
489+
_metadataReader = moduleOverrideMetadataReader ?? metadataReader;
490+
_outerReader = moduleOverrideMetadataReader ?? outerReader;
491+
Reset();
492+
}
493+
494+
private MetadataReader TryGetModuleOverrideMetadataReader()
495+
{
496+
bool moduleOverride = (ReadByte() & (byte)ReadyToRunFixupKind.ModuleOverride) != 0;
497+
// Check first byte for a module override being encoded
498+
if (moduleOverride)
499+
{
500+
int moduleIndex = (int)ReadUInt();
501+
IAssemblyMetadata refAsmEcmaReader = _contextReader.OpenReferenceAssembly(moduleIndex);
502+
return refAsmEcmaReader.MetadataReader;
503+
}
504+
505+
return null;
488506
}
489507

490508
/// <summary>
@@ -1098,17 +1116,15 @@ private ReadyToRunSignature ParseSignature(StringBuilder builder)
10981116
bool moduleOverride = (fixupType & (byte)ReadyToRunFixupKind.ModuleOverride) != 0;
10991117
SignatureDecoder moduleDecoder = this;
11001118

1101-
// Check first byte for a module override being encoded
1119+
// Check first byte for a module override being encoded. The metadata reader for the module
1120+
// override is configured in the R2RSignatureDecoder constructor.
11021121
if (moduleOverride)
11031122
{
11041123
fixupType &= ~(uint)ReadyToRunFixupKind.ModuleOverride;
1105-
int moduleIndex = (int)ReadUIntAndEmitInlineSignatureBinary(builder);
1106-
IAssemblyMetadata refAsmEcmaReader = _contextReader.OpenReferenceAssembly(moduleIndex);
1107-
moduleDecoder = new SignatureDecoder(Context.AssemblyResolver, Context.Options, refAsmEcmaReader.MetadataReader, _image, Offset, refAsmEcmaReader.MetadataReader, _contextReader);
1124+
ReadUIntAndEmitInlineSignatureBinary(builder);
11081125
}
11091126

1110-
ReadyToRunSignature result = moduleDecoder.ParseSignature((ReadyToRunFixupKind)fixupType, builder);
1111-
UpdateOffset(moduleDecoder.Offset);
1127+
ReadyToRunSignature result = ParseSignature((ReadyToRunFixupKind)fixupType, builder);
11121128
return result;
11131129
}
11141130

0 commit comments

Comments
 (0)