// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.FileFormats;
using Microsoft.SymbolStore;
using Microsoft.SymbolStore.KeyGenerators;
using System;
{
public class MetadataHelper
{
+ const int S_OK = 0;
+ const int E_FAIL = unchecked((int)0x80004005);
+
+ // HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)
+ const int E_INSUFFICIENT_BUFFER = unchecked((int)0x8007007a);
+
+ /// <summary>
+ /// Metadata locator helper for the DAC.
+ /// </summary>
+ /// <param name="imagePath">file name and path to module</param>
+ /// <param name="imageTimestamp">module timestamp</param>
+ /// <param name="imageSize">module image</param>
+ /// <param name="mvid">not used</param>
+ /// <param name="mdRva">not used</param>
+ /// <param name="flags">not used</param>
+ /// <param name="bufferSize">size of incoming buffer (pMetadata)</param>
+ /// <param name="pMetadata">pointer to buffer</param>
+ /// <param name="pMetadataSize">size of outgoing metadata</param>
+ /// <returns>HRESULT</returns>
public static int GetMetadataLocator(
[MarshalAs(UnmanagedType.LPWStr)] string imagePath,
uint imageTimestamp,
- uint imageSize,
- [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
+ uint imageSize,
+ [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
uint mdRva,
uint flags,
uint bufferSize,
IntPtr pMetadata,
IntPtr pMetadataSize)
{
- int hr = unchecked((int)0x80004005);
+ int hr = S_OK;
int dataSize = 0;
Debug.Assert(pMetadata != IntPtr.Zero);
-
- Stream peStream = null;
- if (imagePath != null && File.Exists(imagePath))
+ try
{
- peStream = SymbolReader.TryOpenFile(imagePath);
- }
- else if (SymbolReader.IsSymbolStoreEnabled())
- {
- SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
- peStream = SymbolReader.GetSymbolStoreFile(key)?.Stream;
- }
- if (peStream != null)
- {
- using (var peReader = new PEReader(peStream, PEStreamOptions.Default))
+ Stream peStream = null;
+ if (imagePath != null && File.Exists(imagePath))
+ {
+ peStream = SymbolReader.TryOpenFile(imagePath);
+ }
+ else if (SymbolReader.IsSymbolStoreEnabled())
+ {
+ SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
+ peStream = SymbolReader.GetSymbolStoreFile(key)?.Stream;
+ }
+ if (peStream != null)
{
- if (peReader.HasMetadata)
+ using (var peReader = new PEReader(peStream, PEStreamOptions.Default))
{
- PEMemoryBlock metadataInfo = peReader.GetMetadata();
- unsafe
+ if (peReader.HasMetadata)
{
- int size = Math.Min((int)bufferSize, metadataInfo.Length);
- Marshal.Copy(metadataInfo.GetContent().ToArray(), 0, pMetadata, size);
+ PEMemoryBlock metadataInfo = peReader.GetMetadata();
+ dataSize = metadataInfo.Length;
+ unsafe
+ {
+ int size = Math.Min((int)bufferSize, metadataInfo.Length);
+ Marshal.Copy(metadataInfo.GetContent().ToArray(), 0, pMetadata, size);
+ }
+ }
+ else
+ {
+ hr = E_FAIL;
}
- dataSize = metadataInfo.Length;
- hr = 0;
}
}
+ else
+ {
+ hr = E_FAIL;
+ }
+ }
+ catch (Exception ex) when
+ (ex is UnauthorizedAccessException ||
+ ex is BadImageFormatException ||
+ ex is InvalidVirtualAddressException ||
+ ex is IOException)
+ {
+ hr = E_FAIL;
}
-
if (pMetadataSize != IntPtr.Zero)
{
Marshal.WriteInt32(pMetadataSize, dataSize);
}
return hr;
}
+
+ /// <summary>
+ /// Metadata locator helper for the DAC.
+ /// </summary>
+ /// <param name="imagePath">file name and path to module</param>
+ /// <param name="imageTimestamp">module timestamp</param>
+ /// <param name="imageSize">module image</param>
+ /// <param name="localFilePath">local file path of the module</param>
+ /// <returns>HRESULT</returns>
+ public static int GetICorDebugMetadataLocator(
+ [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
+ uint imageTimestamp,
+ uint imageSize,
+ uint pathBufferSize,
+ IntPtr pPathBufferSize,
+ IntPtr pPathBuffer)
+ {
+ int hr = S_OK;
+ int actualSize = 0;
+
+ Debug.Assert(pPathBuffer != IntPtr.Zero);
+ try
+ {
+ if (SymbolReader.IsSymbolStoreEnabled())
+ {
+ SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
+ string localFilePath = SymbolReader.GetSymbolFile(key);
+ localFilePath += "\0"; // null terminate the string
+ actualSize = localFilePath.Length;
+
+ if (pathBufferSize > actualSize)
+ {
+ Marshal.Copy(localFilePath.ToCharArray(), 0, pPathBuffer, actualSize);
+ }
+ else
+ {
+ hr = E_INSUFFICIENT_BUFFER;
+ }
+ }
+ else
+ {
+ hr = E_FAIL;
+ }
+ }
+ catch (Exception ex) when
+ (ex is UnauthorizedAccessException ||
+ ex is BadImageFormatException ||
+ ex is InvalidVirtualAddressException ||
+ ex is IOException)
+ {
+ hr = E_FAIL;
+ }
+
+ if (pPathBufferSize != IntPtr.Zero)
+ {
+ Marshal.WriteInt32(pPathBufferSize, actualSize);
+ }
+
+ return hr;
+ }
}
}
IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "GetLocalVariableName", (void **)&g_SOSNetCoreCallbacks.GetLocalVariableNameDelegate));
IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "GetLineByILOffset", (void **)&g_SOSNetCoreCallbacks.GetLineByILOffsetDelegate));
IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, MetadataHelperClassName, "GetMetadataLocator", (void **)&g_SOSNetCoreCallbacks.GetMetadataLocatorDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, MetadataHelperClassName, "GetICorDebugMetadataLocator", (void **)&g_SOSNetCoreCallbacks.GetICorDebugMetadataLocatorDelegate));
g_hostingInitialized = true;
return Status;
return g_SOSNetCoreCallbacks.GetMetadataLocatorDelegate(imagePath, imageTimestamp, imageSize, mvid, mdRva, flags, bufferSize, buffer, dataSize);
}
+/**********************************************************************\
+ * Returns the metadata from a local or downloaded assembly
+\**********************************************************************/
+HRESULT GetICorDebugMetadataLocator(
+ LPCWSTR imagePath,
+ ULONG32 imageTimestamp,
+ ULONG32 imageSize,
+ ULONG32 cchPathBuffer,
+ ULONG32 *pcchPathBuffer,
+ WCHAR wszPathBuffer[])
+{
+ HRESULT Status = S_OK;
+ IfFailRet(InitializeSymbolStore());
+
+ _ASSERTE(g_SOSNetCoreCallbacks.GetICorDebugMetadataLocatorDelegate != nullptr);
+ return g_SOSNetCoreCallbacks.GetICorDebugMetadataLocatorDelegate(imagePath, imageTimestamp, imageSize, cchPathBuffer, pcchPathBuffer, wszPathBuffer);
+}
+
#ifndef FEATURE_PAL
/**********************************************************************\