Use latest DiaSymReader and support ARM64 host in crossgen2 (#49841)
authorAnton Lapounov <antonl@microsoft.com>
Fri, 19 Mar 2021 09:56:16 +0000 (02:56 -0700)
committerGitHub <noreply@github.com>
Fri, 19 Mar 2021 09:56:16 +0000 (02:56 -0700)
src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs
src/coreclr/tools/aot/crossgen2/crossgen2.csproj

index 620fb78..1483cfb 100644 (file)
@@ -4,6 +4,7 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Reflection;
 using System.Reflection.PortableExecutable;
 using System.Runtime.InteropServices;
 using System.Text;
@@ -73,6 +74,8 @@ namespace ILCompiler.Diagnostics
 
     public class PdbWriter
     {
+        private const string DiaSymReaderLibrary = "Microsoft.DiaSymReader.Native";
+
         string _pdbPath;
         PDBExtraData _pdbExtraData;
 
@@ -86,34 +89,33 @@ namespace ILCompiler.Diagnostics
         UIntPtr _pdbMod;
         ISymNGenWriter2 _ngenWriter;
 
-        private const string DiaSymReaderModuleName32 = "Microsoft.DiaSymReader.Native.x86.dll";
-        private const string DiaSymReaderModuleName64 = "Microsoft.DiaSymReader.Native.amd64.dll";
-
-        private const string CreateNGenPdbWriterFactoryName = "CreateNGenPdbWriter";
-
-        [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)]
-        [DllImport(DiaSymReaderModuleName32, EntryPoint = CreateNGenPdbWriterFactoryName, PreserveSig = false)]
-        private extern static void CreateNGenPdbWriter32([MarshalAs(UnmanagedType.LPWStr)] string ngenImagePath, [MarshalAs(UnmanagedType.LPWStr)] string pdbPath, [MarshalAs(UnmanagedType.IUnknown)] out object ngenPdbWriter);
-
-        [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)]
-        [DllImport(DiaSymReaderModuleName64, EntryPoint = CreateNGenPdbWriterFactoryName, PreserveSig = false)]
-        private extern static void CreateNGenPdbWriter64([MarshalAs(UnmanagedType.LPWStr)] string ngenImagePath, [MarshalAs(UnmanagedType.LPWStr)] string pdbPath, [MarshalAs(UnmanagedType.IUnknown)] out object ngenPdbWriter);
-
-        private static ISymNGenWriter2 CreateNGenWriter(string ngenImagePath, string pdbPath)
+        static PdbWriter()
         {
-            object instance;
+            NativeLibrary.SetDllImportResolver(typeof(PdbWriter).Assembly, DllImportResolver);
+        }
 
-            if (IntPtr.Size == 4)
-            {
-                CreateNGenPdbWriter32(ngenImagePath, pdbPath, out instance);
-            }
-            else
+        private static IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
+        {
+            IntPtr libraryHandle = IntPtr.Zero;
+            if (libraryName == DiaSymReaderLibrary)
             {
-                CreateNGenPdbWriter64(ngenImagePath, pdbPath, out instance);
+                string archSuffix = RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant();
+                if (archSuffix == "x64")
+                {
+                    archSuffix = "amd64";
+                }
+                libraryHandle = NativeLibrary.Load(DiaSymReaderLibrary + "." + archSuffix + ".dll", assembly, searchPath);
             }
-            return (ISymNGenWriter2)instance;
+            return libraryHandle;
         }
 
+        [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)]
+        [DllImport(DiaSymReaderLibrary, PreserveSig = false)]
+        private extern static void CreateNGenPdbWriter(
+            [MarshalAs(UnmanagedType.LPWStr)] string ngenImagePath,
+            [MarshalAs(UnmanagedType.LPWStr)] string pdbPath,
+            [MarshalAs(UnmanagedType.Interface)] out ISymNGenWriter2 ngenPdbWriter);
+
         public PdbWriter(string pdbPath, PDBExtraData pdbExtraData)
         {
             SymDocument unknownDocument = new SymDocument();
@@ -209,10 +211,10 @@ namespace ILCompiler.Diagnostics
                 _pdbFilePath = Path.Combine(_pdbPath, dllNameWithoutExtension + ".ni.pdb");
             }
 
-            // Delete any preexisting PDB file upfront otherwise CreateNGenWriter silently opens it
+            // Delete any preexisting PDB file upfront, otherwise CreateNGenPdbWriter silently opens it
             File.Delete(_pdbFilePath);
 
