Skip to content

Commit 2db9fdf

Browse files
authored
Adding GetAssemblyLoadContext cDAC API (#117939)
* adding GetAssemblyLoadContext cDAC API * simplifying field access * restructuring etc * comments
1 parent 2d3bf38 commit 2db9fdf

File tree

13 files changed

+115
-56
lines changed

13 files changed

+115
-56
lines changed

docs/design/datacontracts/Loader.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ string GetPath(ModuleHandle handle);
6868
string GetFileName(ModuleHandle handle);
6969
TargetPointer GetLoaderAllocator(ModuleHandle handle);
7070
TargetPointer GetILBase(ModuleHandle handle);
71+
TargetPointer GetAssemblyLoadContext(ModuleHandle handle);
7172
ModuleLookupTables GetLookupTables(ModuleHandle handle);
7273
TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags);
7374
bool IsCollectible(ModuleHandle handle);
@@ -107,6 +108,8 @@ TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer);
107108
| `Assembly` | `NotifyFlags` | Flags relating to the debugger/profiler notification state of the assembly |
108109
| `Assembly` | `Level` | File load level of the assembly |
109110
| `PEAssembly` | `PEImage` | Pointer to the PEAssembly's PEImage |
111+
| `PEAssembly` | `AssemblyBinder` | Pointer to the PEAssembly's binder |
112+
| `AssemblyBinder` | `ManagedAssemblyLoadContext` | Pointer to the AssemblyBinder's ManagedAssemblyLoadContext |
110113
| `PEImage` | `LoadedImageLayout` | Pointer to the PEImage's loaded PEImageLayout |
111114
| `PEImage` | `ProbeExtensionResult` | PEImage's ProbeExtensionResult |
112115
| `ProbeExtensionResult` | `Type` | Type of ProbeExtensionResult |
@@ -384,6 +387,14 @@ TargetPointer GetILBase(ModuleHandle handle)
384387
return target.ReadPointer(handle.Address + /* Module::Base offset */);
385388
}
386389

