Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/design/datacontracts/Loader.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ bool IsReadyToRun(ModuleHandle handle);
string GetSimpleName(ModuleHandle handle);
string GetPath(ModuleHandle handle);
string GetFileName(ModuleHandle handle);
bool GetFileHeadersInfo(ModuleHandle handle, out uint timeStamp, out uint imageSize);
TargetPointer GetLoaderAllocator(ModuleHandle handle);
TargetPointer GetILBase(ModuleHandle handle);
TargetPointer GetAssemblyLoadContext(ModuleHandle handle);
Expand Down Expand Up @@ -658,6 +659,19 @@ string GetFileName(ModuleHandle handle)
return new string(fileName);
}

bool GetFileHeadersInfo(ModuleHandle handle, out uint timeStamp, out uint imageSize)
{
timeStamp = 0;
imageSize = 0;

if (!TryGetLoadedImageContents(handle, out TargetPointer baseAddress, out _, out _))
return false;
TargetPointer ntHeadersPtr = baseAddress + // offset to NT headers
timeStamp = // read from NT header
imageSize = // read from NT header
return true;
Comment thread
rcj1 marked this conversation as resolved.
}

TargetPointer GetLoaderAllocator(ModuleHandle handle)
{
return target.ReadPointer(handle.Address + /* Module::LoaderAllocator offset */);
Expand Down
21 changes: 21 additions & 0 deletions src/coreclr/debug/daccess/daccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5936,6 +5936,27 @@ ClrDataAccess::GetHostJitNotificationTable()
return m_jitNotificationTable;
}

/* static */ bool
ClrDataAccess::GetMetaDataFileInfoFromModule(Module *pModule,
DWORD &dwTimeStamp,
DWORD &dwSize,
DWORD &dwDataSize,
DWORD &dwRvaHint,
_Out_writes_(cchFilePath) LPWSTR wszFilePath,
const DWORD cchFilePath)
{
SUPPORTS_DAC_HOST_ONLY;

if (pModule == NULL)
return false;

PEAssembly *pPEAssembly = pModule->GetPEAssembly();
if (pPEAssembly == NULL)
return false;

return ClrDataAccess::GetMetaDataFileInfoFromPEFile(pPEAssembly, dwTimeStamp, dwSize, dwDataSize, dwRvaHint, wszFilePath, cchFilePath);
}
Comment thread
Copilot marked this conversation as resolved.

