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
23 changes: 17 additions & 6 deletions docs/design/datacontracts/Loader.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ ModuleHandle GetModuleHandleFromModulePtr(TargetPointer module);
ModuleHandle GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer);
IEnumerable<ModuleHandle> GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags);
TargetPointer GetRootAssembly();
string GetAppDomainFriendlyName();
TargetPointer GetModule(ModuleHandle handle);
TargetPointer GetAssembly(ModuleHandle handle);
TargetPointer GetPEAssembly(ModuleHandle handle);
Expand Down Expand Up @@ -116,6 +117,7 @@ TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer);
| `CGrowableSymbolStream` | `Size` | Size of the raw symbol stream buffer |
| `AppDomain` | `RootAssembly` | Pointer to the root assembly |
| `AppDomain` | `DomainAssemblyList` | ArrayListBase of assemblies in the AppDomain |
| `AppDomain` | `FriendlyName` | Friendly name of the AppDomain |
| `LoaderAllocator` | `ReferenceCount` | Reference count of LoaderAllocator |
| `LoaderAllocator` | `HighFrequencyHeap` | High-frequency heap of LoaderAllocator |
| `LoaderAllocator` | `LowFrequencyHeap` | Low-frequency heap of LoaderAllocator |
Expand Down Expand Up @@ -270,6 +272,15 @@ TargetPointer GetRootAssembly()
return appDomain.RootAssembly;
}

string ILoader.GetAppDomainFriendlyName()
{
TargetPointer appDomainPointer = target.ReadGlobalPointer(Constants.Globals.AppDomain);
TargetPointer appDomain = target.ReadPointer(appDomainPointer)
TargetPointer pathStart = appDomain + /* AppDomain::FriendlyName offset */;
char[] name = // Read<char> from target starting at pathStart until null terminator
return new string(name);
}

TargetPointer ILoader.GetModule(ModuleHandle handle)
{
return handle.Address;
Expand Down Expand Up @@ -395,20 +406,20 @@ TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out Tar
uint index = rid;
// have to read lookupMap an extra time upfront because only the first map
// has valid supportedFlagsMask
TargetNUInt supportedFlagsMask = _target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */);
TargetNUInt supportedFlagsMask = target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */);
do
{
if (index < _target.Read<uint>(table + /*ModuleLookupMap::Count*/))
if (index < target.Read<uint>(table + /*ModuleLookupMap::Count*/))
{
TargetPointer entryAddress = _target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * _target.PointerSize);
TargetPointer rawValue = _target.ReadPointer(entryAddress);
TargetPointer entryAddress = target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * target.PointerSize);
TargetPointer rawValue = target.ReadPointer(entryAddress);
flags = rawValue & supportedFlagsMask;
return rawValue & ~(supportedFlagsMask.Value);
}
else
{
table = _target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/);
index -= _target.Read<uint>(lookupMap + /*ModuleLookupMap::Count*/);
table = target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/);
index -= target.Read<uint>(lookupMap + /*ModuleLookupMap::Count*/);
}
} while (table != TargetPointer.Null);
return TargetPointer.Null;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/debug/runtimeinfo/datadescriptor.inc
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ CDAC_TYPE_BEGIN(AppDomain)
CDAC_TYPE_INDETERMINATE(AppDomain)
CDAC_TYPE_FIELD(AppDomain, /*pointer*/, RootAssembly, cdac_data<AppDomain>::RootAssembly)
CDAC_TYPE_FIELD(AppDomain, /*DomainAssemblyList*/, DomainAssemblyList, cdac_data<AppDomain>::DomainAssemblyList)
CDAC_TYPE_FIELD(AppDomain, /*pointer*/, FriendlyName, cdac_data<AppDomain>::FriendlyName)
CDAC_TYPE_END(AppDomain)

CDAC_TYPE_BEGIN(SystemDomain)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/appdomain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,7 @@ struct cdac_data<AppDomain>
{
static constexpr size_t RootAssembly = offsetof(AppDomain, m_pRootAssembly);
static constexpr size_t DomainAssemblyList = offsetof(AppDomain, m_Assemblies) + offsetof(AppDomain::DomainAssemblyList, m_array);
static constexpr size_t FriendlyName = offsetof(AppDomain, m_friendlyName);
};

