using System;
using System.Collections.Generic;
using System.IO;
+using System.Reflection;
using System.Reflection.PortableExecutable;
using System.Runtime.InteropServices;
using System.Text;
public class PdbWriter
{
+ private const string DiaSymReaderLibrary = "Microsoft.DiaSymReader.Native";
+
string _pdbPath;
PDBExtraData _pdbExtraData;
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();
_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
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
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)" />