-            _ngenWriter = CreateNGenWriter(dllPath, _pdbFilePath);
+            CreateNGenPdbWriter(dllPath, _pdbFilePath, out _ngenWriter);
 
             {
                 // PDB file is now created. Get its path and update _pdbFilePath so the PDB file
index 87e123a..e30e6d1 100644 (file)
       CopyToOutputDirectory="PreserveNewest"
       CopyToPublishDirectory="PreserveNewest"
       Link="%(FileName)%(Extension)"
-     />
+      />
 
     <Content Include="$(RuntimeBinDir)$(NativeArchFolder)$(LibPrefix)clrjit_*_$(TargetArchitecture)$(LibSuffix)"
       CopyToOutputDirectory="PreserveNewest"
       CopyToPublishDirectory="PreserveNewest"
       Link="%(FileName)%(Extension)"
-     />
+      />
   </ItemGroup>
 
   <!-- On windows we can re-use the clrjit.dll produced in the build for aot compilation. On Linux
@@ -89,7 +89,7 @@
       CopyToOutputDirectory="PreserveNewest"
       CopyToPublishDirectory="PreserveNewest"
       Link="$(LibPrefix)clrjit_$(TargetSpec)$(LibSuffix)"
-     />
+      />
 
     <Content Include="$(RuntimeBinDir)/pgort*.dll"
       CopyToOutputDirectory="PreserveNewest"
       Link="%(FileName)%(Extension)"
       Condition="'$(PgoInstrument)' != ''"
       />
+
+    <PackageReference Include="Microsoft.DiaSymReader.Native"
+      Version="$(MicrosoftDiaSymReaderNativeVersion)"
+      IsImplicitlyDefined="true"
+      ExcludeAssets="all"
+      GeneratePathProperty="true"
+      />
   </ItemGroup>
 
-  <Target Name="CreateCrossTargetingPackage" AfterTargets="Build" Condition="'$(CrossHostArch)' != ''">
+  <PropertyGroup Condition="'$(TargetOS)' == 'windows'">
+    <!-- DiaSymReader for the host architecture, which is used for cross-compilation -->
+    <DiaSymReaderCrossArch>$(CrossHostArch)</DiaSymReaderCrossArch>
+    <DiaSymReaderCrossArch Condition="'$(CrossHostArch)' == 'x64'">amd64</DiaSymReaderCrossArch>
+    <DiaSymReaderCrossArchFileName>Microsoft.DiaSymReader.Native.$(DiaSymReaderCrossArch).dll</DiaSymReaderCrossArchFileName>
+    <DiaSymReaderCrossArchPath>$(PkgMicrosoft_DiaSymReader_Native)\runtimes\win\native\$(DiaSymReaderCrossArchFileName)</DiaSymReaderCrossArchPath>
+
+    <!-- DiaSymReader for the target architecture, which is placed into the package -->
+    <DiaSymReaderTargetArch>$(TargetArchitecture)</DiaSymReaderTargetArch>
+    <DiaSymReaderTargetArch Condition="'$(TargetArchitecture)' == 'x64'">amd64</DiaSymReaderTargetArch>
+    <DiaSymReaderTargetArchFileName>Microsoft.DiaSymReader.Native.$(DiaSymReaderTargetArch).dll</DiaSymReaderTargetArchFileName>
+    <DiaSymReaderTargetArchPath>$(PkgMicrosoft_DiaSymReader_Native)\runtimes\win\native\$(DiaSymReaderTargetArchFileName)</DiaSymReaderTargetArchPath>
+  </PropertyGroup>
+
+  <ItemGroup Condition="'$(TargetOS)' == 'windows'">
+    <Content Include="$(DiaSymReaderTargetArchPath)"
+      CopyToOutputDirectory="PreserveNewest"
+      CopyToPublishDirectory="PreserveNewest"
+      Link="%(FileName)%(Extension)"
+      />
+  </ItemGroup>
 
+  <Target Name="CreateCrossTargetingPackage" AfterTargets="Build" Condition="'$(CrossHostArch)' != ''">
     <PropertyGroup>
       <CrossPackageFolder>$(RuntimeBinDir)$(CrossHostArch)\crossgen2</CrossPackageFolder>
     </PropertyGroup>
 
     <ItemGroup>
-      <PackageFile Include="$(RuntimeBinDir)crossgen2\*"
-        Exclude="$(RuntimeBinDir)crossgen2\$(JitInterfaceLibraryName);$(RuntimeBinDir)crossgen2\$(LibPrefix)clrjit_*$(LibSuffix)" />
+      <!-- The list of files specific to the target architecture, which we need to replace -->
+      <TargetArchSpecificFiles Include="$(JitInterfaceLibraryName);$(LibPrefix)clrjit_*$(LibSuffix)" />
+      <TargetArchSpecificFiles Include="$(DiaSymReaderTargetArchFileName)" Condition="'$(TargetOS)' == 'windows'" />
+
+      <PackageFile Include="$(RuntimeBinDir)crossgen2\*" Exclude="@(TargetArchSpecificFiles->'$(RuntimeBinDir)crossgen2\%(Identity)')" />
       <PackageFile Include="$(RuntimeBinDir)$(CrossHostArch)\$(LibPrefix)jitinterface_$(CrossHostArch)$(LibSuffix)" />
+      <PackageFile Include="$(DiaSymReaderCrossArchPath)" Condition="'$(TargetOS)' == 'windows'" />
     </ItemGroup>
 
     <MakeDir Directories="$(CrossPackageFolder)" />