summaryrefslogtreecommitdiff
path: root/src/vm/newcompressedstack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/newcompressedstack.cpp')
-rw-r--r--src/vm/newcompressedstack.cpp1074
1 files changed, 0 insertions, 1074 deletions
diff --git a/src/vm/newcompressedstack.cpp b/src/vm/newcompressedstack.cpp
deleted file mode 100644
index 5957dc37f4..0000000000
--- a/src/vm/newcompressedstack.cpp
+++ /dev/null
@@ -1,1074 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-
-//
-
-#include "common.h"
-#ifdef FEATURE_COMPRESSEDSTACK
-
-#include "newcompressedstack.h"
-#include "security.h"
-#ifdef FEATURE_REMOTING
-#include "appdomainhelper.h"
-#endif
-#include "securitystackwalk.h"
-#include "appdomainstack.inl"
-#include "appdomain.inl"
-
-
-DomainCompressedStack::DomainCompressedStack(ADID domainID)
-: m_DomainID(domainID),
- m_ignoreAD(FALSE),
- m_dwOverridesCount(0),
- m_dwAssertCount(0),
- m_Homogeneous(FALSE)
-{
- WRAPPER_NO_CONTRACT;
-}
-
-BOOL DomainCompressedStack::IsAssemblyPresent(ISharedSecurityDescriptor* ssd)
-{
- CONTRACTL
- {
- MODE_ANY;
- GC_NOTRIGGER;
- NOTHROW;
- }CONTRACTL_END;
-
-
- // Only checks the first level and does not recurse into compressed stacks
- void* pEntry = NULL;
-
- if (m_EntryList.GetCount() == 0)
- return FALSE;
-
- // Quick check the last entry we added - common case
- pEntry = m_EntryList.Get(m_EntryList.GetCount() - 1);
- if (pEntry == (void *)SET_LOW_BIT(ssd))
- return TRUE;
-
- // Go thru the whole list now - is this optimal?
- ArrayList::Iterator iter = m_EntryList.Iterate();
-
- while (iter.Next())
- {
- pEntry = iter.GetElement();
- if (pEntry == (void *)SET_LOW_BIT(ssd))
- return TRUE;
- }
- return FALSE;
-}
-
-void DomainCompressedStack::AddEntry(void * ptr)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- IfFailThrow(m_EntryList.Append(ptr));
-
-}
-VOID FrameSecurityDescriptorCopyFrom(FRAMESECDESCREF newFsdRef, FRAMESECDESCREF fsd)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- newFsdRef->SetImperativeAssertions(fsd->GetImperativeAssertions());
- newFsdRef->SetImperativeDenials(fsd->GetImperativeDenials());
- newFsdRef->SetImperativeRestrictions(fsd->GetImperativeRestrictions());
- newFsdRef->SetDeclarativeAssertions(fsd->GetDeclarativeAssertions());
- newFsdRef->SetDeclarativeDenials(fsd->GetDeclarativeDenials());
- newFsdRef->SetDeclarativeRestrictions(fsd->GetDeclarativeRestrictions());
- newFsdRef->SetAssertAllPossible(fsd->HasAssertAllPossible());
- newFsdRef->SetAssertFT(fsd->HasAssertFT());
-}
-
-void DomainCompressedStack::AddFrameEntry(AppDomain *pAppDomain, FRAMESECDESCREF fsdRef, BOOL bIsAHDMFrame, OBJECTREF dynamicResolverRef)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- ENTER_DOMAIN_PTR(pAppDomain,ADV_RUNNINGIN) //have it on the stack
- {
- struct gc
- {
- OBJECTREF fsdRef;
- OBJECTREF newFsdRef;
- OBJECTREF dynamicResolverRef;
- } gc;
- ZeroMemory( &gc, sizeof( gc ) );
- gc.fsdRef = (OBJECTREF)fsdRef;
- gc.dynamicResolverRef = dynamicResolverRef;
-
- GCPROTECT_BEGIN(gc);
-
- static MethodTable* pMethFrameSecDesc = NULL;
- if (pMethFrameSecDesc == NULL)
- pMethFrameSecDesc = MscorlibBinder::GetClass(CLASS__FRAME_SECURITY_DESCRIPTOR);
-
- static MethodTable* pMethFrameSecDescWCS = NULL;
- if (pMethFrameSecDescWCS == NULL)
- pMethFrameSecDescWCS = MscorlibBinder::GetClass(CLASS__FRAME_SECURITY_DESCRIPTOR_WITH_RESOLVER);
-
- if(!bIsAHDMFrame)
- {
- gc.newFsdRef = AllocateObject(pMethFrameSecDesc);
- }
- else
- {
- gc.newFsdRef = AllocateObject(pMethFrameSecDescWCS);
- }
-
- // We will not call the ctor and instead patch up the object based on the fsdRef passed in
- FRAMESECDESCREF newFsdRef = (FRAMESECDESCREF)gc.newFsdRef;
- FRAMESECDESCREF fsdRef1 = (FRAMESECDESCREF)gc.fsdRef;
- if(fsdRef1 != NULL)
- {
- FrameSecurityDescriptorCopyFrom(newFsdRef, fsdRef1);
- }
- if(bIsAHDMFrame)
- {
- _ASSERTE(gc.dynamicResolverRef != NULL);
- ((FRAMESECDESWITHRESOLVERCREF)newFsdRef)->SetDynamicMethodResolver(gc.dynamicResolverRef);
- }
- OBJECTHANDLEHolder tmpHnd(pAppDomain->CreateHandle(gc.newFsdRef));
-
- AddEntry((void*)tmpHnd);
- tmpHnd.SuppressRelease();
- GCPROTECT_END();
-
- }
- END_DOMAIN_TRANSITION;
-
-}
-
-
-void DomainCompressedStack::Destroy(void)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Clear Domain info (handles etc.) if the AD has not been unloaded.
- ClearDomainInfo();
- return;
-}
-
-FCIMPL1(DWORD, DomainCompressedStack::GetDescCount, DomainCompressedStack* dcs)
-{
- FCALL_CONTRACT;
-
- FCUnique(0x42);
-
- return dcs->m_EntryList.GetCount();
-}
-FCIMPLEND
-
-FCIMPL3(void, DomainCompressedStack::GetDomainPermissionSets, DomainCompressedStack* dcs, OBJECTREF* ppGranted, OBJECTREF* ppDenied)
-{
- FCALL_CONTRACT;
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
- *ppGranted = NULL;
- *ppDenied = NULL;
-
- AppDomain* appDomain = SystemDomain::GetAppDomainFromId(dcs->GetMyDomain(),ADV_RUNNINGIN);
- if (appDomain == NULL)
- {
- // this might be the unloading AD
- AppDomain *pUnloadingDomain = SystemDomain::System()->AppDomainBeingUnloaded();
- if (pUnloadingDomain && pUnloadingDomain->GetId() == dcs->m_DomainID)
- {
-#ifdef _DEBUG
- CheckADValidity(pUnloadingDomain, ADV_RUNNINGIN);
-#endif
- appDomain = pUnloadingDomain;
- }
- }
- _ASSERTE(appDomain != NULL);
- if (appDomain != NULL)
- {
- IApplicationSecurityDescriptor * pAppSecDesc = appDomain->GetSecurityDescriptor();
- _ASSERTE(pAppSecDesc != NULL);
- if (pAppSecDesc != NULL)
- {
- *ppGranted = pAppSecDesc->GetGrantedPermissionSet(ppDenied);
- }
- }
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-FCIMPL6(FC_BOOL_RET, DomainCompressedStack::GetDescriptorInfo, DomainCompressedStack* dcs, DWORD index, OBJECTREF* ppGranted, OBJECTREF* ppDenied, OBJECTREF* ppAssembly, OBJECTREF* ppFSD)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(dcs != NULL);
- AppDomain* pCurrentDomain = GetAppDomain();
- BOOL bRetVal = FALSE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_0()
- *ppGranted = NULL;
- *ppDenied = NULL;
- *ppAssembly = NULL;
- *ppFSD = NULL;
- void* pEntry = dcs->m_EntryList.Get(index);
- _ASSERTE(pEntry != NULL);
- if (IS_LOW_BIT_SET(pEntry))
- {
- // Assembly found
- SharedSecurityDescriptor* pSharedSecDesc = (SharedSecurityDescriptor* )UNSET_LOW_BIT(pEntry);
- Assembly* pAssembly = pSharedSecDesc->GetAssembly();
- IAssemblySecurityDescriptor* pAsmSecDesc = pAssembly->GetSecurityDescriptor( pCurrentDomain );
- *ppGranted = pAsmSecDesc->GetGrantedPermissionSet(ppDenied);
- *ppAssembly = pAssembly->GetExposedObject();
- }
- else
- {
- //FSD
- OBJECTHANDLE objHnd = (OBJECTHANDLE)pEntry;
- if (objHnd == NULL)
- {
- // throw an ADUnloaded exception which we will catch and then look at the serializedBlob
- COMPlusThrow(kAppDomainUnloadedException);
- }
- *ppFSD = ObjectFromHandle(objHnd);
- bRetVal = TRUE;
- }
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(bRetVal);
-}
-FCIMPLEND
-
-FCIMPL1(FC_BOOL_RET, DomainCompressedStack::IgnoreDomain, DomainCompressedStack* dcs)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(dcs != NULL);
-
- FC_RETURN_BOOL(dcs->IgnoreDomainInternal());
-}
-FCIMPLEND
-
-BOOL DomainCompressedStack::IgnoreDomainInternal()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if (m_ignoreAD)
- return TRUE;
-
- AppDomainFromIDHolder appDomain(GetMyDomain(), TRUE);
- if (!appDomain.IsUnloaded())
- {
- IApplicationSecurityDescriptor *pAppSecDesc = appDomain->GetSecurityDescriptor();
- _ASSERTE(pAppSecDesc != NULL);
- if (pAppSecDesc != NULL)
- {
- return pAppSecDesc->IsDefaultAppDomain() || pAppSecDesc->IsInitializationInProgress();
- }
- }
-
- return FALSE;
-}
-
-
-/*
- Note that this function is called only once: when the managed PLS is being created.
- It's possible that 2 threads could race at that point: only downside of that is that they will both do the work. No races.
- Also, we'll never be operating on a DCS whose domain is not on the current callstack. This eliminates all kinds of ADU/demand eval races.
-*/
-OBJECTREF DomainCompressedStack::GetDomainCompressedStackInternal(AppDomain *pDomain)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- // If we are going to skip this AppDomain, and there is nothing to compress, then we can skip building the DCS.
- if (m_EntryList.GetCount() == 0 && IgnoreDomainInternal())
- return NULL;
-
- AppDomain* pCurrentDomain = GetAppDomain();
-
- NewArrayHolder<BYTE> pbtmpSerializedObject(NULL);
-#ifndef FEATURE_CORECLR
- DWORD cbtmpSerializedObject = 0;
-#endif
-
- struct gc
- {
- OBJECTREF refRetVal;
- } gc;
- ZeroMemory( &gc, sizeof( gc ) );
-
- GCPROTECT_BEGIN( gc );
-
- // Create object
- ENTER_DOMAIN_ID (GetMyDomain()) //on the stack
- {
-
- // Go ahead and create the object
-#ifdef FEATURE_CORECLR // ignore other appdomains
- if (GetAppDomain() == pCurrentDomain)
-#endif
- {
- MethodDescCallSite createManagedObject(METHOD__DOMAIN_COMPRESSED_STACK__CREATE_MANAGED_OBJECT);
- ARG_SLOT args[] = {PtrToArgSlot(this)};
- gc.refRetVal = createManagedObject.Call_RetOBJECTREF(args);
- }
-
-#ifndef FEATURE_CORECLR
- // Do we want to marshal this object also?
- if (GetAppDomain() != pCurrentDomain)
- {
- // Serialize to a blob;
- AppDomainHelper::MarshalObject(GetAppDomain(), &gc.refRetVal, &pbtmpSerializedObject, &cbtmpSerializedObject);
- if (pbtmpSerializedObject == NULL)
- {
- // this is an error: possibly an OOM prevented the blob from getting created.
- // We could return null and let the managed code use a fully restricted object or throw here.
- // Let's throw here...
- COMPlusThrow(kSecurityException);
- }
- }
-#endif
-
- }
- END_DOMAIN_TRANSITION
-
-#ifndef FEATURE_CORECLR // should never happen for core clr
- if (GetMyDomain() != pCurrentDomain->GetId())
- {
- AppDomainHelper::UnmarshalObject(pCurrentDomain,pbtmpSerializedObject, cbtmpSerializedObject, &gc.refRetVal);
- }
-#endif
-
- GCPROTECT_END();
-
- return gc.refRetVal;
-}
-
-
-void DomainCompressedStack::ClearDomainInfo(void)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-
- // So, assume mutual exclusion holds and no races occur here
-
-
- // Now it is time to go NULL out any ObjectHandle we're using in the list of entries
- ArrayList::Iterator iter = m_EntryList.Iterate();
-
- while (iter.Next())
- {
- void* pEntry = iter.GetElement();
- if (!IS_LOW_BIT_SET(pEntry))
- {
- DestroyHandle((OBJECTHANDLE)pEntry);
- }
- pEntry = NULL;
- }
-
-
- // Always clear the index into the domain object list and the domainID.
- m_DomainID = ADID(INVALID_APPDOMAIN_ID);
- return;
-}
-
-NewCompressedStack::NewCompressedStack()
-: m_DCSListCount(0),
- m_currentDCS(NULL),
- m_pCtxTxFrame(NULL),
- m_CSAD(ADID(INVALID_APPDOMAIN_ID)),
- m_ADStack(GetThread()->GetAppDomainStack()),
- m_dwOverridesCount(0),
- m_dwAssertCount(0)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- _ASSERTE(m_ADStack.GetNumDomains() > 0);
- m_ADStack.InitDomainIteration(&adStackIndex);
- m_DCSList = new DomainCompressedStack*[m_ADStack.GetNumDomains()];
- memset(m_DCSList, 0, (m_ADStack.GetNumDomains()*sizeof(DomainCompressedStack*)));
-
-}
-
-
-void NewCompressedStack::Destroy( CLR_BOOL bEntriesOnly )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (m_DCSList != NULL)
- {
- m_currentDCS = NULL;
- m_pCtxTxFrame = NULL;
- for (DWORD i=0; i< m_ADStack.GetNumDomains(); i++)
- {
- DomainCompressedStack* dcs = m_DCSList[i];
- if (dcs != NULL)
- {
- dcs->Destroy();
- delete dcs;
- }
- }
- delete[] m_DCSList;
- m_DCSList = NULL;
- }
- if (!bEntriesOnly)
- delete this;
-
-}
-
-
-void NewCompressedStack::ProcessAppDomainTransition(void)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- } CONTRACTL_END;
-
- // Get the current adstack entry. Note that the first time we enter this function, adStackIndex will
- // equal the size of the adstack array (similar to what happens in IEnumerator).
- // So the initial pEntry will be NULL
- AppDomainStackEntry *pEntry =
- (adStackIndex == m_ADStack.GetNumDomains() ? NULL : m_ADStack.GetCurrentDomainEntryOnStack(adStackIndex));
-
- // Updated the value on the ADStack for current domain
- if (pEntry != NULL)
- {
- DWORD domainOverrides_measured = (m_currentDCS == NULL?0:m_currentDCS->GetOverridesCount());
- DWORD domainAsserts_measured = (m_currentDCS == NULL?0:m_currentDCS->GetAssertCount());
- if (pEntry->m_dwOverridesCount != domainOverrides_measured || pEntry->m_dwAsserts != domainAsserts_measured)
- {
- m_ADStack.UpdateDomainOnStack(adStackIndex, domainAsserts_measured, domainOverrides_measured);
- GetThread()->UpdateDomainOnStack(adStackIndex, domainAsserts_measured, domainOverrides_measured);
- }
- }
-
- // Move the domain index forward if this is not the last entry
- if (adStackIndex > 0)
- m_ADStack.GetNextDomainEntryOnStack(&adStackIndex);
- m_currentDCS = NULL;
-
- return;
-
-}
-DWORD NewCompressedStack::ProcessFrame(AppDomain* pAppDomain, Assembly* pAssembly, MethodDesc* pFunc, ISharedSecurityDescriptor* pSsd, FRAMESECDESCREF* pFsdRef)
-{
- // This function will be called each time we hit a new stack frame in a stack walk.
-
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pAppDomain));
- PRECONDITION(CheckPointer(pSsd));
- } CONTRACTL_END;
-
- // Get the current adstack entry. Note that the first time we enter this function, adStackIndex will
- // equal the size of the adstack array (similar to what happens in IEnumerator).
- // So the initial pEntry will be NULL
- AppDomainStackEntry *pEntry =
- (adStackIndex == m_ADStack.GetNumDomains() ? NULL : m_ADStack.GetCurrentDomainEntryOnStack(adStackIndex));
-
-
- _ASSERTE(pEntry != NULL);
- PREFIX_ASSUME(pEntry != NULL);
- FRAMESECDESCREF FsdRef = (pFsdRef!=NULL?*pFsdRef:NULL);
- DWORD dwFlags = 0;
- if (FsdRef != NULL)
- {
-
- if (FsdRef->HasAssertFT())
- dwFlags |= CORSEC_FT_ASSERT;
- }
-
- BOOL bIsAHDMFrame = FALSE;
-
- if((pFunc != NULL) && !CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_Security_DisableAnonymouslyHostedDynamicMethodCreatorSecurityCheck))
- {
- ENTER_DOMAIN_PTR(pAppDomain, ADV_RUNNINGIN)
- {
- bIsAHDMFrame = SecurityStackWalk::MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(pFunc);
- }
- END_DOMAIN_TRANSITION;
- }
-
- if (!bIsAHDMFrame && ((pEntry->IsFullyTrustedWithNoStackModifiers()) ||
- (m_currentDCS != NULL && m_currentDCS->m_Homogeneous)))
- {
- // Nothing to do in this entire AD.
- return dwFlags;
- }
-
- ADID dNewDomainID = pAppDomain->GetId();
- BOOL bAddSSD = (!pSsd->IsSystem() && !IsAssemblyPresent(dNewDomainID, pSsd));
- BOOL bHasStackModifiers = FALSE;
- DWORD overridesCount = 0;
- DWORD assertCount = 0;
-
-
- if (FsdRef != NULL)
- {
- overridesCount += FsdRef->GetOverridesCount();
- assertCount += FsdRef->GetAssertCount();
- }
-
- // If this is an AHDM frame with a CS to evaluate, it may have overrides or asserts,
- // so treat it as if it does
- if(bIsAHDMFrame)
- {
- overridesCount++;
- assertCount++;
- }
-
- bHasStackModifiers = ( (assertCount + overridesCount) > 0);
-
- //
- // We need to add a new DCS if we don't already have one for this AppDomain. If we've reached this
- // point, either:
- // * the AppDomain is partially trusted
- // * the AppDomain is fully trusted, but may have stack modifiers in play
- // * we're running in legacy mode where FullTrust doesn't mean FullTrust
- //
- // If the domain is partially trusted, we'll always need to capture it. If we got this far due to a
- // fully trusted domain that might have stack modifiers, we only have to capture if there really were
- // stack walk modifiers. In the legacy mode case, we need to capture the domain if we had stack
- // modifiers or we needed to add the shared security descriptor.
- //
-
- BOOL bCreateDCS = (m_currentDCS == NULL || m_currentDCS->m_DomainID != dNewDomainID);
- if (pAppDomain->GetSecurityDescriptor()->IsFullyTrusted())
- {
- bCreateDCS &= (bAddSSD || bHasStackModifiers);
- }
-
- if (bCreateDCS)
- {
- CreateDCS(dNewDomainID);
- }
-
- // Add the ISharedSecurityDescriptor (Assembly) to the list if it is not already present in the list
- if (bAddSSD)
- {
- m_currentDCS->AddEntry((void*)SET_LOW_BIT(pSsd));
- if (pEntry->IsHomogeneousWithNoStackModifiers())
- m_currentDCS->m_Homogeneous = TRUE;
- }
- if (bHasStackModifiers)
- {
- OBJECTREF dynamicResolverRef = NULL;
- if(bIsAHDMFrame)
- {
- _ASSERTE(pFunc->IsLCGMethod());
- dynamicResolverRef = pFunc->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver();
- }
-
- // We need to add the FSD entry here
- m_currentDCS->AddFrameEntry(pAppDomain, FsdRef, bIsAHDMFrame, dynamicResolverRef);
- m_currentDCS->m_dwOverridesCount += overridesCount;
- m_currentDCS->m_dwAssertCount += assertCount;
- m_dwOverridesCount += overridesCount;
- m_dwAssertCount += assertCount;
- }
- return dwFlags;
-}
-
-// Build a CompressedStack given that all domains on the stack are homogeneous with no stack modifiers
-FCIMPL1(void, NewCompressedStack::FCallGetHomogeneousPLS, Object* hgPLSUnsafe)
-{
- FCALL_CONTRACT;
-
- OBJECTREF refHomogeneousPLS = (OBJECTREF)hgPLSUnsafe;
-
- HELPER_METHOD_FRAME_BEGIN_1(refHomogeneousPLS);
-
-
- // Walk the adstack and update the grantSetUnion
- AppDomainStack* pADStack = GetThread()->GetAppDomainStackPointer();
- DWORD dwAppDomainIndex;
- pADStack->InitDomainIteration(&dwAppDomainIndex);
-
-#ifdef FEATURE_REMOTING // without remoting we need only current appdomain
- while (dwAppDomainIndex != 0)
-#endif
- {
- AppDomainStackEntry* pEntry = pADStack->GetNextDomainEntryOnStack(&dwAppDomainIndex);
- _ASSERTE(pEntry != NULL);
-
- pEntry->UpdateHomogeneousPLS(&refHomogeneousPLS);
- }
-
-
- HELPER_METHOD_FRAME_END();
- return ;
-}
-FCIMPLEND;
-
-// Special case of ProcessFrame called with the CS at the base of the thread
-void NewCompressedStack::ProcessCS(AppDomain* pAppDomain, COMPRESSEDSTACKREF csRef, Frame *pFrame)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pAppDomain));
- } CONTRACTL_END;
-
- _ASSERTE(csRef != NULL && "Shouldn't call this function if CS is NULL");
- ADID dNewDomainID = pAppDomain->GetId();
- NewCompressedStack* pCS = (NewCompressedStack* )csRef->GetUnmanagedCompressedStack();
- if (csRef->IsEmptyPLS() && (pCS == NULL || pCS->GetDCSListCount() == 0))
- {
- // Do nothing - empty inner CS
- return;
- }
-
- // Let's special case the 1-domain CS that has no inner CSs here
- // Check for:
- // 1. == 1 DCS
- // 2. DCS is in correct AD (it's possible that pCS is AD-X and it has only one DCS in AD-Y, because AD-X has only mscorlib frames
- // 3. No inner CS
- if ( pCS != NULL &&
- pCS->GetDCSListCount() == 1 &&
- pCS->m_DCSList != NULL &&
- pCS->m_currentDCS != NULL &&
- pCS->m_currentDCS->m_DomainID == dNewDomainID &&
- pCS->m_CSAD == ADID(INVALID_APPDOMAIN_ID))
- {
- ProcessSingleDomainNCS(pCS, pAppDomain);
- }
- else
- {
-
- // set flag to ignore Domain grant set if the current DCS is the same as the one with the CS
- if (m_currentDCS != NULL && m_currentDCS->m_DomainID == dNewDomainID)
- {
- m_currentDCS->m_ignoreAD = TRUE;
- }
-
- // Update overrides/asserts
- if (pCS != NULL)
- {
- m_dwOverridesCount += pCS->GetOverridesCount();
- m_dwAssertCount += pCS->GetAssertCount();
- }
-
-
- // Do we need to store the CtxTransitionFrame or did we get the CS from the thread?
- if (pFrame != NULL)
- {
- _ASSERTE(csRef == SecurityStackWalk::GetCSFromContextTransitionFrame(pFrame));
- // Use data from the CtxTxFrame
- m_pCtxTxFrame = pFrame;
- }
- m_CSAD = dNewDomainID;
- }
-
-}
-void NewCompressedStack::ProcessSingleDomainNCS(NewCompressedStack *pCS, AppDomain* pAppDomain)
-{
-
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pAppDomain));
- } CONTRACTL_END;
-
- _ASSERTE(pCS->GetDCSListCount() <= 1 && pCS->m_CSAD == ADID(INVALID_APPDOMAIN_ID));
- ADID newDomainID = pAppDomain->GetId();
- DomainCompressedStack* otherDCS = pCS->m_currentDCS;
-
- if (otherDCS == NULL)
- return;
- if (m_currentDCS == NULL)
- CreateDCS(newDomainID);
-
-
- // Iterate thru the entryList in the current DCS
- ArrayList::Iterator iter = otherDCS->m_EntryList.Iterate();
- while (iter.Next())
- {
- void* pEntry = iter.GetElement();
- if (IS_LOW_BIT_SET(pEntry))
- {
- if (!IsAssemblyPresent(newDomainID, (ISharedSecurityDescriptor*)UNSET_LOW_BIT(pEntry)))
- {
- //Add the assembly
- m_currentDCS->AddEntry(pEntry);
- }
- }
- else
- {
- // FrameSecurityDescriptor
- OBJECTHANDLE objHnd = (OBJECTHANDLE)pEntry;
- OBJECTREF fsdRef = ObjectFromHandle(objHnd);
- OBJECTHANDLEHolder tmpHnd(pAppDomain->CreateHandle(fsdRef));
-
- m_currentDCS->AddEntry((void*)tmpHnd);
- tmpHnd.SuppressRelease();
-
- }
-
- }
-
- m_currentDCS->m_dwOverridesCount += pCS->m_dwOverridesCount;
- m_currentDCS->m_dwAssertCount += pCS->m_dwAssertCount;
- m_dwOverridesCount += pCS->m_dwOverridesCount;
- m_dwAssertCount += pCS->m_dwAssertCount;
-}
-void NewCompressedStack::CreateDCS(ADID domainID)
-{
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- _ASSERTE(adStackIndex < m_ADStack.GetNumDomains());
- _ASSERTE (m_DCSList != NULL);
- m_DCSList[adStackIndex] = new DomainCompressedStack(domainID);
- m_currentDCS = m_DCSList[adStackIndex];
- m_DCSListCount++;
-
- return;
-}
-
-
-BOOL NewCompressedStack::IsAssemblyPresent(ADID domainID, ISharedSecurityDescriptor* pSsd)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- _ASSERTE(domainID != ADID(INVALID_APPDOMAIN_ID) && "Don't pass invalid domain");
-
- BOOL bEntryPresent = FALSE;
-
- for(DWORD i=0; i < m_ADStack.GetNumDomains(); i++)
- {
-
- DomainCompressedStack* pTmpDCS = m_DCSList[i];
-
- if (pTmpDCS != NULL && pTmpDCS->m_DomainID == domainID && pTmpDCS->IsAssemblyPresent(pSsd))
- {
- bEntryPresent = TRUE;
- break;
- }
- }
- return bEntryPresent;
-}
-
-
-BOOL NewCompressedStack::IsDCSContained(DomainCompressedStack *pDCS)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // return FALSE if no DCS or DCS is for a domain that has been unloaded
- if (pDCS == NULL || pDCS->m_DomainID == ADID(INVALID_APPDOMAIN_ID))
- return FALSE;
-
-
-
- // Iterate thru the entryList in the current DCS
- ArrayList::Iterator iter = pDCS->m_EntryList.Iterate();
- while (iter.Next())
- {
- void* pEntry = iter.GetElement();
- if (IS_LOW_BIT_SET(pEntry))
- {
- // We only check Assemblies.
- if (!IsAssemblyPresent(pDCS->m_DomainID, (ISharedSecurityDescriptor*)UNSET_LOW_BIT(pEntry)))
- return FALSE;
- }
- }
- return TRUE;
-}
-
-BOOL NewCompressedStack::IsNCSContained(NewCompressedStack *pCS)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Check if the first level of pCS is contained in this.
- if (pCS == NULL)
- return TRUE;
-
- // Return FALSE if there are any overrides or asserts
- if (pCS->GetOverridesCount() > 0)
- return FALSE;
- // Return FALSE if there is an inner CS
- if (pCS->m_CSAD != ADID(INVALID_APPDOMAIN_ID))
- return FALSE;
-
- for(DWORD i=0; i < m_ADStack.GetNumDomains(); i++)
- {
- DomainCompressedStack *pDCS = (DomainCompressedStack *) m_DCSList[i];
- if (!IsDCSContained(pDCS))
- return FALSE;
- }
- return TRUE;
-
-}
-
-
-// If there is a compressed stack present in the captured CompressedStack, return that CS in the current domain
-OBJECTREF NewCompressedStack::GetCompressedStackInner()
-{
- _ASSERTE(m_CSAD != ADID(INVALID_APPDOMAIN_ID));
-
- AppDomain* pCurrentDomain = GetAppDomain();
- NewArrayHolder<BYTE> pbtmpSerializedObject(NULL);
-
-
- OBJECTREF refRetVal = NULL;
-
- if (pCurrentDomain->GetId()== m_CSAD)
- {
- // we're in the right domain already
- if (m_pCtxTxFrame == NULL)
- {
- // Get CS from the thread
- refRetVal = GetThread()->GetCompressedStack();
- }
- else
- {
- // Get CS from a Ctx transition frame
- refRetVal = (OBJECTREF)SecurityStackWalk::GetCSFromContextTransitionFrame(m_pCtxTxFrame);
- _ASSERTE(refRetVal != NULL); //otherwise we would not have saved the frame in the CB data
- }
- }
- else
-#ifndef FEATURE_CORECLR // should never happen for core clr
- {
- DWORD cbtmpSerializedObject = 0;
- GCPROTECT_BEGIN (refRetVal);
- // need to marshal the CS over into the current AD
- ENTER_DOMAIN_ID(m_CSAD);
- {
- if (m_pCtxTxFrame == NULL)
- {
-
- // Get CS from the thread
- refRetVal = GetThread()->GetCompressedStack();
- }
- else
- {
- // Get CS from a Ctx transition frame
- refRetVal = (OBJECTREF)SecurityStackWalk::GetCSFromContextTransitionFrame(m_pCtxTxFrame);
- _ASSERTE(refRetVal != NULL); //otherwise we would not have saved the frame in the CB data
- }
- AppDomainHelper::MarshalObject(GetAppDomain(), &refRetVal, &pbtmpSerializedObject, &cbtmpSerializedObject);
- }
- END_DOMAIN_TRANSITION
- refRetVal = NULL;
- AppDomainHelper::UnmarshalObject(pCurrentDomain,pbtmpSerializedObject, cbtmpSerializedObject, &refRetVal);
- GCPROTECT_END ();
- _ASSERTE(refRetVal != NULL); //otherwise we would not have saved the frame in the CB data
- }
-#else
- {
- UNREACHABLE();
- }
-#endif // !FEATURE_CORECLR
-
- return refRetVal;
-
-}
-
-// == Now begin the functions used in building Demand evaluation of a compressed stack
-FCIMPL1(DWORD, NewCompressedStack::FCallGetDCSCount, SafeHandle* hcsUNSAFE)
-{
- FCALL_CONTRACT;
-
- DWORD dwRet = 0;
- if (hcsUNSAFE != NULL)
- {
- SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(hcsSAFE);
-
- NewCompressedStack* ncs = (NewCompressedStack *)hcsSAFE->GetHandle();
-
- dwRet = ncs->m_ADStack.GetNumDomains();
- HELPER_METHOD_FRAME_END();
- }
-
- return dwRet;
-
-}
-FCIMPLEND
-
-
-FCIMPL2(FC_BOOL_RET, NewCompressedStack::FCallIsImmediateCompletionCandidate, SafeHandle* hcsUNSAFE, OBJECTREF *innerCS)
-{
- FCALL_CONTRACT;
-
- BOOL bRet = FALSE;
- if (hcsUNSAFE != NULL)
- {
- SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(hcsSAFE);
-
- *innerCS = NULL;
-
- NewCompressedStack* ncs = (NewCompressedStack *)hcsSAFE->GetHandle();
-
- if (ncs != NULL)
- {
- // Non-FT case
-
- // Is there an inner CS?
- BOOL bHasCS = (ncs->m_CSAD != ADID(INVALID_APPDOMAIN_ID));
-
- // Is there is a DCS not in the current AD
- BOOL bHasOtherAppDomain = FALSE;
- if (ncs->m_DCSList != NULL)
- {
- for(DWORD i=0; i < ncs->m_ADStack.GetNumDomains(); i++)
- {
- DomainCompressedStack* dcs = ncs->m_DCSList[i];
- if (dcs != NULL && dcs->GetMyDomain() != GetAppDomain()->GetId())
- {
- bHasOtherAppDomain = TRUE;
- break;
- }
- }
- }
- if (bHasCS)
- {
-
-
- *innerCS = ncs->GetCompressedStackInner();
- ncs->m_pCtxTxFrame = NULL; // Clear the CtxTxFrame ASAP
-
- }
- bRet = bHasOtherAppDomain||bHasCS;
- }
-
- HELPER_METHOD_FRAME_END();
- }
-
- FC_RETURN_BOOL(bRet);
-}
-FCIMPLEND
-
-
-FCIMPL2(Object*, NewCompressedStack::GetDomainCompressedStack, SafeHandle* hcsUNSAFE, DWORD index)
-{
- FCALL_CONTRACT;
-
- OBJECTREF refRetVal = NULL;
- if (hcsUNSAFE != NULL)
- {
- SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, hcsSAFE);
-
-
-
- NewCompressedStack* ncs = (NewCompressedStack *)hcsSAFE->GetHandle();
-
- // First we check to see if the DCS at index i has a blob. If so, deserialize it into the current AD and return it. Else try create it
- DomainCompressedStack* dcs = ncs->m_DCSList[index];
- if (dcs != NULL)
- {
- refRetVal = dcs->GetDomainCompressedStackInternal(NULL);
- }
-
- HELPER_METHOD_FRAME_END();
- }
-
- return OBJECTREFToObject(refRetVal);
-
-}
-FCIMPLEND
-
-FCIMPL1(void, NewCompressedStack::DestroyDCSList, SafeHandle* hcsUNSAFE)
-{
- FCALL_CONTRACT;
-
- SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_1(hcsSAFE);
-
- NewCompressedStack* ncs = (NewCompressedStack *)hcsSAFE->GetHandle();
-
- ncs->Destroy(TRUE);
-
- HELPER_METHOD_FRAME_END();
-
-}
-FCIMPLEND
-#endif // #ifdef FEATURE_COMPRESSEDSTACK