Skip to content

Commit

Permalink
[cdac] Implement ISOSDacInterface::GetModule and `IXCLRDataModule::…
Browse files Browse the repository at this point in the history
…GetFileName` (#109133)

- Add `ClrDataModule` to cDAC as its implementation of `IXCLRDataModule` and `IXCLRDataModule2`
  - Delegates to legacy implementation for everything except for `GetFileName`
  - Implements `ICustomQueryInterface` to handle QI-ing the legacy DAC for `IMetaDataImport`
- Implement `ISOSDacInterface::GetModule`
  - Gets a module from the legacy DAC and passes it to the cDAC `ClrDataModule`
- Cache the module file name on `Module`
  - Update comments around how it is expected to be set
- Add `GetFileName` to `Loader` contract
- Implement `IXClrDataModule::GetFileName`
  • Loading branch information
elinor-fung authored Oct 24, 2024
1 parent a3fe47e commit d450d9c
Show file tree
Hide file tree
Showing 21 changed files with 634 additions and 55 deletions.
9 changes: 9 additions & 0 deletions docs/design/datacontracts/Loader.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ ModuleHandle GetModuleHandle(TargetPointer module);
TargetPointer GetAssembly(ModuleHandle handle);
ModuleFlags GetFlags(ModuleHandle handle);
string GetPath(ModuleHandle handle);
string GetFileName(ModuleHandle handle);
TargetPointer GetLoaderAllocator(ModuleHandle handle);
TargetPointer GetThunkHeap(ModuleHandle handle);
TargetPointer GetILBase(ModuleHandle handle);
Expand All @@ -52,6 +53,7 @@ Data descriptors used:
| `Module` | `LoaderAllocator` | LoaderAllocator of the Module |
| `Module` | `ThunkHeap` | Pointer to the thunk heap |
| `Module` | `Path` | Path of the Module (UTF-16, null-terminated) |
| `Module` | `FileName` | File name of the Module (UTF-16, null-terminated) |
| `Module` | `FieldDefToDescMap` | Mapping table |
| `Module` | `ManifestModuleReferencesMap` | Mapping table |
| `Module` | `MemberRefToDescMap` | Mapping table |
Expand Down Expand Up @@ -86,6 +88,13 @@ string GetPath(ModuleHandle handle)
return new string(path);
}

string GetFileName(ModuleHandle handle)
{
TargetPointer fileNameStart = target.ReadPointer(handle.Address + /* Module::FileName offset */);
char[] fileName = // Read<char> from target starting at fileNameStart until null terminator
return new string(fileName);
}

TargetPointer GetLoaderAllocator(ModuleHandle handle)
{
return target.ReadPointer(handle.Address + /* Module::LoaderAllocator offset */);
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/debug/runtimeinfo/datadescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,12 @@ CDAC_TYPE_BEGIN(Module)
CDAC_TYPE_INDETERMINATE(Module)
CDAC_TYPE_FIELD(Module, /*pointer*/, Assembly, cdac_data<Module>::Assembly)
CDAC_TYPE_FIELD(Module, /*pointer*/, Base, cdac_data<Module>::Base)
CDAC_TYPE_FIELD(Module, /*pointer*/, Flags, cdac_data<Module>::Flags)
CDAC_TYPE_FIELD(Module, /*uint32*/, Flags, cdac_data<Module>::Flags)
CDAC_TYPE_FIELD(Module, /*pointer*/, LoaderAllocator, cdac_data<Module>::LoaderAllocator)
CDAC_TYPE_FIELD(Module, /*pointer*/, ThunkHeap, cdac_data<Module>::ThunkHeap)
CDAC_TYPE_FIELD(Module, /*pointer*/, DynamicMetadata, cdac_data<Module>::DynamicMetadata)
CDAC_TYPE_FIELD(Module, /*pointer*/, Path, cdac_data<Module>::Path)
CDAC_TYPE_FIELD(Module, /*pointer*/, FileName, cdac_data<Module>::FileName)

CDAC_TYPE_FIELD(Module, /*pointer*/, FieldDefToDescMap, cdac_data<Module>::FieldDefToDescMap)
CDAC_TYPE_FIELD(Module, /*pointer*/, ManifestModuleReferencesMap, cdac_data<Module>::ManifestModuleReferencesMap)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/ceeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName)
m_loaderAllocator = GetAssembly()->GetLoaderAllocator();
m_pSimpleName = m_pPEAssembly->GetSimpleName();
m_path = m_pPEAssembly->GetPath().GetUnicode();
m_fileName = m_pPEAssembly->GetModuleFileNameHint();
_ASSERTE(m_path != NULL);
m_baseAddress = m_pPEAssembly->HasLoadedPEImage() ? m_pPEAssembly->GetLoadedLayout()->GetBase() : NULL;
if (m_pPEAssembly->IsReflectionEmit())
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/vm/ceeload.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,9 @@ class Module : public ModuleBase
VPTR_VTABLE_CLASS(Module, ModuleBase)

