From b5911937adf121661873ce7bab03dbebac1ec1e7 Mon Sep 17 00:00:00 2001 From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com> Date: Tue, 23 May 2023 11:32:36 -0700 Subject: [PATCH] Dogfood ComInterfaceGenerator in crossgen2 (#84643) --- .../ILCompiler.Diagnostics/AssemblyInfo.cs | 3 + .../ILCompilerComWrappers.cs | 32 ---- .../ILCompiler.Diagnostics/ISymNGenWriter.cs | 27 ++-- .../aot/ILCompiler.Diagnostics/PdbWriter.cs | 18 +-- .../SymNgenWriterWrapper.cs | 150 ------------------ 5 files changed, 21 insertions(+), 209 deletions(-) delete mode 100644 src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompilerComWrappers.cs delete mode 100644 src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/AssemblyInfo.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/AssemblyInfo.cs index 02ff300e617e8..60e68309575e6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/AssemblyInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/AssemblyInfo.cs @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Runtime.CompilerServices; + +[assembly: DisableRuntimeMarshalling] namespace ILCompiler.Diagnostics { diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompilerComWrappers.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompilerComWrappers.cs deleted file mode 100644 index 5f4bada59cb0a..0000000000000 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompilerComWrappers.cs +++ /dev/null @@ -1,32 +0,0 @@ - -using System; -using System.Collections; -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace Microsoft.DiaSymReader -{ - internal sealed unsafe class ILCompilerComWrappers : ComWrappers - { - protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) - { - // passing the managed object to COM is not currently supported - throw new NotImplementedException(); - } - - protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags) - { - // Assert use of the UniqueInstance flag since the returned Native Object Wrapper always - // supports IDisposable and its Dispose will always release and suppress finalization. - // If the wrapper doesn't always support IDisposable the assert can be relaxed. - Debug.Assert(flags.HasFlag(CreateObjectFlags.UniqueInstance)); - - // Throw an exception if the type is not supported by the implementation. - // Null can be returned as well, but an ArgumentNullException will be thrown for - // the consumer of this ComWrappers instance. - return SymNgenWriterWrapper.CreateIfSupported(externalComObject) ?? throw new NotSupportedException(); - } - - protected override void ReleaseObjects(IEnumerable objects) => throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ISymNGenWriter.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ISymNGenWriter.cs index 320bbab86c71a..abfd1119f2467 100644 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ISymNGenWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ISymNGenWriter.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; using System.Security; using System.Text; @@ -38,10 +39,10 @@ namespace Microsoft.DiaSymReader /// }; /// /// - internal interface ISymNGenWriter + [GeneratedComInterface] + [Guid("D682FD12-43dE-411C-811B-BE8404CEA126")] + internal partial interface ISymNGenWriter { - public static readonly Guid IID = new Guid("D682FD12-43dE-411C-811B-BE8404CEA126"); - // Add a new public symbol to the NGEN PDB. void AddSymbol([MarshalAs(UnmanagedType.BStr)] string pSymbol, ushort iSection, @@ -110,21 +111,10 @@ internal enum OMF : ushort /// }; /// /// - internal interface ISymNGenWriter2 : ISymNGenWriter + [GeneratedComInterface] + [Guid("B029E51B-4C55-4fe2-B993-9F7BC1F10DB4")] + internal partial interface ISymNGenWriter2 : ISymNGenWriter { - public readonly static new Guid IID = new Guid("B029E51B-4C55-4fe2-B993-9F7BC1F10DB4"); - - // Add a new public symbol to the NGEN PDB. - new void AddSymbol([MarshalAs(UnmanagedType.BStr)] string pSymbol, - ushort iSection, - ulong rva); - - // Adds a new section to the NGEN PDB. - new void AddSection(ushort iSection, - OMF flags, - int offset, - int cb); - void OpenModW([MarshalAs(UnmanagedType.LPWStr)] string wszModule, [MarshalAs(UnmanagedType.LPWStr)] string wszObjFile, out UIntPtr ppmod); @@ -143,7 +133,8 @@ void ModAddSecContribEx( uint dwRelocCrc); void QueryPDBNameExW( - [MarshalAs(UnmanagedType.LPWStr)] char[] pdb, + [MarshalUsing(CountElementName = nameof(cchMax))] + char[] pdb, IntPtr cchMax); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs index 62bdb023525e6..9ec90146a471c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs @@ -7,6 +7,7 @@ using System.Reflection; using System.Reflection.PortableExecutable; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; using System.Text; using Internal.TypeSystem; @@ -73,7 +74,7 @@ public bool Equals(SymDocument other) } } - public class PdbWriter + public partial class PdbWriter { private const string DiaSymReaderLibrary = "Microsoft.DiaSymReader.Native"; @@ -89,7 +90,7 @@ public class PdbWriter Dictionary _documentToChecksumOffsetMapping; UIntPtr _pdbMod; - SymNgenWriterWrapper _ngenWriter; + ISymNGenWriter2 _ngenWriter; static PdbWriter() { @@ -112,10 +113,10 @@ private static IntPtr DllImportResolver(string libraryName, Assembly assembly, D } [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)] - [DllImport(DiaSymReaderLibrary, PreserveSig = false)] - private extern static void CreateNGenPdbWriter( - [MarshalAs(UnmanagedType.LPWStr)] string ngenImagePath, - [MarshalAs(UnmanagedType.LPWStr)] string pdbPath, + [LibraryImport(DiaSymReaderLibrary, StringMarshalling = StringMarshalling.Utf16)] + private static partial void CreateNGenPdbWriter( + string ngenImagePath, + string pdbPath, out IntPtr ngenPdbWriterPtr); public PdbWriter(string pdbPath, PDBExtraData pdbExtraData, TargetDetails target) @@ -145,7 +146,6 @@ public void WritePDBData(string dllPath, IEnumerable methods) if ((_ngenWriter != null) && (_pdbMod != UIntPtr.Zero)) { _ngenWriter.CloseMod(_pdbMod); - _ngenWriter?.Dispose(); } } @@ -208,9 +208,9 @@ private void WritePDBDataHelper(string dllPath, IEnumerable methods) // Delete any preexisting PDB file upfront, otherwise CreateNGenPdbWriter silently opens it File.Delete(_pdbFilePath); - var comWrapper = new ILCompilerComWrappers(); + var comWrapper = new StrategyBasedComWrappers(); CreateNGenPdbWriter(dllPath, _pdbFilePath, out var pdbWriterInst); - _ngenWriter = (SymNgenWriterWrapper)comWrapper.GetOrCreateObjectForComInstance(pdbWriterInst, CreateObjectFlags.UniqueInstance); + _ngenWriter = (ISymNGenWriter2)comWrapper.GetOrCreateObjectForComInstance(pdbWriterInst, CreateObjectFlags.UniqueInstance); { // PDB file is now created. Get its path and update _pdbFilePath so the PDB file diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs deleted file mode 100644 index 619f319888fc9..0000000000000 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs +++ /dev/null @@ -1,150 +0,0 @@ - -using System; -using System.Runtime.InteropServices; -using System.Text; - -#nullable enable - -namespace Microsoft.DiaSymReader -{ - internal class SymNgenWriterWrapper : ISymNGenWriter2, IDisposable - { - private bool _isDisposed = false; - public IntPtr ISymNGenWriter2Inst { get; } - - private SymNgenWriterWrapper(IntPtr writer2Inst) - { - ISymNGenWriter2Inst = writer2Inst; - } - - public static SymNgenWriterWrapper? CreateIfSupported(IntPtr ptr) - { - var iid = ISymNGenWriter2.IID; - int hr = Marshal.QueryInterface(ptr, ref iid, out IntPtr ngenWriterInst); - Marshal.Release(ptr); - if (hr != 0) - { - return null; - } - - return new SymNgenWriterWrapper(ngenWriterInst); - } - - ~SymNgenWriterWrapper() - { - DisposeInternal(); - } - - public void Dispose() - { - DisposeInternal(); - GC.SuppressFinalize(this); - } - - private void DisposeInternal() - { - if (_isDisposed) - { - return; - } - Marshal.Release(ISymNGenWriter2Inst); - _isDisposed = true; - } - - public unsafe void AddSymbol(string pSymbol, ushort iSection, ulong rva) - { - IntPtr strLocal = Marshal.StringToBSTR(pSymbol); - var inst = ISymNGenWriter2Inst; - var func = (delegate* unmanaged)(*(*(void***)inst + 3 /* ISymNGenWriter2.AddSymbol slot */)); - int hr = func(inst, strLocal, iSection, rva); - Marshal.FreeBSTR(strLocal); - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - } - - public unsafe void AddSection(ushort iSection, OMF flags, int offset, int cb) - { - var inst = ISymNGenWriter2Inst; - var func = (delegate* unmanaged)(*(*(void***)inst + 4)); - int hr = func(inst, iSection, flags, offset, cb); - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - } - - public unsafe void OpenModW(string wszModule, string wszObjFile, out UIntPtr ppmod) - { - var inst = ISymNGenWriter2Inst; - fixed (char* wszModulePtr = wszModule) - fixed (char* wszObjFilePtr = wszObjFile) - { - UIntPtr ppmodPtr; - var func = (delegate* unmanaged)(*(*(void***)inst + 5)); - int hr = func(inst, wszModulePtr, wszObjFilePtr, &ppmodPtr); - ppmod = ppmodPtr; - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - } - } - - public unsafe void CloseMod(UIntPtr pmod) - { - var inst = ISymNGenWriter2Inst; - var func = (delegate* unmanaged)(*(*(void***)inst + 6)); - int hr = func(inst, pmod); - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - } - - public unsafe void ModAddSymbols(UIntPtr pmod, byte[] pbSym, int cb) - { - fixed (byte* pbSymPtr = pbSym) - { - var pbSymLocal = (IntPtr)pbSymPtr; - var inst = ISymNGenWriter2Inst; - var func = (delegate* unmanaged)(*(*(void***)inst + 7)); - int hr = func(inst, pmod, pbSymLocal, cb); - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - } - } - - public unsafe void ModAddSecContribEx(UIntPtr pmod, ushort isect, int off, int cb, uint dwCharacteristics, uint dwDataCrc, uint dwRelocCrc) - { - var inst = ISymNGenWriter2Inst; - var func = (delegate* unmanaged)(*(*(void***)inst + 8)); - int hr = func(inst, pmod, isect, off, cb, dwCharacteristics, dwDataCrc, dwRelocCrc); - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - } - - public unsafe void QueryPDBNameExW(char[] pdb, IntPtr cchMax) - { - fixed (char* pdbPtr = pdb) - { - var pdbLocal = (IntPtr)pdbPtr; - var inst = ISymNGenWriter2Inst; - var func = (delegate* unmanaged)(*(*(void***)inst + 9)); - int hr = func(inst, pdbPtr, cchMax); - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - } - } - - void ISymNGenWriter.AddSymbol(string pSymbol, ushort iSection, ulong rva) => AddSymbol(pSymbol, iSection, rva); - void ISymNGenWriter.AddSection(ushort iSection, OMF flags, int offset, int cb) => AddSection(iSection, flags, offset, cb); - } -}