typedef DPTR(class SystemDomain) PTR_SystemDomain;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public interface ILoader : IContract
ModuleHandle GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer) => throw new NotImplementedException();
IEnumerable<ModuleHandle> GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags) => throw new NotImplementedException();
TargetPointer GetRootAssembly() => throw new NotImplementedException();
string GetAppDomainFriendlyName() => throw new NotImplementedException();
TargetPointer GetModule(ModuleHandle handle) => throw new NotImplementedException();
TargetPointer GetAssembly(ModuleHandle handle) => throw new NotImplementedException();
TargetPointer GetPEAssembly(ModuleHandle handle) => throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ TargetPointer ILoader.GetRootAssembly()
Data.AppDomain appDomain = _target.ProcessedData.GetOrAdd<Data.AppDomain>(_target.ReadPointer(appDomainPointer));
return appDomain.RootAssembly;
}

string ILoader.GetAppDomainFriendlyName()
{
TargetPointer appDomainPointer = _target.ReadGlobalPointer(Constants.Globals.AppDomain);
Data.AppDomain appDomain = _target.ProcessedData.GetOrAdd<Data.AppDomain>(_target.ReadPointer(appDomainPointer));
return appDomain.FriendlyName != TargetPointer.Null
? _target.ReadUtf16String(appDomain.FriendlyName)
: string.Empty;
}

TargetPointer ILoader.GetModule(ModuleHandle handle)
{
return handle.Address;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ public AppDomain(Target target, TargetPointer address)

RootAssembly = target.ReadPointer(address + (ulong)type.Fields[nameof(RootAssembly)].Offset);
DomainAssemblyList = address + (ulong)type.Fields[nameof(DomainAssemblyList)].Offset;
FriendlyName = target.ReadPointer(address + (ulong)type.Fields[nameof(FriendlyName)].Offset);
}

public TargetPointer RootAssembly { get; init; }
public TargetPointer DomainAssemblyList { get; init; }
public TargetPointer FriendlyName { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,62 @@ int ISOSDacInterface.GetAppDomainList(uint count, [In, MarshalUsing(CountElement
return hr;
}
int ISOSDacInterface.GetAppDomainName(ClrDataAddress addr, uint count, char* name, uint* pNeeded)
=> _legacyImpl is not null ? _legacyImpl.GetAppDomainName(addr, count, name, pNeeded) : HResults.E_NOTIMPL;
{
int hr = HResults.S_OK;
try
{
ILoader loader = _target.Contracts.Loader;
string friendlyName = loader.GetAppDomainFriendlyName();
TargetPointer systemDomainPtr = _target.ReadGlobalPointer(Constants.Globals.SystemDomain);
ClrDataAddress systemDomain = _target.ReadPointer(systemDomainPtr).ToClrDataAddress(_target);
if (addr == systemDomain || friendlyName == string.Empty)
{
if (pNeeded is not null)
{
*pNeeded = 1;
}
if (name is not null && count > 0)
{
name[0] = '\0'; // Set the first character to null terminator
}
}
else
{
if (pNeeded is not null)
{
*pNeeded = (uint)(friendlyName.Length + 1); // +1 for null terminator
}

if (name is not null && count > 0)
{
OutputBufferHelpers.CopyStringToBuffer(name, count, pNeeded, friendlyName);
}
}
}
catch (System.Exception ex)
{
hr = ex.HResult;
}
#if DEBUG
if (_legacyImpl is not null)
{
uint neededLocal;
char[] nameLocal = new char[count];
int hrLocal;
fixed (char* ptr = nameLocal)
{
hrLocal = _legacyImpl.GetAppDomainName(addr, count, ptr, &neededLocal);
}
Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}");
if (hr == HResults.S_OK)
{
Debug.Assert(pNeeded == null || *pNeeded == neededLocal);
Debug.Assert(name == null || new ReadOnlySpan<char>(nameLocal, 0, (int)neededLocal - 1).SequenceEqual(new string(name)));
}
}
#endif
return hr;
}
int ISOSDacInterface.GetAppDomainStoreData(void* data)
{
DacpAppDomainStoreData* appDomainStoreData = (DacpAppDomainStoreData*)data;
Expand Down
Loading