From 17b8ad1e6306b49d4cf82841e99b6dc738a38af1 Mon Sep 17 00:00:00 2001 From: Tomas Date: Thu, 9 Dec 2021 23:34:08 +0100 Subject: [PATCH 1/3] Skip native composite ReadyToRun images as inputs to Crossgen2 According to the issue https://github.com/dotnet/runtime/issues/49247 a known pre-existing Crossgen2 bug is that it fails when presented with the components of a previous Crossgen2 compilation in the composite mode. This is because Crossgen2 lacks proper logic to recognize the composite images and mistakes them for currently unsupported managed C++ MSIL assemblies. This change adds the extra check; I have also unified it between Crossgen2 and R2RDump. Thanks Tomas --- .../PEReaderExtensions.cs | 11 +++++++++ .../ReadyToRunReader.cs | 11 ++------- src/coreclr/tools/aot/crossgen2.sln | 24 +++++++++++++++++-- src/coreclr/tools/aot/crossgen2/Program.cs | 7 ++++++ .../aot/crossgen2/Properties/Resources.resx | 3 +++ .../tools/aot/crossgen2/crossgen2.props | 1 + 6 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PEReaderExtensions.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PEReaderExtensions.cs index fd0ce63bb6be6f..97fce016e68bda 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PEReaderExtensions.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PEReaderExtensions.cs @@ -124,5 +124,16 @@ public static PEExportTable GetExportTable(this PEReader reader) { return PEExportTable.Parse(reader); } + + /// + /// Check whether the file is a ReadyToRun image and returns the RVA of its ReadyToRun header if positive. + /// + /// PEReader representing the executable to check for the presence of ReadyToRun header + /// RVA of the ReadyToRun header if available, 0 when not + /// true when the PEReader represents a ReadyToRun image, false otherwise + public static bool TryGetReadyToRunHeader(this PEReader reader, out int rva) + { + return reader.GetExportTable().TryGetValue("RTR_HEADER", out rva); + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index a8962fa2e3c1d1..4eab54b43b8628 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -447,7 +447,7 @@ public static bool IsReadyToRunImage(PEReader peReader) if ((peReader.PEHeaders.CorHeader.Flags & CorFlags.ILLibrary) == 0) { - return TryLocateNativeReadyToRunHeader(peReader, out _); + return peReader.TryGetReadyToRunHeader(out _); } else { @@ -565,16 +565,9 @@ public IReadOnlyDictionary GetCustomMethodToRuntimeFu return customMethods; } - private static bool TryLocateNativeReadyToRunHeader(PEReader reader, out int readyToRunHeaderRVA) - { - PEExportTable exportTable = reader.GetExportTable(); - - return exportTable.TryGetValue("RTR_HEADER", out readyToRunHeaderRVA); - } - private bool TryLocateNativeReadyToRunHeader() { - _composite = TryLocateNativeReadyToRunHeader(CompositeReader, out _readyToRunHeaderRVA); + _composite = CompositeReader.TryGetReadyToRunHeader(out _readyToRunHeaderRVA); return _composite; } diff --git a/src/coreclr/tools/aot/crossgen2.sln b/src/coreclr/tools/aot/crossgen2.sln index ac541c0a78d16a..4727feaef44e4f 100644 --- a/src/coreclr/tools/aot/crossgen2.sln +++ b/src/coreclr/tools/aot/crossgen2.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29123.88 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31612.314 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "crossgen2", "crossgen2\crossgen2.csproj", "{9B928D3E-06AB-45E5-BF79-F374F0AE3B98}" EndProject @@ -14,6 +14,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.TypeSystem.Ready EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.Diagnostics", "ILCompiler.Diagnostics\ILCompiler.Diagnostics.csproj", "{3EACD929-4725-4173-A845-734936BBDF87}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.Reflection.ReadyToRun", "ILCompiler.Reflection.ReadyToRun\ILCompiler.Reflection.ReadyToRun.csproj", "{0BB34BA1-1B3A-445C-9C04-0D710D1983F0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Checked|Any CPU = Checked|Any CPU @@ -122,6 +124,24 @@ Global {3EACD929-4725-4173-A845-734936BBDF87}.Release|x64.Build.0 = Release|Any CPU {3EACD929-4725-4173-A845-734936BBDF87}.Release|x86.ActiveCfg = Release|Any CPU {3EACD929-4725-4173-A845-734936BBDF87}.Release|x86.Build.0 = Release|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Checked|Any CPU.Build.0 = Debug|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Checked|x64.ActiveCfg = Debug|x64 + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Checked|x64.Build.0 = Debug|x64 + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Checked|x86.ActiveCfg = Debug|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Checked|x86.Build.0 = Debug|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Debug|x64.ActiveCfg = Debug|x64 + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Debug|x64.Build.0 = Debug|x64 + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Debug|x86.ActiveCfg = Debug|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Debug|x86.Build.0 = Debug|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Release|Any CPU.Build.0 = Release|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Release|x64.ActiveCfg = Release|x64 + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Release|x64.Build.0 = Release|x64 + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Release|x86.ActiveCfg = Release|Any CPU + {0BB34BA1-1B3A-445C-9C04-0D710D1983F0}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/coreclr/tools/aot/crossgen2/Program.cs b/src/coreclr/tools/aot/crossgen2/Program.cs index 4df45e3065e0d3..48236c146fbcc3 100644 --- a/src/coreclr/tools/aot/crossgen2/Program.cs +++ b/src/coreclr/tools/aot/crossgen2/Program.cs @@ -16,6 +16,8 @@ using Internal.TypeSystem; using Internal.TypeSystem.Ecma; +using ILCompiler.Reflection.ReadyToRun; + namespace ILCompiler { internal class Program @@ -764,6 +766,11 @@ private void CheckManagedCppInputFiles(IEnumerable inputPaths) foreach (string inputFilePath in inputPaths) { EcmaModule module = _typeSystemContext.GetModuleFromPath(inputFilePath); + if (module.PEReader.TryGetReadyToRunHeader(out int _)) + { + Console.WriteLine(SR.IgnoringCompositeImage, inputFilePath); + continue; + } if ((module.PEReader.PEHeaders.CorHeader.Flags & (CorFlags.ILLibrary | CorFlags.ILOnly)) == (CorFlags)0) { throw new CommandLineException(string.Format(SR.ManagedCppNotSupported, inputFilePath)); diff --git a/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx b/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx index 7a272037fd14f7..903ae55086e320 100644 --- a/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx +++ b/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx @@ -321,6 +321,9 @@ Error: managed C++ is not supported: '{0}' + + Ignoring composite native image: '{0}' + Verify that struct type layout and field offsets match between compile time and runtime. Use only for diagnostic purposes. diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2.props b/src/coreclr/tools/aot/crossgen2/crossgen2.props index e69b66ceecb3e2..f88c90bcfaad28 100644 --- a/src/coreclr/tools/aot/crossgen2/crossgen2.props +++ b/src/coreclr/tools/aot/crossgen2/crossgen2.props @@ -31,6 +31,7 @@ + From 727b813e17bdbc733939fa5fdc9713b5302fc1a1 Mon Sep 17 00:00:00 2001 From: Tomas Date: Fri, 10 Dec 2021 18:26:26 +0100 Subject: [PATCH 2/3] Fix dependencies --- .../tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj | 1 + src/coreclr/tools/aot/crossgen2/crossgen2.props | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index bce5efe4e0905e..8a1dc4eca0d174 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -102,6 +102,7 @@ + diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2.props b/src/coreclr/tools/aot/crossgen2/crossgen2.props index f88c90bcfaad28..e69b66ceecb3e2 100644 --- a/src/coreclr/tools/aot/crossgen2/crossgen2.props +++ b/src/coreclr/tools/aot/crossgen2/crossgen2.props @@ -31,7 +31,6 @@ - From 5b3f95d3775224a77acee535f7d76ff722f4c853 Mon Sep 17 00:00:00 2001 From: Tomas Date: Fri, 10 Dec 2021 21:09:01 +0100 Subject: [PATCH 3/3] Fix placement of native composite image check I have found out that my previous version of the change wasn't completely correct - the check was getting performed "too late" and so the potential composite image remained in the list of component assemblies and ended up getting rewritten to the output. I have moved it to an earlier point in command line processing. Thanks Tomas --- src/coreclr/tools/aot/crossgen2/Program.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/coreclr/tools/aot/crossgen2/Program.cs b/src/coreclr/tools/aot/crossgen2/Program.cs index 48236c146fbcc3..d4c693805f5e20 100644 --- a/src/coreclr/tools/aot/crossgen2/Program.cs +++ b/src/coreclr/tools/aot/crossgen2/Program.cs @@ -403,6 +403,12 @@ private int Run(string[] args) try { var module = _typeSystemContext.GetModuleFromPath(inputFile.Value); + if ((module.PEReader.PEHeaders.CorHeader.Flags & (CorFlags.ILLibrary | CorFlags.ILOnly)) == (CorFlags)0 + && module.PEReader.TryGetReadyToRunHeader(out int _)) + { + Console.WriteLine(SR.IgnoringCompositeImage, inputFile.Value); + continue; + } _allInputFilePaths.Add(inputFile.Key, inputFile.Value); inputFilePaths.Add(inputFile.Key, inputFile.Value); _referenceableModules.Add(module); @@ -766,11 +772,6 @@ private void CheckManagedCppInputFiles(IEnumerable inputPaths) foreach (string inputFilePath in inputPaths) { EcmaModule module = _typeSystemContext.GetModuleFromPath(inputFilePath); - if (module.PEReader.TryGetReadyToRunHeader(out int _)) - { - Console.WriteLine(SR.IgnoringCompositeImage, inputFilePath); - continue; - } if ((module.PEReader.PEHeaders.CorHeader.Flags & (CorFlags.ILLibrary | CorFlags.ILOnly)) == (CorFlags)0) { throw new CommandLineException(string.Format(SR.ManagedCppNotSupported, inputFilePath));