[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / vm / assembly.hpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*============================================================
6 **
7 ** Header:  Assembly.hpp
8 ** 
9
10 **
11 ** Purpose: Implements assembly (loader domain) architecture
12 **
13 **
14 ===========================================================*/
15 #ifndef _ASSEMBLY_H
16 #define _ASSEMBLY_H
17
18 #include "ceeload.h"
19 #include "exceptmacros.h"
20 #include "clsload.hpp"
21 #include "eehash.h"
22 #include "listlock.h"
23 #include "iceefilegen.h"
24 #include "cordbpriv.h"
25 #include "assemblyspec.hpp"
26
27 class BaseDomain;
28 class AppDomain;
29 class DomainAssembly;
30 class DomainModule;
31 class SystemDomain;
32 class ClassLoader;
33 class ComDynamicWrite;
34 class AssemblySink;
35 class AssemblyNative;
36 class AssemblySpec;
37 class ISharedSecurityDescriptor;
38 class SecurityTransparencyBehavior;
39 class Pending;
40 class AllocMemTracker;
41 class FriendAssemblyDescriptor;
42
43 // Bits in m_dwDynamicAssemblyAccess (see System.Reflection.Emit.AssemblyBuilderAccess.cs)
44 #define ASSEMBLY_ACCESS_RUN     0x01
45 #define ASSEMBLY_ACCESS_SAVE    0x02
46 #define ASSEMBLY_ACCESS_COLLECT 0x8
47
48 struct CreateDynamicAssemblyArgsGC
49 {
50     ASSEMBLYNAMEREF assemblyName;
51     LOADERALLOCATORREF loaderAllocator;
52 };
53
54 struct CreateDynamicAssemblyArgs : CreateDynamicAssemblyArgsGC
55 {
56     INT32           access;
57     StackCrawlMark* stackMark;
58 };
59
60 // An assembly is the unit of deployment for managed code.  Typically Assemblies are one to one with files
61 // (Modules), however this is not necessary, as an assembly can contain serveral files (typically you only
62 // do this so that you can resource-only modules that are national language specific)
63 // 
64 // Conceptually Assemblies are loaded into code:AppDomain
65 // 
66 // So in general an assemly is a list of code:Module, where a code:Module is 1-1 with a DLL or EXE file. 
67 //  
68 // One of the modules the code:Assembly.m_pManifest is special in that it knows about all the other
69 // modules in an assembly (often it is the only one).  
70 //
71 class Assembly
72 {
73     friend class BaseDomain;
74     friend class SystemDomain;
75     friend class ClassLoader;
76     friend class AssemblyNative;
77     friend class AssemblySpec;
78     friend class NDirect;
79     friend class AssemblyNameNative;
80     friend class ClrDataAccess;
81
82 public:
83     Assembly(BaseDomain *pDomain, PEAssembly *pFile, DebuggerAssemblyControlFlags debuggerFlags, BOOL fIsCollectible);
84     void Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocator);
85
86     void StartUnload();
87     void Terminate( BOOL signalProfiler = TRUE );
88
89     static Assembly *Create(BaseDomain *pDomain, PEAssembly *pFile, DebuggerAssemblyControlFlags debuggerFlags, BOOL fIsCollectible, AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocator);
90
91     BOOL IsSystem() { WRAPPER_NO_CONTRACT; return m_pManifestFile->IsSystem(); }
92
93     static Assembly *CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs *args);
94
95     MethodDesc *GetEntryPoint();
96
97     //****************************************************************************************
98     //
99     // Additional init tasks for Modules. This should probably be part of Module::Initialize()
100     // but there's at least one call to ReflectionModule::Create that is *not* followed by a
101     // PrepareModule call.
102     void PrepareModuleForAssembly(Module* module, AllocMemTracker *pamTracker);
103
104     // This is the final step of publishing a Module into an Assembly. This step cannot fail.
105     void PublishModuleIntoAssembly(Module *module);
106
107 #ifndef DACCESS_COMPILE
108     void SetIsTenured()
109     {
110         WRAPPER_NO_CONTRACT;
111         m_pManifest->SetIsTenured();
112     }
113
114     // CAUTION: This should only be used as backout code if an assembly is unsuccessfully
115     //          added to the shared domain assembly map.
116     void UnsetIsTenured()
117     {
118         WRAPPER_NO_CONTRACT;
119         m_pManifest->UnsetIsTenured();
120     }
121 #endif // DACCESS_COMPILE
122
123     //****************************************************************************************
124     //
125     // Returns the class loader associated with the assembly.
126     ClassLoader* GetLoader()
127     {
128         LIMITED_METHOD_CONTRACT;
129         SUPPORTS_DAC;
130         return m_pClassLoader;
131     }
132
133     // ------------------------------------------------------------
134     // Modules
135     // ------------------------------------------------------------
136
137     class ModuleIterator
138     {
139         Module* m_pManifest;
140         DWORD m_i;
141
142       public:
143         // The preferred constructor.  If you use this, you don't have to
144         // call Start() yourself
145         ModuleIterator(Assembly *pAssembly)
146         {
147             WRAPPER_NO_CONTRACT;
148             Start(pAssembly);
149         }
150
151         // When you don't have the Assembly at contruction time, use this
152         // constructor, and explicitly call Start() to begin the iteration.
153         ModuleIterator()
154         {
155             LIMITED_METHOD_CONTRACT;
156             SUPPORTS_DAC;
157
158             m_pManifest = NULL;
159             m_i = (DWORD) -1;
160         }
161
162         void Start(Assembly * pAssembly)
163         {
164             LIMITED_METHOD_CONTRACT;
165             SUPPORTS_DAC;
166           
167             m_pManifest = pAssembly->GetManifestModule();
168             m_i = (DWORD) -1;
169         }
170
171         BOOL Next()
172         {
173             LIMITED_METHOD_CONTRACT;
174             SUPPORTS_DAC;
175             while (++m_i <= m_pManifest->GetFileMax())
176             {
177                 if (GetModule() != NULL)
178                     return TRUE;
179             }
180             return FALSE;
181         }
182
183         Module *GetModule()
184         {
185             LIMITED_METHOD_CONTRACT;
186             SUPPORTS_DAC;
187             return m_pManifest->LookupFile(TokenFromRid(m_i, mdtFile));
188         }
189     };
190
191     ModuleIterator IterateModules()
192     {
193         WRAPPER_NO_CONTRACT;
194         SUPPORTS_DAC;
195         return ModuleIterator(this);
196     }
197
198
199     //****************************************************************************************
200     //
201     // Get the domain the assembly lives in.
202     PTR_BaseDomain Parent()
203     {
204         LIMITED_METHOD_CONTRACT;
205         return m_pDomain;
206     }
207
208     // Sets the assemblies domain.
209     void SetParent(BaseDomain* pParent);
210
211     //-----------------------------------------------------------------------------------------
212     // EnsureActive ensures that the assembly is properly prepped in the current app domain
213     // for active uses like code execution, static field access, and instance allocation
214     //-----------------------------------------------------------------------------------------
215 #ifndef DACCESS_COMPILE
216     VOID EnsureActive();
217 #endif
218
219     //-----------------------------------------------------------------------------------------
220     // CheckActivated is a check predicate which should be used in active use paths like code
221     // execution, static field access, and instance allocation
222     //-----------------------------------------------------------------------------------------
223     CHECK CheckActivated();
224
225     // Returns the parent domain if it is not the system area. Returns NULL if it is the
226     // system domain
227     PTR_BaseDomain GetDomain();
228     PTR_LoaderAllocator GetLoaderAllocator() { LIMITED_METHOD_DAC_CONTRACT; return m_pLoaderAllocator; }
229
230     BOOL GetModuleZapFile(LPCWSTR name, SString &path);
231
232 #ifdef LOGGING
233     LPCWSTR GetDebugName()
234     {
235         WRAPPER_NO_CONTRACT;
236         return GetManifestFile()->GetDebugName();
237     }
238 #endif
239
240     LPCUTF8 GetSimpleName()
241     {
242         WRAPPER_NO_CONTRACT;
243         return GetManifestFile()->GetSimpleName();
244     }
245
246     BOOL IsStrongNamed()
247     {
248         WRAPPER_NO_CONTRACT;
249         return GetManifestFile()->IsStrongNamed();
250     }
251
252     const void *GetPublicKey(DWORD *pcbPK)
253     {
254         WRAPPER_NO_CONTRACT;
255         return GetManifestFile()->GetPublicKey(pcbPK);
256     }
257
258     ULONG GetHashAlgId()
259     {
260         WRAPPER_NO_CONTRACT;
261         return GetManifestFile()->GetHashAlgId();
262     }
263
264     HRESULT GetVersion(USHORT *pMajor, USHORT *pMinor, USHORT *pBuild, USHORT *pRevision)
265     {
266         WRAPPER_NO_CONTRACT;
267         return GetManifestFile()->GetVersion(pMajor, pMinor, pBuild, pRevision);
268     }
269
270     LPCUTF8 GetLocale()
271     {
272         WRAPPER_NO_CONTRACT;
273         return GetManifestFile()->GetLocale();
274     }
275
276     DWORD GetFlags()
277     {
278         WRAPPER_NO_CONTRACT;
279         return GetManifestFile()->GetFlags();
280     }
281
282     PTR_LoaderHeap GetLowFrequencyHeap();
283     PTR_LoaderHeap GetHighFrequencyHeap();
284     PTR_LoaderHeap GetStubHeap();
285
286     PTR_Module GetManifestModule()
287     {
288         LIMITED_METHOD_CONTRACT;
289         SUPPORTS_DAC;
290         return m_pManifest;
291     }
292
293     PTR_PEAssembly GetManifestFile()
294     {
295         LIMITED_METHOD_CONTRACT;
296         SUPPORTS_DAC;
297         return m_pManifestFile;
298     }
299
300     IMDInternalImport* GetManifestImport()
301     {
302         WRAPPER_NO_CONTRACT;
303         SUPPORTS_DAC;
304         return m_pManifestFile->GetPersistentMDImport();
305     }
306
307     HRESULT GetCustomAttribute(mdToken parentToken,
308                                WellKnownAttribute attribute,
309                                const void  **ppData,
310                                ULONG *pcbData)
311     {
312         WRAPPER_NO_CONTRACT;
313         SUPPORTS_DAC;
314         return GetManifestModule()->GetCustomAttribute(parentToken, attribute, ppData, pcbData);
315     }
316
317 #ifndef DACCESS_COMPILE
318     IMetaDataAssemblyImport* GetManifestAssemblyImporter()
319     {
320         WRAPPER_NO_CONTRACT;
321         return m_pManifestFile->GetAssemblyImporter();
322     }
323 #endif // DACCESS_COMPILE
324
325     mdAssembly GetManifestToken()
326     {
327         LIMITED_METHOD_CONTRACT;
328
329         return TokenFromRid(1, mdtAssembly);
330     }
331
332 #ifndef DACCESS_COMPILE
333     void GetDisplayName(SString &result, DWORD flags = 0)
334     {
335         WRAPPER_NO_CONTRACT;
336
337         return m_pManifestFile->GetDisplayName(result, flags);
338     }
339 #endif // DACCESS_COMPILE
340
341     void GetCodeBase(SString &result)
342     {
343         WRAPPER_NO_CONTRACT;
344
345         return m_pManifestFile->GetCodeBase(result);
346     }
347
348     OBJECTREF GetExposedObject();
349
350     DebuggerAssemblyControlFlags GetDebuggerInfoBits(void)
351     {
352         LIMITED_METHOD_CONTRACT;
353
354         return m_debuggerFlags;
355     }
356
357     void SetDebuggerInfoBits(DebuggerAssemblyControlFlags flags)
358     {
359         LIMITED_METHOD_CONTRACT;
360
361         m_debuggerFlags = flags;
362     }
363
364     void SetCopiedPDBs()
365     {
366         LIMITED_METHOD_CONTRACT;
367
368         m_debuggerFlags = (DebuggerAssemblyControlFlags) (m_debuggerFlags | DACF_PDBS_COPIED);
369     }
370
371     ULONG HashIdentity()
372     {
373         return GetManifestFile()->HashIdentity();
374     }
375
376     BOOL IsDisabledPrivateReflection();
377
378     //****************************************************************************************
379     //
380     // Uses the given token to load a module or another assembly. Returns the module in
381     // which the implementation resides.
382
383     mdFile GetManifestFileToken(IMDInternalImport *pImport, mdFile kFile);
384     mdFile GetManifestFileToken(LPCSTR name);
385
386     // On failure:
387     //      if loadFlag == Loader::Load => throw
388     //      if loadFlag != Loader::Load => return NULL
389     Module *FindModuleByExportedType(mdExportedType mdType,
390                                      Loader::LoadFlag loadFlag,
391                                      mdTypeDef mdNested,
392                                      mdTypeDef *pCL);
393
394     static Module * FindModuleByTypeRef(Module *         pModule, 
395                                         mdTypeRef        typeRef, 
396                                         Loader::LoadFlag loadFlag,
397                                         BOOL *           pfNoResolutionScope);
398
399     Module *FindModuleByName(LPCSTR moduleName);
400
401     //****************************************************************************************
402     //
403     INT32 ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThreads);
404
405     //****************************************************************************************
406
407     Assembly();
408     ~Assembly();
409 #ifdef  FEATURE_PREJIT
410     void DeleteNativeCodeRanges();
411 #endif
412
413     BOOL GetResource(LPCSTR szName, DWORD *cbResource,
414                      PBYTE *pbInMemoryResource, Assembly **pAssemblyRef,
415                      LPCSTR *szFileName, DWORD *dwLocation,
416                      BOOL fSkipRaiseResolveEvent = FALSE);
417
418     //****************************************************************************************
419 #ifdef DACCESS_COMPILE
420     void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
421 #endif
422
423     FORCEINLINE BOOL IsDynamic() { LIMITED_METHOD_CONTRACT; return m_isDynamic; }
424     FORCEINLINE BOOL IsCollectible() { LIMITED_METHOD_DAC_CONTRACT; return m_isCollectible; }
425
426     DWORD GetNextModuleIndex() { LIMITED_METHOD_CONTRACT; return m_nextAvailableModuleIndex++; }
427
428     void AddType(Module* pModule,
429                  mdTypeDef cl);
430     void AddExportedType(mdExportedType cl);
431     mdAssemblyRef AddAssemblyRef(Assembly *refedAssembly, IMetaDataAssemblyEmit *pAssemEmitter = NULL, BOOL fUsePublicKeyToken = TRUE);
432
433     //****************************************************************************************
434
435     DomainAssembly *GetDomainAssembly();
436     void SetDomainAssembly(DomainAssembly *pAssembly);
437
438 #if defined(FEATURE_COLLECTIBLE_TYPES) && !defined(DACCESS_COMPILE)
439     OBJECTHANDLE GetLoaderAllocatorObjectHandle() { WRAPPER_NO_CONTRACT; return GetLoaderAllocator()->GetLoaderAllocatorObjectHandle(); }
440 #endif // FEATURE_COLLECTIBLE_TYPES
441
442     BOOL IsSIMDVectorAssembly() { LIMITED_METHOD_DAC_CONTRACT; return m_fIsSIMDVectorAssembly; }
443
444 #if defined(FEATURE_PREJIT) || defined(FEATURE_READYTORUN)
445     BOOL IsInstrumented();
446     BOOL IsInstrumentedHelper();
447 #endif // FEATURE_PREJIT
448
449 #ifdef FEATURE_COMINTEROP
450     static ITypeLib * const InvalidTypeLib;
451
452     // Get any cached ITypeLib* for the assembly.
453     ITypeLib *GetTypeLib();
454
455     // Try to set the ITypeLib*, if one is not already cached.
456     bool TrySetTypeLib(_In_ ITypeLib *pTlb);
457 #endif // FEATURE_COMINTEROP
458
459 #ifndef DACCESS_COMPILE
460
461     void DECLSPEC_NORETURN ThrowTypeLoadException(LPCUTF8 pszFullName, UINT resIDWhy);
462
463     void DECLSPEC_NORETURN ThrowTypeLoadException(LPCUTF8 pszNameSpace, LPCUTF8 pTypeName,
464                                                   UINT resIDWhy);
465
466     void DECLSPEC_NORETURN ThrowTypeLoadException(NameHandle *pName, UINT resIDWhy);
467
468     void DECLSPEC_NORETURN ThrowTypeLoadException(IMDInternalImport *pInternalImport,
469                                                   mdToken token,
470                                                   UINT resIDWhy);
471
472     void DECLSPEC_NORETURN ThrowTypeLoadException(IMDInternalImport *pInternalImport,
473                                                   mdToken token,
474                                                   LPCUTF8 pszFieldOrMethodName,
475                                                   UINT resIDWhy);
476
477     void DECLSPEC_NORETURN ThrowTypeLoadException(LPCUTF8 pszNameSpace,
478                                                   LPCUTF8 pszTypeName,
479                                                   LPCUTF8 pszMethodName,
480                                                   UINT resIDWhy);
481
482     void DECLSPEC_NORETURN ThrowBadImageException(LPCUTF8 pszNameSpace,
483                                                   LPCUTF8 pszTypeName,
484                                                   UINT resIDWhy);
485
486 #endif // #ifndef DACCESS_COMPILE
487
488     //****************************************************************************************
489     //
490
491     static BOOL FileNotFound(HRESULT hr);
492
493     //****************************************************************************************
494     // Is the given assembly a friend of this assembly?
495     bool GrantsFriendAccessTo(Assembly *pAccessingAssembly, FieldDesc *pFD);
496     bool GrantsFriendAccessTo(Assembly *pAccessingAssembly, MethodDesc *pMD);
497     bool GrantsFriendAccessTo(Assembly *pAccessingAssembly, MethodTable *pMT);
498     bool IgnoresAccessChecksTo(Assembly *pAccessedAssembly);
499
500 #ifdef FEATURE_COMINTEROP
501     bool IsImportedFromTypeLib()
502     {
503         WRAPPER_NO_CONTRACT;
504         return ((GetInteropAttributeMask() & INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB) != 0);
505     }
506
507     bool IsPIAOrImportedFromTypeLib()
508     {
509         WRAPPER_NO_CONTRACT;
510         return ((GetInteropAttributeMask() & (INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB | INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY)) != 0);
511     }
512
513     bool IsPIA()
514     {
515         WRAPPER_NO_CONTRACT;
516         return ((GetInteropAttributeMask() & INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY) != 0);
517     }
518
519     // Does this assembly contain windows metadata
520     bool IsWinMD();
521
522     // Does this assembly contain windows metadata with managed implementation
523     bool IsManagedWinMD();
524
525     // Returns the IWinMDImport interface of the manifest module metadata or NULL if this assembly is not a .winmd
526     IWinMDImport *GetManifestWinMDImport();
527 #endif
528
529
530 protected:
531 #ifdef FEATURE_COMINTEROP
532     enum WinMDStatus
533     {
534         WinMDStatus_Unknown,
535         WinMDStatus_IsPureWinMD,
536         WinMDStatus_IsManagedWinMD,
537         WinMDStatus_IsNotWinMD
538     };
539
540     // Determine if the assembly is a pure Windows Metadata file, contians managed implementation, or is not
541     // Windows Metadata at all.
542     WinMDStatus GetWinMDStatus();
543
544     enum InteropAttributeStatus {
545         INTEROP_ATTRIBUTE_UNSET                    = 0,
546         INTEROP_ATTRIBUTE_CACHED                   = 1,
547         INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB    = 2,
548         INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY = 4,
549     };
550
551     InteropAttributeStatus GetInteropAttributeMask()
552     {
553         LIMITED_METHOD_CONTRACT;
554
555         if (m_InteropAttributeStatus & INTEROP_ATTRIBUTE_CACHED)
556             return m_InteropAttributeStatus;
557
558         int mask = INTEROP_ATTRIBUTE_UNSET;
559
560         if (!IsWinMD()) // ignore classic COM interop CAs in .winmd
561         {
562             if (GetManifestModule()->GetCustomAttribute(TokenFromRid(1, mdtAssembly), WellKnownAttribute::ImportedFromTypeLib, NULL, 0) == S_OK)
563                 mask |= INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB;
564             if (GetManifestModule()->GetCustomAttribute(TokenFromRid(1, mdtAssembly), WellKnownAttribute::PrimaryInteropAssembly, NULL, 0) == S_OK)
565                 mask |= INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY;
566         }
567         
568         if (!IsDynamic())
569         {
570             mask |= INTEROP_ATTRIBUTE_CACHED;
571             m_InteropAttributeStatus = static_cast<InteropAttributeStatus>(mask);
572         }
573
574         return static_cast<InteropAttributeStatus>(mask);
575     }
576 #endif // FEATURE_INTEROP
577
578 private:
579
580     //****************************************************************************************
581
582     void CacheManifestExportedTypes(AllocMemTracker *pamTracker);
583     void CacheManifestFiles();
584
585     void CacheFriendAssemblyInfo();
586    
587
588     PTR_BaseDomain        m_pDomain;        // Parent Domain
589     PTR_ClassLoader       m_pClassLoader;   // Single Loader
590
591
592
593     PTR_MethodDesc        m_pEntryPoint;    // Method containing the entry point
594     PTR_Module            m_pManifest;
595     PTR_PEAssembly        m_pManifestFile;
596
597     FriendAssemblyDescriptor *m_pFriendAssemblyDescriptor;
598
599     BOOL                  m_isDynamic;
600 #ifdef FEATURE_COLLECTIBLE_TYPES
601     BOOL                  m_isCollectible;
602 #endif // FEATURE_COLLECTIBLE_TYPES
603     DWORD                 m_nextAvailableModuleIndex;
604     PTR_LoaderAllocator   m_pLoaderAllocator;
605     DWORD                 m_isDisabledPrivateReflection;
606
607 #ifdef FEATURE_COMINTEROP
608     // If a TypeLib is ever required for this module, cache the pointer here.
609     ITypeLib              *m_pITypeLib;
610     InteropAttributeStatus m_InteropAttributeStatus;
611
612     WinMDStatus            m_winMDStatus;
613     IWinMDImport          *m_pManifestWinMDImport;
614 #endif // FEATURE_COMINTEROP
615
616     DebuggerAssemblyControlFlags m_debuggerFlags;
617
618     BOOL                  m_fTerminated;
619
620     BOOL                  m_fIsSIMDVectorAssembly;
621
622 #if defined(FEATURE_PREJIT) || defined(FEATURE_READYTORUN)
623     enum IsInstrumentedStatus {
624         IS_INSTRUMENTED_UNSET = 0,
625         IS_INSTRUMENTED_FALSE = 1,
626         IS_INSTRUMENTED_TRUE = 2,
627     };
628     IsInstrumentedStatus    m_isInstrumentedStatus;
629 #endif // FEATURE_PREJIT
630
631 };
632
633 typedef Assembly::ModuleIterator ModuleIterator;
634
635 #ifndef DACCESS_COMPILE
636
637 //---------------------------------------------------------------------------------------
638 //
639 // FriendSecurityDescriptor contains information on which assemblies are friends of an assembly, as well as
640 // which individual internals are visible to those friend assemblies.
641 //
642
643 class FriendAssemblyDescriptor
644 {
645 public:
646     ~FriendAssemblyDescriptor();
647
648     static
649     FriendAssemblyDescriptor *CreateFriendAssemblyDescriptor(PEAssembly *pAssembly);
650
651     //---------------------------------------------------------------------------------------
652     //
653     // Checks to see if an assembly has friend access to a particular member.
654     //
655     // Arguments:
656     //    pAccessingAssembly - the assembly requesting friend access
657     //    pMember            - the member that is attempting to be accessed
658     //
659     // Return Value:
660     //    true if friend access is allowed, false otherwise
661     //    
662     // Notes:
663     //    Template type T should be either FieldDesc, MethodDesc, or MethodTable.
664     //
665
666     template <class T>
667     bool GrantsFriendAccessTo(Assembly *pAccessingAssembly, T *pMember)
668     {
669         CONTRACTL
670         {
671             THROWS;
672             GC_TRIGGERS;
673             PRECONDITION(CheckPointer(pAccessingAssembly));
674             PRECONDITION(CheckPointer(pMember));
675         }
676         CONTRACTL_END;
677
678         return IsAssemblyOnList(pAccessingAssembly, m_alFullAccessFriendAssemblies);
679     }
680
681
682     bool IgnoresAccessChecksTo(Assembly *pAccessedAssembly)
683     {
684         return IsAssemblyOnList(pAccessedAssembly, m_subjectAssemblies);
685     }
686
687 private:
688     typedef AssemblySpec FriendAssemblyName_t;
689     typedef NewHolder<AssemblySpec> FriendAssemblyNameHolder;
690
691     ArrayList                  m_alFullAccessFriendAssemblies;      // Friend assemblies which have access to all internals
692     ArrayList                  m_subjectAssemblies;                 // Subject assemblies which we will not perform access checks against
693
694     FriendAssemblyDescriptor();
695
696     void AddFriendAssembly(FriendAssemblyName_t *pFriendAssembly);
697     void AddSubjectAssembly(FriendAssemblyName_t *pSubjectAssembly);
698
699     static
700     bool IsAssemblyOnList(Assembly *pAssembly, const ArrayList &alAssemblyNames)
701     {
702         return IsAssemblyOnList(pAssembly->GetManifestFile(), alAssemblyNames);
703     }
704
705     static
706     bool IsAssemblyOnList(PEAssembly *pAssembly, const ArrayList &alAssemblyNames);
707 };
708
709 #endif // !DACCESS_COMPILE
710
711
712 #endif