private:
PTR_CUTF8 m_pSimpleName; // Cached simple name for better performance and easier diagnostics
const WCHAR* m_path; // Cached path for easier diagnostics
PTR_CUTF8 m_pSimpleName; // Cached simple name for better performance and easier diagnostics
const WCHAR* m_path; // Cached path for easier diagnostics
const WCHAR* m_fileName; // Cached file name for easier diagnostics

PTR_PEAssembly m_pPEAssembly;
PTR_VOID m_baseAddress; // Cached base address for easier diagnostics
Expand Down Expand Up @@ -1647,6 +1648,7 @@ struct cdac_data<Module>
static constexpr size_t ThunkHeap = offsetof(Module, m_pThunkHeap);
static constexpr size_t DynamicMetadata = offsetof(Module, m_pDynamicMetadata);
static constexpr size_t Path = offsetof(Module, m_path);
static constexpr size_t FileName = offsetof(Module, m_fileName);

// Lookup map pointers
static constexpr size_t FieldDefToDescMap = offsetof(Module, m_FieldDefToDescMap);
Expand Down
7 changes: 4 additions & 3 deletions src/coreclr/vm/peassembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,11 @@ class PEAssembly final
const SString& GetPath();
const SString& GetIdentityPath();

#ifdef DACCESS_COMPILE
// This is the metadata module name. Used as a hint as file name.
// This is the module file name. Used as a hint as file name.
// For assemblies loaded from a path or single-file bundle, this is the file name portion of the path
// For assemblies loaded from memory, this is the module file name from metadata
// For reflection emitted assemblies, this is an empty string
const SString &GetModuleFileNameHint();
#endif // DACCESS_COMPILE

LPCWSTR GetPathForErrorMessages();

Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/vm/peassembly.inl
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ inline const SString& PEAssembly::GetIdentityPath()
return m_PEImage->GetPath();
}

#ifdef DACCESS_COMPILE
inline const SString &PEAssembly::GetModuleFileNameHint()
{
CONTRACTL
Expand All @@ -201,7 +200,6 @@ inline const SString &PEAssembly::GetModuleFileNameHint()
else
return m_PEImage->GetModuleFileNameHintForDAC();
}
#endif // DACCESS_COMPILE

#ifdef LOGGING
inline LPCUTF8 PEAssembly::GetDebugName()
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/vm/peimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,10 +536,11 @@ void PEImage::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
// these necessary fields enumerated no matter what.
m_path.EnumMemoryRegions(flags);

// We always want this field in mini/triage/heap dumps.
// SString skips enumeration for triage dumps, but we always want this field, so we specify
// CLRDATA_ENUM_MEM_DEFAULT as the flags. This value is used in cases where we either can't
// use the full path (triage dumps) or don't have a path (in-memory assembly)
m_sModuleFileNameHintUsedByDac.EnumMemoryRegions(CLRDATA_ENUM_MEM_DEFAULT);


