From: Jan Kotas Date: Thu, 23 Mar 2017 18:55:26 +0000 (-0700) Subject: Delete NewMerger X-Git-Tag: submit/tizen/20210909.063632~11030^2~7571^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a06e06cec750f52be2fd765bbc318864855e0576;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Delete NewMerger This was only used as part of C++ link.exe for IJW Commit migrated from https://github.com/dotnet/coreclr/commit/5c8cb3f135289edba7d79d121e6861fd611e3404 --- diff --git a/src/coreclr/src/md/compiler/CMakeLists.txt b/src/coreclr/src/md/compiler/CMakeLists.txt index 6d46dc0..4d99d11 100644 --- a/src/coreclr/src/md/compiler/CMakeLists.txt +++ b/src/coreclr/src/md/compiler/CMakeLists.txt @@ -11,7 +11,6 @@ set(MDCOMPILER_SOURCES import.cpp importhelper.cpp mdutil.cpp - newmerger.cpp regmeta.cpp regmeta_compilersupport.cpp regmeta_emit.cpp diff --git a/src/coreclr/src/md/compiler/mdperf.h b/src/coreclr/src/md/compiler/mdperf.h index 77def32..a83c8c9 100644 --- a/src/coreclr/src/md/compiler/mdperf.h +++ b/src/coreclr/src/md/compiler/mdperf.h @@ -143,7 +143,6 @@ MD_FUNC(GetCustomAttributeProps)\ MD_FUNC(FindTypeRef)\ MD_FUNC(RefToDefOptimization)\ - MD_FUNC(ProcessFilter)\ MD_FUNC(DefineAssembly)\ MD_FUNC(DefineAssemblyRef)\ MD_FUNC(DefineFile)\ diff --git a/src/coreclr/src/md/compiler/newmerger.cpp b/src/coreclr/src/md/compiler/newmerger.cpp deleted file mode 100644 index d5199bb..0000000 --- a/src/coreclr/src/md/compiler/newmerger.cpp +++ /dev/null @@ -1,6303 +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. -//***************************************************************************** -// NewMerger.cpp -// - -// -// contains utility code to MD directory -// -// This file provides Compiler Support functionality in metadata. -//***************************************************************************** -#include "stdafx.h" - -#include "newmerger.h" -#include "regmeta.h" - - -#include "importhelper.h" -#include "rwutil.h" -#include "mdlog.h" -#include -#include -#include "ndpversion.h" - -#ifdef FEATURE_METADATA_EMIT_ALL - -#define MODULEDEFTOKEN TokenFromRid(1, mdtModule) - -#define COR_MSCORLIB_NAME "mscorlib" -#define COR_MSCORLIB_TYPEREF {0xb7, 0x7a, 0x5c, 0x56,0x19,0x34,0xe0,0x89} - -#define COR_CONSTRUCTOR_METADATA_IDENTIFIER W(".ctor") - -#define COR_COMPILERSERVICE_NAMESPACE "System.Runtime.CompilerServices" -#define COR_EXCEPTIONSERVICE_NAMESPACE "System.Runtime.ExceptionServices" -#define COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE "SuppressMergeCheckAttribute" -#define COR_HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE "HandleProcessCorruptedStateExceptionsAttribute" -#define COR_MISCBITS_NAMESPACE "Microsoft.VisualC" -#define COR_MISCBITS_ATTRIBUTE "Microsoft.VisualC.MiscellaneousBitsAttribute" -#define COR_NATIVECPPCLASS_ATTRIBUTE "System.Runtime.CompilerServices.NativeCppClassAttribute" - -// MODULE_CA_LOCATION W("System.Runtime.CompilerServices.AssemblyAttributesGoHere") -#define MODULE_CA_TYPENAME "AssemblyAttributesGoHere" // fake assembly type-ref for hanging Assembly-level CAs off of - -//***************************************************************************** -// BEGIN: Security Critical Attributes and Enumeration -//***************************************************************************** -#define COR_SECURITYCRITICALSCOPE_ENUM_W W("System.Security.SecurityCriticalScope") - -#define COR_SECURITYCRITICAL_ATTRIBUTE_FULL "System.Security.SecurityCriticalAttribute" -#define COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL "System.Security.SecurityTransparentAttribute" -#define COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL "System.Security.SecurityTreatAsSafeAttribute" - -#define COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W W("System.Security.SecurityCriticalAttribute") -#define COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL_W W("System.Security.SecurityTransparentAttribute") -#define COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W W("System.Security.SecurityTreatAsSafeAttribute") -#define COR_SECURITYSAFECRITICAL_ATTRIBUTE_FULL_W W("System.Security.SecuritySafeCriticalAttribute") - - // definitions of enumeration for System.Security.SecurityCriticalScope (Explicit or Everything) -#define COR_SECURITYCRITICAL_CTOR_ARGCOUNT_NO_SCOPE 0 -#define COR_SECURITYCRITICAL_CTOR_ARGCOUNT_SCOPE_EVERYTHING 1 -#define COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE (3) -#define COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE (5 + sizeof(mdTypeRef) * 1) - -#define COR_SECURITYCRITICAL_ATTRIBUTE_NAMESPACE "System.Security" -#define COR_SECURITYCRITICAL_ATTRIBUTE "SecurityCriticalAttribute" -#define COR_SECURITYTRANSPARENT_ATTRIBUTE_NAMESPACE "System.Security" -#define COR_SECURITYTRANSPARENT_ATTRIBUTE "SecurityTransparentAttribute" -#define COR_SECURITYTREATASSAFE_ATTRIBUTE_NAMESPACE "System.Security" -#define COR_SECURITYTREATASSAFE_ATTRIBUTE "SecurityTreatAsSafeAttribute" -#define COR_SECURITYSAFECRITICAL_ATTRIBUTE "SecuritySafeCriticalAttribute" - - -#define COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING { 0x01, 0x00 ,0x01, 0x00, 0x00, 0x00 ,0x00, 0x00 } -#define COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EXPLICIT {0x01, 0x00, 0x00 ,0x00} -#define COR_SECURITYTREATASSAFE_ATTRIBUTE_VALUE {0x01, 0x00, 0x00 ,0x00} - - - // if true, then registry has been read for enabling or disabling SecurityCritical support -static BOOL g_fRefShouldMergeCriticalChecked = FALSE; - -// by default, security critical attributes will be merged (e.g. unmarked CRT marked Critical/TAS) -// - unless registry config explicitly disables merging -static BOOL g_fRefShouldMergeCritical = TRUE; -//***************************************************************************** -// END: Security Critical Attributes and Enumeration -//***************************************************************************** - -//***************************************************************************** -// Checks to see if the given type is managed or native. We'll key off of the -// Custom Attribute "Microsoft.VisualC.MiscellaneousBitsAttribute". If the third -// byte has the 01000000 bit set then it is an unmanaged type. -// If we can't find the attribute, we will also check for the presence of the -// "System.Runtime.CompilerServices.NativeCppClassAttribute" Custom Attribute -// since the CPP compiler stopped emitting MiscellaneousBitsAttribute in Dev11. -//***************************************************************************** -HRESULT IsManagedType(CMiniMdRW* pMiniMd, - mdTypeDef td, - BOOL *fIsManagedType) -{ - // First look for the custom attribute - HENUMInternal hEnum; - HRESULT hr = S_OK; - - IfFailRet(pMiniMd->CommonEnumCustomAttributeByName(td, COR_MISCBITS_ATTRIBUTE, false, &hEnum)); - - // If there aren't any custom attributes here, then this must be a managed type - if (hEnum.m_ulCount > 0) - { - // Let's loop through these, and see if any of them have that magical bit set. - mdCustomAttribute ca; - CustomAttributeRec *pRec; - ULONG cbData = 0; - - while(HENUMInternal::EnumNext(&hEnum, &ca)) - { - const BYTE* pData = NULL; - - IfFailGo(pMiniMd->GetCustomAttributeRecord(RidFromToken(ca), &pRec)); - IfFailGo(pMiniMd->getValueOfCustomAttribute(pRec, &pData, &cbData)); - - if (pData != NULL && cbData >=3) - { - // See if the magical bit is set to make this an unmanaged type - if ((*(pData+2)&0x40) > 0) - { - // Yes, this is an unmanaged type - HENUMInternal::ClearEnum(&hEnum); - *fIsManagedType = FALSE; - return S_OK; - } - } - } - - } - - HENUMInternal::ClearEnum(&hEnum); - - // If this was emitted by a Dev11+ CPP compiler, we only have NativeCppClassAttribute - // so let's check for that before calling this a managed class. - IfFailRet(pMiniMd->CommonEnumCustomAttributeByName(td, COR_NATIVECPPCLASS_ATTRIBUTE, false, &hEnum)); - if (hEnum.m_ulCount > 0) - { - // Yes, this is an unmanaged type - HENUMInternal::ClearEnum(&hEnum); - *fIsManagedType = FALSE; - return S_OK; - } - - // Nope, this isn't an unmanaged type.... must be managed - HENUMInternal::ClearEnum(&hEnum); - *fIsManagedType = TRUE; - hr = S_OK; -ErrExit: - return hr; -}// IsManagedType - - -//***************************************************************************** -// "Is CustomAttribute from certain namespace and assembly" check helper -// Returns S_OK and fills **ppTypeRefRec. -// Returns error code or S_FALSE otherwise as not found and fills **ppTypeRefRec with NULL. -//***************************************************************************** -HRESULT IsAttributeFromNamespace( - CMiniMdRW *pMiniMd, - mdToken tk, - LPCSTR szNamespace, - LPCSTR szAssembly, - TypeRefRec **ppTypeRefRec) -{ - HRESULT hr = S_OK; - if(TypeFromToken(tk) == mdtMemberRef) - { - MemberRefRec *pMemRefRec; - IfFailGo(pMiniMd->GetMemberRefRecord(RidFromToken(tk), &pMemRefRec)); - tk = pMiniMd->getClassOfMemberRef(pMemRefRec); - } - if(TypeFromToken(tk) == mdtTypeRef) - { - TypeRefRec *pTypeRefRec; - IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(tk), &pTypeRefRec)); - LPCSTR szTypeRefNamespace; - IfFailGo(pMiniMd->getNamespaceOfTypeRef(pTypeRefRec, &szTypeRefNamespace)); - if (strcmp(szTypeRefNamespace, szNamespace) == 0) - { - mdToken tkResTmp = pMiniMd->getResolutionScopeOfTypeRef(pTypeRefRec); - if (TypeFromToken(tkResTmp) == mdtAssemblyRef) - { - AssemblyRefRec *pAsmRefRec; - IfFailGo(pMiniMd->GetAssemblyRefRecord(RidFromToken(tkResTmp), &pAsmRefRec)); - LPCSTR szAssemblyRefName; - IfFailGo(pMiniMd->getNameOfAssemblyRef(pAsmRefRec, &szAssemblyRefName)); - if(SString::_stricmp(szAssemblyRefName, szAssembly) == 0) - { - *ppTypeRefRec = pTypeRefRec; - return S_OK; - } - } - } - } - // Record not found - hr = S_FALSE; -ErrExit: - *ppTypeRefRec = NULL; - return hr; -} - -//***************************************************************************** -// constructor -//***************************************************************************** -NEWMERGER::NEWMERGER() - : m_pRegMetaEmit(0), - m_pImportDataList(NULL), - m_optimizeRefToDef(MDRefToDefDefault), - m_isscsSecurityCritical(ISSCS_Unknown), - m_isscsSecurityCriticalAllScopes(~ISSCS_Unknown) -{ - m_pImportDataTail = &(m_pImportDataList); -#if _DEBUG - m_iImport = 0; -#endif // _DEBUG -} // NEWMERGER::NEWMERGER() - -//***************************************************************************** -// initializer -//***************************************************************************** -HRESULT NEWMERGER::Init(RegMeta *pRegMeta) -{ - HRESULT hr = NOERROR; - MergeTypeData * pMTD; - - m_pRegMetaEmit = pRegMeta; - - // burn an entry so that the RID matches the array index - IfNullGo(pMTD = m_rMTDs.Append()); - - pMTD->m_bSuppressMergeCheck = false; - pMTD->m_cMethods = 0; - pMTD->m_cFields = 0; - pMTD->m_cEvents = 0; - pMTD->m_cProperties = 0; - -ErrExit: - return hr; -} // NEWMERGER::Init - -//***************************************************************************** -// destructor -//***************************************************************************** -NEWMERGER::~NEWMERGER() -{ - if (m_pImportDataList) - { - // delete this list and release all AddRef'ed interfaces! - MergeImportData *pNext; - for (pNext = m_pImportDataList; pNext != NULL; ) - { - pNext = m_pImportDataList->m_pNextImportData; - if (m_pImportDataList->m_pHandler) - m_pImportDataList->m_pHandler->Release(); - if (m_pImportDataList->m_pHostMapToken) - m_pImportDataList->m_pHostMapToken->Release(); - if (m_pImportDataList->m_pMDTokenMap) - delete m_pImportDataList->m_pMDTokenMap; - m_pImportDataList->m_pRegMetaImport->Release(); - delete m_pImportDataList; - m_pImportDataList = pNext; - } - } -} // NEWMERGER::~NEWMERGER - -//***************************************************************************** -CMiniMdRW *NEWMERGER::GetMiniMdEmit() -{ - return &(m_pRegMetaEmit->m_pStgdb->m_MiniMd); -} // CMiniMdRW *NEWMERGER::GetMiniMdEmit() - -//***************************************************************************** -// Adding a new import -//***************************************************************************** -HRESULT NEWMERGER::AddImport( - IMetaDataImport2 *pImport, // [IN] The scope to be merged. - IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification - IUnknown *pHandler) // [IN] An object to receive error notification. -{ - HRESULT hr = NOERROR; - MergeImportData *pData; - - RegMeta *pRM = static_cast(pImport); - - // Add a MergeImportData to track the information for this import scope - pData = new (nothrow) MergeImportData; - IfNullGo( pData ); - pData->m_pRegMetaImport = pRM; - pData->m_pRegMetaImport->AddRef(); - pData->m_pHostMapToken = pHostMapToken; - if (pData->m_pHostMapToken) - pData->m_pHostMapToken->AddRef(); - if (pHandler) - { - pData->m_pHandler = pHandler; - pData->m_pHandler->AddRef(); - } - else - { - pData->m_pHandler = NULL; - } - - pData->m_pMDTokenMap = NULL; - pData->m_pNextImportData = NULL; -#if _DEBUG - pData->m_iImport = ++m_iImport; -#endif // _DEBUG - - pData->m_tkHandleProcessCorruptedStateCtor = mdTokenNil; - // add the newly create node to the tail of the list - *m_pImportDataTail = pData; - m_pImportDataTail = &(pData->m_pNextImportData); - -ErrExit: - - return hr; -} // HRESULT NEWMERGER::AddImport() - -HRESULT NEWMERGER::InitMergeTypeData() -{ - CMiniMdRW *pMiniMdEmit; - ULONG cTypeDefRecs; - ULONG i, j; - bool bSuppressMergeCheck; - - ULONG ridStart, ridEnd; - RID ridMap; - - mdToken tkSuppressMergeCheckCtor = mdTokenNil; - mdToken tkCA; - mdMethodDef mdEmit; - mdFieldDef fdEmit; - mdEvent evEmit; - mdProperty prEmit; - - TypeDefRec *pTypeDefRec; - EventMapRec *pEventMapRec; - PropertyMapRec *pPropertyMapRec; - - MergeTypeData *pMTD; - - HRESULT hr = NOERROR; - - pMiniMdEmit = GetMiniMdEmit(); - - // cache the SuppressMergeCheckAttribute.ctor token - ImportHelper::FindCustomAttributeCtorByName( - pMiniMdEmit, COR_MSCORLIB_NAME, - COR_COMPILERSERVICE_NAMESPACE, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE, - &tkSuppressMergeCheckCtor); - - cTypeDefRecs = pMiniMdEmit->getCountTypeDefs(); - _ASSERTE(m_rMTDs.Count() > 0); - - for (i = m_rMTDs.Count(); i <= cTypeDefRecs; i++) - { - IfNullGo(pMTD = m_rMTDs.Append()); - - pMTD->m_cMethods = 0; - pMTD->m_cFields = 0; - pMTD->m_cEvents = 0; - pMTD->m_cProperties = 0; - pMTD->m_bSuppressMergeCheck = (tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit, - TokenFromRid(i, mdtTypeDef), tkSuppressMergeCheckCtor, - NULL, 0, &tkCA)); - - IfFailGo(pMiniMdEmit->GetTypeDefRecord(i, &pTypeDefRec)); - - // Count the number methods - ridStart = pMiniMdEmit->getMethodListOfTypeDef(pTypeDefRec); - IfFailGo(pMiniMdEmit->getEndMethodListOfTypeDef(i, &ridEnd)); - - for (j = ridStart; j < ridEnd; j++) - { - IfFailGo(pMiniMdEmit->GetMethodRid(j, (ULONG *)&mdEmit)); - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit, - mdEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (!bSuppressMergeCheck) - { - pMTD->m_cMethods++; - } - } - - // Count the number fields - ridStart = pMiniMdEmit->getFieldListOfTypeDef(pTypeDefRec); - IfFailGo(pMiniMdEmit->getEndFieldListOfTypeDef(i, &ridEnd)); - - for (j = ridStart; j < ridEnd; j++) - { - IfFailGo(pMiniMdEmit->GetFieldRid(j, (ULONG *)&fdEmit)); - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit, - fdEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (!bSuppressMergeCheck) - { - pMTD->m_cFields++; - } - } - - // Count the number of events - IfFailGo(pMiniMdEmit->FindEventMapFor(i, &ridMap)); - if (!InvalidRid(ridMap)) - { - IfFailGo(pMiniMdEmit->GetEventMapRecord(ridMap, &pEventMapRec)); - ridStart = pMiniMdEmit->getEventListOfEventMap(pEventMapRec); - IfFailGo(pMiniMdEmit->getEndEventListOfEventMap(ridMap, &ridEnd)); - - for (j = ridStart; j < ridEnd; j++) - { - IfFailGo(pMiniMdEmit->GetEventRid(j, (ULONG *)&evEmit)); - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit, - evEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (!bSuppressMergeCheck) - { - pMTD->m_cEvents++; - } - } - } - - // Count the number of properties - IfFailGo(pMiniMdEmit->FindPropertyMapFor(i, &ridMap)); - if (!InvalidRid(ridMap)) - { - IfFailGo(pMiniMdEmit->GetPropertyMapRecord(ridMap, &pPropertyMapRec)); - ridStart = pMiniMdEmit->getPropertyListOfPropertyMap(pPropertyMapRec); - IfFailGo(pMiniMdEmit->getEndPropertyListOfPropertyMap(ridMap, &ridEnd)); - - for (j = ridStart; j < ridEnd; j++) - { - IfFailGo(pMiniMdEmit->GetPropertyRid(j, (ULONG *)&prEmit)); - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit, - prEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (!bSuppressMergeCheck) - { - pMTD->m_cProperties++; - } - } - } - } - -ErrExit: - return hr; -} - -//***************************************************************************** -// Merge now -//***************************************************************************** -HRESULT NEWMERGER::Merge(MergeFlags dwMergeFlags, CorRefToDefCheck optimizeRefToDef) -{ - MergeImportData *pImportData = m_pImportDataList; - MDTOKENMAP **pPrevMap = NULL; - MDTOKENMAP *pMDTokenMap; - HRESULT hr = NOERROR; - MDTOKENMAP *pCurTKMap; - int i; - -#if _DEBUG - { - LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n")); - LOG((LOGMD, "Merge scope list\n")); - i = 0; - for (MergeImportData *pID = m_pImportDataList; pID != NULL; pID = pID->m_pNextImportData) - { - WCHAR szScope[1024], szGuid[40]; - GUID mvid; - ULONG cchScope; - pID->m_pRegMetaImport->GetScopeProps(szScope, 1024, &cchScope, &mvid); - szScope[1023] = 0; - GuidToLPWSTR(mvid, szGuid, 40); - ++i; // Counter is 1-based. - LOG((LOGMD, "%3d: %ls : %ls\n", i, szGuid, szScope)); - } - LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n")); - } -#endif // _DEBUG - - m_dwMergeFlags = dwMergeFlags; - m_optimizeRefToDef = optimizeRefToDef; - - // check to see if we need to do dup check - m_fDupCheck = ((m_dwMergeFlags & NoDupCheck) != NoDupCheck); - - while (pImportData) - { - // Verify that we have a filter for each import scope. - IfNullGo( pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd.GetFilterTable() ); - - // cache the SuppressMergeCheckAttribute.ctor token for each import scope - ImportHelper::FindCustomAttributeCtorByName( - &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd, COR_MSCORLIB_NAME, - COR_COMPILERSERVICE_NAMESPACE, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE, - &pImportData->m_tkSuppressMergeCheckCtor); - - // cache the HandleProcessCorruptedStateExceptionsAttribute.ctor token for each import scope - ImportHelper::FindCustomAttributeCtorByName( - &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd, COR_MSCORLIB_NAME, - COR_EXCEPTIONSERVICE_NAMESPACE, COR_HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE, - &pImportData->m_tkHandleProcessCorruptedStateCtor); - - // check for security critical attribute in the assembly (i.e. explicit annotations) - InputScopeSecurityCriticalStatus isscsTemp = CheckInputScopeIsCritical(pImportData, hr); - IfFailGo(hr); - // clear the unset flag bits (e.g. if critical, clear transparent bit) - // whatever bits remain are bits that have been set in all scopes - if (ISSCS_Unknown == (isscsTemp & ISSCS_SECURITYCRITICAL_FLAGS)) - m_isscsSecurityCriticalAllScopes &= ISSCS_SECURITYCRITICAL_LEGACY; - else - m_isscsSecurityCriticalAllScopes &= isscsTemp; - // set the flag bits (essentially, this allows us to see if _any_ scopes requested a bit) - m_isscsSecurityCritical |= isscsTemp; - - // create the tokenmap class to track metadata token remap for each import scope - pMDTokenMap = new (nothrow) MDTOKENMAP; - IfNullGo(pMDTokenMap); - IfFailGo(pMDTokenMap->Init((IMetaDataImport2*)pImportData->m_pRegMetaImport)); - pImportData->m_pMDTokenMap = pMDTokenMap; - pImportData->m_pMDTokenMap->m_pMap = pImportData->m_pHostMapToken; - if (pImportData->m_pHostMapToken) - pImportData->m_pHostMapToken->AddRef(); - pImportData->m_pMDTokenMap->m_pNextMap = NULL; - if (pPrevMap) - *pPrevMap = pImportData->m_pMDTokenMap; - pPrevMap = &(pImportData->m_pMDTokenMap->m_pNextMap); - pImportData = pImportData->m_pNextImportData; - } - - // Populate the m_rMTDs with the type info already defined in the emit scope - IfFailGo( InitMergeTypeData() ); - - // 1. Merge Module - IfFailGo( MergeModule( ) ); - - // 2. Merge TypeDef partially (i.e. only name) - IfFailGo( MergeTypeDefNamesOnly() ); - - // 3. Merge ModuleRef property and do ModuleRef to ModuleDef optimization - IfFailGo( MergeModuleRefs() ); - - // 4. Merge AssemblyRef. - IfFailGo( MergeAssemblyRefs() ); - - // 5. Merge TypeRef with TypeRef to TypeDef optimization - IfFailGo( MergeTypeRefs() ); - - // 6. Merge TypeSpec & MethodSpec - IfFailGo( MergeTypeSpecs() ); - - // 7. Now Merge the remaining of TypeDef records - IfFailGo( CompleteMergeTypeDefs() ); - - // 8. Merge Methods and Fields. Such that Signature translation is respecting the TypeRef to TypeDef optimization. - IfFailGo( MergeTypeDefChildren() ); - - // 9. Merge MemberRef with MemberRef to MethodDef/FieldDef optimization - IfFailGo( MergeMemberRefs( ) ); - - // 10. Merge InterfaceImpl - IfFailGo( MergeInterfaceImpls( ) ); - - // merge all of the remaining in metadata .... - - // 11. constant has dependency on property, field, param - IfFailGo( MergeConstants() ); - - // 12. field marshal has dependency on param and field - IfFailGo( MergeFieldMarshals() ); - - // 13. in ClassLayout, move over the FieldLayout and deal with FieldLayout as well - IfFailGo( MergeClassLayouts() ); - - // 14. FieldLayout has dependency on FieldDef. - IfFailGo( MergeFieldLayouts() ); - - // 15. FieldRVA has dependency on FieldDef. - IfFailGo( MergeFieldRVAs() ); - - // 16. MethodImpl has dependency on MemberRef, MethodDef, TypeRef and TypeDef. - IfFailGo( MergeMethodImpls() ); - - // 17. pinvoke depends on MethodDef and ModuleRef - IfFailGo( MergePinvoke() ); - - IfFailGo( MergeStandAloneSigs() ); - - IfFailGo( MergeMethodSpecs() ); - - IfFailGo( MergeStrings() ); - - if (m_dwMergeFlags & MergeManifest) - { - // keep the manifest!! - IfFailGo( MergeAssembly() ); - IfFailGo( MergeFiles() ); - IfFailGo( MergeExportedTypes() ); - IfFailGo( MergeManifestResources() ); - } - else if (m_dwMergeFlags & ::MergeExportedTypes) - { - IfFailGo( MergeFiles() ); - IfFailGo( MergeExportedTypes() ); - } - - IfFailGo( MergeCustomAttributes() ); - IfFailGo( MergeDeclSecuritys() ); - - - // Please don't add any MergeXxx() below here. CustomAttributess must be - // very late, because custom values are various other types. - - // Fixup list cannot be merged. Linker will need to re-emit them. - - // Now call back to host for the result of token remap - // - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // Send token remap information for each import scope - pCurTKMap = pImportData->m_pMDTokenMap; - TOKENREC *pRec; - if (pImportData->m_pHostMapToken) - { - for (i = 0; i < pCurTKMap->Count(); i++) - { - pRec = pCurTKMap->Get(i); - if (!pRec->IsEmpty()) - pImportData->m_pHostMapToken->Map(pRec->m_tkFrom, pRec->m_tkTo); - } - } - } - - // And last, but not least, let's do Security critical module-level attribute consolidation - // and metadata fixups. - IfFailGo( MergeSecurityCriticalAttributes() ); - - - - - -#if _DEBUG - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // dump the mapping - LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n")); - LOG((LOGMD, "Dumping token remap for one import scope!\n")); - LOG((LOGMD, "This is the %d import scope for merge!\n", pImportData->m_iImport)); - - pCurTKMap = pImportData->m_pMDTokenMap; - TOKENREC *pRec; - for (i = 0; i < pCurTKMap->Count(); i++) - { - pRec = pCurTKMap->Get(i); - if (!pRec->IsEmpty()) - { - LOG((LOGMD, " Token 0x%08x ====>>>> Token 0x%08x\n", pRec->m_tkFrom, pRec->m_tkTo)); - } - } - LOG((LOGMD, "End dumping token remap!\n")); - LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n")); - } -#endif // _DEBUG - -ErrExit: - return hr; -} // HRESULT NEWMERGER::Merge() - - -//***************************************************************************** -// Merge ModuleDef -//***************************************************************************** -HRESULT NEWMERGER::MergeModule() -{ - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - HRESULT hr = NOERROR; - TOKENREC *pTokenRec; - - // we don't really merge Module information but we create a one to one mapping for each module token into the TokenMap - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - // set the current MDTokenMap - - pCurTkMap = pImportData->m_pMDTokenMap; - IfFailGo( pCurTkMap->InsertNotFound(MODULEDEFTOKEN, true, MODULEDEFTOKEN, &pTokenRec) ); - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeModule() - - -//***************************************************************************** -// Merge TypeDef but only Names. This is a partial merge to support TypeRef to TypeDef optimization -//***************************************************************************** -HRESULT NEWMERGER::MergeTypeDefNamesOnly() -{ - HRESULT hr = NOERROR; - TypeDefRec *pRecImport = NULL; - TypeDefRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdTypeDef tdEmit; - mdTypeDef tdImport; - bool bDuplicate; - DWORD dwFlags; - DWORD dwExportFlags; - NestedClassRec *pNestedRec; - RID iNestedRec; - mdTypeDef tdNester; - TOKENREC *pTokenRec; - - LPCUTF8 szNameImp; - LPCUTF8 szNamespaceImp; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - mdCustomAttribute tkCA; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - - iCount = pMiniMdImport->getCountTypeDefs(); - - // Merge the typedefs - for (i = 1; i <= iCount; i++) - { - // only merge those TypeDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false) - continue; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport)); - IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImport, &szNameImp)); - IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImport, &szNamespaceImp)); - - // If the class is a Nested class, get the parent token. - dwFlags = pMiniMdImport->getFlagsOfTypeDef(pRecImport); - if (IsTdNested(dwFlags)) - { - IfFailGo(pMiniMdImport->FindNestedClassHelper(TokenFromRid(i, mdtTypeDef), &iNestedRec)); - if (InvalidRid(iNestedRec)) - { - _ASSERTE(!"Bad state!"); - IfFailGo(META_E_BADMETADATA); - } - else - { - IfFailGo(pMiniMdImport->GetNestedClassRecord(iNestedRec, &pNestedRec)); - tdNester = pMiniMdImport->getEnclosingClassOfNestedClass(pNestedRec); - _ASSERTE(!IsNilToken(tdNester)); - IfFailGo(pCurTkMap->Remap(tdNester, &tdNester)); - } - } - else - tdNester = mdTokenNil; - - bSuppressMergeCheck = (pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - TokenFromRid(i, mdtTypeDef), pImportData->m_tkSuppressMergeCheckCtor, - NULL, 0, &tkCA)); - - // does this TypeDef already exist in the emit scope? - if ( ImportHelper::FindTypeDefByName( - pMiniMdEmit, - szNamespaceImp, - szNameImp, - tdNester, - &tdEmit) == S_OK ) - { - // Yes, it does - bDuplicate = true; - - // Let's look at their accessiblities. - IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(tdEmit), &pRecEmit)); - dwExportFlags = pMiniMdEmit->getFlagsOfTypeDef(pRecEmit); - - // Managed types need to have the same accessiblity - BOOL fManagedType = FALSE; - IfFailGo(IsManagedType(pMiniMdImport, TokenFromRid(i, mdtTypeDef), &fManagedType)); - if (fManagedType) - { - if ((dwFlags&tdVisibilityMask) != (dwExportFlags&tdVisibilityMask)) - { - CheckContinuableErrorEx(META_E_MISMATCHED_VISIBLITY, pImportData, TokenFromRid(i, mdtTypeDef)); - } - - } - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - if (pMTD->m_bSuppressMergeCheck != bSuppressMergeCheck) - { - CheckContinuableErrorEx(META_E_MD_INCONSISTENCY, pImportData, TokenFromRid(i, mdtTypeDef)); - } - } - else - { - // No, it doesn't. Copy it over. - bDuplicate = false; - IfFailGo(pMiniMdEmit->AddTypeDefRecord(&pRecEmit, (RID *)&tdEmit)); - - // make sure the index matches - _ASSERTE(((mdTypeDef)m_rMTDs.Count()) == tdEmit); - - IfNullGo(pMTD = m_rMTDs.Append()); - - pMTD->m_cMethods = 0; - pMTD->m_cFields = 0; - pMTD->m_cEvents = 0; - pMTD->m_cProperties = 0; - pMTD->m_bSuppressMergeCheck = bSuppressMergeCheck; - - tdEmit = TokenFromRid( tdEmit, mdtTypeDef ); - - // Set Full Qualified Name. - IfFailGo( CopyTypeDefPartially( pRecEmit, pMiniMdImport, pRecImport) ); - - // Create a NestedClass record if the class is a Nested class. - if (! IsNilToken(tdNester)) - { - IfFailGo(pMiniMdEmit->AddNestedClassRecord(&pNestedRec, &iNestedRec)); - - // copy over the information - IfFailGo( pMiniMdEmit->PutToken(TBL_NestedClass, NestedClassRec::COL_NestedClass, - pNestedRec, tdEmit)); - - // tdNester has already been remapped above to the Emit scope. - IfFailGo( pMiniMdEmit->PutToken(TBL_NestedClass, NestedClassRec::COL_EnclosingClass, - pNestedRec, tdNester)); - IfFailGo( pMiniMdEmit->AddNestedClassToHash(iNestedRec) ); - - } - } - - // record the token movement - tdImport = TokenFromRid(i, mdtTypeDef); - IfFailGo( pCurTkMap->InsertNotFound(tdImport, bDuplicate, tdEmit, &pTokenRec) ); - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeTypeDefNamesOnly() - - -//***************************************************************************** -// Merge EnclosingType tables -//***************************************************************************** -HRESULT NEWMERGER::CopyTypeDefPartially( - TypeDefRec *pRecEmit, // [IN] the emit record to fill - CMiniMdRW *pMiniMdImport, // [IN] the importing scope - TypeDefRec *pRecImp) // [IN] the record to import - -{ - HRESULT hr; - LPCUTF8 szNameImp; - LPCUTF8 szNamespaceImp; - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - - IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImp, &szNameImp)); - IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImp, &szNamespaceImp)); - - IfFailGo( pMiniMdEmit->PutString( TBL_TypeDef, TypeDefRec::COL_Name, pRecEmit, szNameImp) ); - IfFailGo( pMiniMdEmit->PutString( TBL_TypeDef, TypeDefRec::COL_Namespace, pRecEmit, szNamespaceImp) ); - - pRecEmit->SetFlags(pRecImp->GetFlags()); - - // Don't copy over the extends until TypeRef's remap is calculated - -ErrExit: - return hr; - -} // HRESULT NEWMERGER::CopyTypeDefPartially() - - -//***************************************************************************** -// Merge ModuleRef tables including ModuleRef to ModuleDef optimization -//***************************************************************************** -HRESULT NEWMERGER::MergeModuleRefs() -{ - HRESULT hr = NOERROR; - ModuleRefRec *pRecImport = NULL; - ModuleRefRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdModuleRef mrEmit; - bool bDuplicate = false; - TOKENREC *pTokenRec; - LPCUTF8 szNameImp; - bool isModuleDef; - - MergeImportData *pImportData; - MergeImportData *pData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountModuleRefs(); - - // loop through all ModuleRef - for (i = 1; i <= iCount; i++) - { - // only merge those ModuleRefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsModuleRefMarked(TokenFromRid(i, mdtModuleRef)) == false) - continue; - - isModuleDef = false; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetModuleRefRecord(i, &pRecImport)); - IfFailGo(pMiniMdImport->getNameOfModuleRef(pRecImport, &szNameImp)); - - // Only do the ModuleRef to ModuleDef optimization if ModuleRef's name is meaningful! - if ( szNameImp && szNameImp[0] != '\0') - { - - // Check to see if this ModuleRef has become the ModuleDef token - for (pData = m_pImportDataList; pData != NULL; pData = pData->m_pNextImportData) - { - CMiniMdRW *pMiniMd = &(pData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - ModuleRec *pRec; - LPCUTF8 szName; - - IfFailGo(pMiniMd->GetModuleRecord(MODULEDEFTOKEN, &pRec)); - IfFailGo(pMiniMd->getNameOfModule(pRec, &szName)); - if (szName && szName[0] != '\0' && strcmp(szNameImp, szName) == 0) - { - // We found an import Module for merging that has the same name as the ModuleRef - isModuleDef = true; - bDuplicate = true; - mrEmit = MODULEDEFTOKEN; // set the resulting token to ModuleDef Token - break; - } - } - } - - if (isModuleDef == false) - { - // does this ModuleRef already exist in the emit scope? - hr = ImportHelper::FindModuleRef(pMiniMdEmit, - szNameImp, - &mrEmit); - if (hr == S_OK) - { - // Yes, it does - bDuplicate = true; - } - else if (hr == CLDB_E_RECORD_NOTFOUND) - { - // No, it doesn't. Copy it over. - bDuplicate = false; - IfFailGo(pMiniMdEmit->AddModuleRefRecord(&pRecEmit, (RID*)&mrEmit)); - mrEmit = TokenFromRid(mrEmit, mdtModuleRef); - - // Set ModuleRef Name. - IfFailGo( pMiniMdEmit->PutString(TBL_ModuleRef, ModuleRefRec::COL_Name, pRecEmit, szNameImp) ); - } - else - IfFailGo(hr); - } - - // record the token movement - IfFailGo( pCurTkMap->InsertNotFound( - TokenFromRid(i, mdtModuleRef), - bDuplicate, - mrEmit, - &pTokenRec) ); - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeModuleRefs() - - -//***************************************************************************** -// Merge AssemblyRef tables -//***************************************************************************** -HRESULT NEWMERGER::MergeAssemblyRefs() -{ - HRESULT hr = NOERROR; - AssemblyRefRec *pRecImport = NULL; - AssemblyRefRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - mdAssemblyRef arEmit; - bool bDuplicate = false; - LPCUTF8 szTmp; - const void *pbTmp; - ULONG cbTmp; - ULONG iCount; - ULONG i; - ULONG iRecord; - TOKENREC *pTokenRec; - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountAssemblyRefs(); - - // loope through all the AssemblyRefs. - for (i = 1; i <= iCount; i++) - { - // Compare with the emit scope. - IfFailGo(pMiniMdImport->GetAssemblyRefRecord(i, &pRecImport)); - IfFailGo(pMiniMdImport->getPublicKeyOrTokenOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp)); - hr = CLDB_E_RECORD_NOTFOUND; - if (m_fDupCheck) - { - LPCSTR szAssemblyRefName; - LPCSTR szAssemblyRefLocale; - IfFailGo(pMiniMdImport->getNameOfAssemblyRef(pRecImport, &szAssemblyRefName)); - IfFailGo(pMiniMdImport->getLocaleOfAssemblyRef(pRecImport, &szAssemblyRefLocale)); - hr = ImportHelper::FindAssemblyRef( - pMiniMdEmit, - szAssemblyRefName, - szAssemblyRefLocale, - pbTmp, - cbTmp, - pRecImport->GetMajorVersion(), - pRecImport->GetMinorVersion(), - pRecImport->GetBuildNumber(), - pRecImport->GetRevisionNumber(), - pRecImport->GetFlags(), - &arEmit); - } - if (hr == S_OK) - { - // Yes, it does - bDuplicate = true; - - // @FUTURE: more verification? - } - else if (hr == CLDB_E_RECORD_NOTFOUND) - { - // No, it doesn't. Copy it over. - bDuplicate = false; - IfFailGo(pMiniMdEmit->AddAssemblyRefRecord(&pRecEmit, &iRecord)); - arEmit = TokenFromRid(iRecord, mdtAssemblyRef); - - pRecEmit->Copy(pRecImport); - - IfFailGo(pMiniMdImport->getPublicKeyOrTokenOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp)); - IfFailGo(pMiniMdEmit->PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_PublicKeyOrToken, - pRecEmit, pbTmp, cbTmp)); - - IfFailGo(pMiniMdImport->getNameOfAssemblyRef(pRecImport, &szTmp)); - IfFailGo(pMiniMdEmit->PutString(TBL_AssemblyRef, AssemblyRefRec::COL_Name, - pRecEmit, szTmp)); - - IfFailGo(pMiniMdImport->getLocaleOfAssemblyRef(pRecImport, &szTmp)); - IfFailGo(pMiniMdEmit->PutString(TBL_AssemblyRef, AssemblyRefRec::COL_Locale, - pRecEmit, szTmp)); - - IfFailGo(pMiniMdImport->getHashValueOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp)); - IfFailGo(pMiniMdEmit->PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_HashValue, - pRecEmit, pbTmp, cbTmp)); - - } - else - IfFailGo(hr); - - // record the token movement. - IfFailGo(pCurTkMap->InsertNotFound( - TokenFromRid(i, mdtAssemblyRef), - bDuplicate, - arEmit, - &pTokenRec)); - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeAssemblyRefs() - - -//***************************************************************************** -// Merge TypeRef tables also performing TypeRef to TypeDef opitimization. ie. -// we will not introduce a TypeRef record if we can optimize it to a TypeDef. -//***************************************************************************** -HRESULT NEWMERGER::MergeTypeRefs() -{ - HRESULT hr = NOERROR; - TypeRefRec *pRecImport = NULL; - TypeRefRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdTypeRef trEmit; - bool bDuplicate = false; - TOKENREC *pTokenRec; - bool isTypeDef; - - mdToken tkResImp; - mdToken tkResEmit; - LPCUTF8 szNameImp; - LPCUTF8 szNamespaceImp; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountTypeRefs(); - - // loop through all TypeRef - for (i = 1; i <= iCount; i++) - { - // only merge those TypeRefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsTypeRefMarked(TokenFromRid(i, mdtTypeRef)) == false) - continue; - - isTypeDef = false; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetTypeRefRecord(i, &pRecImport)); - tkResImp = pMiniMdImport->getResolutionScopeOfTypeRef(pRecImport); - IfFailGo(pMiniMdImport->getNamespaceOfTypeRef(pRecImport, &szNamespaceImp)); - IfFailGo(pMiniMdImport->getNameOfTypeRef(pRecImport, &szNameImp)); - if (!IsNilToken(tkResImp)) - { - IfFailGo(pCurTkMap->Remap(tkResImp, &tkResEmit)); - } - else - { - tkResEmit = tkResImp; - } - - // There are some interesting cases to consider here. - // 1) If the TypeRef's ResolutionScope is a nil token, or is the MODULEDEFTOKEN (current module), - // then the TypeRef refers to a type in the current scope, so we should find a corresponding - // TypeDef in the output scope. If we find the TypeDef, we'll remap this TypeRef token - // to that TypeDef token. - // If we don't find that TypeDef, or if "TypeRef to TypeDef" optimization is turned off, we'll - // create the TypeRef in the output scope. - // 2) If the TypeRef's ResolutionScope has been resolved to a TypeDef, then this TypeRef was part - // of a nested type definition. In that case, we'd better find a corresponding TypeDef - // or we have an error. - if (IsNilToken(tkResEmit) || tkResEmit == MODULEDEFTOKEN || TypeFromToken(tkResEmit) == mdtTypeDef) - { - hr = ImportHelper::FindTypeDefByName( - pMiniMdEmit, - szNamespaceImp, - szNameImp, - (TypeFromToken(tkResEmit) == mdtTypeDef) ? tkResEmit : mdTokenNil, - &trEmit); - if (hr == S_OK) - { - isTypeDef = true; - - // it really does not matter if we set the duplicate to true or false. - bDuplicate = true; - } - } - - // If the ResolutionScope was merged as a TypeDef, and this token wasn't found as TypeDef, send the error. - if (TypeFromToken(tkResEmit) == mdtTypeDef && !isTypeDef) - { - // Send the error notification. Use the "continuable error" callback, but even if linker says it is - // ok, don't continue. - CheckContinuableErrorEx(META_E_TYPEDEF_MISSING, pImportData, TokenFromRid(i, mdtTypeRef)); - IfFailGo(META_E_TYPEDEF_MISSING); - } - - // If this TypeRef cannot be optmized to a TypeDef or the Ref to Def optimization is turned off, do the following. - if (!isTypeDef || !((m_optimizeRefToDef & MDTypeRefToDef) == MDTypeRefToDef)) - { - // does this TypeRef already exist in the emit scope? - if ( m_fDupCheck && ImportHelper::FindTypeRefByName( - pMiniMdEmit, - tkResEmit, - szNamespaceImp, - szNameImp, - &trEmit) == S_OK ) - { - // Yes, it does - bDuplicate = true; - } - else - { - // No, it doesn't. Copy it over. - bDuplicate = false; - IfFailGo(pMiniMdEmit->AddTypeRefRecord(&pRecEmit, (RID*)&trEmit)); - trEmit = TokenFromRid(trEmit, mdtTypeRef); - - // Set ResolutionScope. tkResEmit has already been re-mapped. - IfFailGo(pMiniMdEmit->PutToken(TBL_TypeRef, TypeRefRec::COL_ResolutionScope, - pRecEmit, tkResEmit)); - - // Set Name. - IfFailGo(pMiniMdEmit->PutString(TBL_TypeRef, TypeRefRec::COL_Name, - pRecEmit, szNameImp)); - IfFailGo(pMiniMdEmit->AddNamedItemToHash(TBL_TypeRef, trEmit, szNameImp, 0)); - - // Set Namespace. - IfFailGo(pMiniMdEmit->PutString(TBL_TypeRef, TypeRefRec::COL_Namespace, - pRecEmit, szNamespaceImp)); - } - } - - // record the token movement - IfFailGo( pCurTkMap->InsertNotFound( - TokenFromRid(i, mdtTypeRef), - bDuplicate, - trEmit, - &pTokenRec) ); - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeTypeRefs() - - -//***************************************************************************** -// copy over the remaining information of partially merged TypeDef records. Right now only -// extends field is delayed to here. The reason that we delay extends field is because we want -// to optimize TypeRef to TypeDef if possible. -//***************************************************************************** -HRESULT NEWMERGER::CompleteMergeTypeDefs() -{ - HRESULT hr = NOERROR; - TypeDefRec *pRecImport = NULL; - TypeDefRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - TOKENREC *pTokenRec; - mdToken tkExtendsImp; - mdToken tkExtendsEmit; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - - iCount = pMiniMdImport->getCountTypeDefs(); - - // Merge the typedefs - for (i = 1; i <= iCount; i++) - { - // only merge those TypeDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false) - continue; - - if ( !pCurTkMap->Find(TokenFromRid(i, mdtTypeDef), &pTokenRec) ) - { - _ASSERTE( !"bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - - if (pTokenRec->m_isDuplicate == false) - { - // get the extends token from the import - IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport)); - tkExtendsImp = pMiniMdImport->getExtendsOfTypeDef(pRecImport); - - // map the extends token to an merged token - IfFailGo( pCurTkMap->Remap(tkExtendsImp, &tkExtendsEmit) ); - - // set the extends to the merged TypeDef records. - IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(pTokenRec->m_tkTo), &pRecEmit)); - IfFailGo(pMiniMdEmit->PutToken(TBL_TypeDef, TypeDefRec::COL_Extends, pRecEmit, tkExtendsEmit)); - } - else - { - // @FUTURE: we can check to make sure the import extends maps to the one that is set to the emit scope. - // Otherwise, it is a error to report to linker. - } - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::CompleteMergeTypeDefs() - - -//***************************************************************************** -// merging TypeSpecs -//***************************************************************************** -HRESULT NEWMERGER::MergeTypeSpecs() -{ - HRESULT hr = NOERROR; - TypeSpecRec *pRecImport = NULL; - TypeSpecRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - TOKENREC *pTokenRec; - mdTypeSpec tsImp; - mdTypeSpec tsEmit; - bool fDuplicate; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - - iCount = pMiniMdImport->getCountTypeSpecs(); - - // loop through all TypeSpec - for (i = 1; i <= iCount; i++) - { - // only merge those TypeSpecs that are marked - if ( pMiniMdImport->GetFilterTable()->IsTypeSpecMarked(TokenFromRid(i, mdtTypeSpec)) == false) - continue; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetTypeSpecRecord(i, &pRecImport)); - IfFailGo(pMiniMdImport->getSignatureOfTypeSpec(pRecImport, &pbSig, &cbSig)); - - // convert tokens contained in signature to new scope - IfFailGo(ImportHelper::MergeUpdateTokenInFieldSig( - NULL, // Assembly emit scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly information. - pMiniMdImport, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit)); // number of bytes write to cbEmit - - hr = CLDB_E_RECORD_NOTFOUND; - if (m_fDupCheck) - hr = ImportHelper::FindTypeSpec( - pMiniMdEmit, - (PCOR_SIGNATURE) qbSig.Ptr(), - cbEmit, - &tsEmit ); - - if ( hr == S_OK ) - { - // find a duplicate - fDuplicate = true; - } - else - { - // copy over - fDuplicate = false; - IfFailGo(pMiniMdEmit->AddTypeSpecRecord(&pRecEmit, (ULONG *)&tsEmit)); - tsEmit = TokenFromRid(tsEmit, mdtTypeSpec); - IfFailGo( pMiniMdEmit->PutBlob( - TBL_TypeSpec, - TypeSpecRec::COL_Signature, - pRecEmit, - (PCOR_SIGNATURE)qbSig.Ptr(), - cbEmit)); - } - tsImp = TokenFromRid(i, mdtTypeSpec); - - // Record the token movement - IfFailGo( pCurTkMap->InsertNotFound(tsImp, fDuplicate, tsEmit, &pTokenRec) ); - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeTypeSpecs() - - -//***************************************************************************** -// merging Children of TypeDefs. This includes field, method, parameter, property, event -//***************************************************************************** -HRESULT NEWMERGER::MergeTypeDefChildren() -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdTypeDef tdEmit; - mdTypeDef tdImport; - TOKENREC *pTokenRec; - -#if _DEBUG - TypeDefRec *pRecImport = NULL; - LPCUTF8 szNameImp; - LPCUTF8 szNamespaceImp; -#endif // _DEBUG - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountTypeDefs(); - - // loop through all TypeDef again to merge/copy Methods, fields, events, and properties - // - for (i = 1; i <= iCount; i++) - { - // only merge those TypeDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false) - continue; - -#if _DEBUG - IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport)); - IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImport, &szNameImp)); - IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImport, &szNamespaceImp)); -#endif // _DEBUG - - // check to see if the typedef is duplicate or not - tdImport = TokenFromRid(i, mdtTypeDef); - if ( pCurTkMap->Find( tdImport, &pTokenRec) == false) - { - _ASSERTE( !"bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - tdEmit = pTokenRec->m_tkTo; - if (pTokenRec->m_isDuplicate == false) - { - // now move all of the children records over - IfFailGo( CopyMethods(pImportData, tdImport, tdEmit) ); - IfFailGo( CopyFields(pImportData, tdImport, tdEmit) ); - - IfFailGo( CopyEvents(pImportData, tdImport, tdEmit) ); - - // Property has dependency on events - IfFailGo( CopyProperties(pImportData, tdImport, tdEmit) ); - - // Generic Params. - IfFailGo( CopyGenericParams(pImportData, tdImport, tdEmit) ); - } - else - { - // verify the children records - IfFailGo( VerifyMethods(pImportData, tdImport, tdEmit) ); - IfFailGo( VerifyFields(pImportData, tdImport, tdEmit) ); - IfFailGo( VerifyEvents(pImportData, tdImport, tdEmit) ); - - // property has dependency on events - IfFailGo( VerifyProperties(pImportData, tdImport, tdEmit) ); - - IfFailGo( VerifyGenericParams(pImportData, tdImport, tdEmit) ); - } - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeTypeDefChildren() - - -//******************************************************************************* -// Helper to copy an Method record -//******************************************************************************* -HRESULT NEWMERGER::CopyMethod( - MergeImportData *pImportData, // [IN] import scope - MethodRec *pRecImp, // [IN] the record to import - MethodRec *pRecEmit) // [IN] the emit record to fill -{ - HRESULT hr; - CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - LPCUTF8 szName; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - MDTOKENMAP *pCurTkMap; - - pCurTkMap = pImportData->m_pMDTokenMap; - - // copy over the fix part of the record - pRecEmit->Copy(pRecImp); - - // copy over the name - IfFailGo(pMiniMdImp->getNameOfMethod(pRecImp, &szName)); - IfFailGo(pMiniMdEmit->PutString(TBL_Method, MethodRec::COL_Name, pRecEmit, szName)); - - // copy over the signature - IfFailGo(pMiniMdImp->getSignatureOfMethod(pRecImp, &pbSig, &cbSig)); - - // convert rid contained in signature to new scope - IfFailGo(ImportHelper::MergeUpdateTokenInSig( - NULL, // Assembly emit scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly scope information. - pMiniMdImp, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit)); // number of bytes write to cbEmit - - IfFailGo(pMiniMdEmit->PutBlob(TBL_Method, MethodRec::COL_Signature, pRecEmit, qbSig.Ptr(), cbEmit)); - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyMethod() - - -//******************************************************************************* -// Helper to copy an field record -//******************************************************************************* -HRESULT NEWMERGER::CopyField( - MergeImportData *pImportData, // [IN] import scope - FieldRec *pRecImp, // [IN] the record to import - FieldRec *pRecEmit) // [IN] the emit record to fill -{ - HRESULT hr; - CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - LPCUTF8 szName; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - MDTOKENMAP *pCurTkMap; - - pCurTkMap = pImportData->m_pMDTokenMap; - - // copy over the fix part of the record - pRecEmit->SetFlags(pRecImp->GetFlags()); - - // copy over the name - IfFailGo(pMiniMdImp->getNameOfField(pRecImp, &szName)); - IfFailGo(pMiniMdEmit->PutString(TBL_Field, FieldRec::COL_Name, pRecEmit, szName)); - - // copy over the signature - IfFailGo(pMiniMdImp->getSignatureOfField(pRecImp, &pbSig, &cbSig)); - - // convert rid contained in signature to new scope - IfFailGo(ImportHelper::MergeUpdateTokenInSig( - NULL, // Emit assembly scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly scope information. - pMiniMdImp, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit)); // number of bytes write to cbEmit - - IfFailGo(pMiniMdEmit->PutBlob(TBL_Field, FieldRec::COL_Signature, pRecEmit, qbSig.Ptr(), cbEmit)); - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyField() - -//******************************************************************************* -// Helper to copy an field record -//******************************************************************************* -HRESULT NEWMERGER::CopyParam( - MergeImportData *pImportData, // [IN] import scope - ParamRec *pRecImp, // [IN] the record to import - ParamRec *pRecEmit) // [IN] the emit record to fill -{ - HRESULT hr; - CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - LPCUTF8 szName; - MDTOKENMAP *pCurTkMap; - - pCurTkMap = pImportData->m_pMDTokenMap; - - // copy over the fix part of the record - pRecEmit->Copy(pRecImp); - - // copy over the name - IfFailGo(pMiniMdImp->getNameOfParam(pRecImp, &szName)); - IfFailGo(pMiniMdEmit->PutString(TBL_Param, ParamRec::COL_Name, pRecEmit, szName)); - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyParam() - -//******************************************************************************* -// Helper to copy an Event record -//******************************************************************************* -HRESULT NEWMERGER::CopyEvent( - MergeImportData *pImportData, // [IN] import scope - EventRec *pRecImp, // [IN] the record to import - EventRec *pRecEmit) // [IN] the emit record to fill -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - mdToken tkEventTypeImp; - mdToken tkEventTypeEmit; // could be TypeDef or TypeRef - LPCUTF8 szName; - MDTOKENMAP *pCurTkMap; - - pCurTkMap = pImportData->m_pMDTokenMap; - - pRecEmit->SetEventFlags(pRecImp->GetEventFlags()); - - //move over the event name - IfFailGo(pMiniMdImp->getNameOfEvent(pRecImp, &szName)); - IfFailGo( pMiniMdEmit->PutString(TBL_Event, EventRec::COL_Name, pRecEmit, szName) ); - - // move over the EventType - tkEventTypeImp = pMiniMdImp->getEventTypeOfEvent(pRecImp); - if ( !IsNilToken(tkEventTypeImp) ) - { - IfFailGo( pCurTkMap->Remap(tkEventTypeImp, &tkEventTypeEmit) ); - IfFailGo(pMiniMdEmit->PutToken(TBL_Event, EventRec::COL_EventType, pRecEmit, tkEventTypeEmit)); - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyEvent() - - -//******************************************************************************* -// Helper to copy a property record -//******************************************************************************* -HRESULT NEWMERGER::CopyProperty( - MergeImportData *pImportData, // [IN] import scope - PropertyRec *pRecImp, // [IN] the record to import - PropertyRec *pRecEmit) // [IN] the emit record to fill -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - LPCUTF8 szName; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - MDTOKENMAP *pCurTkMap; - - pCurTkMap = pImportData->m_pMDTokenMap; - - // move over the flag value - pRecEmit->SetPropFlags(pRecImp->GetPropFlags()); - - //move over the property name - IfFailGo(pMiniMdImp->getNameOfProperty(pRecImp, &szName)); - IfFailGo( pMiniMdEmit->PutString(TBL_Property, PropertyRec::COL_Name, pRecEmit, szName) ); - - // move over the type of the property - IfFailGo(pMiniMdImp->getTypeOfProperty(pRecImp, &pbSig, &cbSig)); - - // convert rid contained in signature to new scope - IfFailGo( ImportHelper::MergeUpdateTokenInSig( - NULL, // Assembly emit scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly scope information. - pMiniMdImp, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit) ); // number of bytes write to cbEmit - - IfFailGo(pMiniMdEmit->PutBlob(TBL_Property, PropertyRec::COL_Type, pRecEmit, qbSig.Ptr(), cbEmit)); - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyProperty() - - -//***************************************************************************** -// Copy MethodSemantics for an event or a property -//***************************************************************************** -HRESULT NEWMERGER::CopyMethodSemantics( - MergeImportData *pImportData, - mdToken tkImport, // Event or property in the import scope - mdToken tkEmit) // corresponding event or property in the emitting scope -{ - HRESULT hr = NOERROR; - MethodSemanticsRec *pRecImport = NULL; - MethodSemanticsRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - ULONG i; - ULONG msEmit; // MethodSemantics are just index not tokens - mdToken tkMethodImp; - mdToken tkMethodEmit; - MDTOKENMAP *pCurTkMap; - HENUMInternal hEnum; - - pCurTkMap = pImportData->m_pMDTokenMap; - - // copy over the associates - IfFailGo( pMiniMdImport->FindMethodSemanticsHelper(tkImport, &hEnum) ); - while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &i)) - { - IfFailGo(pMiniMdImport->GetMethodSemanticsRecord(i, &pRecImport)); - IfFailGo(pMiniMdEmit->AddMethodSemanticsRecord(&pRecEmit, &msEmit)); - pRecEmit->SetSemantic(pRecImport->GetSemantic()); - - // set the MethodSemantics - tkMethodImp = pMiniMdImport->getMethodOfMethodSemantics(pRecImport); - IfFailGo( pCurTkMap->Remap(tkMethodImp, &tkMethodEmit) ); - IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSemantics, MethodSemanticsRec::COL_Method, pRecEmit, tkMethodEmit)); - - // set the associate - _ASSERTE( pMiniMdImport->getAssociationOfMethodSemantics(pRecImport) == tkImport ); - IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSemantics, MethodSemanticsRec::COL_Association, pRecEmit, tkEmit)); - - // no need to record the movement since it is not a token - IfFailGo( pMiniMdEmit->AddMethodSemanticsToHash(msEmit) ); - } -ErrExit: - HENUMInternal::ClearEnum(&hEnum); - return hr; -} // HRESULT NEWMERGER::CopyMethodSemantics() - - -//***************************************************************************** -// Copy Methods given a TypeDef -//***************************************************************************** -HRESULT NEWMERGER::CopyMethods( - MergeImportData *pImportData, - mdTypeDef tdImport, - mdTypeDef tdEmit) -{ - HRESULT hr = NOERROR; - MethodRec *pRecImport = NULL; - MethodRec *pRecEmit = NULL; - TypeDefRec *pTypeDefRec; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG ridStart, ridEnd; - ULONG i; - mdMethodDef mdEmit; - mdMethodDef mdImp; - TOKENREC *pTokenRec; - MDTOKENMAP *pCurTkMap; - - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - mdCustomAttribute tkCA; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec)); - ridStart = pMiniMdImport->getMethodListOfTypeDef(pTypeDefRec); - IfFailGo(pMiniMdImport->getEndMethodListOfTypeDef(RidFromToken(tdImport), &ridEnd)); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - - // make sure we didn't count the methods yet - _ASSERTE(pMTD->m_cMethods == 0); - - // loop through all Methods - for (i = ridStart; i < ridEnd; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetMethodRid(i, (ULONG *)&mdImp)); - - // only merge those MethodDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(TokenFromRid(mdImp, mdtMethodDef)) == false) - continue; - - IfFailGo(pMiniMdImport->GetMethodRecord(mdImp, &pRecImport)); - IfFailGo(pMiniMdEmit->AddMethodRecord(&pRecEmit, (RID *)&mdEmit)); - - // copy the method content over - IfFailGo( CopyMethod(pImportData, pRecImport, pRecEmit) ); - - IfFailGo( pMiniMdEmit->AddMethodToTypeDef(RidFromToken(tdEmit), mdEmit)); - - // record the token movement - mdImp = TokenFromRid(mdImp, mdtMethodDef); - mdEmit = TokenFromRid(mdEmit, mdtMethodDef); - IfFailGo( pMiniMdEmit->AddMemberDefToHash( - mdEmit, - tdEmit) ); - - IfFailGo( pCurTkMap->InsertNotFound(mdImp, false, mdEmit, &pTokenRec) ); - - // copy over the children - IfFailGo( CopyParams(pImportData, mdImp, mdEmit) ); - IfFailGo( CopyGenericParams(pImportData, mdImp, mdEmit) ); - - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - mdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - - if (!bSuppressMergeCheck) { - pMTD->m_cMethods++; - } - } - - // make sure we don't count any methods if merge check is suppressed on the type - _ASSERTE(pMTD->m_cMethods == 0 || !pMTD->m_bSuppressMergeCheck); -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyMethods() - - -//***************************************************************************** -// Copy Fields given a TypeDef -//***************************************************************************** -HRESULT NEWMERGER::CopyFields( - MergeImportData *pImportData, - mdTypeDef tdImport, - mdTypeDef tdEmit) -{ - HRESULT hr = NOERROR; - FieldRec *pRecImport = NULL; - FieldRec *pRecEmit = NULL; - TypeDefRec *pTypeDefRec; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG ridStart, ridEnd; - ULONG i; - mdFieldDef fdEmit; - mdFieldDef fdImp; - bool bDuplicate; - TOKENREC *pTokenRec; - PCCOR_SIGNATURE pvSigBlob; - ULONG cbSigBlob; - MDTOKENMAP *pCurTkMap; - - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - mdCustomAttribute tkCA; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec)); - ridStart = pMiniMdImport->getFieldListOfTypeDef(pTypeDefRec); - IfFailGo(pMiniMdImport->getEndFieldListOfTypeDef(RidFromToken(tdImport), &ridEnd)); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - - // make sure we didn't count the methods yet - _ASSERTE(pMTD->m_cFields == 0); - - // loop through all FieldDef of a TypeDef - for (i = ridStart; i < ridEnd; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetFieldRid(i, (ULONG *)&fdImp)); - - // only merge those FieldDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(fdImp, mdtFieldDef)) == false) - continue; - - - IfFailGo(pMiniMdImport->GetFieldRecord(fdImp, &pRecImport)); - bDuplicate = false; - IfFailGo(pMiniMdEmit->AddFieldRecord(&pRecEmit, (RID *)&fdEmit)); - - // copy the field content over - IfFailGo( CopyField(pImportData, pRecImport, pRecEmit) ); - - IfFailGo( pMiniMdEmit->AddFieldToTypeDef(RidFromToken(tdEmit), fdEmit)); - - // record the token movement - fdImp = TokenFromRid(fdImp, mdtFieldDef); - fdEmit = TokenFromRid(fdEmit, mdtFieldDef); - IfFailGo(pMiniMdEmit->getSignatureOfField(pRecEmit, &pvSigBlob, &cbSigBlob)); - IfFailGo( pMiniMdEmit->AddMemberDefToHash( - fdEmit, - tdEmit) ); - - IfFailGo( pCurTkMap->InsertNotFound(fdImp, false, fdEmit, &pTokenRec) ); - - // count the number of fields that didn't suppress merge check - // non-static fields doesn't inherite the suppress merge check attribute from the type - bSuppressMergeCheck = - (IsFdStatic(pRecEmit->GetFlags()) && pMTD->m_bSuppressMergeCheck) || - ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - fdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (!bSuppressMergeCheck) { - pMTD->m_cFields++; - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyFields() - - -//***************************************************************************** -// Copy Events given a TypeDef -//***************************************************************************** -HRESULT NEWMERGER::CopyEvents( - MergeImportData *pImportData, - mdTypeDef tdImport, - mdTypeDef tdEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - RID ridEventMap; - EventMapRec *pEventMapRec; - EventRec *pRecImport; - EventRec *pRecEmit; - ULONG ridStart; - ULONG ridEnd; - ULONG i; - mdEvent evImp; - mdEvent evEmit; - TOKENREC *pTokenRec; - ULONG iEventMap; - EventMapRec *pEventMap; - MDTOKENMAP *pCurTkMap; - - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - mdCustomAttribute tkCA; - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - pCurTkMap = pImportData->m_pMDTokenMap; - - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - - // make sure we didn't count the events yet - _ASSERTE(pMTD->m_cEvents == 0); - - IfFailGo(pMiniMdImport->FindEventMapFor(RidFromToken(tdImport), &ridEventMap)); - if (!InvalidRid(ridEventMap)) - { - IfFailGo(pMiniMdImport->GetEventMapRecord(ridEventMap, &pEventMapRec)); - ridStart = pMiniMdImport->getEventListOfEventMap(pEventMapRec); - IfFailGo(pMiniMdImport->getEndEventListOfEventMap(ridEventMap, &ridEnd)); - - if (ridEnd > ridStart) - { - // If there is any event, create the eventmap record in the emit scope - // Create new record. - IfFailGo(pMiniMdEmit->AddEventMapRecord(&pEventMap, &iEventMap)); - - // Set parent. - IfFailGo(pMiniMdEmit->PutToken(TBL_EventMap, EventMapRec::COL_Parent, pEventMap, tdEmit)); - } - - for (i = ridStart; i < ridEnd; i++) - { - // get the real event rid - IfFailGo(pMiniMdImport->GetEventRid(i, (ULONG *)&evImp)); - - // only merge those Events that are marked - if ( pMiniMdImport->GetFilterTable()->IsEventMarked(TokenFromRid(evImp, mdtEvent)) == false) - continue; - - IfFailGo(pMiniMdImport->GetEventRecord(evImp, &pRecImport)); - IfFailGo(pMiniMdEmit->AddEventRecord(&pRecEmit, (RID *)&evEmit)); - - // copy the event record over - IfFailGo( CopyEvent(pImportData, pRecImport, pRecEmit) ); - - // Add Event to the EventMap. - IfFailGo( pMiniMdEmit->AddEventToEventMap(iEventMap, evEmit) ); - - // record the token movement - evImp = TokenFromRid(evImp, mdtEvent); - evEmit = TokenFromRid(evEmit, mdtEvent); - - IfFailGo( pCurTkMap->InsertNotFound(evImp, false, evEmit, &pTokenRec) ); - - // copy over the method semantics - IfFailGo( CopyMethodSemantics(pImportData, evImp, evEmit) ); - - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - evImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (!bSuppressMergeCheck) { - pMTD->m_cEvents++; - } - } - } - - // make sure we don't count any events if merge check is suppressed on the type - _ASSERTE(pMTD->m_cEvents == 0 || !pMTD->m_bSuppressMergeCheck); -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyEvents() - - -//***************************************************************************** -// Copy Properties given a TypeDef -//***************************************************************************** -HRESULT NEWMERGER::CopyProperties( - MergeImportData *pImportData, - mdTypeDef tdImport, - mdTypeDef tdEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - RID ridPropertyMap; - PropertyMapRec *pPropertyMapRec; - PropertyRec *pRecImport; - PropertyRec *pRecEmit; - ULONG ridStart; - ULONG ridEnd; - ULONG i; - mdProperty prImp; - mdProperty prEmit; - TOKENREC *pTokenRec; - ULONG iPropertyMap; - PropertyMapRec *pPropertyMap; - MDTOKENMAP *pCurTkMap; - - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - mdCustomAttribute tkCA; - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - pCurTkMap = pImportData->m_pMDTokenMap; - - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - - // make sure we didn't count the properties yet - _ASSERTE(pMTD->m_cProperties == 0); - - IfFailGo(pMiniMdImport->FindPropertyMapFor(RidFromToken(tdImport), &ridPropertyMap)); - if (!InvalidRid(ridPropertyMap)) - { - IfFailGo(pMiniMdImport->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec)); - ridStart = pMiniMdImport->getPropertyListOfPropertyMap(pPropertyMapRec); - IfFailGo(pMiniMdImport->getEndPropertyListOfPropertyMap(ridPropertyMap, &ridEnd)); - - if (ridEnd > ridStart) - { - // If there is any event, create the PropertyMap record in the emit scope - // Create new record. - IfFailGo(pMiniMdEmit->AddPropertyMapRecord(&pPropertyMap, &iPropertyMap)); - - // Set parent. - IfFailGo(pMiniMdEmit->PutToken(TBL_PropertyMap, PropertyMapRec::COL_Parent, pPropertyMap, tdEmit)); - } - - for (i = ridStart; i < ridEnd; i++) - { - // get the property rid - IfFailGo(pMiniMdImport->GetPropertyRid(i, (ULONG *)&prImp)); - - // only merge those Properties that are marked - if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(TokenFromRid(prImp, mdtProperty)) == false) - continue; - - - IfFailGo(pMiniMdImport->GetPropertyRecord(prImp, &pRecImport)); - IfFailGo(pMiniMdEmit->AddPropertyRecord(&pRecEmit, (RID *)&prEmit)); - - // copy the property record over - IfFailGo( CopyProperty(pImportData, pRecImport, pRecEmit) ); - - // Add Property to the PropertyMap. - IfFailGo( pMiniMdEmit->AddPropertyToPropertyMap(iPropertyMap, prEmit) ); - - // record the token movement - prImp = TokenFromRid(prImp, mdtProperty); - prEmit = TokenFromRid(prEmit, mdtProperty); - - IfFailGo( pCurTkMap->InsertNotFound(prImp, false, prEmit, &pTokenRec) ); - - // copy over the method semantics - IfFailGo( CopyMethodSemantics(pImportData, prImp, prEmit) ); - - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - prImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (!bSuppressMergeCheck) { - pMTD->m_cProperties++; - } - } - } - - // make sure we don't count any properties if merge check is suppressed on the type - _ASSERTE(pMTD->m_cProperties == 0 || !pMTD->m_bSuppressMergeCheck); - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyProperties() - - -//***************************************************************************** -// Copy Parameters given a TypeDef -//***************************************************************************** -HRESULT NEWMERGER::CopyParams( - MergeImportData *pImportData, - mdMethodDef mdImport, - mdMethodDef mdEmit) -{ - HRESULT hr = NOERROR; - ParamRec *pRecImport = NULL; - ParamRec *pRecEmit = NULL; - MethodRec *pMethodRec; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG ridStart, ridEnd; - ULONG i; - mdParamDef pdEmit; - mdParamDef pdImp; - TOKENREC *pTokenRec; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - - IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImport), &pMethodRec)); - ridStart = pMiniMdImport->getParamListOfMethod(pMethodRec); - IfFailGo(pMiniMdImport->getEndParamListOfMethod(RidFromToken(mdImport), &ridEnd)); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // loop through all InterfaceImpl - for (i = ridStart; i < ridEnd; i++) - { - // Get the param rid - IfFailGo(pMiniMdImport->GetParamRid(i, (ULONG *)&pdImp)); - - // only merge those Params that are marked - if ( pMiniMdImport->GetFilterTable()->IsParamMarked(TokenFromRid(pdImp, mdtParamDef)) == false) - continue; - - - IfFailGo(pMiniMdImport->GetParamRecord(pdImp, &pRecImport)); - IfFailGo(pMiniMdEmit->AddParamRecord(&pRecEmit, (RID *)&pdEmit)); - - // copy the Parameter record over - IfFailGo( CopyParam(pImportData, pRecImport, pRecEmit) ); - - // warning!! warning!! - // We cannot add paramRec to method list until it is fully set. - // AddParamToMethod will use the ulSequence in the record - IfFailGo( pMiniMdEmit->AddParamToMethod(RidFromToken(mdEmit), pdEmit)); - - // record the token movement - pdImp = TokenFromRid(pdImp, mdtParamDef); - pdEmit = TokenFromRid(pdEmit, mdtParamDef); - - IfFailGo( pCurTkMap->InsertNotFound(pdImp, false, pdEmit, &pTokenRec) ); - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyParams() - - -//***************************************************************************** -// Copy GenericParams given a TypeDef -//***************************************************************************** -HRESULT NEWMERGER::CopyGenericParams( - MergeImportData *pImportData, - mdToken tkImport, - mdToken tkEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - TOKENREC *pTokenRec; - GenericParamRec *pRecImport = NULL; - GenericParamRec *pRecEmit = NULL; - MDTOKENMAP *pCurTkMap; - HENUMInternal hEnum; - mdGenericParam gpImport; - mdGenericParam gpEmit; - LPCSTR szGenericParamName; - - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pMiniMdEmit = GetMiniMdEmit(); - pCurTkMap = pImportData->m_pMDTokenMap; - - IfFailGo( pMiniMdImport->FindGenericParamHelper(tkImport, &hEnum) ); - - while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &gpImport)) - { - // Get the import GenericParam record - _ASSERTE(TypeFromToken(gpImport) == mdtGenericParam); - IfFailGo(pMiniMdImport->GetGenericParamRecord(RidFromToken(gpImport), &pRecImport)); - - // Create new emit record. - IfFailGo(pMiniMdEmit->AddGenericParamRecord(&pRecEmit, (RID *)&gpEmit)); - - // copy the GenericParam content - pRecEmit->SetNumber( pRecImport->GetNumber()); - pRecEmit->SetFlags( pRecImport->GetFlags()); - - IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParam, GenericParamRec::COL_Owner, pRecEmit, tkEmit)); - - IfFailGo(pMiniMdImport->getNameOfGenericParam(pRecImport, &szGenericParamName)); - IfFailGo( pMiniMdEmit->PutString(TBL_GenericParam, GenericParamRec::COL_Name, pRecEmit, szGenericParamName)); - - // record the token movement - gpImport = TokenFromRid(gpImport, mdtGenericParam); - gpEmit = TokenFromRid(gpEmit, mdtGenericParam); - - IfFailGo( pCurTkMap->InsertNotFound(gpImport, false, gpEmit, &pTokenRec) ); - - // copy over any constraints - IfFailGo( CopyGenericParamConstraints(pImportData, gpImport, gpEmit) ); - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyGenericParams() - - -//***************************************************************************** -// Copy GenericParamConstraints given a GenericParam -//***************************************************************************** -HRESULT NEWMERGER::CopyGenericParamConstraints( - MergeImportData *pImportData, - mdGenericParamConstraint tkImport, - mdGenericParamConstraint tkEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - TOKENREC *pTokenRec; - GenericParamConstraintRec *pRecImport = NULL; - GenericParamConstraintRec *pRecEmit = NULL; - MDTOKENMAP *pCurTkMap; - HENUMInternal hEnum; - mdGenericParamConstraint gpImport; - mdGenericParamConstraint gpEmit; - mdToken tkConstraint; - - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pMiniMdEmit = GetMiniMdEmit(); - pCurTkMap = pImportData->m_pMDTokenMap; - - IfFailGo( pMiniMdImport->FindGenericParamConstraintHelper(tkImport, &hEnum) ); - - while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &gpImport)) - { - // Get the import GenericParam record - _ASSERTE(TypeFromToken(gpImport) == mdtGenericParamConstraint); - IfFailGo(pMiniMdImport->GetGenericParamConstraintRecord(RidFromToken(gpImport), &pRecImport)); - - // Translate the constraint before creating new record. - tkConstraint = pMiniMdImport->getConstraintOfGenericParamConstraint(pRecImport); - if (pCurTkMap->Find(tkConstraint, &pTokenRec) == false) - { - // This should never fire unless the TypeDefs/Refs weren't merged - // before this code runs. - _ASSERTE(!"GenericParamConstraint Constraint not found in MERGER::CopyGenericParamConstraints. Bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - tkConstraint = pTokenRec->m_tkTo; - - // Create new emit record. - IfFailGo(pMiniMdEmit->AddGenericParamConstraintRecord(&pRecEmit, (RID *)&gpEmit)); - - // copy the GenericParamConstraint content - IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParamConstraint, GenericParamConstraintRec::COL_Owner, pRecEmit, tkEmit)); - - IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParamConstraint, GenericParamConstraintRec::COL_Constraint, pRecEmit, tkConstraint)); - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyGenericParamConstraints() - - -//***************************************************************************** -// Verify GenericParams given a TypeDef -//***************************************************************************** -HRESULT NEWMERGER::VerifyGenericParams( - MergeImportData *pImportData, - mdToken tkImport, - mdToken tkEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - TOKENREC *pTokenRec; - MDTOKENMAP *pCurTkMap; - HENUMInternal hEnumImport; // Enumerator for import scope. - HENUMInternal hEnumEmit; // Enumerator for emit scope. - ULONG cImport, cEmit; // Count of import & emit records. - ULONG i; // Enumerating records in import scope. - ULONG iEmit; // Tracking records in emit scope. - mdGenericParam gpImport; // Import scope GenericParam token. - mdGenericParam gpEmit; // Emit scope GenericParam token. - GenericParamRec *pRecImport = NULL; - GenericParamRec *pRecEmit = NULL; - LPCSTR szNameImport; // Name of param in import scope. - LPCSTR szNameEmit; // Name of param in emit scope. - - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pMiniMdEmit = GetMiniMdEmit(); - pCurTkMap = pImportData->m_pMDTokenMap; - - // Get enumerators for the input and output scopes. - IfFailGo(pMiniMdImport->FindGenericParamHelper(tkImport, &hEnumImport)); - IfFailGo(pMiniMdEmit->FindGenericParamHelper(tkEmit, &hEnumEmit)); - - // The counts should be the same. - IfFailGo(HENUMInternal::GetCount(&hEnumImport, &cImport)); - IfFailGo(HENUMInternal::GetCount(&hEnumEmit, &cEmit)); - - if (cImport != cEmit) - { - CheckContinuableErrorEx(META_E_GENERICPARAM_INCONSISTENT, pImportData, tkImport); - // If we are here, the linker says this error is OK. - } - - for (i=iEmit=0; iGetGenericParamRecord(RidFromToken(gpImport), &pRecImport)); - - // Find the emit record. If the import and emit scopes are ordered the same - // this is easy; otherwise go looking for it. - // Get the "next" emit record. - if (iEmit < cEmit) - { - IfFailGo(HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit)); - _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParam); - IfFailGo(pMiniMdEmit->GetGenericParamRecord(RidFromToken(gpEmit), &pRecEmit)); - } - - // If the import and emit sequence numbers don't match, go looking. - // Also, if we would have walked off end of array, go looking. - if (iEmit >= cEmit || pRecImport->GetNumber() != pRecEmit->GetNumber()) - { - for (iEmit=0; iEmitGetGenericParamRecord(RidFromToken(gpEmit), &pRecEmit)); - - // The one we want? - if (pRecImport->GetNumber() == pRecEmit->GetNumber()) - break; - } - if (iEmit >= cEmit) - goto Error; // Didn't find it - } - - // Check that these "n'th" GenericParam records match. - - // Flags. - if (pRecImport->GetFlags() != pRecEmit->GetFlags()) - goto Error; - - // Name. - IfFailGo(pMiniMdImport->getNameOfGenericParam(pRecImport, &szNameImport)); - IfFailGo(pMiniMdEmit->getNameOfGenericParam(pRecEmit, &szNameEmit)); - if (strcmp(szNameImport, szNameEmit) != 0) - goto Error; - - // Verify any constraints. - gpImport = TokenFromRid(gpImport, mdtGenericParam); - gpEmit = TokenFromRid(gpEmit, mdtGenericParam); - hr = VerifyGenericParamConstraints(pImportData, gpImport, gpEmit); - - if (SUCCEEDED(hr)) - { - // record the token movement - IfFailGo( pCurTkMap->InsertNotFound(gpImport, true, gpEmit, &pTokenRec) ); - } - else - { -Error: - // inconsistent in GenericParams - hr = S_OK; // discard old error; new error will be returned from CheckContinuableError - CheckContinuableErrorEx(META_E_GENERICPARAM_INCONSISTENT, pImportData, tkImport); - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::VerifyGenericParams() - - -//***************************************************************************** -// Verify GenericParamConstraints given a GenericParam -//***************************************************************************** -HRESULT NEWMERGER::VerifyGenericParamConstraints( - MergeImportData *pImportData, // The import scope. - mdGenericParam gpImport, // Import GenericParam. - mdGenericParam gpEmit) // Emit GenericParam. -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - TOKENREC *pTokenRec; - HENUMInternal hEnumImport; // Enumerator for import scope. - HENUMInternal hEnumEmit; // Enumerator for emit scope. - ULONG cImport, cEmit; // Count of import & emit records. - ULONG i; // Enumerating records in import scope. - ULONG iEmit; // Tracking records in emit scope. - GenericParamConstraintRec *pRecImport = NULL; - GenericParamConstraintRec *pRecEmit = NULL; - MDTOKENMAP *pCurTkMap; - mdToken tkConstraintImport = mdTokenNil; - mdToken tkConstraintEmit = mdTokenNil; - - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pMiniMdEmit = GetMiniMdEmit(); - pCurTkMap = pImportData->m_pMDTokenMap; - - // Get enumerators for the input and output scopes. - IfFailGo(pMiniMdImport->FindGenericParamConstraintHelper(gpImport, &hEnumImport)); - IfFailGo(pMiniMdEmit->FindGenericParamConstraintHelper(gpEmit, &hEnumEmit)); - - // The counts should be the same. - IfFailGo(HENUMInternal::GetCount(&hEnumImport, &cImport)); - IfFailGo(HENUMInternal::GetCount(&hEnumEmit, &cEmit)); - - if (cImport != cEmit) - IfFailGo(META_E_GENERICPARAM_INCONSISTENT); // Different numbers of constraints. - - for (i=iEmit=0; iGetGenericParamConstraintRecord(RidFromToken(gpImport), &pRecImport)); - - // Get the constraint. - tkConstraintImport = pMiniMdImport->getConstraintOfGenericParamConstraint(pRecImport); - if (pCurTkMap->Find(tkConstraintImport, &pTokenRec) == false) - { - // This should never fire unless the TypeDefs/Refs weren't merged - // before this code runs. - _ASSERTE(!"GenericParamConstraint Constraint not found in MERGER::VerifyGenericParamConstraints. Bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - tkConstraintImport = pTokenRec->m_tkTo; - - // Find the emit record. If the import and emit scopes are ordered the same - // this is easy; otherwise go looking for it. - // Get the "next" emit record. - if (iEmit < cEmit) - { - IfFailGo( HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit)); - _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParamConstraint); - IfFailGo(pMiniMdEmit->GetGenericParamConstraintRecord(RidFromToken(gpEmit), &pRecEmit)); - tkConstraintEmit = pMiniMdEmit->getConstraintOfGenericParamConstraint(pRecEmit); - } - - // If the import and emit constraints don't match, go looking. - if (iEmit >= cEmit || tkConstraintEmit != tkConstraintImport) - { - for (iEmit=0; iEmitGetGenericParamConstraintRecord(RidFromToken(gpEmit), &pRecEmit)); - tkConstraintEmit = pMiniMdEmit->getConstraintOfGenericParamConstraint(pRecEmit); - - // The one we want? - if (tkConstraintEmit == tkConstraintImport) - break; - } - if (iEmit >= cEmit) - { - IfFailGo(META_E_GENERICPARAM_INCONSISTENT); // Didn't find the constraint - } - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::VerifyGenericParamConstraints() - - -//***************************************************************************** -// Verify Methods -//***************************************************************************** -HRESULT NEWMERGER::VerifyMethods( - MergeImportData *pImportData, - mdTypeDef tdImport, - mdTypeDef tdEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - MethodRec *pRecImp; - MethodRec *pRecEmit; - ULONG ridStart; - ULONG ridEnd; - ULONG i; - - TypeDefRec *pTypeDefRec; - LPCUTF8 szName; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - TOKENREC *pTokenRec; - mdMethodDef mdImp; - mdMethodDef mdEmit; - MDTOKENMAP *pCurTkMap; - - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - ULONG cImport = 0; // count of non-merge check suppressed methods - mdCustomAttribute tkCA; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // Get a count of records in the import scope; prepare to enumerate them. - IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec)); - ridStart = pMiniMdImport->getMethodListOfTypeDef(pTypeDefRec); - IfFailGo(pMiniMdImport->getEndMethodListOfTypeDef(RidFromToken(tdImport), &ridEnd)); - - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - - // loop through all Methods of the TypeDef - for (i = ridStart; i < ridEnd; i++) - { - IfFailGo(pMiniMdImport->GetMethodRid(i, (ULONG *)&mdImp)); - - // only verify those Methods that are marked - if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(TokenFromRid(mdImp, mdtMethodDef)) == false) - continue; - - IfFailGo(pMiniMdImport->GetMethodRecord(mdImp, &pRecImp)); - - if (m_fDupCheck == FALSE && tdImport == pImportData->m_pRegMetaImport->m_tdModule) // TokenFromRid(1, mdtTypeDef)) - { - // No dup check. This is the scenario that we only have one import scope. Just copy over the - // globals. - goto CopyMethodLabel; - } - - IfFailGo(pMiniMdImport->getNameOfMethod(pRecImp, &szName)); - IfFailGo(pMiniMdImport->getSignatureOfMethod(pRecImp, &pbSig, &cbSig)); - - mdImp = TokenFromRid(mdImp, mdtMethodDef); - - if ( IsMdPrivateScope( pRecImp->GetFlags() ) ) - { - // Trigger additive merge - goto CopyMethodLabel; - } - - // convert rid contained in signature to new scope - IfFailGo(ImportHelper::MergeUpdateTokenInSig( - NULL, // Assembly emit scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly scope information. - pMiniMdImport, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit)); // number of bytes write to cbEmit - - hr = ImportHelper::FindMethod( - pMiniMdEmit, - tdEmit, - szName, - (const COR_SIGNATURE *)qbSig.Ptr(), - cbEmit, - &mdEmit); - - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - mdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (bSuppressMergeCheck || (tdImport == pImportData->m_pRegMetaImport->m_tdModule)) - { - // global functions! Make sure that we move over the non-duplicate global function - // declaration - // - if (hr == S_OK) - { - // found the duplicate - IfFailGo( VerifyMethod(pImportData, mdImp, mdEmit) ); - } - else - { -CopyMethodLabel: - // not a duplicate! Copy over the - IfFailGo(pMiniMdEmit->AddMethodRecord(&pRecEmit, (RID *)&mdEmit)); - - // copy the method content over - IfFailGo( CopyMethod(pImportData, pRecImp, pRecEmit) ); - - IfFailGo( pMiniMdEmit->AddMethodToTypeDef(RidFromToken(tdEmit), mdEmit)); - - // record the token movement - mdEmit = TokenFromRid(mdEmit, mdtMethodDef); - IfFailGo( pMiniMdEmit->AddMemberDefToHash( - mdEmit, - tdEmit) ); - - mdImp = TokenFromRid(mdImp, mdtMethodDef); - IfFailGo( pCurTkMap->InsertNotFound(mdImp, false, mdEmit, &pTokenRec) ); - - // copy over the children - IfFailGo( CopyParams(pImportData, mdImp, mdEmit) ); - IfFailGo( CopyGenericParams(pImportData, mdImp, mdEmit) ); - - } - } - else - { - if (hr == S_OK) - { - // Good! We are supposed to find a duplicate - IfFailGo( VerifyMethod(pImportData, mdImp, mdEmit) ); - } - else - { - // Oops! The typedef is duplicated but the method is not!! - hr = S_OK; // discard old error; new error will be returned from CheckContinuableError - CheckContinuableErrorEx(META_E_METHD_NOT_FOUND, pImportData, mdImp); - } - - cImport++; - } - } - - // The counts should be the same, unless this is - if (cImport != pMTD->m_cMethods && tdImport != pImportData->m_pRegMetaImport->m_tdModule) - { - CheckContinuableErrorEx(META_E_METHOD_COUNTS, pImportData, tdImport); - // If we are here, the linker says this error is OK. - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::VerifyMethods() - - -//***************************************************************************** -// verify a duplicated method -//***************************************************************************** -HRESULT NEWMERGER::VerifyMethod( - MergeImportData *pImportData, - mdMethodDef mdImp, // [IN] the emit record to fill - mdMethodDef mdEmit) // [IN] the record to import -{ - HRESULT hr; - MethodRec *pRecImp; - MethodRec *pRecEmit; - TOKENREC *pTokenRec; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - IfFailGo( pCurTkMap->InsertNotFound(mdImp, true, mdEmit, &pTokenRec) ); - - IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImp), &pRecImp)); - - // We need to make sure that the impl flags are propagated . - // Rules are: if the first method has miForwardRef flag set but the new method does not, - // we want to disable the miForwardRef flag. If the one found in the emit scope does not have - // miForwardRef set and the second one doesn't either, we want to make sure that the rest of - // impl flags are the same. - // - if ( !IsMiForwardRef( pRecImp->GetImplFlags() ) ) - { - IfFailGo(pMiniMdEmit->GetMethodRecord(RidFromToken(mdEmit), &pRecEmit)); - if (!IsMiForwardRef(pRecEmit->GetImplFlags())) - { - // make sure the rest of ImplFlags are the same - if (pRecEmit->GetImplFlags() != pRecImp->GetImplFlags()) - { - // inconsistent in implflags - CheckContinuableErrorEx(META_E_METHDIMPL_INCONSISTENT, pImportData, mdImp); - } - } - else - { - // propagate the importing ImplFlags - pRecEmit->SetImplFlags(pRecImp->GetImplFlags()); - } - } - - // verify the children - IfFailGo( VerifyParams(pImportData, mdImp, mdEmit) ); - IfFailGo( VerifyGenericParams(pImportData, mdImp, mdEmit) ); - -ErrExit: - return hr; -} // HRESULT NEWMERGER::VerifyMethod() - - -//***************************************************************************** -// Verify Fields -//***************************************************************************** -HRESULT NEWMERGER::VerifyFields( - MergeImportData *pImportData, - mdTypeDef tdImport, - mdTypeDef tdEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - FieldRec *pRecImp; - FieldRec *pRecEmit; - mdFieldDef fdImp; - mdFieldDef fdEmit; - ULONG ridStart; - ULONG ridEnd; - ULONG i; - - TypeDefRec *pTypeDefRec; - LPCUTF8 szName; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - TOKENREC *pTokenRec; - MDTOKENMAP *pCurTkMap; - - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - ULONG cImport = 0; // count of non-merge check suppressed fields - mdCustomAttribute tkCA; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // Get a count of records in the import scope; prepare to enumerate them. - IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec)); - ridStart = pMiniMdImport->getFieldListOfTypeDef(pTypeDefRec); - IfFailGo(pMiniMdImport->getEndFieldListOfTypeDef(RidFromToken(tdImport), &ridEnd)); - - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - - // loop through all fields of the TypeDef - for (i = ridStart; i < ridEnd; i++) - { - IfFailGo(pMiniMdImport->GetFieldRid(i, (ULONG *)&fdImp)); - - // only verify those fields that are marked - if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(fdImp, mdtFieldDef)) == false) - continue; - - IfFailGo(pMiniMdImport->GetFieldRecord(fdImp, &pRecImp)); - - if (m_fDupCheck == FALSE && tdImport == pImportData->m_pRegMetaImport->m_tdModule) - { - // No dup check. This is the scenario that we only have one import scope. Just copy over the - // globals. - goto CopyFieldLabel; - } - - IfFailGo(pMiniMdImport->getNameOfField(pRecImp, &szName)); - IfFailGo(pMiniMdImport->getSignatureOfField(pRecImp, &pbSig, &cbSig)); - - if ( IsFdPrivateScope(pRecImp->GetFlags())) - { - // Trigger additive merge - fdImp = TokenFromRid(fdImp, mdtFieldDef); - goto CopyFieldLabel; - } - - // convert rid contained in signature to new scope - IfFailGo(ImportHelper::MergeUpdateTokenInSig( - NULL, // Assembly emit scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly scope information. - pMiniMdImport, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit)); // number of bytes write to cbEmit - - hr = ImportHelper::FindField( - pMiniMdEmit, - tdEmit, - szName, - (const COR_SIGNATURE *)qbSig.Ptr(), - cbEmit, - &fdEmit); - - fdImp = TokenFromRid(fdImp, mdtFieldDef); - - bSuppressMergeCheck = - (IsFdStatic(pRecImp->GetFlags()) && pMTD->m_bSuppressMergeCheck) || - ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - fdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (bSuppressMergeCheck || (tdImport == pImportData->m_pRegMetaImport->m_tdModule)) - { - // global data! Make sure that we move over the non-duplicate global function - // declaration - // - if (hr == S_OK) - { - // found the duplicate - IfFailGo( pCurTkMap->InsertNotFound(fdImp, true, fdEmit, &pTokenRec) ); - } - else - { -CopyFieldLabel: - // not a duplicate! Copy over the - IfFailGo(pMiniMdEmit->AddFieldRecord(&pRecEmit, (RID *)&fdEmit)); - - // copy the field record over - IfFailGo( CopyField(pImportData, pRecImp, pRecEmit) ); - - IfFailGo( pMiniMdEmit->AddFieldToTypeDef(RidFromToken(tdEmit), fdEmit)); - - // record the token movement - fdEmit = TokenFromRid(fdEmit, mdtFieldDef); - IfFailGo( pMiniMdEmit->AddMemberDefToHash( - fdEmit, - tdEmit) ); - - fdImp = TokenFromRid(fdImp, mdtFieldDef); - IfFailGo( pCurTkMap->InsertNotFound(fdImp, false, fdEmit, &pTokenRec) ); - } - } - else - { - if (hr == S_OK) - { - // Good! We are supposed to find a duplicate - IfFailGo( pCurTkMap->InsertNotFound(fdImp, true, fdEmit, &pTokenRec) ); - } - else - { - // Oops! The typedef is duplicated but the field is not!! - hr = S_OK; // discard old error; new error will be returned from CheckContinuableError - CheckContinuableErrorEx(META_E_FIELD_NOT_FOUND, pImportData, fdImp); - } - - cImport++; - } - } - - // The counts should be the same, unless this is - if (cImport != pMTD->m_cFields && tdImport != pImportData->m_pRegMetaImport->m_tdModule) - { - CheckContinuableErrorEx(META_E_FIELD_COUNTS, pImportData, tdImport); - // If we are here, the linker says this error is OK. - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::VerifyFields() - - -//***************************************************************************** -// Verify Events -//***************************************************************************** -HRESULT NEWMERGER::VerifyEvents( - MergeImportData *pImportData, - mdTypeDef tdImport, - mdTypeDef tdEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - RID ridEventMap, ridEventMapEmit; - EventMapRec *pEventMapRec; - EventRec *pRecImport; - ULONG ridStart; - ULONG ridEnd; - ULONG i; - mdEvent evImport; - mdEvent evEmit; - TOKENREC *pTokenRec; - LPCUTF8 szName; - mdToken tkType; - MDTOKENMAP *pCurTkMap; - - EventMapRec *pEventMapEmit; - EventRec *pRecEmit; - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - ULONG cImport = 0; // count of non-merge check suppressed events - mdCustomAttribute tkCA; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - IfFailGo(pMiniMdImport->FindEventMapFor(RidFromToken(tdImport), &ridEventMap)); - if (!InvalidRid(ridEventMap)) - { - // Get a count of records already in emit scope. - IfFailGo(pMiniMdEmit->FindEventMapFor(RidFromToken(tdEmit), &ridEventMapEmit)); - - if (InvalidRid(ridEventMapEmit)) { - // If there is any event, create the eventmap record in the emit scope - // Create new record. - IfFailGo(pMiniMdEmit->AddEventMapRecord(&pEventMapEmit, &ridEventMapEmit)); - - // Set parent. - IfFailGo(pMiniMdEmit->PutToken(TBL_EventMap, EventMapRec::COL_Parent, pEventMapEmit, tdEmit)); - } - - // Get a count of records in the import scope; prepare to enumerate them. - IfFailGo(pMiniMdImport->GetEventMapRecord(ridEventMap, &pEventMapRec)); - ridStart = pMiniMdImport->getEventListOfEventMap(pEventMapRec); - IfFailGo(pMiniMdImport->getEndEventListOfEventMap(ridEventMap, &ridEnd)); - - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - - for (i = ridStart; i < ridEnd; i++) - { - // get the property rid - IfFailGo(pMiniMdImport->GetEventRid(i, (ULONG *)&evImport)); - - // only verify those Events that are marked - if ( pMiniMdImport->GetFilterTable()->IsEventMarked(TokenFromRid(evImport, mdtEvent)) == false) - continue; - - IfFailGo(pMiniMdImport->GetEventRecord(evImport, &pRecImport)); - IfFailGo(pMiniMdImport->getNameOfEvent(pRecImport, &szName)); - tkType = pMiniMdImport->getEventTypeOfEvent( pRecImport ); - IfFailGo( pCurTkMap->Remap(tkType, &tkType) ); - evImport = TokenFromRid( evImport, mdtEvent); - - hr = ImportHelper::FindEvent( - pMiniMdEmit, - tdEmit, - szName, - &evEmit); - - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - evImport, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (bSuppressMergeCheck) - { - - if (hr == S_OK ) - { - // Good. We found the matching event when we have a duplicate typedef - IfFailGo( pCurTkMap->InsertNotFound(evImport, true, evEmit, &pTokenRec) ); - } - else - { - // not a duplicate! Copy over the - IfFailGo(pMiniMdEmit->AddEventRecord(&pRecEmit, (RID *)&evEmit)); - - // copy the event record over - IfFailGo( CopyEvent(pImportData, pRecImport, pRecEmit) ); - - // Add Event to the EventMap. - IfFailGo( pMiniMdEmit->AddEventToEventMap(ridEventMapEmit, evEmit) ); - - // record the token movement - evEmit = TokenFromRid(evEmit, mdtEvent); - - IfFailGo( pCurTkMap->InsertNotFound(evImport, false, evEmit, &pTokenRec) ); - - // copy over the method semantics - IfFailGo( CopyMethodSemantics(pImportData, evImport, evEmit) ); - } - } - else - { - if (hr == S_OK ) - { - // Good. We found the matching event when we have a duplicate typedef - IfFailGo( pCurTkMap->InsertNotFound(evImport, true, evEmit, &pTokenRec) ); - } - else - { - // Oops! The typedef is duplicated but the event is not!! - hr = S_OK; // discard old error; new error will be returned from CheckContinuableError - CheckContinuableErrorEx(META_E_EVENT_NOT_FOUND, pImportData, evImport); - - } - - cImport++; - } - } - - // The counts should be the same, unless this is - if (cImport != pMTD->m_cEvents && tdImport != pImportData->m_pRegMetaImport->m_tdModule) - { - CheckContinuableErrorEx(META_E_EVENT_COUNTS, pImportData, tdImport); - // If we are here, the linker says this error is OK. - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::VerifyEvents() - - -//***************************************************************************** -// Verify Properties -//***************************************************************************** -HRESULT NEWMERGER::VerifyProperties( - MergeImportData *pImportData, - mdTypeDef tdImport, - mdTypeDef tdEmit) -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - RID ridPropertyMap, ridPropertyMapEmit; - PropertyMapRec *pPropertyMapRec; - PropertyRec *pRecImport; - ULONG ridStart; - ULONG ridEnd; - ULONG i; - mdProperty prImp; - mdProperty prEmit; - TOKENREC *pTokenRec; - LPCUTF8 szName; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - MDTOKENMAP *pCurTkMap; - - PropertyMapRec *pPropertyMapEmit; - PropertyRec *pRecEmit; - MergeTypeData *pMTD; - BOOL bSuppressMergeCheck; - ULONG cImport = 0; // count of non-merge check suppressed properties - mdCustomAttribute tkCA; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - IfFailGo(pMiniMdImport->FindPropertyMapFor(RidFromToken(tdImport), &ridPropertyMap)); - if (!InvalidRid(ridPropertyMap)) - { - // Get a count of records already in emit scope. - IfFailGo(pMiniMdEmit->FindPropertyMapFor(RidFromToken(tdEmit), &ridPropertyMapEmit)); - - if (InvalidRid(ridPropertyMapEmit)) - { - // If there is any event, create the PropertyMap record in the emit scope - // Create new record. - IfFailGo(pMiniMdEmit->AddPropertyMapRecord(&pPropertyMapEmit, &ridPropertyMapEmit)); - - // Set parent. - IfFailGo(pMiniMdEmit->PutToken(TBL_PropertyMap, PropertyMapRec::COL_Parent, pPropertyMapEmit, tdEmit)); - } - - // Get a count of records in the import scope; prepare to enumerate them. - IfFailGo(pMiniMdImport->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec)); - ridStart = pMiniMdImport->getPropertyListOfPropertyMap(pPropertyMapRec); - IfFailGo(pMiniMdImport->getEndPropertyListOfPropertyMap(ridPropertyMap, &ridEnd)); - - pMTD = m_rMTDs.Get(RidFromToken(tdEmit)); - - for (i = ridStart; i < ridEnd; i++) - { - // get the property rid - IfFailGo(pMiniMdImport->GetPropertyRid(i, (ULONG *)&prImp)); - - // only verify those Properties that are marked - if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(TokenFromRid(prImp, mdtProperty)) == false) - continue; - - IfFailGo(pMiniMdImport->GetPropertyRecord(prImp, &pRecImport)); - IfFailGo(pMiniMdImport->getNameOfProperty(pRecImport, &szName)); - IfFailGo(pMiniMdImport->getTypeOfProperty(pRecImport, &pbSig, &cbSig)); - prImp = TokenFromRid( prImp, mdtProperty); - - // convert rid contained in signature to new scope - IfFailGo( ImportHelper::MergeUpdateTokenInSig( - NULL, // Emit assembly. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly scope information. - pMiniMdImport, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit) ); // number of bytes write to cbEmit - - hr = ImportHelper::FindProperty( - pMiniMdEmit, - tdEmit, - szName, - (PCCOR_SIGNATURE) qbSig.Ptr(), - cbEmit, - &prEmit); - - bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck || - ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) && - (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport, - prImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA))); - - if (bSuppressMergeCheck) - { - if (hr == S_OK) - { - // Good. We found the matching property when we have a duplicate typedef - IfFailGo( pCurTkMap->InsertNotFound(prImp, true, prEmit, &pTokenRec) ); - } - else - { - IfFailGo(pMiniMdEmit->AddPropertyRecord(&pRecEmit, (RID *)&prEmit)); - - // copy the property record over - IfFailGo( CopyProperty(pImportData, pRecImport, pRecEmit) ); - - // Add Property to the PropertyMap. - IfFailGo( pMiniMdEmit->AddPropertyToPropertyMap(ridPropertyMapEmit, prEmit) ); - - // record the token movement - prEmit = TokenFromRid(prEmit, mdtProperty); - - IfFailGo( pCurTkMap->InsertNotFound(prImp, false, prEmit, &pTokenRec) ); - - // copy over the method semantics - IfFailGo( CopyMethodSemantics(pImportData, prImp, prEmit) ); - } - } - else - { - if (hr == S_OK) - { - // Good. We found the matching property when we have a duplicate typedef - IfFailGo( pCurTkMap->InsertNotFound(prImp, true, prEmit, &pTokenRec) ); - } - else - { - hr = S_OK; // discard old error; new error will be returned from CheckContinuableError - CheckContinuableErrorEx(META_E_PROP_NOT_FOUND, pImportData, prImp); - } - - cImport++; - } - } - - // The counts should be the same, unless this is - if (cImport != pMTD->m_cProperties && tdImport != pImportData->m_pRegMetaImport->m_tdModule) - { - CheckContinuableErrorEx(META_E_PROPERTY_COUNTS, pImportData, tdImport); - // If we are here, the linker says this error is OK. - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::VerifyProperties() - - -//***************************************************************************** -// Verify Parameters given a Method -//***************************************************************************** -HRESULT NEWMERGER::VerifyParams( - MergeImportData *pImportData, - mdMethodDef mdImport, - mdMethodDef mdEmit) -{ - HRESULT hr = NOERROR; - ParamRec *pRecImport = NULL; - ParamRec *pRecEmit = NULL; - MethodRec *pMethodRec; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG ridStart, ridEnd; - ULONG ridStartEmit, ridEndEmit; - ULONG cImport, cEmit; - ULONG i, j; - mdParamDef pdEmit = 0; - mdParamDef pdImp; - TOKENREC *pTokenRec; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - pCurTkMap = pImportData->m_pMDTokenMap; - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // Get count of params in import scope; prepare to enumerate. - IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImport), &pMethodRec)); - ridStart = pMiniMdImport->getParamListOfMethod(pMethodRec); - IfFailGo(pMiniMdImport->getEndParamListOfMethod(RidFromToken(mdImport), &ridEnd)); - cImport = ridEnd - ridStart; - - // Get count of params in emit scope; prepare to enumerate. - IfFailGo(pMiniMdEmit->GetMethodRecord(RidFromToken(mdEmit), &pMethodRec)); - ridStartEmit = pMiniMdEmit->getParamListOfMethod(pMethodRec); - IfFailGo(pMiniMdEmit->getEndParamListOfMethod(RidFromToken(mdEmit), &ridEndEmit)); - cEmit = ridEndEmit - ridStartEmit; - - // The counts should be the same. - if (cImport != cEmit) - { - // That is, unless this is , so get the method's parent. - mdTypeDef tdImport; - IfFailGo(pMiniMdImport->FindParentOfMethodHelper(mdImport, &tdImport)); - if (tdImport != pImportData->m_pRegMetaImport->m_tdModule) - CheckContinuableErrorEx(META_E_PARAM_COUNTS, pImportData, mdImport); - // If we are here, the linker says this error is OK. - } - - // loop through all Parameters - for (i = ridStart; i < ridEnd; i++) - { - // Get the importing param row - IfFailGo(pMiniMdImport->GetParamRid(i, (ULONG *)&pdImp)); - - // only verify those Params that are marked - if ( pMiniMdImport->GetFilterTable()->IsParamMarked(TokenFromRid(pdImp, mdtParamDef)) == false) - continue; - - - IfFailGo(pMiniMdImport->GetParamRecord(pdImp, &pRecImport)); - pdImp = TokenFromRid(pdImp, mdtParamDef); - - // It turns out when we merge a typelib with itself, the emit and import scope - // has different sequence of parameter - // - // find the corresponding emit param row - for (j = ridStartEmit; j < ridEndEmit; j++) - { - IfFailGo(pMiniMdEmit->GetParamRid(j, (ULONG *)&pdEmit)); - IfFailGo(pMiniMdEmit->GetParamRecord(pdEmit, &pRecEmit)); - if (pRecEmit->GetSequence() == pRecImport->GetSequence()) - break; - } - - if (j == ridEndEmit) - { - // did not find the corresponding parameter in the emiting scope - hr = S_OK; // discard old error; new error will be returned from CheckContinuableError - CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp); - } - - else - { - _ASSERTE( pRecEmit->GetSequence() == pRecImport->GetSequence() ); - - pdEmit = TokenFromRid(pdEmit, mdtParamDef); - - // record the token movement -#ifdef WE_DONT_NEED_TO_CHECK_NAMES__THEY_DONT_AFFECT_ANYTHING - LPCUTF8 szNameImp; - LPCUTF8 szNameEmit; - IfFailGo(pMiniMdImport->getNameOfParam(pRecImport, &szNameImp)); - IfFailGo(pMiniMdEmit->getNameOfParam(pRecEmit, &szNameEmit)); - if (szNameImp && szNameEmit && strcmp(szNameImp, szNameEmit) != 0) - { - // parameter name doesn't match - CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp); - } -#endif - if (pRecEmit->GetFlags() != pRecImport->GetFlags()) - { - // flags doesn't match - CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp); - } - - // record token movement. This is a duplicate. - IfFailGo( pCurTkMap->InsertNotFound(pdImp, true, pdEmit, &pTokenRec) ); - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::VerifyParams() - - -//***************************************************************************** -// merging MemberRef -//***************************************************************************** -HRESULT NEWMERGER::MergeMemberRefs( ) -{ - HRESULT hr = NOERROR; - MemberRefRec *pRecImport = NULL; - MemberRefRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdMemberRef mrEmit; - mdMemberRef mrImp; - bool bDuplicate = false; - TOKENREC *pTokenRec; - mdToken tkParentImp; - mdToken tkParentEmit; - - LPCUTF8 szNameImp; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - - bool isRefOptimizedToDef; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - - iCount = pMiniMdImport->getCountMemberRefs(); - - // loop through all MemberRef - for (i = 1; i <= iCount; i++) - { - - // only merge those MemberRefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsMemberRefMarked(TokenFromRid(i, mdtMemberRef)) == false) - continue; - - isRefOptimizedToDef = false; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetMemberRefRecord(i, &pRecImport)); - IfFailGo(pMiniMdImport->getNameOfMemberRef(pRecImport, &szNameImp)); - IfFailGo(pMiniMdImport->getSignatureOfMemberRef(pRecImport, &pbSig, &cbSig)); - tkParentImp = pMiniMdImport->getClassOfMemberRef(pRecImport); - - IfFailGo( pCurTkMap->Remap(tkParentImp, &tkParentEmit) ); - - // convert rid contained in signature to new scope - IfFailGo(ImportHelper::MergeUpdateTokenInSig( - NULL, // Assembly emit scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly information. - pMiniMdImport, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit)); // number of bytes write to cbEmit - - // We want to know if we can optimize this MemberRef to a FieldDef or MethodDef - if (TypeFromToken(tkParentEmit) == mdtTypeDef && RidFromToken(tkParentEmit) != 0) - { - // The parent of this MemberRef has been successfully optimized to a TypeDef. Then this MemberRef should be - // be able to optimized to a MethodDef or FieldDef unless one of the parent in the inheritance hierachy - // is through TypeRef. Then this MemberRef stay as MemberRef. If This is a VarArg calling convention, then - // we will remap the MemberRef's parent to a MethodDef or stay as TypeRef. - // - mdToken tkParent = tkParentEmit; - mdToken tkMethDefOrFieldDef; - PCCOR_SIGNATURE pbSigTmp = (const COR_SIGNATURE *) qbSig.Ptr(); - - while (TypeFromToken(tkParent) == mdtTypeDef && RidFromToken(tkParent) != 0) - { - TypeDefRec *pRec; - hr = ImportHelper::FindMember(pMiniMdEmit, tkParent, szNameImp, pbSigTmp, cbEmit, &tkMethDefOrFieldDef); - if (hr == S_OK) - { - // We have found a match!! - if (isCallConv(CorSigUncompressCallingConv(pbSigTmp), IMAGE_CEE_CS_CALLCONV_VARARG)) - { - // The found MethodDef token will replace this MemberRef's parent token - _ASSERTE(TypeFromToken(tkMethDefOrFieldDef) == mdtMethodDef); - tkParentEmit = tkMethDefOrFieldDef; - break; - } - else - { - // The found MethodDef/FieldDef token will replace this MemberRef token and we won't introduce a MemberRef - // record. - // - mrEmit = tkMethDefOrFieldDef; - isRefOptimizedToDef = true; - bDuplicate = true; - break; - } - } - - // now walk up to the parent class of tkParent and try to resolve this MemberRef - IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(tkParent), &pRec)); - tkParent = pMiniMdEmit->getExtendsOfTypeDef(pRec); - } - - // When we exit the loop, there are several possibilities: - // 1. We found a MethodDef/FieldDef to replace the MemberRef - // 2. We found a MethodDef matches the MemberRef but the MemberRef is VarArg, thus we want to use the MethodDef in the - // parent column but not replacing it. - // 3. We exit because we run out the TypeDef on the parent chain. If it is because we encounter a TypeRef, this TypeRef will - // replace the parent column of the MemberRef. Or we encounter nil token! (This can be unresolved global MemberRef or - // compiler error to put an undefined MemberRef. In this case, we should just use the old tkParentEmit - // on the parent column for the MemberRef. - - if (TypeFromToken(tkParent) == mdtTypeRef && RidFromToken(tkParent) != 0) - { - // we had walked up the parent's chain to resolve it but we have not been successful and got stopped by a TypeRef. - // Then we will use this TypeRef as the parent of the emit MemberRef record - // - tkParentEmit = tkParent; - } - } - else if ((TypeFromToken(tkParentEmit) == mdtMethodDef && - !isCallConv(CorSigUncompressCallingConv(pbSig), IMAGE_CEE_CS_CALLCONV_VARARG)) || - (TypeFromToken(tkParentEmit) == mdtFieldDef)) - { - // If the MemberRef's parent is already a non-vararg MethodDef or FieldDef, we can also - // safely drop the MemberRef - mrEmit = tkParentEmit; - isRefOptimizedToDef = true; - bDuplicate = true; - } - - // If the Ref cannot be optimized to a Def or MemberRef to Def optmization is turned off, do the following. - if (isRefOptimizedToDef == false || !((m_optimizeRefToDef & MDMemberRefToDef) == MDMemberRefToDef)) - { - // does this MemberRef already exist in the emit scope? - if ( m_fDupCheck && ImportHelper::FindMemberRef( - pMiniMdEmit, - tkParentEmit, - szNameImp, - (const COR_SIGNATURE *) qbSig.Ptr(), - cbEmit, - &mrEmit) == S_OK ) - { - // Yes, it does - bDuplicate = true; - } - else - { - // No, it doesn't. Copy it over. - bDuplicate = false; - IfFailGo(pMiniMdEmit->AddMemberRefRecord(&pRecEmit, (RID *)&mrEmit)); - mrEmit = TokenFromRid( mrEmit, mdtMemberRef ); - - // Copy over the MemberRef context - IfFailGo(pMiniMdEmit->PutString(TBL_MemberRef, MemberRefRec::COL_Name, pRecEmit, szNameImp)); - IfFailGo(pMiniMdEmit->PutToken(TBL_MemberRef, MemberRefRec::COL_Class, pRecEmit, tkParentEmit)); - IfFailGo(pMiniMdEmit->PutBlob(TBL_MemberRef, MemberRefRec::COL_Signature, pRecEmit, - qbSig.Ptr(), cbEmit)); - IfFailGo(pMiniMdEmit->AddMemberRefToHash(mrEmit) ); - } - } - // record the token movement - mrImp = TokenFromRid(i, mdtMemberRef); - IfFailGo( pCurTkMap->InsertNotFound(mrImp, bDuplicate, mrEmit, &pTokenRec) ); - } - } - - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeMemberRefs() - - -//***************************************************************************** -// merge interface impl -//***************************************************************************** -HRESULT NEWMERGER::MergeInterfaceImpls( ) -{ - HRESULT hr = NOERROR; - InterfaceImplRec *pRecImport = NULL; - InterfaceImplRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdTypeDef tkParent; - mdInterfaceImpl iiEmit; - bool bDuplicate; - TOKENREC *pTokenRec; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountInterfaceImpls(); - - // loop through all InterfaceImpl - for (i = 1; i <= iCount; i++) - { - // only merge those InterfaceImpls that are marked - if ( pMiniMdImport->GetFilterTable()->IsInterfaceImplMarked(TokenFromRid(i, mdtInterfaceImpl)) == false) - continue; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetInterfaceImplRecord(i, &pRecImport)); - tkParent = pMiniMdImport->getClassOfInterfaceImpl(pRecImport); - - // does this TypeRef already exist in the emit scope? - if ( pCurTkMap->Find(tkParent, &pTokenRec) ) - { - if ( pTokenRec->m_isDuplicate ) - { - // parent in the emit scope - mdToken tkParentEmit; - mdToken tkInterface; - - // remap the typedef token - tkParentEmit = pTokenRec->m_tkTo; - - // remap the implemented interface token - tkInterface = pMiniMdImport->getInterfaceOfInterfaceImpl(pRecImport); - IfFailGo( pCurTkMap->Remap( tkInterface, &tkInterface) ); - - // Set duplicate flag - bDuplicate = true; - - // find the corresponding interfaceimpl in the emit scope - if ( ImportHelper::FindInterfaceImpl(pMiniMdEmit, tkParentEmit, tkInterface, &iiEmit) != S_OK ) - { - // bad state!! We have a duplicate typedef but the interface impl is not the same!! - - // continuable error - CheckContinuableErrorEx( - META_E_INTFCEIMPL_NOT_FOUND, - pImportData, - TokenFromRid(i, mdtInterfaceImpl)); - - iiEmit = mdTokenNil; - } - } - else - { - // No, it doesn't. Copy it over. - bDuplicate = false; - IfFailGo(pMiniMdEmit->AddInterfaceImplRecord(&pRecEmit, (RID *)&iiEmit)); - - // copy the interfaceimp record over - IfFailGo( CopyInterfaceImpl( pRecEmit, pImportData, pRecImport) ); - } - } - else - { - _ASSERTE( !"bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - - // record the token movement - IfFailGo( pCurTkMap->InsertNotFound( - TokenFromRid(i, mdtInterfaceImpl), - bDuplicate, - TokenFromRid( iiEmit, mdtInterfaceImpl ), - &pTokenRec) ); - } - } - - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeInterfaceImpls() - - -//***************************************************************************** -// merge all of the constant for field, property, and parameter -//***************************************************************************** -HRESULT NEWMERGER::MergeConstants() -{ - HRESULT hr = NOERROR; - ConstantRec *pRecImport = NULL; - ConstantRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - ULONG csEmit; // constant value is not a token - mdToken tkParentImp; - TOKENREC *pTokenRec; - void const *pValue; - ULONG cbBlob; -#if _DEBUG - ULONG typeParent; -#endif // _DEBUG - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountConstants(); - - // loop through all Constants - for (i = 1; i <= iCount; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetConstantRecord(i, &pRecImport)); - tkParentImp = pMiniMdImport->getParentOfConstant(pRecImport); - - // only move those constant over if their parents are marked - // If MDTOKENMAP::Find returns false, we don't need to copy the constant value over - if ( pCurTkMap->Find(tkParentImp, &pTokenRec) ) - { - // If the parent is duplicated, no need to move over the constant value - if ( !pTokenRec->m_isDuplicate ) - { - IfFailGo(pMiniMdEmit->AddConstantRecord(&pRecEmit, &csEmit)); - pRecEmit->SetType(pRecImport->GetType()); - - // set the parent - IfFailGo( pMiniMdEmit->PutToken(TBL_Constant, ConstantRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo) ); - - // move over the constant blob value - IfFailGo(pMiniMdImport->getValueOfConstant(pRecImport, (const BYTE **)&pValue, &cbBlob)); - IfFailGo( pMiniMdEmit->PutBlob(TBL_Constant, ConstantRec::COL_Value, pRecEmit, pValue, cbBlob) ); - IfFailGo( pMiniMdEmit->AddConstantToHash(csEmit) ); - } - else - { - // @FUTURE: more verification on the duplicate?? - } - } -#if _DEBUG - // Include this block only under Debug build. The reason is that - // the linker chooses all the errors that we report (such as unmatched MethodDef or FieldDef) - // as a continuable error. It is likely to hit this else while the tkparentImp is marked if there - // is any error reported earlier!! - else - { - typeParent = TypeFromToken(tkParentImp); - if (typeParent == mdtFieldDef) - { - // FieldDef should not be marked. - if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkParentImp) == false) - continue; - } - else if (typeParent == mdtParamDef) - { - // ParamDef should not be marked. - if ( pMiniMdImport->GetFilterTable()->IsParamMarked(tkParentImp) == false) - continue; - } - else - { - _ASSERTE(typeParent == mdtProperty); - // Property should not be marked. - if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(tkParentImp) == false) - continue; - } - - // If we come to here, we have a constant whose parent is marked but we could not - // find it in the map!! Bad state. - - _ASSERTE(!"Ignore this error if you have seen error reported earlier! Otherwise bad token map or bad metadata!"); - } -#endif // _DEBUG - // Note that we don't need to record the token movement since constant is not a valid token kind. - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeConstants() - - -//***************************************************************************** -// Merge field marshal information -//***************************************************************************** -HRESULT NEWMERGER::MergeFieldMarshals() -{ - HRESULT hr = NOERROR; - FieldMarshalRec *pRecImport = NULL; - FieldMarshalRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - ULONG fmEmit; // FieldMarhsal is not a token - mdToken tkParentImp; - TOKENREC *pTokenRec; - void const *pValue; - ULONG cbBlob; -#if _DEBUG - ULONG typeParent; -#endif // _DEBUG - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountFieldMarshals(); - - // loop through all TypeRef - for (i = 1; i <= iCount; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetFieldMarshalRecord(i, &pRecImport)); - tkParentImp = pMiniMdImport->getParentOfFieldMarshal(pRecImport); - - // We want to merge only those field marshals that parents are marked. - // Find will return false if the parent is not marked - // - if ( pCurTkMap->Find(tkParentImp, &pTokenRec) ) - { - // If the parent is duplicated, no need to move over the constant value - if ( !pTokenRec->m_isDuplicate ) - { - IfFailGo(pMiniMdEmit->AddFieldMarshalRecord(&pRecEmit, &fmEmit)); - - // set the parent - IfFailGo( pMiniMdEmit->PutToken( - TBL_FieldMarshal, - FieldMarshalRec::COL_Parent, - pRecEmit, - pTokenRec->m_tkTo) ); - - // move over the constant blob value - IfFailGo(pMiniMdImport->getNativeTypeOfFieldMarshal(pRecImport, (const BYTE **)&pValue, &cbBlob)); - IfFailGo( pMiniMdEmit->PutBlob(TBL_FieldMarshal, FieldMarshalRec::COL_NativeType, pRecEmit, pValue, cbBlob) ); - IfFailGo( pMiniMdEmit->AddFieldMarshalToHash(fmEmit) ); - - } - else - { - // @FUTURE: more verification on the duplicate?? - } - } -#if _DEBUG - else - { - typeParent = TypeFromToken(tkParentImp); - - if (typeParent == mdtFieldDef) - { - // FieldDefs should not be marked - if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkParentImp) == false) - continue; - } - else - { - _ASSERTE(typeParent == mdtParamDef); - // ParamDefs should not be marked - if ( pMiniMdImport->GetFilterTable()->IsParamMarked(tkParentImp) == false) - continue; - } - - // If we come to here, that is we have a FieldMarshal whose parent is marked and we don't find it - // in the map!!! - - // either bad lookup map or bad metadata - _ASSERTE(!"Ignore this assert if you have seen error reported earlier. Otherwise, it is bad state!"); - } -#endif // _DEBUG - } - // Note that we don't need to record the token movement since FieldMarshal is not a valid token kind. - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeFieldMarshals() - - -//***************************************************************************** -// Merge class layout information -//***************************************************************************** -HRESULT NEWMERGER::MergeClassLayouts() -{ - HRESULT hr = NOERROR; - ClassLayoutRec *pRecImport = NULL; - ClassLayoutRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - ULONG iRecord; // class layout is not a token - mdToken tkParentImp; - TOKENREC *pTokenRec; - RID ridClassLayout; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountClassLayouts(); - - // loop through all TypeRef - for (i = 1; i <= iCount; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetClassLayoutRecord(i, &pRecImport)); - tkParentImp = pMiniMdImport->getParentOfClassLayout(pRecImport); - - // only merge those TypeDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(tkParentImp) == false) - continue; - - if ( pCurTkMap->Find(tkParentImp, &pTokenRec) ) - { - if ( !pTokenRec->m_isDuplicate ) - { - // If the parent is not duplicated, just copy over the classlayout information - IfFailGo(pMiniMdEmit->AddClassLayoutRecord(&pRecEmit, &iRecord)); - - // copy over the fix part information - pRecEmit->Copy(pRecImport); - IfFailGo( pMiniMdEmit->PutToken(TBL_ClassLayout, ClassLayoutRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo)); - IfFailGo( pMiniMdEmit->AddClassLayoutToHash(iRecord) ); - } - else - { - - IfFailGo(pMiniMdEmit->FindClassLayoutHelper(pTokenRec->m_tkTo, &ridClassLayout)); - - if (InvalidRid(ridClassLayout)) - { - // class is duplicated but not class layout info - CheckContinuableErrorEx(META_E_CLASS_LAYOUT_INCONSISTENT, pImportData, tkParentImp); - } - else - { - IfFailGo(pMiniMdEmit->GetClassLayoutRecord(RidFromToken(ridClassLayout), &pRecEmit)); - if (pMiniMdImport->getPackingSizeOfClassLayout(pRecImport) != pMiniMdEmit->getPackingSizeOfClassLayout(pRecEmit) || - pMiniMdImport->getClassSizeOfClassLayout(pRecImport) != pMiniMdEmit->getClassSizeOfClassLayout(pRecEmit) ) - { - CheckContinuableErrorEx(META_E_CLASS_LAYOUT_INCONSISTENT, pImportData, tkParentImp); - } - } - } - } - else - { - // bad lookup map - _ASSERTE( !"bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - // no need to record the index movement. Classlayout is not a token. - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeClassLayouts() - -//***************************************************************************** -// Merge field layout information -//***************************************************************************** -HRESULT NEWMERGER::MergeFieldLayouts() -{ - HRESULT hr = NOERROR; - FieldLayoutRec *pRecImport = NULL; - FieldLayoutRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - ULONG iRecord; // field layout2 is not a token. - mdToken tkFieldImp; - TOKENREC *pTokenRec; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountFieldLayouts(); - - // loop through all FieldLayout records. - for (i = 1; i <= iCount; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetFieldLayoutRecord(i, &pRecImport)); - tkFieldImp = pMiniMdImport->getFieldOfFieldLayout(pRecImport); - - // only merge those FieldDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkFieldImp) == false) - continue; - - if ( pCurTkMap->Find(tkFieldImp, &pTokenRec) ) - { - if ( !pTokenRec->m_isDuplicate ) - { - // If the Field is not duplicated, just copy over the FieldLayout information - IfFailGo(pMiniMdEmit->AddFieldLayoutRecord(&pRecEmit, &iRecord)); - - // copy over the fix part information - pRecEmit->Copy(pRecImport); - IfFailGo( pMiniMdEmit->PutToken(TBL_FieldLayout, FieldLayoutRec::COL_Field, pRecEmit, pTokenRec->m_tkTo)); - IfFailGo( pMiniMdEmit->AddFieldLayoutToHash(iRecord) ); - } - else - { - // @FUTURE: more verification?? - } - } - else - { - // bad lookup map - _ASSERTE( !"bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - // no need to record the index movement. fieldlayout2 is not a token. - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeFieldLayouts() - - -//***************************************************************************** -// Merge field RVAs -//***************************************************************************** -HRESULT NEWMERGER::MergeFieldRVAs() -{ - HRESULT hr = NOERROR; - FieldRVARec *pRecImport = NULL; - FieldRVARec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - ULONG iRecord; // FieldRVA is not a token. - mdToken tkFieldImp; - TOKENREC *pTokenRec; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountFieldRVAs(); - - // loop through all FieldRVA records. - for (i = 1; i <= iCount; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetFieldRVARecord(i, &pRecImport)); - tkFieldImp = pMiniMdImport->getFieldOfFieldRVA(pRecImport); - - // only merge those FieldDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(tkFieldImp, mdtFieldDef)) == false) - continue; - - if ( pCurTkMap->Find(tkFieldImp, &pTokenRec) ) - { - if ( !pTokenRec->m_isDuplicate ) - { - // If the Field is not duplicated, just copy over the FieldRVA information - IfFailGo(pMiniMdEmit->AddFieldRVARecord(&pRecEmit, &iRecord)); - - // copy over the fix part information - pRecEmit->Copy(pRecImport); - IfFailGo( pMiniMdEmit->PutToken(TBL_FieldRVA, FieldRVARec::COL_Field, pRecEmit, pTokenRec->m_tkTo)); - IfFailGo( pMiniMdEmit->AddFieldRVAToHash(iRecord) ); - } - else - { - // @FUTURE: more verification?? - } - } - else - { - // bad lookup map - _ASSERTE( !"bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - // no need to record the index movement. FieldRVA is not a token. - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeFieldRVAs() - - -//***************************************************************************** -// Merge MethodImpl information -//***************************************************************************** -HRESULT NEWMERGER::MergeMethodImpls() -{ - HRESULT hr = NOERROR; - MethodImplRec *pRecImport = NULL; - MethodImplRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - RID iRecord; - mdTypeDef tkClassImp; - mdToken tkBodyImp; - mdToken tkDeclImp; - TOKENREC *pTokenRecClass; - mdToken tkBodyEmit; - mdToken tkDeclEmit; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountMethodImpls(); - - // loop through all the MethodImpls. - for (i = 1; i <= iCount; i++) - { - // only merge those MethodImpls that are marked. - if ( pMiniMdImport->GetFilterTable()->IsMethodImplMarked(i) == false) - continue; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetMethodImplRecord(i, &pRecImport)); - tkClassImp = pMiniMdImport->getClassOfMethodImpl(pRecImport); - tkBodyImp = pMiniMdImport->getMethodBodyOfMethodImpl(pRecImport); - tkDeclImp = pMiniMdImport->getMethodDeclarationOfMethodImpl(pRecImport); - - if ( pCurTkMap->Find(tkClassImp, &pTokenRecClass)) - { - // If the TypeDef is duplicated, no need to move over the MethodImpl record. - if ( !pTokenRecClass->m_isDuplicate ) - { - // Create a new record and set the data. - - // @FUTURE: We might want to consider changing the error for the remap into a continuable error. - // Because we probably can continue merging for more data... - - IfFailGo( pCurTkMap->Remap(tkBodyImp, &tkBodyEmit) ); - IfFailGo( pCurTkMap->Remap(tkDeclImp, &tkDeclEmit) ); - IfFailGo(pMiniMdEmit->AddMethodImplRecord(&pRecEmit, &iRecord)); - IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_Class, pRecEmit, pTokenRecClass->m_tkTo) ); - IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_MethodBody, pRecEmit, tkBodyEmit) ); - IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_MethodDeclaration, pRecEmit, tkDeclEmit) ); - IfFailGo( pMiniMdEmit->AddMethodImplToHash(iRecord) ); - } - else - { - // @FUTURE: more verification on the duplicate?? - } - // No need to record the token movement, MethodImpl is not a token. - } - else - { - // either bad lookup map or bad metadata - _ASSERTE(!"bad state"); - IfFailGo( META_E_BADMETADATA ); - } - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeMethodImpls() - - -//***************************************************************************** -// Merge PInvoke -//***************************************************************************** -HRESULT NEWMERGER::MergePinvoke() -{ - HRESULT hr = NOERROR; - ImplMapRec *pRecImport = NULL; - ImplMapRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdModuleRef mrImp; - mdModuleRef mrEmit; - mdMethodDef mdImp; - RID mdImplMap; - TOKENREC *pTokenRecMR; - TOKENREC *pTokenRecMD; - - USHORT usMappingFlags; - LPCUTF8 szImportName; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountImplMaps(); - - // loop through all ImplMaps - for (i = 1; i <= iCount; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetImplMapRecord(i, &pRecImport)); - - // Get the MethodDef token in the new space. - mdImp = pMiniMdImport->getMemberForwardedOfImplMap(pRecImport); - - // only merge those MethodDefs that are marked - if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(mdImp) == false) - continue; - - // Get the ModuleRef token in the new space. - mrImp = pMiniMdImport->getImportScopeOfImplMap(pRecImport); - - // map the token to the new scope - if (pCurTkMap->Find(mrImp, &pTokenRecMR) == false) - { - // This should never fire unless the module refs weren't merged - // before this code ran. - _ASSERTE(!"Parent ModuleRef not found in MERGER::MergePinvoke. Bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - - // If the ModuleRef has been remapped to the "module token", we need to undo that - // for the pinvokeimpl. A pinvoke can only have a ModuleRef for the ImportScope. - mrEmit = pTokenRecMR->m_tkTo; - if (mrEmit == MODULEDEFTOKEN) - { // Yes, the ModuleRef has been remapped to the module token. So, - // find the ModuleRef in the output scope; if it is not found, add - // it. - ModuleRefRec *pModRefImport; - LPCUTF8 szNameImp; - IfFailGo(pMiniMdImport->GetModuleRefRecord(RidFromToken(mrImp), &pModRefImport)); - IfFailGo(pMiniMdImport->getNameOfModuleRef(pModRefImport, &szNameImp)); - - // does this ModuleRef already exist in the emit scope? - hr = ImportHelper::FindModuleRef(pMiniMdEmit, - szNameImp, - &mrEmit); - - if (hr == CLDB_E_RECORD_NOTFOUND) - { // No, it doesn't. Copy it over. - ModuleRefRec *pModRefEmit; - IfFailGo(pMiniMdEmit->AddModuleRefRecord(&pModRefEmit, (RID*)&mrEmit)); - mrEmit = TokenFromRid(mrEmit, mdtModuleRef); - - // Set ModuleRef Name. - IfFailGo( pMiniMdEmit->PutString(TBL_ModuleRef, ModuleRefRec::COL_Name, pModRefEmit, szNameImp) ); - } - else - IfFailGo(hr); - } - - - if (pCurTkMap->Find(mdImp, &pTokenRecMD) == false) - { - // This should never fire unless the method defs weren't merged - // before this code ran. - _ASSERTE(!"Parent MethodDef not found in MERGER::MergePinvoke. Bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - - - // Get copy of rest of data. - usMappingFlags = pMiniMdImport->getMappingFlagsOfImplMap(pRecImport); - IfFailGo(pMiniMdImport->getImportNameOfImplMap(pRecImport, &szImportName)); - - // If the method associated with PInvokeMap is not duplicated, then don't bother to look up the - // duplicated PInvokeMap information. - if (pTokenRecMD->m_isDuplicate == true) - { - // Does the correct ImplMap entry exist in the emit scope? - IfFailGo(pMiniMdEmit->FindImplMapHelper(pTokenRecMD->m_tkTo, &mdImplMap)); - } - else - { - mdImplMap = mdTokenNil; - } - if (!InvalidRid(mdImplMap)) - { - // Verify that the rest of the data is identical, else it's an error. - IfFailGo(pMiniMdEmit->GetImplMapRecord(mdImplMap, &pRecEmit)); - _ASSERTE(pMiniMdEmit->getMemberForwardedOfImplMap(pRecEmit) == pTokenRecMD->m_tkTo); - LPCSTR szImplMapImportName; - IfFailGo(pMiniMdEmit->getImportNameOfImplMap(pRecEmit, &szImplMapImportName)); - if (pMiniMdEmit->getImportScopeOfImplMap(pRecEmit) != mrEmit || - pMiniMdEmit->getMappingFlagsOfImplMap(pRecEmit) != usMappingFlags || - strcmp(szImplMapImportName, szImportName)) - { - // Mismatched p-invoke entries are found. - _ASSERTE(!"Mismatched P-invoke entries during merge. Bad State!"); - IfFailGo(E_FAIL); - } - } - else - { - IfFailGo(pMiniMdEmit->AddImplMapRecord(&pRecEmit, &mdImplMap)); - - // Copy rest of data. - IfFailGo( pMiniMdEmit->PutToken(TBL_ImplMap, ImplMapRec::COL_MemberForwarded, pRecEmit, pTokenRecMD->m_tkTo) ); - IfFailGo( pMiniMdEmit->PutToken(TBL_ImplMap, ImplMapRec::COL_ImportScope, pRecEmit, mrEmit) ); - IfFailGo( pMiniMdEmit->PutString(TBL_ImplMap, ImplMapRec::COL_ImportName, pRecEmit, szImportName) ); - pRecEmit->SetMappingFlags(usMappingFlags); - IfFailGo( pMiniMdEmit->AddImplMapToHash(mdImplMap) ); - } - } - } - - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergePinvoke() - - -//***************************************************************************** -// Merge StandAloneSigs -//***************************************************************************** -HRESULT NEWMERGER::MergeStandAloneSigs() -{ - HRESULT hr = NOERROR; - StandAloneSigRec *pRecImport = NULL; - StandAloneSigRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - TOKENREC *pTokenRec; - mdSignature saImp; - mdSignature saEmit; - bool fDuplicate; - PCCOR_SIGNATURE pbSig; - ULONG cbSig; - ULONG cbEmit; - CQuickBytes qbSig; - PCOR_SIGNATURE rgSig; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountStandAloneSigs(); - - // loop through all Signatures - for (i = 1; i <= iCount; i++) - { - // only merge those Signatures that are marked - if ( pMiniMdImport->GetFilterTable()->IsSignatureMarked(TokenFromRid(i, mdtSignature)) == false) - continue; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetStandAloneSigRecord(i, &pRecImport)); - IfFailGo(pMiniMdImport->getSignatureOfStandAloneSig(pRecImport, &pbSig, &cbSig)); - - // This is a signature containing the return type after count of args - // convert rid contained in signature to new scope - IfFailGo(ImportHelper::MergeUpdateTokenInSig( - NULL, // Assembly emit scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Assembly import scope info. - pMiniMdImport, // The scope to merge into the emit scope. - pbSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit)); // number of bytes write to cbEmit - rgSig = ( PCOR_SIGNATURE ) qbSig.Ptr(); - - hr = ImportHelper::FindStandAloneSig( - pMiniMdEmit, - rgSig, - cbEmit, - &saEmit ); - if ( hr == S_OK ) - { - // find a duplicate - fDuplicate = true; - } - else - { - // copy over - fDuplicate = false; - IfFailGo(pMiniMdEmit->AddStandAloneSigRecord(&pRecEmit, (ULONG *)&saEmit)); - saEmit = TokenFromRid(saEmit, mdtSignature); - IfFailGo( pMiniMdEmit->PutBlob(TBL_StandAloneSig, StandAloneSigRec::COL_Signature, pRecEmit, rgSig, cbEmit)); - } - saImp = TokenFromRid(i, mdtSignature); - - // Record the token movement - IfFailGo( pCurTkMap->InsertNotFound(saImp, fDuplicate, saEmit, &pTokenRec) ); - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeStandAloneSigs() - -//***************************************************************************** -// Merge MethodSpecs -//***************************************************************************** -HRESULT NEWMERGER::MergeMethodSpecs() -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdToken tk; - ULONG iRecord; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - - // Loop through all MethodSpec - iCount = pMiniMdImport->getCountMethodSpecs(); - for (i=1; i<=iCount; ++i) - { - MethodSpecRec *pRecImport; - MethodSpecRec *pRecEmit; - TOKENREC *pTokenRecMethod; - TOKENREC *pTokenRecMethodNew; - PCCOR_SIGNATURE pvSig; - ULONG cbSig; - CQuickBytes qbSig; - ULONG cbEmit; - - // Only copy marked records. - if (!pMiniMdImport->GetFilterTable()->IsMethodSpecMarked(i)) - continue; - - IfFailGo(pMiniMdImport->GetMethodSpecRecord(i, &pRecImport)); - tk = pMiniMdImport->getMethodOfMethodSpec(pRecImport); - - // Map the token to the new scope. - if (pCurTkMap->Find(tk, &pTokenRecMethod) == false) - { - // This should never fire unless the TypeDefs/Refs weren't merged - // before this code runs. - _ASSERTE(!"MethodSpec method not found in MERGER::MergeGenericsInfo. Bad state!"); - IfFailGo( META_E_BADMETADATA ); - } - // Copy to output scope. - IfFailGo(pMiniMdEmit->AddMethodSpecRecord(&pRecEmit, &iRecord)); - IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSpec, MethodSpecRec::COL_Method, pRecEmit, pTokenRecMethod->m_tkTo)); - - // Copy the signature, translating any embedded tokens. - IfFailGo(pMiniMdImport->getInstantiationOfMethodSpec(pRecImport, &pvSig, &cbSig)); - - // ...convert rid contained in signature to new scope - IfFailGo(ImportHelper::MergeUpdateTokenInSig( - NULL, // Assembly emit scope. - pMiniMdEmit, // The emit scope. - NULL, NULL, 0, // Import assembly scope information. - pMiniMdImport, // The scope to merge into the emit scope. - pvSig, // signature from the imported scope - pCurTkMap, // Internal token mapping structure. - &qbSig, // [OUT] translated signature - 0, // start from first byte of the signature - 0, // don't care how many bytes consumed - &cbEmit)); // number of bytes write to cbEmit - - // ...persist the converted signature - IfFailGo( pMiniMdEmit->PutBlob(TBL_MethodSpec, MethodSpecRec::COL_Instantiation, pRecEmit, qbSig.Ptr(), cbEmit) ); - - IfFailGo( pCurTkMap->InsertNotFound(TokenFromRid(i, mdtMethodSpec), false, - TokenFromRid(iRecord, mdtMethodSpec), &pTokenRecMethodNew) ); - } - } - - ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeMethodSpecs() - -//***************************************************************************** -// Merge DeclSecuritys -//***************************************************************************** -HRESULT NEWMERGER::MergeDeclSecuritys() -{ - HRESULT hr = NOERROR; - DeclSecurityRec *pRecImport = NULL; - DeclSecurityRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdToken tkParentImp; - TOKENREC *pTokenRec; - void const *pValue; - ULONG cbBlob; - mdPermission pmImp; - mdPermission pmEmit; - bool fDuplicate; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountDeclSecuritys(); - - // loop through all DeclSecurity - for (i = 1; i <= iCount; i++) - { - // only merge those DeclSecurities that are marked - if ( pMiniMdImport->GetFilterTable()->IsDeclSecurityMarked(TokenFromRid(i, mdtPermission)) == false) - continue; - - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetDeclSecurityRecord(i, &pRecImport)); - tkParentImp = pMiniMdImport->getParentOfDeclSecurity(pRecImport); - if ( pCurTkMap->Find(tkParentImp, &pTokenRec) ) - { - if ( !pTokenRec->m_isDuplicate ) - { - // If the parent is not duplicated, just copy over the custom value - goto CopyPermission; - } - else - { - // Try to see if the Permission is there in the emit scope or not. - // If not, move it over still - if ( ImportHelper::FindPermission( - pMiniMdEmit, - pTokenRec->m_tkTo, - pRecImport->GetAction(), - &pmEmit) == S_OK ) - { - // found a match - // @FUTURE: more verification?? - fDuplicate = true; - } - else - { - // Parent is duplicated but the Permission is not. Still copy over the - // Permission. -CopyPermission: - fDuplicate = false; - IfFailGo(pMiniMdEmit->AddDeclSecurityRecord(&pRecEmit, (ULONG *)&pmEmit)); - pmEmit = TokenFromRid(pmEmit, mdtPermission); - - pRecEmit->Copy(pRecImport); - - // set the parent - IfFailGo( pMiniMdEmit->PutToken( - TBL_DeclSecurity, - DeclSecurityRec::COL_Parent, - pRecEmit, - pTokenRec->m_tkTo) ); - - // move over the CustomAttribute blob value - IfFailGo(pMiniMdImport->getPermissionSetOfDeclSecurity(pRecImport, (const BYTE **)&pValue, &cbBlob)); - IfFailGo(pMiniMdEmit->PutBlob( - TBL_DeclSecurity, - DeclSecurityRec::COL_PermissionSet, - pRecEmit, - pValue, - cbBlob)); - } - } - pmEmit = TokenFromRid(pmEmit, mdtPermission); - pmImp = TokenFromRid(i, mdtPermission); - - // Record the token movement - IfFailGo( pCurTkMap->InsertNotFound(pmImp, fDuplicate, pmEmit, &pTokenRec) ); - } - else - { - // bad lookup map - _ASSERTE(!"bad state"); - IfFailGo( META_E_BADMETADATA ); - } - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeDeclSecuritys() - - -//***************************************************************************** -// Merge Strings -//***************************************************************************** -HRESULT NEWMERGER::MergeStrings() -{ - HRESULT hr = NOERROR; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - TOKENREC *pTokenRec; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - - for (UINT32 nIndex = 0; ;) - { - MetaData::DataBlob userString; - UINT32 nNextIndex; - UINT32 nEmitIndex; - - hr = pMiniMdImport->GetUserStringAndNextIndex( - nIndex, - &userString, - &nNextIndex); - IfFailGo(hr); - if (hr == S_FALSE) - { // We reached the last user string - hr = S_OK; - break; - } - _ASSERTE(hr == S_OK); - - // Skip empty strings - if (userString.IsEmpty()) - { - nIndex = nNextIndex; - continue; - } - - if (pMiniMdImport->GetFilterTable()->IsUserStringMarked(TokenFromRid(nIndex, mdtString)) == false) - { - // Process next user string in the heap - nIndex = nNextIndex; - continue; - } - - IfFailGo(pMiniMdEmit->PutUserString( - userString, - &nEmitIndex)); - - IfFailGo(pCurTkMap->InsertNotFound( - TokenFromRid(nIndex, mdtString), - false, - TokenFromRid(nEmitIndex, mdtString), - &pTokenRec)); - - // Process next user string in the heap - nIndex = nNextIndex; - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeStrings() - -// Helper method to merge the module-level security critical attributes -// Strips all module-level security critical attribute [that won't be ultimately needed] -// Returns: -// FAILED(hr): Failure occurred retrieving metadata or parsing scopes -// S_OK: Attribute should be merged into final output scope -// S_FALSE: Attribute should be ignored/dropped from output scope -HRESULT NEWMERGER::MergeSecurityCriticalModuleLevelAttributes( - MergeImportData* pImportData, // import scope - mdToken tkParentImp, // parent token with attribute - TOKENREC* pTypeRec, // token record of attribute ctor - mdToken mrSecurityTreatAsSafeAttributeCtor, // 'generic' TAS attribute token - mdToken mrSecurityTransparentAttributeCtor, // 'generic' Transparent attribute token - mdToken mrSecurityCriticalExplicitAttributeCtor, // 'generic' Critical attribute token - mdToken mrSecurityCriticalEverythingAttributeCtor) -{ - HRESULT hr = S_OK; - - // if ANY assembly-level critical attributes were specified, then we'll output - // one assembly-level Critical(Explicit) attribute only - // AND if this scope has tags - if (ISSCS_Unknown != pImportData->m_isscsSecurityCriticalStatus) - { - _ASSERTE(ISSCS_Unknown != m_isscsSecurityCritical); - // drop only assembly-level attributes - TypeRefRec* pTypeRefRec; - // metadata emitter - CMiniMdRW* pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // if compiler is generating a module - then this will be a module token - LPCSTR szTypeRefName; - if (tkParentImp == MODULEDEFTOKEN || - // otherwise, if merging assemblies, we have a fake type ref called MODULE_CA_LOCATION - (TypeFromToken(tkParentImp) == mdtTypeRef && - (IsAttributeFromNamespace(pMiniMdImport, tkParentImp, - COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME, - &pTypeRefRec) == S_OK) && - (pMiniMdImport->getNameOfTypeRef(pTypeRefRec, &szTypeRefName) == S_OK) && - (strcmp(MODULE_CA_TYPENAME, szTypeRefName) == 0))) - { - // drop the TAS attribute (unless all scopes have TAS) - if ( pTypeRec->m_tkTo == mrSecurityTreatAsSafeAttributeCtor ) - { - if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTreatAsSafe) == - ISSCS_SecurityTreatAsSafe) - { - _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityTreatAsSafe) == - ISSCS_SecurityTreatAsSafe); - return S_OK; - } - return S_FALSE; - } - // drop the Transparent attribute (unless all scopes have Transparent) - else if (pTypeRec->m_tkTo == mrSecurityTransparentAttributeCtor) - { - if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTransparent) == - ISSCS_SecurityTransparent) - { - _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityTransparent) == - ISSCS_SecurityTransparent); - return S_OK; - } - return S_FALSE; - } - else if (pTypeRec->m_tkTo == mrSecurityCriticalExplicitAttributeCtor) - { - // if NOT Critical Everything, then leave the Critical.Explicit attribute - // the Critical.Explicit attribute will be used as the final global attribute - if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) != - ISSCS_SecurityCriticalEverything) - { - _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityCriticalExplicit) == - ISSCS_SecurityCriticalExplicit); - return S_OK; - } - else - { - // drop this attribute - return S_FALSE; - } - } - else if (pTypeRec->m_tkTo == mrSecurityCriticalEverythingAttributeCtor) - { - // OPTIMIZATION: if all attributes are Critical.Everything, - // then leave the global Critical attribute - if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) == - ISSCS_SecurityCriticalEverything) - { - _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityCriticalEverything) == - ISSCS_SecurityCriticalEverything); - return S_OK; - } - else - { - // drop this attribute - return S_FALSE; - } - } - } - } - - return hr; -} // NEWMERGER::MergeSecurityCriticalModuleLevelAttributes - -// HELPER: Retrieve the meta-data info related to SecurityCritical -HRESULT NEWMERGER::RetrieveStandardSecurityCriticalMetaData( - mdAssemblyRef& tkMscorlib, - mdTypeRef& securityEnum, - BYTE*& rgSigBytesSecurityCriticalEverythingCtor, - DWORD& dwSigEverythingSize, - BYTE*& rgSigBytesSecurityCriticalExplicitCtor, - DWORD& dwSigExplicitSize) -{ - HRESULT hr = S_OK; - - CMiniMdRW* emit = GetMiniMdEmit(); - - // get typeref for mscorlib - BYTE pbMscorlibToken[] = COR_MSCORLIB_TYPEREF; - BYTE* pCurr = rgSigBytesSecurityCriticalEverythingCtor; - - IfFailGo(ImportHelper::FindAssemblyRef(emit, - COR_MSCORLIB_NAME, - NULL, - pbMscorlibToken, - sizeof(pbMscorlibToken), - asm_rmj, - asm_rmm, - asm_rup, - asm_rpt, - 0, - &tkMscorlib)); - - IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(tkMscorlib, - COR_SECURITYCRITICALSCOPE_ENUM_W, - &securityEnum)); - - // build the constructor sig that takes SecurityCriticalScope argument - if (rgSigBytesSecurityCriticalEverythingCtor) - { - *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS; - *pCurr++ = COR_SECURITYCRITICAL_CTOR_ARGCOUNT_SCOPE_EVERYTHING; // one argument to constructor - *pCurr++ = ELEMENT_TYPE_VOID; - *pCurr++ = ELEMENT_TYPE_VALUETYPE; - pCurr += CorSigCompressToken(securityEnum, pCurr); - dwSigEverythingSize = (DWORD)(pCurr - rgSigBytesSecurityCriticalEverythingCtor); - _ASSERTE(dwSigEverythingSize <= COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE); - } - - // if Explicit ctor is requested - if (rgSigBytesSecurityCriticalExplicitCtor) - { - // build the constructor sig that has NO arguments - pCurr = rgSigBytesSecurityCriticalExplicitCtor; - *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS; - *pCurr++ = COR_SECURITYCRITICAL_CTOR_ARGCOUNT_NO_SCOPE; // no arguments to constructor - *pCurr++ = ELEMENT_TYPE_VOID; - dwSigExplicitSize = (DWORD)(pCurr - rgSigBytesSecurityCriticalExplicitCtor); - _ASSERTE(dwSigExplicitSize <= COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE); - } - -ErrExit: - return hr; -} // NEWMERGER::RetrieveStandardSecurityCriticalMetaData - -//***************************************************************************** -// Merge CustomAttributes -//***************************************************************************** -HRESULT NEWMERGER::MergeCustomAttributes() -{ - - HRESULT hr = NOERROR; - CustomAttributeRec *pRecImport = NULL; - CustomAttributeRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - ULONG iCount; - ULONG i; - mdToken tkParentImp; // Token of attributed object (parent). - TOKENREC *pTokenRec; // Parent's remap. - mdToken tkType; // Token of attribute's type. - TOKENREC *pTypeRec; // Type's remap. - void const *pValue; // The actual value. - ULONG cbBlob; // Size of the value. - mdToken cvImp; - mdToken cvEmit; - bool fDuplicate; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - TypeRefRec *pTypeRefRec; - ULONG cTypeRefRecs; - mdToken mrSuppressMergeCheckAttributeCtor = mdTokenNil; - mdToken mrSecurityCriticalExplicitAttributeCtor = mdTokenNil; - mdToken mrSecurityCriticalEverythingAttributeCtor = mdTokenNil; - mdToken mrSecurityTransparentAttributeCtor = mdTokenNil; - mdToken mrSecurityTreatAsSafeAttributeCtor = mdTokenNil; - - pMiniMdEmit = GetMiniMdEmit(); - - // Find out the TypeRef referring to our library's System.CompilerServices.SuppressMergeCheckAttribute, - // System.Security.SecurityCriticalAttribute, System.Security.SecurityTransparentAttribute, and - // System.Security.SecurityTreatAsSafeAttibute - cTypeRefRecs = pMiniMdEmit->getCountTypeRefs(); - - { // retrieve global attribute TypeRefs - - mdAssemblyRef tkMscorlib = mdTokenNil; - mdTypeRef securityEnum = mdTokenNil; - - NewArrayHolder rgSigBytesSecurityCriticalEverythingCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE]); - BYTE* pSigBytesSecurityCriticalEverythingCtor = rgSigBytesSecurityCriticalEverythingCtor.GetValue(); - IfFailGo((pSigBytesSecurityCriticalEverythingCtor == NULL)?E_OUTOFMEMORY:S_OK); - DWORD dwSigEverythingSize = 0; - - NewArrayHolder rgSigBytesSecurityCriticalExplicitCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE]); - BYTE* pSigBytesSecurityCriticalExplicitCtor = rgSigBytesSecurityCriticalExplicitCtor.GetValue(); - IfFailGo((pSigBytesSecurityCriticalExplicitCtor == NULL)?E_OUTOFMEMORY:S_OK); - DWORD dwSigExplicitSize = 0; - - // retrieve security critical metadata info if necessary - if(ISSCS_Unknown != m_isscsSecurityCritical) - { - - hr = RetrieveStandardSecurityCriticalMetaData( - tkMscorlib, - securityEnum, - pSigBytesSecurityCriticalEverythingCtor, - dwSigEverythingSize, - pSigBytesSecurityCriticalExplicitCtor, - dwSigExplicitSize); - - } - - // Search for the TypeRef. - for (i = 1; i <= cTypeRefRecs; i++) - { - mdToken tkTmp = TokenFromRid(i,mdtTypeRef); - - if (IsAttributeFromNamespace(pMiniMdEmit, tkTmp, - COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME, - &pTypeRefRec) == S_OK) - { - LPCSTR szNameOfTypeRef; - IfFailGo(pMiniMdEmit->getNameOfTypeRef(pTypeRefRec, &szNameOfTypeRef)); - if (strcmp(szNameOfTypeRef, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE) == 0) - { - hr = ImportHelper::FindMemberRef( - pMiniMdEmit, tkTmp, - COR_CTOR_METHOD_NAME, - NULL, 0, - &mrSuppressMergeCheckAttributeCtor); - if (S_OK == hr) continue; - } - } - else - // if we are merging security critical attributes, then look for transparent-related attributes - if ((ISSCS_Unknown != m_isscsSecurityCritical) && - (IsAttributeFromNamespace(pMiniMdEmit, tkTmp, - COR_SECURITYCRITICAL_ATTRIBUTE_NAMESPACE, COR_MSCORLIB_NAME, - &pTypeRefRec) == S_OK)) - { - LPCSTR szNameOfTypeRef; - IfFailGo(pMiniMdEmit->getNameOfTypeRef(pTypeRefRec, &szNameOfTypeRef)); - - // look for the SecurityCritical attribute - if (strcmp(szNameOfTypeRef, COR_SECURITYCRITICAL_ATTRIBUTE) == 0) - { - // since the SecurityCritical attribute can be either - // parameterless constructor or SecurityCriticalScope constructor, we - // look for both - hr = ImportHelper::FindMemberRef( - pMiniMdEmit, tkTmp, - COR_CTOR_METHOD_NAME, - rgSigBytesSecurityCriticalEverythingCtor.GetValue(), dwSigEverythingSize, - &mrSecurityCriticalEverythingAttributeCtor); - if (S_OK == hr) continue; - hr = ImportHelper::FindMemberRef( - pMiniMdEmit, tkTmp, - COR_CTOR_METHOD_NAME, - rgSigBytesSecurityCriticalExplicitCtor.GetValue(), dwSigExplicitSize, - &mrSecurityCriticalExplicitAttributeCtor); - if (S_OK == hr) continue; - } - else - // look for the SecurityTransparent attribute - if (strcmp(szNameOfTypeRef, COR_SECURITYTRANSPARENT_ATTRIBUTE) == 0) - { - hr = ImportHelper::FindMemberRef( - pMiniMdEmit, tkTmp, - COR_CTOR_METHOD_NAME, - NULL, 0, - &mrSecurityTransparentAttributeCtor); - if (S_OK == hr) continue; - } - else - // look for the SecurityTreatAsSafe attribute - if (strcmp(szNameOfTypeRef, COR_SECURITYTREATASSAFE_ATTRIBUTE) == 0) - { - hr = ImportHelper::FindMemberRef( - pMiniMdEmit, tkTmp, - COR_CTOR_METHOD_NAME, - NULL, 0, - &mrSecurityTreatAsSafeAttributeCtor); - if (S_OK == hr) continue; - } - } - hr = S_OK; // ignore failures since the attribute may not be used - } - } - - // Loop over every module scope - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // We know that the filter table is not null here. Tell PREFIX that we know it. - PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL ); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountCustomAttributes(); - - // loop through all CustomAttribute - for (i = 1; i <= iCount; i++) - { - // compare it with the emit scope - IfFailGo(pMiniMdImport->GetCustomAttributeRecord(i, &pRecImport)); - tkParentImp = pMiniMdImport->getParentOfCustomAttribute(pRecImport); - tkType = pMiniMdImport->getTypeOfCustomAttribute(pRecImport); - IfFailGo(pMiniMdImport->getValueOfCustomAttribute(pRecImport, (const BYTE **)&pValue, &cbBlob)); - - // only merge those CustomAttributes that are marked - if ( pMiniMdImport->GetFilterTable()->IsCustomAttributeMarked(TokenFromRid(i, mdtCustomAttribute)) == false) - continue; - - // Check the type of the CustomAttribute. If it is not marked, then we don't need to move over the CustomAttributes. - // This will only occur for compiler defined discardable CAs during linking. - // - if ( pMiniMdImport->GetFilterTable()->IsTokenMarked(tkType) == false) - continue; - - if ( pCurTkMap->Find(tkParentImp, &pTokenRec) ) - { - // If the From token type is different from the To token's type, we have optimized the ref to def. - // In this case, we are dropping the CA associated with the Ref tokens. - // - if (TypeFromToken(tkParentImp) == TypeFromToken(pTokenRec->m_tkTo)) - { - - // If tkParentImp is a MemberRef and it is also mapped to a MemberRef in the merged scope with a MethodDef - // parent, then it is a MemberRef optimized to a MethodDef. We are keeping the MemberRef because it is a - // vararg call. So we can drop CAs on this MemberRef. - if (TypeFromToken(tkParentImp) == mdtMemberRef) - { - MemberRefRec *pTempRec; - IfFailGo(pMiniMdEmit->GetMemberRefRecord(RidFromToken(pTokenRec->m_tkTo), &pTempRec)); - if (TypeFromToken(pMiniMdEmit->getClassOfMemberRef(pTempRec)) == mdtMethodDef) - continue; - } - - - if (! pCurTkMap->Find(tkType, &pTypeRec) ) - { - _ASSERTE(!"CustomAttribute Type not found in output scope"); - IfFailGo(META_E_BADMETADATA); - } - - // Determine if we need to copy or ignore security-critical-related attributes - hr = MergeSecurityCriticalModuleLevelAttributes( - pImportData, tkParentImp, pTypeRec, - mrSecurityTreatAsSafeAttributeCtor, mrSecurityTransparentAttributeCtor, - mrSecurityCriticalExplicitAttributeCtor, - mrSecurityCriticalEverythingAttributeCtor); - IfFailGo(hr); - // S_FALSE means skip attribute - if (hr == S_FALSE) continue; - // S_OK means consider copying attribute - - // if it's the SuppressMergeCheckAttribute, don't copy it - if ( pTypeRec->m_tkTo == mrSuppressMergeCheckAttributeCtor ) - { - continue; - } - - if ( pTokenRec->m_isDuplicate) - { - // Try to see if the custom value is there in the emit scope or not. - // If not, move it over still - hr = ImportHelper::FindCustomAttributeByToken( - pMiniMdEmit, - pTokenRec->m_tkTo, - pTypeRec->m_tkTo, - pValue, - cbBlob, - &cvEmit); - - if ( hr == S_OK ) - { - // found a match - // @FUTURE: more verification?? - fDuplicate = true; - } - else - { - TypeRefRec *pAttributeTypeRefRec; - // We need to allow additive merge on TypeRef for CustomAttributes because compiler - // could build module but not assembly. They are hanging of Assembly level CAs on a bogus - // TypeRef. - // Also allow additive merge for CAs from CompilerServices and Microsoft.VisualC - if (tkParentImp == MODULEDEFTOKEN - || TypeFromToken(tkParentImp) == mdtTypeRef - || (IsAttributeFromNamespace(pMiniMdImport, tkType, - COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME, - &pAttributeTypeRefRec) == S_OK) - || (IsAttributeFromNamespace(pMiniMdImport, tkType, - COR_MISCBITS_NAMESPACE, COR_MISCBITS_NAMESPACE, - &pAttributeTypeRefRec) == S_OK)) - { - // clear the error - hr = NOERROR; - - // custom value of module token! Copy over the custom value - goto CopyCustomAttribute; - } - - // another case to support additive merge if the CA on MehtodDef is - // HandleProcessCorruptedStateExceptionsAttribute - if ( TypeFromToken(tkParentImp) == mdtMethodDef && tkType == pImportData->m_tkHandleProcessCorruptedStateCtor) - { - // clear the error - hr = NOERROR; - - // custom value of module token! Copy over the custom value - goto CopyCustomAttribute; - } - CheckContinuableErrorEx(META_E_MD_INCONSISTENCY, pImportData, TokenFromRid(i, mdtCustomAttribute)); - } - } - else - { -CopyCustomAttribute: - if ((m_dwMergeFlags & DropMemberRefCAs) && TypeFromToken(pTokenRec->m_tkTo) == mdtMemberRef) - { - // CustomAttributes associated with MemberRef. If the parent of MemberRef is a MethodDef or FieldDef, drop - // the custom attribute. - MemberRefRec *pMemberRefRec; - IfFailGo(pMiniMdEmit->GetMemberRefRecord(RidFromToken(pTokenRec->m_tkTo), &pMemberRefRec)); - mdToken mrParent = pMiniMdEmit->getClassOfMemberRef(pMemberRefRec); - if (TypeFromToken(mrParent) == mdtMethodDef || TypeFromToken(mrParent) == mdtFieldDef) - { - // Don't bother to copy over - continue; - } - } - - // Parent is duplicated but the custom value is not. Still copy over the - // custom value. - fDuplicate = false; - IfFailGo(pMiniMdEmit->AddCustomAttributeRecord(&pRecEmit, (ULONG *)&cvEmit)); - cvEmit = TokenFromRid(cvEmit, mdtCustomAttribute); - - // set the parent - IfFailGo( pMiniMdEmit->PutToken(TBL_CustomAttribute, CustomAttributeRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo) ); - // set the type - IfFailGo( pMiniMdEmit->PutToken(TBL_CustomAttribute, CustomAttributeRec::COL_Type, pRecEmit, pTypeRec->m_tkTo)); - - // move over the CustomAttribute blob value - IfFailGo(pMiniMdImport->getValueOfCustomAttribute(pRecImport, (const BYTE **)&pValue, &cbBlob)); - - IfFailGo( pMiniMdEmit->PutBlob(TBL_CustomAttribute, CustomAttributeRec::COL_Value, pRecEmit, pValue, cbBlob)); - IfFailGo( pMiniMdEmit->AddCustomAttributesToHash(cvEmit) ); - } - cvEmit = TokenFromRid(cvEmit, mdtCustomAttribute); - cvImp = TokenFromRid(i, mdtCustomAttribute); - - // Record the token movement - IfFailGo( pCurTkMap->InsertNotFound(cvImp, pTokenRec->m_isDuplicate, cvEmit, &pTokenRec) ); - } - } - else - { - - // either bad lookup map or bad metadata - _ASSERTE(!"Bad state"); - IfFailGo( META_E_BADMETADATA ); - } - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeCustomAttributes() - -//******************************************************************************* -// Helper to check if input scope has assembly-level security transparent awareness (either SecurityTransparent or SecurityCritical) -// SIDE EFFECT: pImportData->m_isscsSecurityCriticalStatus will be explicitly set [same value as return value] -// SecurityCritical.Explicit attribute injection occurs for all scopes that have tags (e.g. NOT ISSCS_Unknown) -// If the tagged scopes are all SecurityCritical.Everything, then the final attribute should be SecurityCritical.Everything -// anyway. Otherwise, at least one SecurityCritical.Explicit tag will be used/injected -//******************************************************************************* -InputScopeSecurityCriticalStatus NEWMERGER::CheckInputScopeIsCritical(MergeImportData* pImportData, HRESULT& hr) -{ - hr = S_OK; - - // the attribute should be in a known state no matter how we return from this function - // default to no attribute explicitly specified - pImportData->m_isscsSecurityCriticalStatus = ISSCS_Unknown; - - mdTypeRef fakeModuleTypeRef = mdTokenNil; - mdAssemblyRef tkMscorlib = mdTokenNil; - - // TODO: Should we remove the ability to disable merging critical attributes? - if (g_fRefShouldMergeCriticalChecked == FALSE) - { - // shouldn't require thread safety lock - g_fRefShouldMergeCritical = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_MergeCriticalAttributes) != 0); - g_fRefShouldMergeCriticalChecked = TRUE; - } - - // return no merge needed, if the merge critical attribute setting is not enabled. - if (!g_fRefShouldMergeCritical) return ISSCS_Unknown; - - // get typeref for mscorlib - BYTE pbMscorlibToken[] = COR_MSCORLIB_TYPEREF; - - CMiniMdRW* pImportedMiniMd = &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd; - - if (S_OK != ImportHelper::FindAssemblyRef(pImportedMiniMd, - COR_MSCORLIB_NAME, - NULL, - pbMscorlibToken, - sizeof(pbMscorlibToken), - asm_rmj, - asm_rmm, - asm_rup, - asm_rpt, - 0, - &tkMscorlib)) - { - // there isn't an mscorlib ref here... we can't have the security critical attribute - return ISSCS_Unknown; - } - - if (S_OK != ImportHelper::FindTypeRefByName(pImportedMiniMd, - tkMscorlib, - COR_COMPILERSERVICE_NAMESPACE, - MODULE_CA_TYPENAME, - &fakeModuleTypeRef)) - { - // for now let use the fake module ref as the assembly def - fakeModuleTypeRef = 0x000001; - } - - // Check the input scope for TreatAsSafe - if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd, - fakeModuleTypeRef, // This is the assembly def token - COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL, - NULL, - NULL)) - { - pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityTreatAsSafe; - } - - // Check the input scope for security transparency awareness - // For example, the assembly is marked SecurityTransparent, SecurityCritical(Explicit), or SecurityCritical(Everything) - - - const void *pbData = NULL; // [OUT] Put pointer to data here. - ULONG cbData = 0; // number of bytes in pbData - - // Check if the SecurityTransparent attribute is present - if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd, - fakeModuleTypeRef, // This is the assembly def token - COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL, - NULL, - NULL)) - { - pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityTransparent; - } - else - // Check if the SecurityCritical attribute is present - if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd, - fakeModuleTypeRef, // This is the assembly def token - COR_SECURITYCRITICAL_ATTRIBUTE_FULL, - &pbData, - &cbData)) - { - // find out if critical everything or explicit - - // default to critical - pImportData->m_isscsSecurityCriticalStatus = ISSCS_SecurityCritical; - - BYTE rgSecurityCriticalEverythingCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING; - // if value is non-0 (i.e. 1), then mark as SecurityCritical everything, otherwise, explicit - if (NULL != pbData && cbData == 8 && - memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0) - { - pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityCriticalEverything; - } - else - { - pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityCriticalExplicit; - } - } - - return pImportData->m_isscsSecurityCriticalStatus; -} // HRESULT NEWMERGER::CheckInputScopeIsCritical() - -//******************************************************************************* -// Helper to merge security critical annotations across assemblies and types -//******************************************************************************* -HRESULT NEWMERGER::MergeSecurityCriticalAttributes() -{ - // if no assembly-level critical attributes were specified, then none are needed, - // and no need to do special attribute merging - if (ISSCS_Unknown == m_isscsSecurityCritical) - { - return S_OK; - } - // or if the global-scope already has TAS/Critical.Everything, then ignore individual type fixes - else if ((ISSCS_SECURITYCRITICAL_LEGACY & m_isscsSecurityCriticalAllScopes) == ISSCS_SECURITYCRITICAL_LEGACY) - { - return S_OK; - } - - HRESULT hr = S_OK; - - CMiniMdRW* emit = GetMiniMdEmit(); - // The attribute we want to decorate all of the types with has not been defined. - mdMemberRef tkSecurityCriticalEverythingAttribute = mdTokenNil; - mdMemberRef tkSecurityTreatAsSafeAttribute = mdTokenNil; - mdMemberRef tkSecuritySafeCriticalAttribute = mdTokenNil; - - mdAssemblyRef tkMscorlib = mdTokenNil; - mdTypeRef fakeModuleTypeRef = mdTokenNil; - mdTypeRef securityEnum = mdTokenNil; - - DWORD dwSigSize; - BYTE* rgSigBytesSecurityCriticalExplicitCtor = 0; - DWORD dwSigSize_TEMP; - - BYTE rgSigBytesTreatAsSafeCtor[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID}; - - BYTE rgSecurityCriticalEverythingCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING; - - - mdTypeRef tkSecurityCriticalEverythingAttributeType = mdTokenNil; - mdTypeRef tkSecurityTreatAsSafeAttributeType = mdTokenNil; - - NewArrayHolder rgSigBytesSecurityCriticalEverythingCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE]); - BYTE* pSigBytesSecurityCriticalEverythingCtor = rgSigBytesSecurityCriticalEverythingCtor.GetValue(); - IfFailGo((pSigBytesSecurityCriticalEverythingCtor == NULL)?E_OUTOFMEMORY:S_OK); - - IfFailGo(RetrieveStandardSecurityCriticalMetaData( - tkMscorlib, - securityEnum, - pSigBytesSecurityCriticalEverythingCtor, - dwSigSize, - rgSigBytesSecurityCriticalExplicitCtor, - dwSigSize_TEMP)); - - if (S_OK != ImportHelper::FindTypeRefByName(emit, - tkMscorlib, - COR_COMPILERSERVICE_NAMESPACE, - MODULE_CA_TYPENAME, - &fakeModuleTypeRef)) - { - // for now let use the fake module ref as the assembly def - fakeModuleTypeRef = 0x000001; - } - - IfFailGo(m_pRegMetaEmit->DefineTypeRefByName( - tkMscorlib, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W, &tkSecurityCriticalEverythingAttributeType)); - - IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityCriticalEverythingAttributeType, - COR_CONSTRUCTOR_METADATA_IDENTIFIER, - rgSigBytesSecurityCriticalEverythingCtor.GetValue(), - dwSigSize, - &tkSecurityCriticalEverythingAttribute)); - - IfFailGo(m_pRegMetaEmit->DefineTypeRefByName( - tkMscorlib, COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W, - &tkSecurityTreatAsSafeAttributeType)); - - IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityTreatAsSafeAttributeType, - COR_CONSTRUCTOR_METADATA_IDENTIFIER, - rgSigBytesTreatAsSafeCtor, - sizeof(rgSigBytesTreatAsSafeCtor), - &tkSecurityTreatAsSafeAttribute)); - - - // place this block in a new scope so that we can safely goto past it - { - mdTypeRef tkSecuritySafeCriticalAttributeType = mdTokenNil; - if (FAILED (hr = m_pRegMetaEmit->DefineTypeRefByName(tkMscorlib, COR_SECURITYSAFECRITICAL_ATTRIBUTE_FULL_W, - &tkSecuritySafeCriticalAttributeType))) - { - _ASSERTE(!"Couldn't Emit a Typeref for SafeCritical attribute"); - return hr; - } - - BYTE rgSigBytesSafeCriticalCtor[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID}; - if (FAILED(hr = m_pRegMetaEmit->DefineMemberRef(tkSecuritySafeCriticalAttributeType, - W(".ctor"), - rgSigBytesSafeCriticalCtor, - sizeof(rgSigBytesSafeCriticalCtor), - &tkSecuritySafeCriticalAttribute))) - { - _ASSERTE(!"Couldn't Emit a MemberRef for SafeCritical attribute .ctor"); - return hr; - } - } - - - for (MergeImportData* pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // if the import is marked TAS, then we need to explicitly mark each type as TAS - // if the import is marked Crit/Everything, then we need to explicitly mark each type as Crit - // if the import is not marked at all, then we need to explicitly mark each type TAS/Crit - - // if the import is marked ONLY Crit/Explicit or ONLY Transparent then we can ignore it - if (ISSCS_SecurityTransparent == pImportData->m_isscsSecurityCriticalStatus || - ISSCS_SecurityCriticalExplicit == pImportData->m_isscsSecurityCriticalStatus) continue; - - // Run through the scopes that need to have their types decorated with this attribute - MDTOKENMAP*pCurTKMap = pImportData->m_pMDTokenMap; - BYTE rgTreatAsSafeCtorValue[] = COR_SECURITYTREATASSAFE_ATTRIBUTE_VALUE; - - BOOL fMarkEachTokenAsCritical = FALSE; - // if the import is unmarked or marked Crit/Everything, - // then we need to explicitly mark each token as Crit - // Unless the the global scope already has SecurityCritical.Everything - if (((ISSCS_SecurityCriticalEverything & m_isscsSecurityCriticalAllScopes) != ISSCS_SecurityCriticalEverything) && - (((ISSCS_SecurityCriticalEverything & pImportData->m_isscsSecurityCriticalStatus) == ISSCS_SecurityCriticalEverything ) || - - // OR this scope is NOT transparent or critical-explicit - (ISSCS_SecurityTransparent & pImportData->m_isscsSecurityCriticalStatus) == 0 || - (ISSCS_SecurityCritical & pImportData->m_isscsSecurityCriticalStatus) == 0 || - - // OR this scope is UNKNOWN - (ISSCS_Unknown == (ISSCS_SECURITYCRITICAL_FLAGS & pImportData->m_isscsSecurityCriticalStatus)))) - { - fMarkEachTokenAsCritical = TRUE; - } - - BOOL fMarkEachTokenAsSafe = FALSE; - // if the import is unmarked or marked TAS, - // then we need to explicitly mark each token as TAS - // Unless the the global scope already has SecurityTreatAsSafe - if (((ISSCS_SecurityTreatAsSafe & m_isscsSecurityCriticalAllScopes) != ISSCS_SecurityTreatAsSafe) && - ((ISSCS_SecurityTreatAsSafe & pImportData->m_isscsSecurityCriticalStatus) || - ISSCS_Unknown == (pImportData->m_isscsSecurityCriticalStatus & ISSCS_SECURITYCRITICAL_FLAGS))) - { - fMarkEachTokenAsSafe = TRUE; - } - - BYTE rgSafeCriticalCtorValue[] = {0x01, 0x00, 0x00 ,0x00}; - - for (int i = 0; i < pCurTKMap->Count(); i++) - { - TOKENREC* pRec = pCurTKMap->Get(i); - BOOL fInjectSecurityAttributes = FALSE; - - // skip empty records - if (pRec->IsEmpty()) continue; - - // If this scope contained a typeref that was resolved to a typedef, let's not mark it. We'll let the owner - // of the actual typedef decide if that type should be marked. - if ((TypeFromToken(pRec->m_tkFrom) == mdtTypeRef) && (TypeFromToken(pRec->m_tkTo) == mdtTypeDef)) - continue; - - // Same for method refs/method defs - if ((TypeFromToken(pRec->m_tkFrom) == mdtMemberRef) && (TypeFromToken(pRec->m_tkTo) == mdtMethodDef)) - continue; - - // check for typedefs, but don't put this on the global typedef - if ((TypeFromToken(pRec->m_tkTo) == mdtTypeDef) && (pRec->m_tkTo != TokenFromRid(1, mdtTypeDef))) - { - // by default we will inject - fInjectSecurityAttributes = TRUE; - // except for Enums - DWORD dwClassAttrs = 0; - mdTypeRef crExtends = mdTokenNil; - - if (FAILED(hr = m_pRegMetaEmit->GetTypeDefProps(pRec->m_tkTo, NULL, NULL, 0 , &dwClassAttrs, &crExtends))) - { - // TODO: should we fail ?? - } - - // check for Enum types - if (!IsNilToken(crExtends) && (TypeFromToken(crExtends)==mdtTypeRef)) - { - // get the namespace and the name for this token - CMiniMdRW *pMiniMd = GetMiniMdEmit(); - TypeRefRec *pTypeRefRec; - IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(crExtends), &pTypeRefRec)); - LPCSTR szNamespace; - LPCSTR szName; - IfFailGo(pMiniMd->getNamespaceOfTypeRef(pTypeRefRec, &szNamespace));; - IfFailGo(pMiniMd->getNameOfTypeRef(pTypeRefRec, &szName)); - // check for System.Enum - BOOL bIsEnum = (!strcmp(szNamespace,"System"))&&(!strcmp(szName,"Enum")); - if (bIsEnum) - { - fInjectSecurityAttributes = FALSE; - } - } - } - else // check for global method defs - if (TypeFromToken(pRec->m_tkTo) == mdtMethodDef) - { - int isGlobal = 0; - if (!FAILED(m_pRegMetaEmit->IsGlobal(pRec->m_tkTo, &isGlobal))) - { - // check for global methods - if (isGlobal != 0) - { - fInjectSecurityAttributes = TRUE; - } - } - } - - if (fInjectSecurityAttributes) - { - // check to see if the token already has a custom attribute - const void *pbData = NULL; // [OUT] Put pointer to data here. - ULONG cbData = 0; - - if (fMarkEachTokenAsCritical) - { - // Check if the Type already has SecurityCritical - BOOL fInjectSecurityCriticalEverything = TRUE; - if (S_OK == m_pRegMetaEmit->GetCustomAttributeByName(pRec->m_tkTo, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W, &pbData, &cbData)) - { - // if value is non-0 (i.e. 1), then it is SecurityCritical.Everything - so do not inject another - fInjectSecurityCriticalEverything = !(NULL != pbData && cbData == 8 && - memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0); - } - - // either inject or overwrite SecurityCritical.Everything - if (fInjectSecurityCriticalEverything) - { - IfFailGo(m_pRegMetaEmit->DefineCustomAttribute( - pRec->m_tkTo, tkSecurityCriticalEverythingAttribute, - rgSecurityCriticalEverythingCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough) - sizeof(rgSecurityCriticalEverythingCtorValue), // Length of your custom attribute data - NULL)); - } - } - - // If the Type does NOT already have TAS then add it - if (fMarkEachTokenAsSafe && - S_OK != m_pRegMetaEmit->GetCustomAttributeByName(pRec->m_tkTo, COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W, &pbData, &cbData)) - { - IfFailGo(m_pRegMetaEmit->DefineCustomAttribute( - pRec->m_tkTo, tkSecurityTreatAsSafeAttribute, - rgTreatAsSafeCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough) - sizeof(rgTreatAsSafeCtorValue), // Length of your custom attribute data - NULL)); - } - - hr = m_pRegMetaEmit->DefineCustomAttribute(pRec->m_tkTo, tkSecuritySafeCriticalAttribute, - rgSafeCriticalCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough) - sizeof(rgSafeCriticalCtorValue), // Length of your custom attribute data - NULL); - - } - } - } - - // If the global scope is not Transparent, we should emit SecurityCritical.Explicit || Everything - if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTransparent) != ISSCS_SecurityTransparent && - (m_isscsSecurityCritical & ISSCS_SecurityCriticalEverything) != ISSCS_SecurityCriticalExplicit) - { - BOOL fEmitSecurityEverything = FALSE; - // in the case of Unmarked and TAS/Unmarked, we need to emit the SecurityCritical.Everything attribute - // if it hasn't already been emitted - if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) == - ISSCS_SecurityCriticalEverything) - { - fEmitSecurityEverything = TRUE; - } - // otherwise, emit the SecurityCritical.Explicit attribute - - BOOL fSecurityCriticalExists = FALSE; - // check to see if the assembly already has the appropriate SecurityCritical attribute - // [from one of the input scopes] - const void *pbData = NULL; - ULONG cbData = 0; - if (S_OK == ImportHelper::GetCustomAttributeByName(emit, - fakeModuleTypeRef, // This is the assembly def token - COR_SECURITYCRITICAL_ATTRIBUTE_FULL, - &pbData, - &cbData)) - { - // find out if critical everything or explicit - // default to critical - // if value is non-0 (i.e. 1), then mark as SecurityCritical everything, otherwise, explicit - if (NULL != pbData && cbData == 8 && - memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0) - { - if (!fEmitSecurityEverything) - { - _ASSERTE(!"Unexpected SecurityCritical.Everything attribute detected"); - IfFailGo(META_E_BADMETADATA); - } - } - else - { - if (fEmitSecurityEverything) - { - _ASSERTE(!"Unexpected SecurityCritical.Explicit attribute detected"); - IfFailGo(META_E_BADMETADATA); - } - } - fSecurityCriticalExists = TRUE; - } - - if (!fSecurityCriticalExists) - { - // retrieve the type and CustomAttribute - mdCustomAttribute tkSecurityCriticalAttributeExplicit; - - mdTypeRef tkSecurityCriticalExplicitAttributeType = mdTokenNil; - - IfFailGo(m_pRegMetaEmit->DefineTypeRefByName( - tkMscorlib, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W, - &tkSecurityCriticalExplicitAttributeType)); - - BYTE rgSigBytesSecurityCriticalExplicitCtorLocal[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID}; - BYTE rgSecurityCriticalExplicitCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EXPLICIT; - - IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityCriticalExplicitAttributeType, - COR_CONSTRUCTOR_METADATA_IDENTIFIER, - rgSigBytesSecurityCriticalExplicitCtorLocal, - sizeof(rgSigBytesSecurityCriticalExplicitCtorLocal), - &tkSecurityCriticalAttributeExplicit)); - - IfFailGo(m_pRegMetaEmit->DefineCustomAttribute( - fakeModuleTypeRef, - fEmitSecurityEverything?tkSecurityCriticalEverythingAttribute:tkSecurityCriticalAttributeExplicit, - fEmitSecurityEverything?rgSecurityCriticalEverythingCtorValue:rgSecurityCriticalExplicitCtorValue, - fEmitSecurityEverything?sizeof(rgSecurityCriticalEverythingCtorValue):sizeof(rgSecurityCriticalExplicitCtorValue), - NULL)); - - } - } - -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeSecurityCriticalAttributes() - -//******************************************************************************* -// Helper to copy an InterfaceImpl record -//******************************************************************************* -HRESULT NEWMERGER::CopyInterfaceImpl( - InterfaceImplRec *pRecEmit, // [IN] the emit record to fill - MergeImportData *pImportData, // [IN] the importing context - InterfaceImplRec *pRecImp) // [IN] the record to import -{ - HRESULT hr; - mdToken tkParent; - mdToken tkInterface; - CMiniMdRW *pMiniMdEmit = GetMiniMdEmit(); - CMiniMdRW *pMiniMdImp; - MDTOKENMAP *pCurTkMap; - - pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - - tkParent = pMiniMdImp->getClassOfInterfaceImpl(pRecImp); - tkInterface = pMiniMdImp->getInterfaceOfInterfaceImpl(pRecImp); - - IfFailGo( pCurTkMap->Remap(tkParent, &tkParent) ); - IfFailGo( pCurTkMap->Remap(tkInterface, &tkInterface) ); - - IfFailGo( pMiniMdEmit->PutToken( TBL_InterfaceImpl, InterfaceImplRec::COL_Class, pRecEmit, tkParent) ); - IfFailGo( pMiniMdEmit->PutToken( TBL_InterfaceImpl, InterfaceImplRec::COL_Interface, pRecEmit, tkInterface) ); - -ErrExit: - return hr; -} // HRESULT NEWMERGER::CopyInterfaceImpl() - - -//***************************************************************************** -// Merge Assembly table -//***************************************************************************** -HRESULT NEWMERGER::MergeAssembly() -{ - HRESULT hr = NOERROR; - AssemblyRec *pRecImport = NULL; - AssemblyRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - LPCUTF8 szTmp; - const BYTE *pbTmp; - ULONG cbTmp; - ULONG iRecord; - TOKENREC *pTokenRec; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - if (!pMiniMdImport->getCountAssemblys()) - goto ErrExit; // There is no Assembly in the import scope to merge. - - // Copy the Assembly map record to the Emit scope and send a token remap notifcation - // to the client. No duplicate checking needed since the Assembly can be present in - // only one scope and there can be atmost one entry. - IfFailGo(pMiniMdImport->GetAssemblyRecord(1, &pRecImport)); - IfFailGo(pMiniMdEmit->AddAssemblyRecord(&pRecEmit, &iRecord)); - - pRecEmit->Copy(pRecImport); - - IfFailGo(pMiniMdImport->getPublicKeyOfAssembly(pRecImport, &pbTmp, &cbTmp)); - IfFailGo(pMiniMdEmit->PutBlob(TBL_Assembly, AssemblyRec::COL_PublicKey, pRecEmit, - pbTmp, cbTmp)); - - IfFailGo(pMiniMdImport->getNameOfAssembly(pRecImport, &szTmp)); - IfFailGo(pMiniMdEmit->PutString(TBL_Assembly, AssemblyRec::COL_Name, pRecEmit, szTmp)); - - IfFailGo(pMiniMdImport->getLocaleOfAssembly(pRecImport, &szTmp)); - IfFailGo(pMiniMdEmit->PutString(TBL_Assembly, AssemblyRec::COL_Locale, pRecEmit, szTmp)); - - // record the token movement. - IfFailGo(pCurTkMap->InsertNotFound( - TokenFromRid(1, mdtAssembly), - false, - TokenFromRid(iRecord, mdtAssembly), - &pTokenRec)); - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeAssembly() - - - - -//***************************************************************************** -// Merge File table -//***************************************************************************** -HRESULT NEWMERGER::MergeFiles() -{ - HRESULT hr = NOERROR; - FileRec *pRecImport = NULL; - FileRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - LPCUTF8 szTmp; - const void *pbTmp; - ULONG cbTmp; - ULONG iCount; - ULONG i; - ULONG iRecord; - TOKENREC *pTokenRec; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountFiles(); - - // Loop through all File records and copy them to the Emit scope. - // Since there can only be one File table in all the scopes combined, - // there isn't any duplicate checking that needs to be done. - for (i = 1; i <= iCount; i++) - { - IfFailGo(pMiniMdImport->GetFileRecord(i, &pRecImport)); - IfFailGo(pMiniMdEmit->AddFileRecord(&pRecEmit, &iRecord)); - - pRecEmit->Copy(pRecImport); - - IfFailGo(pMiniMdImport->getNameOfFile(pRecImport, &szTmp)); - IfFailGo(pMiniMdEmit->PutString(TBL_File, FileRec::COL_Name, pRecEmit, szTmp)); - - IfFailGo(pMiniMdImport->getHashValueOfFile(pRecImport, (const BYTE **)&pbTmp, &cbTmp)); - IfFailGo(pMiniMdEmit->PutBlob(TBL_File, FileRec::COL_HashValue, pRecEmit, pbTmp, cbTmp)); - - // record the token movement. - IfFailGo(pCurTkMap->InsertNotFound( - TokenFromRid(i, mdtFile), - false, - TokenFromRid(iRecord, mdtFile), - &pTokenRec)); - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeFiles() - - -//***************************************************************************** -// Merge ExportedType table -//***************************************************************************** -HRESULT NEWMERGER::MergeExportedTypes() -{ - HRESULT hr = NOERROR; - ExportedTypeRec *pRecImport = NULL; - ExportedTypeRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - LPCUTF8 szTmp; - mdToken tkTmp; - ULONG iCount; - ULONG i; - ULONG iRecord; - TOKENREC *pTokenRec; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountExportedTypes(); - - // Loop through all ExportedType records and copy them to the Emit scope. - // Since there can only be one ExportedType table in all the scopes combined, - // there isn't any duplicate checking that needs to be done. - for (i = 1; i <= iCount; i++) - { - IfFailGo(pMiniMdImport->GetExportedTypeRecord(i, &pRecImport)); - IfFailGo(pMiniMdEmit->AddExportedTypeRecord(&pRecEmit, &iRecord)); - - pRecEmit->Copy(pRecImport); - - IfFailGo(pMiniMdImport->getTypeNameOfExportedType(pRecImport, &szTmp)); - IfFailGo(pMiniMdEmit->PutString(TBL_ExportedType, ExportedTypeRec::COL_TypeName, pRecEmit, szTmp)); - - IfFailGo(pMiniMdImport->getTypeNamespaceOfExportedType(pRecImport, &szTmp)); - IfFailGo(pMiniMdEmit->PutString(TBL_ExportedType, ExportedTypeRec::COL_TypeNamespace, pRecEmit, szTmp)); - - tkTmp = pMiniMdImport->getImplementationOfExportedType(pRecImport); - IfFailGo(pCurTkMap->Remap(tkTmp, &tkTmp)); - IfFailGo(pMiniMdEmit->PutToken(TBL_ExportedType, ExportedTypeRec::COL_Implementation, - pRecEmit, tkTmp)); - - - // record the token movement. - IfFailGo(pCurTkMap->InsertNotFound( - TokenFromRid(i, mdtExportedType), - false, - TokenFromRid(iRecord, mdtExportedType), - &pTokenRec)); - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeExportedTypes() - - -//***************************************************************************** -// Merge ManifestResource table -//***************************************************************************** -HRESULT NEWMERGER::MergeManifestResources() -{ - HRESULT hr = NOERROR; - ManifestResourceRec *pRecImport = NULL; - ManifestResourceRec *pRecEmit = NULL; - CMiniMdRW *pMiniMdImport; - CMiniMdRW *pMiniMdEmit; - LPCUTF8 szTmp; - mdToken tkTmp; - ULONG iCount; - ULONG i; - ULONG iRecord; - TOKENREC *pTokenRec; - - MergeImportData *pImportData; - MDTOKENMAP *pCurTkMap; - - pMiniMdEmit = GetMiniMdEmit(); - - for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData) - { - // for each import scope - pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - - // set the current MDTokenMap - pCurTkMap = pImportData->m_pMDTokenMap; - iCount = pMiniMdImport->getCountManifestResources(); - - // Loop through all ManifestResource records and copy them to the Emit scope. - // Since there can only be one ManifestResource table in all the scopes combined, - // there isn't any duplicate checking that needs to be done. - for (i = 1; i <= iCount; i++) - { - IfFailGo(pMiniMdImport->GetManifestResourceRecord(i, &pRecImport)); - IfFailGo(pMiniMdEmit->AddManifestResourceRecord(&pRecEmit, &iRecord)); - - pRecEmit->Copy(pRecImport); - - IfFailGo(pMiniMdImport->getNameOfManifestResource(pRecImport, &szTmp)); - IfFailGo(pMiniMdEmit->PutString(TBL_ManifestResource, ManifestResourceRec::COL_Name, - pRecEmit, szTmp)); - - tkTmp = pMiniMdImport->getImplementationOfManifestResource(pRecImport); - IfFailGo(pCurTkMap->Remap(tkTmp, &tkTmp)); - IfFailGo(pMiniMdEmit->PutToken(TBL_ManifestResource, ManifestResourceRec::COL_Implementation, - pRecEmit, tkTmp)); - - // record the token movement. - IfFailGo(pCurTkMap->InsertNotFound( - TokenFromRid(i, mdtManifestResource), - false, - TokenFromRid(iRecord, mdtManifestResource), - &pTokenRec)); - } - } -ErrExit: - return hr; -} // HRESULT NEWMERGER::MergeManifestResources() - - - - - -//***************************************************************************** -// Error handling. Call back to host to see what they want to do. -//***************************************************************************** -HRESULT NEWMERGER::OnError( - HRESULT hrIn, // The error HR we're reporting. - MergeImportData *pImportData, // The input scope with the error. - mdToken token) // The token with the error. -{ - // This function does a QI and a Release on every call. However, it should be - // called very infrequently, and lets the scope just keep a generic handler. - IMetaDataError *pIErr = NULL; - IUnknown *pHandler = pImportData->m_pHandler; - CMiniMdRW *pMiniMd = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd); - CQuickArray rName; // Name of the TypeDef in unicode. - LPCUTF8 szTypeName; - LPCUTF8 szNSName; - TypeDefRec *pTypeRec; - int iLen; // Length of a name. - mdToken tkParent; - HRESULT hr = NOERROR; - - if (pHandler && pHandler->QueryInterface(IID_IMetaDataError, (void**)&pIErr)==S_OK) - { - switch (hrIn) - { - - case META_E_PARAM_COUNTS: - case META_E_METHD_NOT_FOUND: - case META_E_METHDIMPL_INCONSISTENT: - { - LPCUTF8 szMethodName; - MethodRec *pMethodRec; - - // Method name. - _ASSERTE(TypeFromToken(token) == mdtMethodDef); - IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(token), &pMethodRec)); - IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName)); - MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName); - IfNullGo(wzMethodName); - - // Type and its name. - IfFailGo( pMiniMd->FindParentOfMethodHelper(token, &tkParent) ); - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - - PostError(hrIn, (LPWSTR) rName.Ptr(), wzMethodName, token); - break; - } - case META_E_FIELD_NOT_FOUND: - { - LPCUTF8 szFieldName; - FieldRec *pFieldRec; - - // Field name. - _ASSERTE(TypeFromToken(token) == mdtFieldDef); - IfFailGo(pMiniMd->GetFieldRecord(RidFromToken(token), &pFieldRec)); - IfFailGo(pMiniMd->getNameOfField(pFieldRec, &szFieldName)); - MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzFieldName, szFieldName); - IfNullGo(wzFieldName); - - // Type and its name. - IfFailGo( pMiniMd->FindParentOfFieldHelper(token, &tkParent) ); - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - - PostError(hrIn, (LPWSTR) rName.Ptr(), wzFieldName, token); - break; - } - case META_E_EVENT_NOT_FOUND: - { - LPCUTF8 szEventName; - EventRec *pEventRec; - - // Event name. - _ASSERTE(TypeFromToken(token) == mdtEvent); - IfFailGo(pMiniMd->GetEventRecord(RidFromToken(token), &pEventRec)); - IfFailGo(pMiniMd->getNameOfEvent(pEventRec, &szEventName)); - MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzEventName, szEventName); - IfNullGo(wzEventName); - - // Type and its name. - IfFailGo( pMiniMd->FindParentOfEventHelper(token, &tkParent) ); - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - - PostError(hrIn, (LPWSTR) rName.Ptr(), wzEventName, token); - break; - } - case META_E_PROP_NOT_FOUND: - { - LPCUTF8 szPropertyName; - PropertyRec *pPropertyRec; - - // Property name. - _ASSERTE(TypeFromToken(token) == mdtProperty); - IfFailGo(pMiniMd->GetPropertyRecord(RidFromToken(token), &pPropertyRec)); - IfFailGo(pMiniMd->getNameOfProperty(pPropertyRec, &szPropertyName)); - MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzPropertyName, szPropertyName); - IfNullGo(wzPropertyName); - - // Type and its name. - IfFailGo( pMiniMd->FindParentOfPropertyHelper(token, &tkParent) ); - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - - PostError(hrIn, (LPWSTR) rName.Ptr(), wzPropertyName, token); - break; - } - case META_S_PARAM_MISMATCH: - { - LPCUTF8 szMethodName; - MethodRec *pMethodRec; - mdToken tkMethod; - - // Method name. - _ASSERTE(TypeFromToken(token) == mdtParamDef); - IfFailGo( pMiniMd->FindParentOfParamHelper(token, &tkMethod) ); - IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(tkMethod), &pMethodRec)); - IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName)); - MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName); - IfNullGo(wzMethodName); - - // Type and its name. - IfFailGo( pMiniMd->FindParentOfMethodHelper(token, &tkParent) ); - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - - // use the error hresult so that we can post the correct error. - PostError(META_E_PARAM_MISMATCH, wzMethodName, (LPWSTR) rName.Ptr(), token); - break; - } - case META_E_INTFCEIMPL_NOT_FOUND: - { - InterfaceImplRec *pRec; // The InterfaceImpl - mdToken tkIface; // Token of the implemented interface. - CQuickArray rIface; // Name of the Implemented Interface in unicode. - TypeRefRec *pRef; // TypeRef record when II is a typeref. - InterfaceImplRec *pInterfaceImplRec; - - // Get the record. - _ASSERTE(TypeFromToken(token) == mdtInterfaceImpl); - IfFailGo(pMiniMd->GetInterfaceImplRecord(RidFromToken(token), &pRec)); - // Get the name of the class. - tkParent = pMiniMd->getClassOfInterfaceImpl(pRec); - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - - // Get the name of the implemented interface. - IfFailGo(pMiniMd->GetInterfaceImplRecord(RidFromToken(token), &pInterfaceImplRec)); - tkIface = pMiniMd->getInterfaceOfInterfaceImpl(pInterfaceImplRec); - if (TypeFromToken(tkIface) == mdtTypeDef) - { // If it is a typedef... - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkIface), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - } - else - { // If it is a typeref... - _ASSERTE(TypeFromToken(tkIface) == mdtTypeRef); - IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(tkIface), &pRef)); - IfFailGo(pMiniMd->getNameOfTypeRef(pRef, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeRef(pRef, &szNSName)); - } - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rIface.ReSizeNoThrow(iLen+1)); - ns::MakePath(rIface.Ptr(), iLen+1, szNSName, szTypeName); - - - PostError(hrIn, (LPWSTR) rName.Ptr(), (LPWSTR)rIface.Ptr(), token); - break; - } - case META_E_CLASS_LAYOUT_INCONSISTENT: - case META_E_METHOD_COUNTS: - case META_E_FIELD_COUNTS: - case META_E_EVENT_COUNTS: - case META_E_PROPERTY_COUNTS: - { - // get the type name. - _ASSERTE(TypeFromToken(token) == mdtTypeDef); - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(token), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - - PostError(hrIn, (LPWSTR) rName.Ptr(), token); - break; - } - case META_E_GENERICPARAM_INCONSISTENT: - { - // If token is type, get type name; if method, get method name. - LPWSTR wzName; - LPCUTF8 szMethodName; - MethodRec *pMethodRec; - - if ((TypeFromToken(token) == mdtMethodDef)) - { - // Get the method name. - IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(token), &pMethodRec)); - IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName)); - MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName); - IfNullGo(wzMethodName); - wzName = wzMethodName; - } - else - { - // Get the type name. - _ASSERTE(TypeFromToken(token) == mdtTypeDef); - IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(token), &pTypeRec)); - IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName)); - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - wzName = (LPWSTR)rName.Ptr(); - } - - PostError(hrIn, wzName, token); - break; - } - case META_E_TYPEDEF_MISSING: - { - TypeRefRec *pRef; // TypeRef record when II is a typeref. - - // Get the record. - _ASSERTE(TypeFromToken(token) == mdtTypeRef); - IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(token), &pRef)); - IfFailGo(pMiniMd->getNameOfTypeRef(pRef, &szTypeName)); - IfFailGo(pMiniMd->getNamespaceOfTypeRef(pRef, &szNSName)); - - // Put namespace + name together. - iLen = ns::GetFullLength(szNSName, szTypeName); - IfFailGo(rName.ReSizeNoThrow(iLen+1)); - ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName); - - - PostError(hrIn, (LPWSTR) rName.Ptr(), token); - break; - } - default: - { - PostError(hrIn, token); - break; - } - } - hr = pIErr->OnError(hrIn, token); - } - else - hr = S_FALSE; -ErrExit: - if (pIErr) - pIErr->Release(); - return (hr); -} // NEWMERGER::OnError - -#endif //FEATURE_METADATA_EMIT_ALL diff --git a/src/coreclr/src/md/compiler/newmerger.h b/src/coreclr/src/md/compiler/newmerger.h deleted file mode 100644 index fc89ab7..0000000 --- a/src/coreclr/src/md/compiler/newmerger.h +++ /dev/null @@ -1,256 +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. -//***************************************************************************** -// NewMerger.h -// - -// -// Contains utility code for MD directory -// -//***************************************************************************** -#ifndef __NEWMERGER__h__ -#define __NEWMERGER__h__ - -class RegMeta; - -class MDTOKENMAP; - -// module-level awareness of Security critical annotions -typedef BYTE InputScopeSecurityCriticalStatus; -#define ISSCS_Unknown 0x0 -#define ISSCS_SecurityCritical 0x1 -#define ISSCS_SecurityCriticalEverything (ISSCS_SecurityCritical | 0x2) -#define ISSCS_SecurityCriticalExplicit (ISSCS_SecurityCritical) -#define ISSCS_SecurityTransparent 0x4 -#define ISSCS_SecurityTreatAsSafe 0x8 -#define ISSCS_SECURITYCRITICAL_LEGACY (ISSCS_SecurityCriticalEverything | ISSCS_SecurityTreatAsSafe) -#define ISSCS_SECURITYCRITICAL_FLAGS (ISSCS_SecurityCriticalEverything | ISSCS_SecurityTransparent) - -//********************************************************************* -// MergeImportData -//********************************************************************* -class MergeImportData -{ -public: - RegMeta *m_pRegMetaImport; - IUnknown *m_pHandler; - IMapToken *m_pHostMapToken; - MDTOKENMAP *m_pMDTokenMap; - MergeImportData *m_pNextImportData; - - mdMemberRef m_tkSuppressMergeCheckCtor; // caches the SuppressMergeCheckAttribute's .ctor token - mdMemberRef m_tkHandleProcessCorruptedStateCtor; // caches the memberRef token to HandleProcessCorruptedStateExceptionsAttribute's .ctor token - - // import contains assembly-level SecurityTransparent or SecurityCritical - InputScopeSecurityCriticalStatus m_isscsSecurityCriticalStatus; -#if _DEBUG - int m_iImport; // debug only. This is the ith import for merge. -#endif // _DEBUG -}; - -//********************************************************************* -// MergeTypeData -//********************************************************************* -struct MergeTypeData -{ - ULONG m_cMethods; - ULONG m_cFields; - ULONG m_cEvents; - ULONG m_cProperties; - BOOL m_bSuppressMergeCheck; -}; - - -//********************************************************************* -// Class to handle merge -//********************************************************************* -class NEWMERGER -{ - friend class RegMeta; -public: - NEWMERGER(); - ~NEWMERGER(); - - HRESULT Init(RegMeta *pRegMetaDest); - - HRESULT AddImport( - IMetaDataImport2 *pImport, // [IN] The scope to be merged. - IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification - IUnknown *pHandler); // [IN] An object to receive to receive error notification. - - HRESULT Merge(MergeFlags flags, CorRefToDefCheck optimizeRefToDef); - -protected: - - CMiniMdRW *GetMiniMdEmit(); - - HRESULT InitMergeTypeData(); - - HRESULT MergeTypeDefNamesOnly(); - HRESULT MergeModuleRefs(); - HRESULT MergeAssemblyRefs(); - HRESULT MergeTypeRefs(); - HRESULT CompleteMergeTypeDefs(); - - HRESULT CopyTypeDefPartially( - TypeDefRec *pRecEmit, // [IN] the emit record to fill - CMiniMdRW *pMiniMdImport, // [IN] the importing scope - TypeDefRec *pRecImp); // [IN] the record to import - - // helpers for merging tables - HRESULT MergeModule( ); - HRESULT MergeTypeDefChildren(); - HRESULT MergeInterfaceImpls( ); - HRESULT MergeMemberRefs( ); - HRESULT MergePinvoke(); - - HRESULT MergeConstants( ); - HRESULT MergeCustomAttributes( ); - HRESULT MergeFieldMarshals( ); - HRESULT MergeDeclSecuritys( ); - HRESULT MergeClassLayouts( ); - HRESULT MergeFieldLayouts( ); - HRESULT MergeFieldRVAs(); - HRESULT MergeMethodImpls( ); - HRESULT MergeStandAloneSigs(); - HRESULT MergeMethodSpecs(); - HRESULT MergeTypeSpecs(); - HRESULT MergeSourceFiles( ); - HRESULT MergeBlocks( ); - HRESULT MergeScopes( ); - HRESULT MergeLocalVariables( ); - HRESULT MergeStrings( ); - - HRESULT MergeAssembly(); - HRESULT MergeFiles(); - HRESULT MergeExportedTypes(); - HRESULT MergeManifestResources(); - - // helpers for SecurityCritical-related merging - InputScopeSecurityCriticalStatus CheckInputScopeIsCritical(MergeImportData* pImportData, HRESULT& hr); - HRESULT RetrieveStandardSecurityCriticalMetaData( - mdAssemblyRef& tkMscorlib, - mdTypeRef& securityEnum, - BYTE*& rgSigBytesSecurityCriticalEverythingCtor, - DWORD& dwSigEverythingSize, - BYTE*& rgSigBytesSecurityCriticalExplicitCtor, - DWORD& dwSigExplicitSize); - - HRESULT MergeSecurityCriticalModuleLevelAttributes( - MergeImportData* pImportData, - mdToken tkParentImp, TOKENREC* pTypeRec, - mdToken mrSecurityTreatAsSafeAttributeCtor, - mdToken mrSecurityTransparentAttributeCtor, - mdToken mrSecurityCriticalExplicitAttributeCtor, - mdToken mrSecurityCriticalEverythingAttributeCtor); - HRESULT MergeSecurityCriticalAttributes(); - - // copy over a interfaceimpl record - HRESULT CopyInterfaceImpl( - InterfaceImplRec *pRecEmit, // [IN] the emit record to fill - MergeImportData *pImportData, // [IN] the importing context - InterfaceImplRec *pRecImp); // [IN] the record to import - - // verification helpers - HRESULT VerifyMethods(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT VerifyFields(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT VerifyEvents(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT VerifyProperties(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT VerifyParams(MergeImportData *pImportData, mdMethodDef mdImp, mdMethodDef mdEmit); - HRESULT VerifyGenericParams(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT VerifyGenericParamConstraints(MergeImportData *pImportData, mdGenericParam gpImp, mdGenericParam gpEmit); - - // Copy helpers - HRESULT CopyMethods(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT CopyFields(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT CopyEvents(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT CopyProperties(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit); - HRESULT CopyParams(MergeImportData *pImportData, mdMethodDef mdImp, mdMethodDef mdEmit); - HRESULT CopyGenericParams(MergeImportData *pImportData, mdToken tkImp, mdToken tkEmit); - HRESULT CopyGenericParamConstraints(MergeImportData *pImportData, mdGenericParam gpImp, mdGenericParam gpEmit); - - HRESULT CopyMethod( - MergeImportData *pImportData, // [IN] import scope - MethodRec *pRecImp, // [IN] the record to import - MethodRec *pRecEmit); // [IN] the emit record to fill - - HRESULT CopyField( - MergeImportData *pImportData, // [IN] import scope - FieldRec *pRecImp, // [IN] the record to import - FieldRec *pRecEmit); // [IN] the emit record to fill - - HRESULT CopyEvent( - MergeImportData *pImportData, // [IN] import scope - EventRec *pRecImp, // [IN] the record to import - EventRec *pRecEmit); // [IN] the emit record to fill - - HRESULT CopyProperty( - MergeImportData *pImportData, // [IN] import scope - PropertyRec *pRecImp, // [IN] the record to import - PropertyRec *pRecEmit); // [IN] the emit record to fill - - HRESULT CopyParam( - MergeImportData *pImportData, // [IN] import scope - ParamRec *pRecImp, // [IN] the record to import - ParamRec *pRecEmit); // [IN] the emit record to fill - - HRESULT CopyMethodSemantics( - MergeImportData *pImportData, - mdToken tkImport, // Event or property in the import scope - mdToken tkEmit); // corresponding event or property in the emitting scope - - HRESULT VerifyMethod( - MergeImportData *pImportData, - mdMethodDef mdImp, // [IN] the emit record to fill - mdMethodDef mdEmit); // [IN] the record to import - - HRESULT OnError(HRESULT hr, MergeImportData *pImportData, mdToken token); - -private: - RegMeta *m_pRegMetaEmit; - MergeImportData *m_pImportDataList; - MergeImportData **m_pImportDataTail; - MergeFlags m_dwMergeFlags; - BOOL m_fDupCheck; - CorRefToDefCheck m_optimizeRefToDef; - // the combined value of the Security Critical input scopes (e.g. UNION of each scope's attributes) - // if ANY of the scopes have a bit set, then we must do some merging - InputScopeSecurityCriticalStatus m_isscsSecurityCritical; - // the common values of the Security Critical input scopes (e.g. INTERSECTION of each scope's attributes) - // if all scopes have the same bit set, then we can emit one bit at the final output scope - InputScopeSecurityCriticalStatus m_isscsSecurityCriticalAllScopes; - - CDynArray m_rMTDs; -#if _DEBUG - int m_iImport; // debug only. To count how many import scopes to be merged. -#endif // _DEBUG -}; - - -#define CheckContinuableErrorEx(EXPR, HANDLER, TOKEN) \ -{ \ - HRESULT hrOnErr, hrExpr; \ - hrExpr = EXPR; \ - \ - hrOnErr = OnError(hrExpr, HANDLER, TOKEN); \ - if (hrOnErr != S_OK) \ - { \ - if (hrOnErr == S_FALSE) \ - { \ - hr = hrExpr; \ - } \ - else if (SUCCEEDED(hrOnErr)) \ - { \ - hr = E_UNEXPECTED; \ - } \ - else if (FAILED(hrOnErr)) \ - { \ - hr = hrOnErr; \ - } \ - IfFailGo(hr); \ - } \ -} - - -#endif // __NEWMERGER__h__ diff --git a/src/coreclr/src/md/compiler/regmeta.cpp b/src/coreclr/src/md/compiler/regmeta.cpp index 337c572..f591a6e 100644 --- a/src/coreclr/src/md/compiler/regmeta.cpp +++ b/src/coreclr/src/md/compiler/regmeta.cpp @@ -277,11 +277,6 @@ RegMeta::CreateNewMD() INDEBUG(m_pStgdb->m_MiniMd.Debug_SetLock(m_pSemReadWrite);) } -#ifdef FEATURE_METADATA_EMIT_ALL - // initialize the embedded merger - m_newMerger.Init(this); -#endif //FEATURE_METADATA_EMIT_ALL - ErrExit: return hr; } // RegMeta::CreateNewMD @@ -340,11 +335,6 @@ HRESULT RegMeta::OpenExistingMD( if (!IsOfReOpen(dwOpenFlags)) { -#ifdef FEATURE_METADATA_EMIT_ALL - // initialize the embedded merger - m_newMerger.Init(this); -#endif //FEATURE_METADATA_EMIT_ALL - // There must always be a Global Module class and its the first entry in // the TypeDef table. m_tdModule = TokenFromRid(1, mdtTypeDef); @@ -398,11 +388,6 @@ HRESULT RegMeta::OpenExistingMD( if (!IsOfReOpen(dwOpenFlags)) { -#ifdef FEATURE_METADATA_EMIT_ALL - // initialize the embedded merger - m_newMerger.Init(this); -#endif //FEATURE_METADATA_EMIT_ALL - // There must always be a Global Module class and its the first entry in // the TypeDef table. m_tdModule = TokenFromRid(1, mdtTypeDef); diff --git a/src/coreclr/src/md/compiler/regmeta.h b/src/coreclr/src/md/compiler/regmeta.h index 0c4e076..04456d8 100644 --- a/src/coreclr/src/md/compiler/regmeta.h +++ b/src/coreclr/src/md/compiler/regmeta.h @@ -20,8 +20,6 @@ #include "../inc/mdlog.h" #include "utsem.h" -#include "newmerger.h" - #include "rwutil.h" #include "mdperf.h" #include @@ -183,7 +181,6 @@ class RegMeta : #endif , public IMDCommon { - friend class NEWMERGER; friend class CImportTlb; friend class MDInternalRW; friend class MDInternalRO; @@ -1626,8 +1623,6 @@ protected: } HRESULT PreSave(); - HRESULT ProcessFilter(); - HRESULT ProcessFilterWorker(); // Initialize the EE HRESULT StartupEE(); @@ -2025,9 +2020,6 @@ private: ULONG m_OpenFlags; // Open time flags. LONG m_cRef; // Ref count. -#ifdef FEATURE_METADATA_EMIT_ALL - NEWMERGER m_newMerger; // class for handling merge -#endif //FEATURE_METADATA_EMIT_ALL IUnknown *m_pFreeThreadedMarshaler; // FreeThreadedMarshaler #ifdef FEATURE_METADATA_PERF_STATS diff --git a/src/coreclr/src/md/compiler/regmeta_compilersupport.cpp b/src/coreclr/src/md/compiler/regmeta_compilersupport.cpp index 0bea066..571f928 100644 --- a/src/coreclr/src/md/compiler/regmeta_compilersupport.cpp +++ b/src/coreclr/src/md/compiler/regmeta_compilersupport.cpp @@ -49,35 +49,7 @@ STDMETHODIMP RegMeta::Merge( // S_OK or error. IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification IUnknown *pHandler) // [IN] An object to receive to receive error notification. { -#ifdef FEATURE_METADATA_EMIT_ALL - HRESULT hr = NOERROR; - - BEGIN_ENTRYPOINT_NOTHROW; - - IMetaDataImport2 *pI2=NULL; - - LOG((LOGMD, "RegMeta::Merge(0x%08x, 0x%08x)\n", pImport, pHandler)); - START_MD_PERF(); - LOCKWRITE(); - - IfFailGo(VerifyNotWinMD(pImport, "IMetaDataEmit::Merge(): merging with a .winmd file not supported.")); - - IfFailGo(pImport->QueryInterface(IID_IMetaDataImport2, (void**)&pI2)); - m_hasOptimizedRefToDef = false; - - // track this import - IfFailGo( m_newMerger.AddImport(pI2, pHostMapToken, pHandler) ); - -ErrExit: - if (pI2) - pI2->Release(); - STOP_MD_PERF(Merge); - END_ENTRYPOINT_NOTHROW; - - return (hr); -#else //!FEATURE_METADATA_EMIT_ALL return E_NOTIMPL; -#endif //!FEATURE_METADATA_EMIT_ALL } // RegMeta::Merge @@ -86,32 +58,7 @@ ErrExit: //***************************************************************************** STDMETHODIMP RegMeta::MergeEnd() // S_OK or error. { -#ifdef FEATURE_METADATA_EMIT_ALL - HRESULT hr = NOERROR; - - BEGIN_ENTRYPOINT_NOTHROW; - - LOG((LOGMD, "RegMeta::MergeEnd()\n")); - START_MD_PERF(); - LOCKWRITE(); - // Merge happens here!! - - // bug 16719. Merge itself is doing a lots of small changes in literally - // dozens of places. It would be to hard to maintain and would cause code - // bloat to auto-grow the tables. So instead, we've opted to just expand - // the world right away and avoid the trouble. - IfFailGo(m_pStgdb->m_MiniMd.ExpandTables()); - - IfFailGo(m_newMerger.Merge(m_OptionValue.m_MergeOptions, m_OptionValue.m_RefToDefCheck) ); - -ErrExit: - STOP_MD_PERF(MergeEnd); - END_ENTRYPOINT_NOTHROW; - - return (hr); -#else //!FEATURE_METADATA_EMIT_ALL return E_NOTIMPL; -#endif //!FEATURE_METADATA_EMIT_ALL } // RegMeta::MergeEnd @@ -282,225 +229,4 @@ ErrExit: #endif //!FEATURE_METADATA_EMIT_ALL } // RegMeta::ResetENCLog -#ifdef FEATURE_METADATA_EMIT_ALL - -// Helper for code:RegMeta::ProcessFilter -HRESULT RegMeta::ProcessFilterWorker() -{ - HRESULT hr = S_OK; - - CMiniMdRW *pMiniMd; // The MiniMd with the data. - RegMeta *pMetaNew = NULL; - CMapToken *pMergeMap = NULL; - IMapToken *pMapNew = NULL; - MergeTokenManager *pCompositHandler = NULL; - IMapToken *pHostMapToken = NULL; - - // For convenience. - pMiniMd = &(m_pStgdb->m_MiniMd); - IfNullGo( pMiniMd->GetFilterTable() ); - _ASSERTE(pMiniMd->GetFilterTable()->Count() != 0); // caller verified this - - // Yes, client has used filter to specify what are the metadata needed. - // We will create another instance of RegMeta and make this module an imported module - // to be merged into the new RegMeta. We will provide the handler to track all of the token - // movements. We will replace the merged light weight stgdb to this RegMeta.. - // Then we will need to fix up the MergeTokenManager with this new movement. - // The reason that we decide to choose this approach is because it will be more complicated - // and very likely less efficient to fix up the signature blob pool and then compact all of the pools! - // - - // Create a new RegMeta. - pMetaNew = new (nothrow) RegMeta(); - IfNullGo( pMetaNew ); - pMetaNew->AddRef(); - IfFailGo(pMetaNew->SetOption(&m_OptionValue)); - - - // Remember the open type. - IfFailGo(pMetaNew->CreateNewMD()); - IfFailGo(pMetaNew->AddToCache()); - - // Ignore the error return by setting handler - hr = pMetaNew->SetHandler(m_pHandler); - - // create the IMapToken to receive token remap information from merge - pMergeMap = new (nothrow) CMapToken; - IfNullGo( pMergeMap ); - - // use merge to filter out the unneeded data. But we need to keep COMType and also need to drop off the - // CustomAttributes that associated with MemberRef with parent MethodDef - // - pMetaNew->m_hasOptimizedRefToDef = false; - IfFailGo( pMetaNew->m_newMerger.AddImport(this, pMergeMap, NULL) ); - IfFailGo( pMetaNew->m_pStgdb->m_MiniMd.ExpandTables()); - IfFailGo( pMetaNew->m_newMerger.Merge((MergeFlags)(MergeManifest | DropMemberRefCAs | NoDupCheck), MDRefToDefDefault) ); - - // Now we need to recalculate the token movement - // - if (m_newMerger.m_pImportDataList) - { - - // This is the case the filter is applied to merged emit scope. We need calculate how this implicit merge - // affects the original merge remap. Basically we need to walk all the m_pTkMapList in the merger and replace - // the to token to the most recent to token. - // - MDTOKENMAP *pMDTokenMapList; - - pMDTokenMapList = m_newMerger.m_pImportDataList->m_pMDTokenMap; - - MDTOKENMAP *pMap; - TOKENREC *pTKRec; - ULONG i; - mdToken tkFinalTo; - ModuleRec *pMod; - ModuleRec *pModNew; - LPCUTF8 szName; - - // update each import map from merge to have the m_tkTo points to the final mapped to token - for (pMap = pMDTokenMapList; pMap; pMap = pMap->m_pNextMap) - { - // update each record - for (i = 0; i < (ULONG) (pMap->Count()); i++) - { - TOKENREC *pRecTo; - pTKRec = pMap->Get(i); - if ( pMergeMap->Find( pTKRec->m_tkTo, &pRecTo ) ) - { - // This record is kept by the filter and the tkTo is changed - pRecTo->m_isFoundInImport = true; - tkFinalTo = pRecTo->m_tkTo; - pTKRec->m_tkTo = tkFinalTo; - pTKRec->m_isDeleted = false; - - // send the notification now. Because after merge, we may have everything in order and - // won't send another set of notification. - // - LOG((LOGMD, "TokenRemap in RegMeta::ProcessFilter (IMapToken 0x%08x): from 0x%08x to 0x%08x\n", pMap->m_pMap, pTKRec->m_tkFrom, pTKRec->m_tkTo)); - - pMap->m_pMap->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo); - } - else - { - // This record is pruned by the filter upon save - pTKRec->m_isDeleted = true; - } - } - } - - // now walk the pMergeMap and check to see if there is any entry that is not set to true for m_isFoundInImport. - // These are the records that from calling DefineXXX methods directly on the Emitting scope! - if (m_pHandler) - m_pHandler->QueryInterface(IID_IMapToken, (void **)&pHostMapToken); - if (pHostMapToken) - { - for (i = 0; i < (ULONG) (pMergeMap->m_pTKMap->Count()); i++) - { - pTKRec = pMergeMap->m_pTKMap->Get(i); - if (pTKRec->m_isFoundInImport == false) - { - LOG((LOGMD, "TokenRemap in RegMeta::ProcessFilter (default IMapToken 0x%08x): from 0x%08x to 0x%08x\n", pHostMapToken, pTKRec->m_tkFrom, pTKRec->m_tkTo)); - - // send the notification on the IMapToken from SetHandler of this RegMeta - pHostMapToken->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo); - } - } - } - - // Preserve module name across merge. - IfFailGo(m_pStgdb->m_MiniMd.GetModuleRecord(1, &pMod)); - IfFailGo(pMetaNew->m_pStgdb->m_MiniMd.GetModuleRecord(1, &pModNew)); - IfFailGo(m_pStgdb->m_MiniMd.getNameOfModule(pMod, &szName)); - IfFailGo(pMetaNew->m_pStgdb->m_MiniMd.PutString(TBL_Module, ModuleRec::COL_Name, pModNew, szName)); - - // now swap the stgdb but keep the merger... - _ASSERTE( !IsOfExternalStgDB(m_OpenFlags) ); - - CLiteWeightStgdbRW * pStgdbTmp = m_pStgdb; - m_pStgdb = pMetaNew->m_pStgdb; - pMetaNew->m_pStgdb = pStgdbTmp; - // Update RuntimeVersion string pointers to point to the owning RegMeta string (the strings are 2 copies of the same string content) - m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = m_OptionValue.m_RuntimeVersion; - pMetaNew->m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = pMetaNew->m_OptionValue.m_RuntimeVersion; - } - else - { - // swap the Stgdb - CLiteWeightStgdbRW * pStgdbTmp = m_pStgdb; - m_pStgdb = pMetaNew->m_pStgdb; - pMetaNew->m_pStgdb = pStgdbTmp; - // Update RuntimeVersion string pointers to point to the owning RegMeta string (the strings are 2 copies of the same string content) - m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = m_OptionValue.m_RuntimeVersion; - pMetaNew->m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = pMetaNew->m_OptionValue.m_RuntimeVersion; - - // Client either open an existing scope and apply the filter mechanism, or client define the scope and then - // apply the filter mechanism. - - // In this case, host better has supplied the handler!! - _ASSERTE( m_bRemap && m_pHandler); - IfFailGo( m_pHandler->QueryInterface(IID_IMapToken, (void **) &pMapNew) ); - - - { - // Send the notification of token movement now because after merge we may not move tokens again - // and thus no token notification will be send. - MDTOKENMAP *pMap = pMergeMap->m_pTKMap; - TOKENREC *pTKRec; - ULONG i; - - for (i=0; i < (ULONG) (pMap->Count()); i++) - { - pTKRec = pMap->Get(i); - pMap->m_pMap->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo); - } - - } - - - // What we need to do here is create a IMapToken that will replace the original handler. This new IMapToken - // upon called will first map the from token to the most original from token. - // - pCompositHandler = new (nothrow) MergeTokenManager(pMergeMap->m_pTKMap, NULL); - IfNullGo( pCompositHandler ); - - // now update the following field to hold on to the real IMapToken supplied by our client by SetHandler - if (pMergeMap->m_pTKMap->m_pMap) - pMergeMap->m_pTKMap->m_pMap->Release(); - _ASSERTE(pMapNew); - pMergeMap->m_pTKMap->m_pMap = pMapNew; - - // ownership transferred - pMergeMap = NULL; - pMapNew = NULL; - - // now you want to replace all of the IMapToken set by calling SetHandler to this new MergeTokenManager - IfFailGo( m_pStgdb->m_MiniMd.SetHandler(pCompositHandler) ); - - m_pHandler = pCompositHandler; - - // ownership transferred - pCompositHandler = NULL; - } - - // Force a ref to def optimization because the remap information was stored in the thrown away CMiniMdRW - m_hasOptimizedRefToDef = false; - IfFailGo( RefToDefOptimization() ); - -ErrExit: - if (pHostMapToken) - pHostMapToken->Release(); - if (pMetaNew) - pMetaNew->Release(); - if (pMergeMap) - pMergeMap->Release(); - if (pCompositHandler) - pCompositHandler->Release(); - if (pMapNew) - pMapNew->Release(); - - return hr; -} // RegMeta::ProcessFilter - -#endif //FEATURE_METADATA_EMIT_ALL - #endif //FEATURE_METADATA_EMIT diff --git a/src/coreclr/src/md/compiler/regmeta_emit.cpp b/src/coreclr/src/md/compiler/regmeta_emit.cpp index 22d2979..d3268fe 100644 --- a/src/coreclr/src/md/compiler/regmeta_emit.cpp +++ b/src/coreclr/src/md/compiler/regmeta_emit.cpp @@ -279,13 +279,6 @@ STDMETHODIMP RegMeta::GetSaveSize( // S_OK or error. IfFailGo(m_pFilterManager->Mark(TokenFromRid(iCount, mdtAssembly))); } } -#ifdef FEATURE_METADATA_EMIT_ALL - else if (m_newMerger.m_pImportDataList) - { - // always pipe through another pass of merge to drop unnecessary ref for linker. - MarkAll(); - } -#endif //FEATURE_METADATA_EMIT_ALL IfFailGo(PreSave()); @@ -734,7 +727,6 @@ HRESULT RegMeta::PreSave() // Return code. HRESULT hr = S_OK; // A result. CMiniMdRW *pMiniMd; // The MiniMd with the data. unsigned bRemapOld = m_bRemap; - MergeTokenManager *ptkMgr = NULL; // For convenience. pMiniMd = &(m_pStgdb->m_MiniMd); @@ -745,21 +737,6 @@ HRESULT RegMeta::PreSave() // Return code. if (m_bSaveOptimized) goto ErrExit; -#ifdef FEATURE_METADATA_EMIT_ALL - if (m_newMerger.m_pImportDataList != NULL) - { - // This is the linker scenario. We we have IMap for each scope. We will create an instance of our own mapper - // who knows how to send notification back to host! - - // cache the host provided handler to the end our MergeTokenManager - - ptkMgr = new (nothrow) MergeTokenManager(m_newMerger.m_pImportDataList->m_pMDTokenMap, m_pHandler); - IfNullGo(ptkMgr); - hr = m_pStgdb->m_MiniMd.SetHandler(ptkMgr); - _ASSERTE(SUCCEEDED(hr)); - } -#endif //FEATURE_METADATA_EMIT_ALL - IfFailGo(RefToDefOptimization()); // we need to update MethodImpl table here with ref to def result @@ -808,19 +785,7 @@ HRESULT RegMeta::PreSave() // Return code. } } } - -#ifdef FEATURE_METADATA_EMIT_ALL - IfFailGo(ProcessFilter()); - - if (m_newMerger.m_pImportDataList != NULL) - { - // Allocate a token mapper object that will be used for phase 1 if there is not Handler but - // linker has provided the IMapToken - // - m_bRemap = true; - } -#endif //FEATURE_METADATA_EMIT_ALL - + // reget the minimd because it can be swapped in the call of ProcessFilter pMiniMd = &(m_pStgdb->m_MiniMd); @@ -831,13 +796,6 @@ HRESULT RegMeta::PreSave() // Return code. IfFailGo(m_pStgdb->m_MiniMd.PreSave(m_ReorderingOptions, m_pCorProfileData)); ErrExit: - if (ptkMgr != NULL) - { - // recovery the initial state - hr = m_pStgdb->m_MiniMd.SetHandler(NULL); - ptkMgr->Release(); - } - m_bRemap = bRemapOld; return hr; @@ -1008,37 +966,6 @@ ErrExit: return hr; } // RegMeta::RefToDefOptimization -#ifdef FEATURE_METADATA_EMIT_ALL - -//***************************************************************************** -// Process filter -//***************************************************************************** -HRESULT RegMeta::ProcessFilter() -{ - HRESULT hr = S_OK; - - CMiniMdRW *pMiniMd; // The MiniMd with the data. - - START_MD_PERF(); - - // For convenience. - pMiniMd = &(m_pStgdb->m_MiniMd); - IfNullGo( pMiniMd->GetFilterTable() ); - if ( pMiniMd->GetFilterTable()->Count() == 0 ) - { - // there is no filter - goto ErrExit; - } - hr = ProcessFilterWorker(); - -ErrExit: - STOP_MD_PERF(ProcessFilter); - - return hr; -} // RegMeta::ProcessFilter - -#endif //FEATURE_METADATA_EMIT_ALL - //***************************************************************************** // Define a TypeRef given the fully qualified name. //***************************************************************************** diff --git a/src/coreclr/src/md/enc/rwutil.cpp b/src/coreclr/src/md/enc/rwutil.cpp index 874d972..a00eddb 100644 --- a/src/coreclr/src/md/enc/rwutil.cpp +++ b/src/coreclr/src/md/enc/rwutil.cpp @@ -952,149 +952,6 @@ ErrExit: - -//********************************************************************************************************* -// -// Merge Token manager's constructor -// -//********************************************************************************************************* -MergeTokenManager::MergeTokenManager(MDTOKENMAP *pTkMapList, IUnknown *pHandler) -{ - m_cRef = 1; - m_pTkMapList = pTkMapList; - m_pDefaultHostRemap = NULL; - if (pHandler) - pHandler->QueryInterface(IID_IMapToken, (void **) &m_pDefaultHostRemap); -} // TokenManager::TokenManager() - - - -//********************************************************************************************************* -// -// Merge Token manager's destructor -// -//********************************************************************************************************* -MergeTokenManager::~MergeTokenManager() -{ - if (m_pDefaultHostRemap) - m_pDefaultHostRemap->Release(); -} // TokenManager::~TokenManager() - - - - -ULONG MergeTokenManager::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} // TokenManager::AddRef() - - - -ULONG MergeTokenManager::Release() -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (!cRef) - delete this; - return (cRef); -} // TokenManager::Release() - - -HRESULT MergeTokenManager::QueryInterface(REFIID riid, void **ppUnk) -{ - if (ppUnk == NULL) - return E_INVALIDARG; - - if (IsEqualIID(riid, IID_IMapToken)) - { - //*ppUnk = (IUnknown *) (IMapToken *) this; - // it should return the accurate type requested, - // if IUnknown is returned, it will finally converted to IMapToken* - *ppUnk = (IMapToken *) this; - } - else if (IsEqualIID(riid, IID_IUnknown)) - { - // add query handling for IUnknown - // this upcasting (converting a derived-class - // reference or pointer to a base-class) is safe - *ppUnk = (IUnknown *) this; - } - else - { - *ppUnk = NULL; - return (E_NOINTERFACE); - } - - AddRef(); - return (S_OK); -} // TokenManager::QueryInterface - - - -//********************************************************************************************************* -// -// Token manager keep tracks a list of tokenmaps. Each tokenmap corresponding -// to an imported scope. Note that with this, we do have problem in how to -// tell linker regarding the token movement when the token is added by Define -// rather than merge. This should be fixed with new merge implementation. -// The tkImp is the old tokens in the emit scope, tkEmit is the new token in the -// emit scope. We need to find the token from an import scope that is resolved -// to the tkImp. We then need to tell linker about this token movement. -// If we don't find any import scope which generates the tkImp token, that is -// this tkImp is generated by calling DefinXXX directly on the final merged scope. -// Then we use the default host remap to send the notification. -// -//********************************************************************************************************* -HRESULT MergeTokenManager::Map(mdToken tkImp, mdToken tkEmit) -{ - HRESULT hr = NOERROR; - MDTOKENMAP *pTkMapList = m_pTkMapList; - bool fFoundInImport = false; - int iPosition; - TOKENREC *pRec; - - _ASSERTE(m_pTkMapList); - while ( pTkMapList ) - { - // FindWithToToken will return the first match with the To token. - // pTkMapList is sorted with To token. It might contain several From tokens - // that map to the To token due to ref to def optimiation. Make sure that - // all notification is sent to all of these From tokens. - // - if ( pTkMapList->FindWithToToken(tkImp, &iPosition) ) - { - // make sure that we don't walk over the last entry - while (iPosition < pTkMapList->Count()) - { - pRec = pTkMapList->Get(iPosition); - if (pRec->m_tkTo != tkImp) - { - // we are done! - break; - } - - // more matching record... - fFoundInImport = true; - if (pTkMapList->m_pMap) - hr = pTkMapList->m_pMap->Map(pRec->m_tkFrom, tkEmit); - _ASSERTE(SUCCEEDED(hr)); - IfFailGo( hr ); - iPosition++; - } - } - pTkMapList = pTkMapList->m_pNextMap; - } - - if (fFoundInImport == false && m_pDefaultHostRemap) - { - // use the default remap to send the notification - IfFailGo( m_pDefaultHostRemap->Map(tkImp, tkEmit) ); - } -ErrExit: - return hr; -} - - - //********************************************************************************************************* // // CMapToken's constructor diff --git a/src/coreclr/src/md/inc/liteweightstgdb.h b/src/coreclr/src/md/inc/liteweightstgdb.h index 1234524..057e29d 100644 --- a/src/coreclr/src/md/inc/liteweightstgdb.h +++ b/src/coreclr/src/md/inc/liteweightstgdb.h @@ -66,8 +66,6 @@ protected: friend class CorMetaDataScope; friend class COR; friend class RegMeta; - friend class MERGER; - friend class NEWMERGER; friend class MDInternalRO; friend class MDInternalRW; }; diff --git a/src/coreclr/src/md/inc/rwutil.h b/src/coreclr/src/md/inc/rwutil.h index 5d7f989..81966b7 100644 --- a/src/coreclr/src/md/inc/rwutil.h +++ b/src/coreclr/src/md/inc/rwutil.h @@ -181,30 +181,6 @@ private: //********************************************************************* // -// Merge Token manager. This class is created in GetSaveSize as an agent to -// notify linker regarding token movements. It does not have the ability to -// keep track token movement. -// -//********************************************************************* -class MergeTokenManager : public IMapToken -{ -public: - STDMETHODIMP QueryInterface(REFIID riid, PVOID *pp); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - STDMETHODIMP Map(mdToken tkImp, mdToken tkEmit); - MergeTokenManager(MDTOKENMAP *pTkMapList, IUnknown *pHandler); - virtual ~MergeTokenManager(); -private: - LONG m_cRef; - MDTOKENMAP *m_pTkMapList; - IMapToken *m_pDefaultHostRemap; -}; - - - -//********************************************************************* -// // This CMapToken class implemented the IMapToken. It is used in RegMeta for // filter process. This class can track all of the tokens are mapped. It also // supplies a Find function.