390+
TargetPointer ILoader.GetAssemblyLoadContext(ModuleHandle handle)
391+
{
392+
PEAssembly peAssembly = target.ReadPointer(handle.Address + /* Module::PEAssembly offset */);
393+
AssemblyBinder binder = target.ReadPointer(peAssembly + /* PEAssembly::AssemblyBinder offset */);
394+
ObjectHandle objectHandle = new ObjectHandle(binder);
395+
return objectHandle.Object;
396+
}
397+
387398
ModuleLookupTables GetLookupTables(ModuleHandle handle)
388399
{
389400
return new ModuleLookupTables(

docs/design/datacontracts/Thread.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ record struct ThreadData (
4646
ThreadStoreData GetThreadStoreData();
4747
ThreadStoreCounts GetThreadCounts();
4848
ThreadData GetThreadData(TargetPointer threadPointer);
49-
TargetPointer GetManagedThreadObject(TargetPointer threadPointer);
5049
```
5150

5251
## Version 1
@@ -128,10 +127,4 @@ ThreadData GetThreadData(TargetPointer address)
128127
NextThread: target.ReadPointer(address + /* Thread::LinkNext offset */) - threadLinkOffset;
129128
);
130129
}
131-
132-
TargetPointer GetManagedThreadObject(TargetPointer threadPointer)
133-
{
134-
var runtimeThread = new Thread(Target, threadPointer);
135-
return Contracts.GCHandle.GetObject(new DacGCHandle(runtimeThread.m_ExposedObject));
136-
}
137130
```

src/coreclr/debug/runtimeinfo/datadescriptor.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,14 @@ CDAC_TYPE_END(LoaderAllocator)
266266
CDAC_TYPE_BEGIN(PEAssembly)
267267
CDAC_TYPE_INDETERMINATE(PEAssembly)
268268
CDAC_TYPE_FIELD(PEAssembly, /*pointer*/, PEImage, cdac_data<PEAssembly>::PEImage)
269+
CDAC_TYPE_FIELD(PEAssembly, /*pointer*/, AssemblyBinder, cdac_data<PEAssembly>::AssemblyBinder)
269270
CDAC_TYPE_END(PEAssembly)
270271

272+
CDAC_TYPE_BEGIN(AssemblyBinder)
273+
CDAC_TYPE_INDETERMINATE(AssemblyBinder)
274+
CDAC_TYPE_FIELD(AssemblyBinder, /*pointer*/, ManagedAssemblyLoadContext, cdac_data<AssemblyBinder>::ManagedAssemblyLoadContext)
275+
CDAC_TYPE_END(AssemblyBinder)
276+
271277
CDAC_TYPE_BEGIN(PEImage)
272278
CDAC_TYPE_INDETERMINATE(PEImage)
273279
CDAC_TYPE_FIELD(PEImage, /*pointer*/, LoadedImageLayout, cdac_data<PEImage>::LoadedImageLayout)

src/coreclr/vm/assembly.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,10 +431,7 @@ Assembly *Assembly::CreateDynamic(AssemblyBinder* pBinder, NativeAssemblyNamePar
431431
IfFailThrow(pAssemblyEmit->DefineAssembly(pAssemblyNameParts->_pPublicKeyOrToken, pAssemblyNameParts->_cbPublicKeyOrToken, hashAlgorithm,
432432
pAssemblyNameParts->_pName, &assemData, pAssemblyNameParts->_flags,
433433
&ma));
434-
pPEAssembly = PEAssembly::Create(pAssemblyEmit);
435-
436-
// Set it as the fallback load context binder for the dynamic assembly being created
437-
pPEAssembly->SetFallbackBinder(pBinder);
434+
pPEAssembly = PEAssembly::Create(pAssemblyEmit, pBinder);
438435
}
439436

440437
AppDomain* pDomain = ::GetAppDomain();

src/coreclr/vm/assemblybinder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ class AssemblyBinder
128128
INT_PTR m_ptrManagedAssemblyLoadContext;
129129

130130
SArray<Assembly*> m_loadedAssemblies;
131+
friend struct cdac_data<AssemblyBinder>;
131132
};
132133

134+
template<>
135+
struct cdac_data<AssemblyBinder>
136+
{
137+
static constexpr size_t ManagedAssemblyLoadContext = offsetof(AssemblyBinder, m_ptrManagedAssemblyLoadContext);
138+
};
133139
#endif

src/coreclr/vm/peassembly.cpp

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ PEAssembly::PEAssembly(
647647
BINDER_SPACE::Assembly* pBindResultInfo,
648648
IMetaDataEmit* pEmit,
649649
BOOL isSystem,
650+
AssemblyBinder* pFallbackBinder /*= NULL*/,
650651
PEImage * pPEImage /*= NULL*/,
651652
BINDER_SPACE::Assembly * pHostAssembly /*= NULL*/)
652653
{
@@ -670,7 +671,7 @@ PEAssembly::PEAssembly(
670671
m_refCount = 1;
671672
m_isSystem = isSystem;
672673
m_pHostAssembly = nullptr;
673-
m_pFallbackBinder = nullptr;
674+
m_pAssemblyBinder = nullptr;
674675

675676
pPEImage = pBindResultInfo ? pBindResultInfo->GetPEImage() : pPEImage;
676677
if (pPEImage)
@@ -722,6 +723,15 @@ PEAssembly::PEAssembly(
722723
m_pHostAssembly = pBindResultInfo;
723724
}
724725

726+
if (m_pHostAssembly != nullptr)
727+
{
728+
m_pAssemblyBinder = m_pHostAssembly->GetBinder();
729+
}
730+
else
731+
{
732+
m_pAssemblyBinder = pFallbackBinder;
733+
}
734+
725735
#ifdef LOGGING
726736
GetPathOrCodeBase(m_debugName);
727737
m_pDebugName = m_debugName.GetUTF8();
@@ -740,6 +750,7 @@ PEAssembly *PEAssembly::Open(
740750
nullptr, // BindResult
741751
nullptr, // IMetaDataEmit
742752
FALSE, // isSystem
753+
nullptr, // FallbackBinder
743754
pPEImageIL,
744755
pHostAssembly);
745756

@@ -833,7 +844,7 @@ PEAssembly* PEAssembly::Open(BINDER_SPACE::Assembly* pBindResult)
833844
};
834845

835846
/* static */
836-
PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit)
847+
PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit, AssemblyBinder *pFallbackBinder)
837848
{
838849
CONTRACT(PEAssembly *)
839850
{
@@ -847,7 +858,7 @@ PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit)
847858
// we have.)
848859
SafeComHolder<IMetaDataEmit> pEmit;
849860
pAssemblyEmit->QueryInterface(IID_IMetaDataEmit, (void **)&pEmit);
850-
RETURN new PEAssembly(NULL, pEmit, FALSE);
861+
RETURN new PEAssembly(NULL, pEmit, FALSE, pFallbackBinder);
851862
}
852863

853864
#endif // #ifndef DACCESS_COMPILE
@@ -1083,25 +1094,5 @@ TADDR PEAssembly::GetMDInternalRWAddress()
10831094
// Returns the AssemblyBinder* instance associated with the PEAssembly
10841095
PTR_AssemblyBinder PEAssembly::GetAssemblyBinder()
10851096
{
1086-
LIMITED_METHOD_CONTRACT;
1087-
1088-
PTR_AssemblyBinder pBinder = NULL;
1089-
1090-
PTR_BINDER_SPACE_Assembly pHostAssembly = GetHostAssembly();
1091-
if (pHostAssembly)
1092-
{
1093-
pBinder = pHostAssembly->GetBinder();
1094-
}
1095-
else
1096-
{
1097-
// If we do not have a host assembly, check if we are dealing with
1098-
// a dynamically emitted assembly and if so, use its fallback load context
1099-
// binder reference.
1100-
if (IsReflectionEmit())
1101-
{
1102-
pBinder = GetFallbackBinder();
1103-
}
1104-
}
1105-
1106-
return pBinder;
1097+
return m_pAssemblyBinder;
11071098
}

src/coreclr/vm/peassembly.h

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -312,20 +312,18 @@ class PEAssembly final
312312
// For Dynamic assemblies this is the fallback binder.
313313
PTR_AssemblyBinder GetAssemblyBinder();
314314

315-
#ifndef DACCESS_COMPILE
316-
void SetFallbackBinder(PTR_AssemblyBinder pFallbackBinder)
317-
{
318-
LIMITED_METHOD_CONTRACT;
319-
m_pFallbackBinder = pFallbackBinder;
320-
}
321-
322-
#endif //!DACCESS_COMPILE
323-
315+
// For certain assemblies, we do not have m_pHostAssembly since they are not bound using an actual binder.
316+
// An example is Ref-Emitted assemblies. Thus, when such assemblies trigger load of their dependencies,
317+
// we need to ensure they are loaded in appropriate load context.
318+
//
319+
// To enable this, we maintain a concept of "FallbackBinder", which will be set to the Binder of the
320+
// assembly that created the dynamic assembly. If the creator assembly is dynamic itself, then its fallback
321+
// load context would be propagated to the assembly being dynamically generated.
324322
PTR_AssemblyBinder GetFallbackBinder()
325323
{
326324
LIMITED_METHOD_CONTRACT;
327325

328-
return m_pFallbackBinder;
326+
return (m_pHostAssembly != NULL) ? NULL : m_pAssemblyBinder;
329327
}
330328

331329
// ------------------------------------------------------------
@@ -341,7 +339,7 @@ class PEAssembly final
341339

342340
static PEAssembly* Open(BINDER_SPACE::Assembly* pBindResult);
343341

344-
static PEAssembly* Create(IMetaDataAssemblyEmit* pEmit);
342+
static PEAssembly* Create(IMetaDataAssemblyEmit* pEmit, AssemblyBinder* pFallbackBinder);
345343

346344
// ------------------------------------------------------------
347345
// Utility functions
@@ -372,6 +370,7 @@ class PEAssembly final
372370
BINDER_SPACE::Assembly* pBindResultInfo,
373371
IMetaDataEmit* pEmit,
374372
BOOL isSystem,
373+
AssemblyBinder* pFallbackBinder = NULL,
375374
PEImage* pPEImageIL = NULL,
376375
BINDER_SPACE::Assembly* pHostAssembly = NULL
377376
);
@@ -425,15 +424,7 @@ class PEAssembly final
425424
bool m_isSystem;
426425