EX_TRY
{
if (HasLoadedLayout() && HasNTHeaders() && HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG))
Expand Down
12 changes: 5 additions & 7 deletions src/coreclr/vm/peimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ class PEImage final
void SetModuleFileNameHintForDAC();
#ifdef DACCESS_COMPILE
void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
const SString &GetModuleFileNameHintForDAC();
#endif
const SString &GetModuleFileNameHintForDAC();

private:
#ifndef DACCESS_COMPILE
Expand Down Expand Up @@ -302,12 +302,10 @@ class PEImage final
DWORD m_dwPEKind;
DWORD m_dwMachine;

// This variable will have the data of module name.
// It is only used by DAC to remap fusion loaded modules back to
// disk IL. This really is a workaround. The real fix is for fusion loader
// hook (public API on hosting) to take an additional file name hint.
// We are piggy backing on the fact that module name is the same as file name!!!
SString m_sModuleFileNameHintUsedByDac; // This is only used by DAC
// This only used by DAC
// For assemblies loaded from a path or single-file bundle, this is the file name portion of the path
// For assemblies loaded from memory, this is the module file name from metadata
SString m_sModuleFileNameHintUsedByDac;

enum
{
Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/vm/peimage.inl
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,12 @@ inline void PEImage::SetModuleFileNameHintForDAC()
}
}

#ifdef DACCESS_COMPILE
inline const SString &PEImage::GetModuleFileNameHintForDAC()
{
LIMITED_METHOD_CONTRACT;

return m_sModuleFileNameHintUsedByDac;
}
#endif



inline BOOL PEImage::IsFile()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ internal interface ILoader : IContract
public virtual TargetPointer GetAssembly(ModuleHandle handle) => throw new NotImplementedException();
public virtual ModuleFlags GetFlags(ModuleHandle handle) => throw new NotImplementedException();
public virtual string GetPath(ModuleHandle handle) => throw new NotImplementedException();
public virtual string GetFileName(ModuleHandle handle) => throw new NotImplementedException();

public virtual TargetPointer GetLoaderAllocator(ModuleHandle handle) => throw new NotImplementedException();
public virtual TargetPointer GetThunkHeap(ModuleHandle handle) => throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,17 @@ ModuleFlags ILoader.GetFlags(ModuleHandle handle)
string ILoader.GetPath(ModuleHandle handle)
{
Data.Module module = _target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);
return _target.ReadUtf16String(module.Path);
return module.Path != TargetPointer.Null
? _target.ReadUtf16String(module.Path)
: string.Empty;
}

string ILoader.GetFileName(ModuleHandle handle)
{
Data.Module module = _target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);
return module.FileName != TargetPointer.Null
? _target.ReadUtf16String(module.FileName)
: string.Empty;
}

TargetPointer ILoader.GetLoaderAllocator(ModuleHandle handle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public Module(Target target, TargetPointer address)
ThunkHeap = target.ReadPointer(address + (ulong)type.Fields[nameof(ThunkHeap)].Offset);
DynamicMetadata = target.ReadPointer(address + (ulong)type.Fields[nameof(DynamicMetadata)].Offset);
Path = target.ReadPointer(address + (ulong)type.Fields[nameof(Path)].Offset);
FileName = target.ReadPointer(address + (ulong)type.Fields[nameof(FileName)].Offset);

FieldDefToDescMap = address + (ulong)type.Fields[nameof(FieldDefToDescMap)].Offset;
ManifestModuleReferencesMap = address + (ulong)type.Fields[nameof(ManifestModuleReferencesMap)].Offset;
Expand All @@ -41,6 +42,7 @@ public Module(Target target, TargetPointer address)
public TargetPointer ThunkHeap { get; init; }
public TargetPointer DynamicMetadata { get; init; }
public TargetPointer Path { get; init; }
public TargetPointer FileName { get; init; }

public TargetPointer FieldDefToDescMap { get; init; }
public TargetPointer ManifestModuleReferencesMap { get; init; }
Expand Down
Loading

0 comments on commit d450d9c

Please sign in to comment.