/* static */ bool
ClrDataAccess::GetMetaDataFileInfoFromPEFile(PEAssembly *pPEAssembly,
DWORD &dwTimeStamp,
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/debug/daccess/dacdbiimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ mdSignature DacDbiInterfaceImpl::GetILCodeAndSigHelper(Module * pModule,
}


HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetMetaDataFileInfoFromPEFile(VMPTR_PEAssembly vmPEAssembly, DWORD * pTimeStamp, DWORD * pImageSize, IStringHolder* pStrFilename, OUT BOOL * pResult)
HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetModuleMetaDataFileInfo(VMPTR_Module vmModule, DWORD * pTimeStamp, DWORD * pImageSize, IStringHolder* pStrFilename, OUT BOOL * pResult)
{
if (pTimeStamp == NULL || pImageSize == NULL || pStrFilename == NULL || pResult == NULL)
return E_POINTER;
Expand All @@ -1138,9 +1138,9 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetMetaDataFileInfoFromPEFile(VMP

DWORD dwDataSize;
DWORD dwRvaHint;
PEAssembly * pPEAssembly = vmPEAssembly.GetDacPtr();
_ASSERTE(pPEAssembly != NULL);
if (pPEAssembly == NULL)
Module * pModule = vmModule.GetDacPtr();
_ASSERTE(pModule != NULL);
if (pModule == NULL)
{
*pResult = FALSE;
return E_FAIL;
Expand All @@ -1149,7 +1149,7 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetMetaDataFileInfoFromPEFile(VMP
{
WCHAR wszFilePath[MAX_LONGPATH] = {0};
DWORD cchFilePath = MAX_LONGPATH;
bool ret = ClrDataAccess::GetMetaDataFileInfoFromPEFile(pPEAssembly,
bool ret = ClrDataAccess::GetMetaDataFileInfoFromModule(pModule,
*pTimeStamp,
*pImageSize,
dwDataSize,
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/daccess/dacdbiimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,7 @@ class DacDbiInterfaceImpl :

public:
// API for picking up the info needed for a debugger to look up an image from its search path.
HRESULT STDMETHODCALLTYPE GetMetaDataFileInfoFromPEFile(VMPTR_PEAssembly vmPEAssembly, DWORD * pTimeStamp, DWORD * pImageSize, IStringHolder* pStrFilename, OUT BOOL * pResult);
HRESULT STDMETHODCALLTYPE GetModuleMetaDataFileInfo(VMPTR_Module vmModule, DWORD * pTimeStamp, DWORD * pImageSize, IStringHolder* pStrFilename, OUT BOOL * pResult);
};


Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/debug/daccess/dacimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,14 @@ class ClrDataAccess
DWORD &dwRvaHint,
_Out_writes_(cchFilePath) LPWSTR wszFilePath,
DWORD cchFilePath);

static bool GetMetaDataFileInfoFromModule(Module *pModule,
DWORD &dwTimeStamp,
DWORD &dwSize,
DWORD &dwDataSize,
DWORD &dwRvaHint,
_Out_writes_(cchFilePath) LPWSTR wszFilePath,
const DWORD cchFilePath);
};

extern ClrDataAccess* g_dacImpl;
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/debug/di/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ IMetaDataImport * CordbModule::GetMetaDataImporter()
// Since we've already done everything possible from the Module anyhow, just call the
// stuff that talks to the debugger.
// Don't do anything with the ptr returned here, since it's really m_pInternalMetaDataImport.
pProcess->LookupMetaDataFromDebugger(m_vmPEFile, this);
pProcess->LookupMetaDataFromDebugger(this);
}

// If we still can't get it, throw.
Expand Down Expand Up @@ -788,10 +788,10 @@ HRESULT CordbModule::InitPublicMetaDataFromFile(const WCHAR * pszFullPathName,
StringCopyHolder filePath;


_ASSERTE(!m_vmPEFile.IsNull());
_ASSERTE(!m_vmModule.IsNull());
// MetaData lookup favors the NGEN image, which is what we want here.
BOOL _mdFileInfoResult;
IfFailThrow(this->GetProcess()->GetDAC()->GetMetaDataFileInfoFromPEFile(m_vmPEFile,
IfFailThrow(this->GetProcess()->GetDAC()->GetModuleMetaDataFileInfo(m_vmModule,
&dwImageTimeStamp,
&dwImageSize,
&filePath,
Expand Down Expand Up @@ -1175,9 +1175,9 @@ HRESULT CordbModule::GetName(ULONG32 cchName, ULONG32 *pcchName, _Out_writes_to_
DWORD dwImageSize = 0; // unused
StringCopyHolder filePath;

_ASSERTE(!m_vmPEFile.IsNull());
_ASSERTE(!m_vmModule.IsNull());
BOOL _mdFileInfoResult;
IfFailThrow(this->GetProcess()->GetDAC()->GetMetaDataFileInfoFromPEFile(m_vmPEFile,
IfFailThrow(this->GetProcess()->GetDAC()->GetModuleMetaDataFileInfo(m_vmModule,
&dwImageTimeStamp,
&dwImageSize,
&filePath,
Expand Down
8 changes: 3 additions & 5 deletions src/coreclr/debug/di/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ IMDInternalImport * CordbProcess::LookupMetaData(VMPTR_PEAssembly vmPEAssembly)
// debugger if it can find the metadata elsewhere.
// If this was live debugging, we should have just gotten the memory contents.
// Thus this code is for dump debugging, when you don't have the metadata in the dump.
pMDII = LookupMetaDataFromDebugger(vmPEAssembly, pModule);
pMDII = LookupMetaDataFromDebugger(pModule);
}
return pMDII;
}
Expand All @@ -398,9 +398,7 @@ IMDInternalImport * CordbProcess::LookupMetaData(VMPTR_PEAssembly vmPEAssembly)
}


IMDInternalImport * CordbProcess::LookupMetaDataFromDebugger(
VMPTR_PEAssembly vmPEAssembly,
CordbModule * pModule)
IMDInternalImport * CordbProcess::LookupMetaDataFromDebugger(CordbModule * pModule)
{
DWORD dwImageTimeStamp = 0;
DWORD dwImageSize = 0;
Expand All @@ -409,7 +407,7 @@ IMDInternalImport * CordbProcess::LookupMetaDataFromDebugger(

// First, see if the debugger can locate the exact metadata we want.
BOOL _metaDataFileInfoResult;
IfFailThrow(this->GetDAC()->GetMetaDataFileInfoFromPEFile(vmPEAssembly, &dwImageTimeStamp, &dwImageSize, &filePath, &_metaDataFileInfoResult));
IfFailThrow(this->GetDAC()->GetModuleMetaDataFileInfo(pModule->GetRuntimeModule(), &dwImageTimeStamp, &dwImageSize, &filePath, &_metaDataFileInfoResult));
if (_metaDataFileInfoResult)
{
_ASSERTE(filePath.IsSet());
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/debug/di/rspriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2993,8 +2993,7 @@ class CordbProcess :
IMDInternalImport * LookupMetaData(VMPTR_PEAssembly vmPEAssembly);

// Helper functions for LookupMetaData implementation
IMDInternalImport * LookupMetaDataFromDebugger(VMPTR_PEAssembly vmPEAssembly,
CordbModule * pModule);
IMDInternalImport * LookupMetaDataFromDebugger(CordbModule * pModule);

IMDInternalImport * LookupMetaDataFromDebuggerForSingleFile(CordbModule * pModule,
LPCWSTR pwszImagePath,
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/inc/dacdbiinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -1933,7 +1933,7 @@ IDacDbiInterface : public IUnknown
// to terminate the process when the attach is canceled.
virtual HRESULT STDMETHODCALLTYPE GetAttachStateFlags(OUT CLR_DEBUGGING_PROCESS_FLAGS * pRetVal) = 0;

virtual HRESULT STDMETHODCALLTYPE GetMetaDataFileInfoFromPEFile(VMPTR_PEAssembly vmPEAssembly, DWORD * pTimeStamp, DWORD * pImageSize, IStringHolder* pStrFilename, OUT BOOL * pResult) = 0;
virtual HRESULT STDMETHODCALLTYPE GetModuleMetaDataFileInfo(VMPTR_Module vmModule, DWORD * pTimeStamp, DWORD * pImageSize, IStringHolder* pStrFilename, OUT BOOL * pResult) = 0;

virtual HRESULT STDMETHODCALLTYPE IsThreadSuspendedOrHijacked(VMPTR_Thread vmThread, OUT BOOL * pResult) = 0;

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/inc/dacdbi.idl
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ interface IDacDbiInterface : IUnknown
HRESULT GetAttachStateFlags([out] CLR_DEBUGGING_PROCESS_FLAGS * pRetVal);

// Metadata
HRESULT GetMetaDataFileInfoFromPEFile(
[in] VMPTR_PEAssembly vmPEAssembly,
HRESULT GetModuleMetaDataFileInfo(
[in] VMPTR_Module vmModule,
[out] DWORD * pTimeStamp,
[out] DWORD * pImageSize,
[in] IDacDbiStringHolder pStrFilename,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public interface ILoader : IContract
string GetSimpleName(ModuleHandle handle) => throw new NotImplementedException();
string GetPath(ModuleHandle handle) => throw new NotImplementedException();
string GetFileName(ModuleHandle handle) => throw new NotImplementedException();
bool GetFileHeadersInfo(ModuleHandle handle, out uint timeStamp, out uint imageSize) => throw new NotImplementedException();
Comment thread
rcj1 marked this conversation as resolved.
Comment thread
rcj1 marked this conversation as resolved.
Comment thread
rcj1 marked this conversation as resolved.
TargetPointer GetLoaderAllocator(ModuleHandle handle) => throw new NotImplementedException();
TargetPointer GetILBase(ModuleHandle handle) => throw new NotImplementedException();
TargetPointer GetAssemblyLoadContext(ModuleHandle handle) => throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,29 @@ string ILoader.GetFileName(ModuleHandle handle)
: string.Empty;
}

bool ILoader.GetFileHeadersInfo(ModuleHandle handle, out uint timeStamp, out uint imageSize)
{
timeStamp = 0;
imageSize = 0;

if (!TryGetPEImage(handle, out Data.PEImage? peImage))
return false;

if (peImage.LoadedImageLayout == TargetPointer.Null)
return false; // no loaded image layout

Data.PEImageLayout peImageLayout = _target.ProcessedData.GetOrAdd<Data.PEImageLayout>(peImage.LoadedImageLayout);

if (peImageLayout.Format == (uint)ImageFormat.Webcil)
return false; // Webcil images do not have NT headers

TargetPointer ntHeadersPtr = FindNTHeaders(peImageLayout);
Data.ImageNTHeaders ntHeaders = _target.ProcessedData.GetOrAdd<Data.ImageNTHeaders>(ntHeadersPtr);
timeStamp = ntHeaders.FileHeader.TimeDateStamp;
imageSize = ntHeaders.OptionalHeader.SizeOfImage;
return true;
}
Comment thread
rcj1 marked this conversation as resolved.

TargetPointer ILoader.GetLoaderAllocator(ModuleHandle handle)
{
Data.Module module = _target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ namespace Microsoft.Diagnostics.DataContractReader.Data;
internal sealed partial class ImageFileHeader : IData<ImageFileHeader>
{
private const int NumberOfSectionsOffset = 2;
private const int TimeDateStampOffset = 4;
private const int SizeOfOptionalHeaderOffset = 16;

[RawOffset(NumberOfSectionsOffset, LittleEndian = true)]
public ushort NumberOfSections { get; }

[RawOffset(TimeDateStampOffset, LittleEndian = true)]
public uint TimeDateStamp { get; }

[RawOffset(SizeOfOptionalHeaderOffset, LittleEndian = true)]
public ushort SizeOfOptionalHeader { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ namespace Microsoft.Diagnostics.DataContractReader.Data;
internal sealed partial class ImageOptionalHeader : IData<ImageOptionalHeader>
{
private const int SectionAlignmentOffset = 32;
private const int SizeOfImageOffset = 56;

[RawOffset(SectionAlignmentOffset, LittleEndian = true)]
public uint SectionAlignment { get; }

[RawOffset(SizeOfImageOffset, LittleEndian = true)]
public uint SizeOfImage { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,7 @@ int IXCLRDataModule.GetFileName(uint bufLen, uint* nameLen, char* name)
}
catch (VirtualReadException)
{
// The memory for the path may not be enumerated - for example, in triage dumps
// In this case, GetPath will throw VirtualReadException
result = contract.GetFileName(handle);
}

if (string.IsNullOrEmpty(result))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,20 @@ public int GetModulePath(ulong vmModule, nint pStrFilename, Interop.BOOL* pResul
{
Contracts.ILoader loader = _target.Contracts.Loader;
Contracts.ModuleHandle handle = loader.GetModuleHandleFromModulePtr(new TargetPointer(vmModule));
string path = loader.GetPath(handle);
string path = string.Empty;
try
{
path = loader.GetPath(handle);
}
catch (VirtualReadException)
{
path = loader.GetFileName(handle);
}

if (string.IsNullOrEmpty(path))
{
path = loader.GetFileName(handle);
}
if (string.IsNullOrEmpty(path))
{
*pResult = Interop.BOOL.FALSE;
Expand Down Expand Up @@ -3398,8 +3411,71 @@ public int GetAttachStateFlags(int* pRetVal)
return hr;
}

public int GetMetaDataFileInfoFromPEFile(ulong vmPEAssembly, uint* dwTimeStamp, uint* dwImageSize, nint pStrFilename, Interop.BOOL* pResult)
=> LegacyFallbackHelper.CanFallback() && _legacy is not null ? _legacy.GetMetaDataFileInfoFromPEFile(vmPEAssembly, dwTimeStamp, dwImageSize, pStrFilename, pResult) : HResults.E_NOTIMPL;
public int GetModuleMetaDataFileInfo(ulong vmModule, uint* dwTimeStamp, uint* dwImageSize, nint pStrFilename, Interop.BOOL* pResult)
{
int hr = HResults.S_OK;
string path = string.Empty;
try
Comment thread
rcj1 marked this conversation as resolved.
{
if (dwTimeStamp is null || dwImageSize is null || pStrFilename == 0 || pResult is null)
throw new NullReferenceException("One or more parameters are null");
*pResult = Interop.BOOL.FALSE;
*dwTimeStamp = 0;
*dwImageSize = 0;
if (vmModule == 0)
throw Marshal.GetExceptionForHR(HResults.E_FAIL)!;
Comment thread
rcj1 marked this conversation as resolved.
Contracts.ILoader loader = _target.Contracts.Loader;
Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(vmModule);
bool result = loader.GetFileHeadersInfo(moduleHandle, out uint timeStamp, out uint imageSize);
if (result)
{
*dwTimeStamp = timeStamp;
*dwImageSize = imageSize;
}
Comment thread
rcj1 marked this conversation as resolved.
try
{
path = loader.GetPath(moduleHandle);
}
catch (VirtualReadException)
{
path = loader.GetFileName(moduleHandle);
}
if (string.IsNullOrEmpty(path))
{
path = loader.GetFileName(moduleHandle);
}
hr = StringHolderAssignCopy(pStrFilename, path);
*pResult = result ? Interop.BOOL.TRUE : Interop.BOOL.FALSE;
}
catch (System.Exception ex)
{
hr = ex.HResult;
}
#if DEBUG
if (_legacy is not null)
{
uint timeStampLocal;
uint imageSizeLocal;
Interop.BOOL resultLocal;
using var legacyHolder = new NativeStringHolder();
int hrLocal = _legacy.GetModuleMetaDataFileInfo(vmModule, &timeStampLocal, &imageSizeLocal, legacyHolder.Ptr, &resultLocal);
Debug.ValidateHResult(hr, hrLocal);
if (hr == HResults.S_OK)
{
Debug.Assert(*pResult == resultLocal, $"GetModuleMetaDataFileInfo result mismatch - cDAC: {*pResult}, DAC: {resultLocal}");
if (*pResult == Interop.BOOL.TRUE)
{
Debug.Assert(*dwTimeStamp == timeStampLocal, $"GetModuleMetaDataFileInfo timestamp mismatch - cDAC: {*dwTimeStamp}, DAC: {timeStampLocal}");
Debug.Assert(*dwImageSize == imageSizeLocal, $"GetModuleMetaDataFileInfo image size mismatch - cDAC: {*dwImageSize}, DAC: {imageSizeLocal}");
Debug.Assert(
string.Equals(path, legacyHolder.Value, System.StringComparison.Ordinal),
$"GetModuleMetaDataFileInfo path mismatch - cDAC: '{path}', DAC: '{legacyHolder.Value}'");
}
}
}
#endif
return hr;
}

public int IsThreadSuspendedOrHijacked(ulong vmThread, Interop.BOOL* pResult)
=> LegacyFallbackHelper.CanFallback() && _legacy is not null ? _legacy.IsThreadSuspendedOrHijacked(vmThread, pResult) : HResults.E_NOTIMPL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ int EnumerateTypeHandleParams(ulong vmTypeHandle,
int GetAttachStateFlags(int* pRetVal);

[PreserveSig]
int GetMetaDataFileInfoFromPEFile(ulong vmPEAssembly, uint* dwTimeStamp, uint* dwImageSize, nint pStrFilename, Interop.BOOL* pResult);
int GetModuleMetaDataFileInfo(ulong vmModule, uint* dwTimeStamp, uint* dwImageSize, nint pStrFilename, Interop.BOOL* pResult);

[PreserveSig]
int IsThreadSuspendedOrHijacked(ulong vmThread, Interop.BOOL* pResult);
Expand Down
Loading
Loading