427426
PTR_BINDER_SPACE_Assembly m_pHostAssembly;
428-
429-
// For certain assemblies, we do not have m_pHostAssembly since they are not bound using an actual binder.
430-
// An example is Ref-Emitted assemblies. Thus, when such assemblies trigger load of their dependencies,
431-
// we need to ensure they are loaded in appropriate load context.
432-
//
433-
// To enable this, we maintain a concept of "FallbackBinder", which will be set to the Binder of the
434-
// assembly that created the dynamic assembly. If the creator assembly is dynamic itself, then its fallback
435-
// load context would be propagated to the assembly being dynamically generated.
436-
PTR_AssemblyBinder m_pFallbackBinder;
427+
PTR_AssemblyBinder m_pAssemblyBinder;
437428

438429
friend struct cdac_data<PEAssembly>;
439430
}; // class PEAssembly
@@ -442,6 +433,7 @@ template<>
442433
struct cdac_data<PEAssembly>
443434
{
444435
static constexpr size_t PEImage = offsetof(PEAssembly, m_PEImage);
436+
static constexpr size_t AssemblyBinder = offsetof(PEAssembly, m_pAssemblyBinder);
445437
};
446438

447439
typedef ReleaseHolder<PEAssembly> PEAssemblyHolder;

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public interface ILoader : IContract
9191
string GetFileName(ModuleHandle handle) => throw new NotImplementedException();
9292
TargetPointer GetLoaderAllocator(ModuleHandle handle) => throw new NotImplementedException();
9393
TargetPointer GetILBase(ModuleHandle handle) => throw new NotImplementedException();
94+
TargetPointer GetAssemblyLoadContext(ModuleHandle handle) => throw new NotImplementedException();
9495
ModuleLookupTables GetLookupTables(ModuleHandle handle) => throw new NotImplementedException();
9596
TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags) => throw new NotImplementedException();
9697
bool IsCollectible(ModuleHandle handle) => throw new NotImplementedException();

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public enum DataType
3535
Assembly,
3636
LoaderAllocator,
3737
PEAssembly,
38+
AssemblyBinder,
3839
PEImage,
3940
PEImageLayout,
4041
CGrowableSymbolStream,

src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,15 @@ TargetPointer ILoader.GetILBase(ModuleHandle handle)
306306
return module.Base;
307307
}
308308

309+
TargetPointer ILoader.GetAssemblyLoadContext(ModuleHandle handle)
310+
{
311+
Data.Module module = _target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);
312+
Data.PEAssembly peAssembly = _target.ProcessedData.GetOrAdd<Data.PEAssembly>(module.PEAssembly);
313+
Data.AssemblyBinder binder = _target.ProcessedData.GetOrAdd<Data.AssemblyBinder>(peAssembly.AssemblyBinder);
314+
Data.ObjectHandle objectHandle = _target.ProcessedData.GetOrAdd<Data.ObjectHandle>(binder.ManagedAssemblyLoadContext);
315+
return objectHandle.Object;
316+
}
317+
309318
ModuleLookupTables ILoader.GetLookupTables(ModuleHandle handle)
310319
{
311320
Data.Module module = _target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);

0 commit comments

Comments
 (0)