BOOL PELoader::getVAforRVA(DWORD rva,void **ppva) { PIMAGE_SECTION_HEADER pSectionHeader; if (m_bIsPE32) { // Get the image header from the image, then get the directory location // of the COM+ header which may or may not be filled out. PIMAGE_NT_HEADERS32 pImageHeader; pImageHeader = (PIMAGE_NT_HEADERS32) Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize); PREFIX_ASSUME(pImageHeader != NULL); pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa32(pImageHeader, (PBYTE)m_hMod, rva, (DWORD)m_FileSizeAligned /* FileLength */); } else { PIMAGE_NT_HEADERS64 pImageHeader; pImageHeader = (PIMAGE_NT_HEADERS64) Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize); PREFIX_ASSUME(pImageHeader != NULL); pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa64(pImageHeader, (PBYTE)m_hMod, rva, (DWORD)m_FileSizeAligned /* FileLength */); } // If the section header exists, then return ok and the address. if (pSectionHeader) { *ppva = pSectionHeader; return TRUE; } // If there is no COM+ Data in this image, return false. else return FALSE; }
//***************************************************************************** // cascading Mark of a MemberRef //***************************************************************************** HRESULT FilterManager::MarkMemberRef(mdMemberRef mr) { HRESULT hr = NOERROR; MemberRefRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); mdToken md; TOKENMAP *tkMap; mdToken tkParent; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if MemberRef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsMemberRefMarked(mr)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkMemberRef( mr ) ); if (pFilter) pFilter->MarkToken(mr); IfFailGo(m_pMiniMd->GetMemberRefRecord(RidFromToken(mr), &pRec)); // we want to mark the parent of MemberRef as well tkParent = m_pMiniMd->getClassOfMemberRef(pRec); // If the parent is the global TypeDef, mark only the TypeDef itself (low-level function). // Other parents, do the transitive mark (ie, the high-level function). // if (IsGlobalTypeDef(tkParent)) IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef( tkParent ) ); else IfFailGo( Mark( tkParent ) ); // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->getSignatureOfMemberRef(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); tkMap = m_pMiniMd->GetMemberRefToMemberDefMap(); PREFIX_ASSUME(tkMap != NULL); md = *(tkMap->Get(RidFromToken(mr))); // can be fielddef or methoddef if ( RidFromToken(md) != mdTokenNil ) { // MemberRef is referring to either a FieldDef or MethodDef. // If it is referring to MethodDef, we have fix the parent of MemberRef to be the MethodDef. // However, if it is mapped to a FieldDef, the parent column does not track this information. // Therefore we need to mark it explicitly. // IfFailGo( Mark(md) ); } IfFailGo( MarkCustomAttributesWithParentToken(mr) ); ErrExit: return hr; } // HRESULT FilterManager::MarkMemberRef()
// RegRegValueHome::GetEnregisteredValue // Gets an enregistered value and returns it to the caller (see EnregisteredValueHome::GetEnregisteredValue // for full header comment) void RegRegValueHome::GetEnregisteredValue(MemoryRange valueOutBuffer) { UINT_PTR* highWordAddr = m_pFrame->GetAddressOfRegister(m_reg1Info.m_kRegNumber); PREFIX_ASSUME(highWordAddr != NULL); UINT_PTR* lowWordAddr = m_pFrame->GetAddressOfRegister(m_reg2Info.m_kRegNumber); PREFIX_ASSUME(lowWordAddr != NULL); _ASSERTE(sizeof(*highWordAddr) + sizeof(*lowWordAddr) == valueOutBuffer.Size()); memcpy(valueOutBuffer.StartAddress(), lowWordAddr, sizeof(*lowWordAddr)); memcpy((BYTE *)valueOutBuffer.StartAddress() + sizeof(*lowWordAddr), highWordAddr, sizeof(*highWordAddr)); } // RegRegValueHome::GetEnregisteredValue
//***************************************************************************** // cascading Mark of a field token //***************************************************************************** HRESULT FilterManager::MarkField(mdFieldDef fd) { HRESULT hr = NOERROR; FieldRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if FieldDef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsFieldMarked(fd)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkField( fd ) ); if (pFilter) pFilter->MarkToken(fd); // We should not mark all of the MemberRef with the parent of this FieldDef token. // Because not all of the call sites are needed. // // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->GetFieldRecord(RidFromToken(fd), &pRec)); IfFailGo(m_pMiniMd->getSignatureOfField(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); IfFailGo( MarkCustomAttributesWithParentToken(fd) ); // IfFailGo( MarkDeclSecuritiesWithParentToken(fd) ); ErrExit: return hr; } // HRESULT FilterManager::MarkField()
//***************************************************************************** // cascading Mark of a Property token //***************************************************************************** HRESULT FilterManager::MarkProperty(mdProperty pr) { HRESULT hr = NOERROR; PropertyRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if Property is already marked, just return if (m_pMiniMd->GetFilterTable()->IsPropertyMarked(pr)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkProperty( pr ) ); // marking the backing field, event changing and event changed IfFailGo(m_pMiniMd->GetPropertyRecord(RidFromToken(pr), &pRec)); // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->getTypeOfProperty(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); // Note that we don't need to mark the MethodSemantics. Because the association of MethodSemantics // is marked. The Method column can only store MethodDef, ie the MethodDef has the same parent as // this Property. IfFailGo( MarkCustomAttributesWithParentToken(pr) ); // IfFailGo( MarkDeclSecuritiesWithParentToken(pr) ); ErrExit: return hr; } // HRESULT FilterManager::MarkProperty()
HRESULT PESection::applyRelocs(CeeGenTokenMapper *pTokenMapper) { // For each section, go through each of its relocs for(PESectionReloc* pCurReloc = m_relocStart; pCurReloc < m_relocCur; pCurReloc++) { if (pCurReloc->type == srRelocMapToken) { unsigned * pos = (unsigned*) m_blobFetcher.ComputePointer(pCurReloc->offset); mdToken newToken; PREFIX_ASSUME(pos != NULL); if (pTokenMapper->HasTokenMoved(*pos, newToken)) { // we have a mapped token *pos = newToken; } } #if 0 _ASSERTE(pCurReloc->offset + 4 <= CurSection.m_blobFetcher.GetDataLen()); unsigned * pAddr = (unsigned *) CurSection.m_blobFetcher.ComputePointer(pCurReloc->offset); _ASSERTE(pCurReloc->type == srRelocAbsolute); // Current contents contain an offset into pCurReloc->section // computePointer() is like pCurReloc-section + *pAddr, but for non-linear section // This will resolve *pAddr to be a complete address *pAddr = (unsigned) pCurReloc->section->computePointer(*pAddr); #endif } // End relocs return S_OK; }
//***************************************************************************** // cascading Mark of all MethodImpls associated with a TypeDef token //***************************************************************************** HRESULT FilterManager::MarkMethodImplsWithParentToken(mdTypeDef td) { HRESULT hr = NOERROR; RID index; mdToken tkBody; mdToken tkDecl; MethodImplRec *pMethodImplRec; HENUMInternal hEnum; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); memset(&hEnum, 0, sizeof(HENUMInternal)); IfFailGo( m_pMiniMd->FindMethodImplHelper(td, &hEnum) ); while (HENUMInternal::EnumNext(&hEnum, (mdToken *)&index)) { IfFailGo(m_pMiniMd->GetMethodImplRecord(index, &pMethodImplRec)); IfFailGo(m_pMiniMd->GetFilterTable()->MarkMethodImpl(index)); tkBody = m_pMiniMd->getMethodBodyOfMethodImpl(pMethodImplRec); IfFailGo( Mark(tkBody) ); tkDecl = m_pMiniMd->getMethodDeclarationOfMethodImpl(pMethodImplRec); IfFailGo( Mark(tkDecl) ); } ErrExit: HENUMInternal::ClearEnum(&hEnum); return hr; } // HRESULT FilterManager::MarkMethodImplsWithParentToken()
//***************************************************************************** // cascading Mark of a MethodSpec //***************************************************************************** HRESULT FilterManager::MarkMethodSpec(mdMethodSpec ms) { HRESULT hr = NOERROR; MethodSpecRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if MethodSpec is already marked, just return if (m_pMiniMd->GetFilterTable()->IsMethodSpecMarked(ms)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkMethodSpec( ms ) ); // Mark MethodRef or MethodDef and embedded TypeRef and TypeDef tokens IfFailGo(m_pMiniMd->GetMethodSpecRecord(RidFromToken(ms), &pRec)); IfFailGo( Mark(m_pMiniMd->getMethodOfMethodSpec(pRec)) ); IfFailGo(m_pMiniMd->getInstantiationOfMethodSpec(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); ErrExit: return hr; } // HRESULT FilterManager::MarkMethodSpec()
//***************************************************************************** // cascading Mark of an event token //***************************************************************************** HRESULT FilterManager::MarkEvent(mdEvent ev) { HRESULT hr = NOERROR; EventRec *pRec; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if Event is already marked, just return if (m_pMiniMd->GetFilterTable()->IsEventMarked(ev)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkEvent( ev ) ); // mark the event type as well IfFailGo(m_pMiniMd->GetEventRecord(RidFromToken(ev), &pRec)); IfFailGo( Mark(m_pMiniMd->getEventTypeOfEvent(pRec)) ); // Note that we don't need to mark the MethodSemantics. Because the association of MethodSemantics // is marked. The Method column can only store MethodDef, ie the MethodDef has the same parent as // this Event. IfFailGo( MarkCustomAttributesWithParentToken(ev) ); // IfFailGo( MarkDeclSecuritiesWithParentToken(ev) ); ErrExit: return hr; } // HRESULT FilterManager::MarkEvent()
//***************************************************************************** // cascading Mark of a TypeSpec //***************************************************************************** HRESULT FilterManager::MarkTypeSpec(mdTypeSpec ts) { HRESULT hr = NOERROR; TypeSpecRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if TypeRef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsTypeSpecMarked(ts)) goto ErrExit; // To mark the TypeSpec, we will need to mark // all of the embedded TypeRef or TypeDef // IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeSpec( ts ) ); if (pFilter) pFilter->MarkToken(ts); // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->GetTypeSpecRecord(RidFromToken(ts), &pRec)); IfFailGo(m_pMiniMd->getSignatureOfTypeSpec(pRec, &pbSig, &cbSize)); IfFailGo( MarkFieldSignature(pbSig, cbSize, &cbUsed) ); IfFailGo( MarkCustomAttributesWithParentToken(ts) ); ErrExit: return hr; } // HRESULT FilterManager::MarkTypeSpec()
// RegValueHome::GetEnregisteredValue // Gets an enregistered value and returns it to the caller (see EnregisteredValueHome::GetEnregisteredValue // for full header comment) void RegValueHome::GetEnregisteredValue(MemoryRange valueOutBuffer) { UINT_PTR* reg = m_pFrame->GetAddressOfRegister(m_reg1Info.m_kRegNumber); PREFIX_ASSUME(reg != NULL); _ASSERTE(sizeof(*reg) == valueOutBuffer.Size()); memcpy(valueOutBuffer.StartAddress(), reg, sizeof(*reg)); } // RegValueHome::GetEnregisteredValue
//***************************************************************************** // cascading Mark of an TypeDef token //***************************************************************************** HRESULT FilterManager::MarkTypeDef( mdTypeDef td) { HRESULT hr = NOERROR; TypeDefRec *pRec; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); DWORD dwFlags; RID iNester; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if TypeDef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsTypeDefMarked(td)) goto ErrExit; // Mark the TypeDef first to avoid duplicate marking IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef(td) ); if (pFilter) pFilter->MarkToken(td); // We don't need to mark InterfaceImpl but we need to mark the // TypeDef/TypeRef associated with InterfaceImpl. IfFailGo( MarkInterfaceImpls(td) ); // mark the base class IfFailGo(m_pMiniMd->GetTypeDefRecord(RidFromToken(td), &pRec)); IfFailGo( Mark(m_pMiniMd->getExtendsOfTypeDef(pRec)) ); // mark all of the children of this TypeDef IfFailGo( MarkMethodsWithParentToken(td) ); IfFailGo( MarkMethodImplsWithParentToken(td) ); IfFailGo( MarkFieldsWithParentToken(td) ); IfFailGo( MarkEventsWithParentToken(td) ); IfFailGo( MarkPropertiesWithParentToken(td) ); // mark any GenericParam of this TypeDef IfFailGo( MarkGenericParamWithParentToken(td) ); // mark custom value and permission IfFailGo( MarkCustomAttributesWithParentToken(td) ); IfFailGo( MarkDeclSecuritiesWithParentToken(td) ); // If the class is a Nested class mark the parent, recursively. dwFlags = m_pMiniMd->getFlagsOfTypeDef(pRec); if (IsTdNested(dwFlags)) { NestedClassRec *pNestClassRec; IfFailGo(m_pMiniMd->FindNestedClassHelper(td, &iNester)); if (InvalidRid(iNester)) IfFailGo(CLDB_E_RECORD_NOTFOUND); IfFailGo(m_pMiniMd->GetNestedClassRecord(iNester, &pNestClassRec)); IfFailGo(MarkTypeDef(m_pMiniMd->getEnclosingClassOfNestedClass(pNestClassRec))); } ErrExit: return hr; } // HRESULT FilterManager::MarkTypeDef()
//***************************************************************************** // cascading Mark of a TypeRef //***************************************************************************** HRESULT FilterManager::MarkTypeRef(mdTypeRef tr) { HRESULT hr = NOERROR; TOKENMAP *tkMap; mdTypeDef td; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); TypeRefRec *pRec; mdToken parentTk; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if TypeRef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsTypeRefMarked(tr)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeRef( tr ) ); if (pFilter) pFilter->MarkToken(tr); IfFailGo(m_pMiniMd->GetTypeRefRecord(RidFromToken(tr), &pRec)); parentTk = m_pMiniMd->getResolutionScopeOfTypeRef(pRec); if ( RidFromToken(parentTk) ) { IfFailGo( Mark( parentTk ) ); } tkMap = m_pMiniMd->GetTypeRefToTypeDefMap(); PREFIX_ASSUME(tkMap != NULL); td = *(tkMap->Get(RidFromToken(tr))); if ( td != mdTokenNil ) { // TypeRef is referring to a TypeDef within the same module. // Mark the TypeDef as well. // IfFailGo( Mark(td) ); } IfFailGo( MarkCustomAttributesWithParentToken(tr) ); ErrExit: return hr; } // HRESULT FilterManager::MarkTypeRef()
//***************************************************************************** // cascading Mark of a DeclSecurity //***************************************************************************** HRESULT FilterManager::MarkDeclSecurity(mdPermission pe) { HRESULT hr = NOERROR; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); IfFailGo( m_pMiniMd->GetFilterTable()->MarkDeclSecurity( pe ) ); ErrExit: return hr; } // HRESULT FilterManager::MarkDeclSecurity()
//***************************************************************************** // Mark of a new UserString //***************************************************************************** HRESULT FilterManager::MarkNewUserString(mdString str) { HRESULT hr = NOERROR; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); IfFailGo( m_pMiniMd->GetFilterTable()->MarkNewUserString( str ) ); ErrExit: return hr; } // HRESULT FilterManager::MarkUserString()
BOOL PELoader::getCOMHeader(IMAGE_COR20_HEADER **ppCorHeader) { PIMAGE_SECTION_HEADER pSectionHeader; if (m_bIsPE32) { PIMAGE_NT_HEADERS32 pImageHeader; // Get the image header from the image, then get the directory location // of the COM+ header which may or may not be filled out. pImageHeader = (PIMAGE_NT_HEADERS32)Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize); PREFIX_ASSUME(pImageHeader != NULL); pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa32(pImageHeader, (PBYTE)m_hMod, VAL32(pImageHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress), (DWORD)m_FileSizeAligned /* FileLength */); } else { PIMAGE_NT_HEADERS64 pImageHeader; // Get the image header from the image, then get the directory location // of the COM+ header which may or may not be filled out. pImageHeader = (PIMAGE_NT_HEADERS64)Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize); PREFIX_ASSUME(pImageHeader != NULL); pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa64(pImageHeader, (PBYTE)m_hMod, VAL32(pImageHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress), (DWORD)m_FileSizeAligned /* FileLength */); } // If the section header exists, then return ok and the address. if (pSectionHeader) { *ppCorHeader = (IMAGE_COR20_HEADER *) pSectionHeader; return TRUE; } // If there is no COM+ Data in this image, return false. else return FALSE; }
//***************************************************************************** // cascading Mark of a UserString //***************************************************************************** HRESULT FilterManager::MarkUserString(mdString str) { HRESULT hr = NOERROR; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if UserString is already marked, just return if (m_pMiniMd->GetFilterTable()->IsUserStringMarked(str)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkUserString( str ) ); ErrExit: return hr; } // HRESULT FilterManager::MarkUserString()
//***************************************************************************** // cascading Mark of a ParamDef token //***************************************************************************** HRESULT FilterManager::MarkParam(mdParamDef pd) { HRESULT hr; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); IfFailGo( m_pMiniMd->GetFilterTable()->MarkParam( pd ) ); IfFailGo( MarkCustomAttributesWithParentToken(pd) ); // Parameter does not have declsecurity // IfFailGo( MarkDeclSecuritiesWithParentToken(pd) ); ErrExit: return hr; } // HRESULT FilterManager::MarkParam()
//***************************************************************************** // cascading Mark of a CustomAttribute //***************************************************************************** HRESULT FilterManager::MarkCustomAttribute(mdCustomAttribute cv) { HRESULT hr = NOERROR; CustomAttributeRec *pRec; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); IfFailGo( m_pMiniMd->GetFilterTable()->MarkCustomAttribute( cv ) ); // Mark the type (and any family) of the CustomAttribue. IfFailGo(m_pMiniMd->GetCustomAttributeRecord(RidFromToken(cv), &pRec)); IfFailGo( Mark(m_pMiniMd->getTypeOfCustomAttribute(pRec)) ); ErrExit: return hr; } // HRESULT FilterManager::MarkCustomAttribute()
//***************************************************************************** // cascading Mark of a AssemblyRef //***************************************************************************** HRESULT FilterManager::MarkAssemblyRef(mdAssemblyRef ar) { HRESULT hr = NOERROR; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if ModuleREf is already marked, just return if (m_pMiniMd->GetFilterTable()->IsAssemblyRefMarked(ar)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkAssemblyRef( ar ) ); IfFailGo( MarkCustomAttributesWithParentToken(ar) ); ErrExit: return hr; } // HRESULT FilterManager::MarkAssemblyRef()
//***************************************************************************** // Given a namespace and a class name, return the typedef //***************************************************************************** STDMETHODIMP RegMeta::FindTypeDefByName(// S_OK or error. LPCWSTR wzTypeDef, // [IN] Name of the Type. mdToken tkEnclosingClass, // [IN] Enclosing class. mdTypeDef *ptd) // [OUT] Put the TypeDef token here. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW LOG((LOGMD, "{%08x} RegMeta::FindTypeDefByName(%S, 0x%08x, 0x%08x)\n", this, MDSTR(wzTypeDef), tkEnclosingClass, ptd)); START_MD_PERF(); LOCKREAD(); if (wzTypeDef == NULL) IfFailGo(E_INVALIDARG); PREFIX_ASSUME(wzTypeDef != NULL); LPSTR szTypeDef; UTF8STR(wzTypeDef, szTypeDef); LPCSTR szNamespace; LPCSTR szName; _ASSERTE(ptd); _ASSERTE(TypeFromToken(tkEnclosingClass) == mdtTypeDef || TypeFromToken(tkEnclosingClass) == mdtTypeRef || IsNilToken(tkEnclosingClass)); // initialize output parameter *ptd = mdTypeDefNil; ns::SplitInline(szTypeDef, szNamespace, szName); hr = ImportHelper::FindTypeDefByName(&(m_pStgdb->m_MiniMd), szNamespace, szName, tkEnclosingClass, ptd); ErrExit: STOP_MD_PERF(FindTypeDefByName); END_ENTRYPOINT_NOTHROW; return hr; } // STDMETHODIMP RegMeta::FindTypeDefByName()
//***************************************************************************** // cascading Mark of all securities associated with a token //***************************************************************************** HRESULT FilterManager::MarkDeclSecuritiesWithParentToken(mdToken tkParent) { HRESULT hr = NOERROR; RID ridStart, ridEnd; RID index; DeclSecurityRec *pRec; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); if ( m_pMiniMd->IsSorted( TBL_DeclSecurity ) ) { // table is sorted. ridStart to ridEnd - 1 are all DeclSecurity // associated with tkParent // IfFailGo(m_pMiniMd->getDeclSecurityForToken(tkParent, &ridEnd, &ridStart)); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo( m_pMiniMd->GetFilterTable()->MarkDeclSecurity( TokenFromRid(index, mdtPermission) ) ); } } else { // table scan is needed ridStart = 1; ridEnd = m_pMiniMd->getCountDeclSecuritys() + 1; for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(m_pMiniMd->GetDeclSecurityRecord(index, &pRec)); if ( tkParent == m_pMiniMd->getParentOfDeclSecurity(pRec) ) { // This DeclSecurity is associated with tkParent IfFailGo( m_pMiniMd->GetFilterTable()->MarkDeclSecurity( TokenFromRid(index, mdtPermission) ) ); } } } ErrExit: return hr; } // HRESULT FilterManager::MarkDeclSecuritiesWithParentToken()
//***************************************************************************** // cascading Mark of an TypeDef token //***************************************************************************** HRESULT FilterManager::MarkInterfaceImpls( mdTypeDef td) { HRESULT hr = NOERROR; ULONG ridStart, ridEnd; ULONG i; InterfaceImplRec *pRec; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); if ( m_pMiniMd->IsSorted(TBL_InterfaceImpl) ) { IfFailGo(m_pMiniMd->getInterfaceImplsForTypeDef(RidFromToken(td), &ridEnd, &ridStart)); } else { ridStart = 1; ridEnd = m_pMiniMd->getCountInterfaceImpls() + 1; } // Search for the interfaceimpl with the parent of td for (i = ridStart; i < ridEnd; i++) { IfFailGo(m_pMiniMd->GetInterfaceImplRecord(i, &pRec)); if ( td != m_pMiniMd->getClassOfInterfaceImpl(pRec) ) continue; // found an InterfaceImpl associate with td. Mark the interface row and the interfaceimpl type IfFailGo( m_pMiniMd->GetFilterTable()->MarkInterfaceImpl(TokenFromRid(i, mdtInterfaceImpl)) ); IfFailGo( MarkCustomAttributesWithParentToken(TokenFromRid(i, mdtInterfaceImpl)) ); // IfFailGo( MarkDeclSecuritiesWithParentToken(TokenFromRid(i, mdtInterfaceImpl)) ); IfFailGo( Mark(m_pMiniMd->getInterfaceOfInterfaceImpl(pRec)) ); } ErrExit: return hr; } // HRESULT FilterManager::MarkInterfaceImpls()
void AsmMan::EmitDebuggableAttribute(mdToken tkOwner) { mdToken tkCA; Assembler* pAsm = (Assembler*)m_pAssembler; mdToken tkTypeSpec, tkMscorlib, tkParamType; BinStr *pbsSig = new BinStr(); BinStr* bsBytes = new BinStr();; char* szName; tkMscorlib = pAsm->m_fIsMscorlib ? 1 : pAsm->GetAsmRef("mscorlib"); tkTypeSpec = pAsm->ResolveClassRef(tkMscorlib,"System.Diagnostics.DebuggableAttribute",NULL); EmitAssemblyRefs(); // just in case we gained 'mscorlib' AsmRef in GetAsmRef above BOOL fOldStyle = FALSE; if(tkMscorlib == 1) fOldStyle = (m_pAssembly->usVerMajor == 1); else { AsmManAssembly *pAssembly = GetAsmRefByName("mscorlib"); _ASSERTE(pAssembly != NULL); PREFIX_ASSUME(pAssembly != NULL); fOldStyle = (pAssembly->usVerMajor == 1); } bsBytes->appendInt8(1); bsBytes->appendInt8(0); if(fOldStyle) { pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS); corEmitInt(pbsSig,2); pbsSig->appendInt8(ELEMENT_TYPE_VOID); pbsSig->appendInt8(ELEMENT_TYPE_BOOLEAN); pbsSig->appendInt8(ELEMENT_TYPE_BOOLEAN); //New to old: 0x101->(true,true),0x03->(true,false),0x103->(true,true)+warning bsBytes->appendInt8(1); bsBytes->appendInt8((pAsm->m_dwIncludeDebugInfo==0x03 ? 0 : 1)); if(pAsm->m_dwIncludeDebugInfo == 0x103) { report->warn("\nOption /DEBUG=IMPL is invalid for legacy DebuggableAttribute, /DEBUG used.\n" ); } } else { BinStr bsSigArg; char buffer[80]; sprintf_s(buffer,80, "%s%c%s", "System.Diagnostics.DebuggableAttribute", NESTING_SEP, "DebuggingModes" ); tkParamType = pAsm->ResolveClassRef(tkMscorlib,buffer, NULL); bsSigArg.appendInt8(ELEMENT_TYPE_VALUETYPE); unsigned cnt = CorSigCompressToken(tkParamType, bsSigArg.getBuff(5)); bsSigArg.remove(5 - cnt); pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS); corEmitInt(pbsSig,1); pbsSig->appendInt8(ELEMENT_TYPE_VOID); pbsSig->append(&bsSigArg); bsBytes->appendInt32(pAsm->m_dwIncludeDebugInfo); } bsBytes->appendInt8(0); bsBytes->appendInt8(0); szName = new char[16]; strcpy_s(szName,16,".ctor"); tkCA = pAsm->MakeMemberRef(tkTypeSpec,szName,pbsSig); pAsm->DefineCV(new CustomDescr(tkOwner,tkCA,bsBytes)); }
//***************************************************************************** // // Unmark the TypeDef // //***************************************************************************** HRESULT FilterManager::UnmarkTypeDef( mdTypeDef td) { HRESULT hr = NOERROR; TypeDefRec *pTypeDefRec; RID ridStart, ridEnd; RID index; CustomAttributeRec *pCARec; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if TypeDef is already unmarked, just return if (m_pMiniMd->GetFilterTable()->IsTypeDefMarked(td) == false) goto ErrExit; // Mark the TypeDef first to avoid duplicate marking IfFailGo( m_pMiniMd->GetFilterTable()->UnmarkTypeDef(td) ); // Don't need to unmark InterfaceImpl because the TypeDef is unmarked that will make // the InterfaceImpl automatically unmarked. // unmark all of the children of this TypeDef IfFailGo(m_pMiniMd->GetTypeDefRecord(RidFromToken(td), &pTypeDefRec)); // unmark the methods ridStart = m_pMiniMd->getMethodListOfTypeDef(pTypeDefRec); IfFailGo(m_pMiniMd->getEndMethodListOfTypeDef(RidFromToken(td), &ridEnd)); for ( index = ridStart; index < ridEnd; index ++ ) { RID rid; IfFailGo(m_pMiniMd->GetMethodRid(index, &rid)); IfFailGo(m_pMiniMd->GetFilterTable()->UnmarkMethod(TokenFromRid( rid, mdtMethodDef))); } // unmark the fields ridStart = m_pMiniMd->getFieldListOfTypeDef(pTypeDefRec); IfFailGo(m_pMiniMd->getEndFieldListOfTypeDef(RidFromToken(td), &ridEnd)); for ( index = ridStart; index < ridEnd; index ++ ) { RID rid; IfFailGo(m_pMiniMd->GetFieldRid(index, &rid)); IfFailGo(m_pMiniMd->GetFilterTable()->UnmarkField(TokenFromRid( rid, mdtFieldDef))); } // unmark custom value if ( m_pMiniMd->IsSorted( TBL_CustomAttribute ) ) { // table is sorted. ridStart to ridEnd - 1 are all CustomAttribute // associated with tkParent // IfFailGo(m_pMiniMd->getCustomAttributeForToken(td, &ridEnd, &ridStart)); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo( m_pMiniMd->GetFilterTable()->UnmarkCustomAttribute( TokenFromRid(index, mdtCustomAttribute) ) ); } } else { // table scan is needed ridStart = 1; ridEnd = m_pMiniMd->getCountCustomAttributes() + 1; for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(m_pMiniMd->GetCustomAttributeRecord(index, &pCARec)); if ( td == m_pMiniMd->getParentOfCustomAttribute(pCARec) ) { // This CustomAttribute is associated with tkParent IfFailGo( m_pMiniMd->GetFilterTable()->UnmarkCustomAttribute( TokenFromRid(index, mdtCustomAttribute) ) ); } } } // We don't support nested type!! ErrExit: return hr; } // HRESULT FilterManager::UnmarkTypeDef()
//***************************************************************************** // This is used in conjunction with GetClassFromCORPath. See it for details // of the algorithm. One thing to note is that the dir passed here must be // _MAX_PATH size and will be written to by this routine. This routine will // frequently leave junk at the end of the directory string and dir[iLen] may // not be '\0' on return. //***************************************************************************** HRESULT CORPATHService::GetClassFromDir( __in __in_z LPWSTR wzClassname, // Fully qualified class name. __in __in_z LPWSTR dir, // Directory to try. int iLen, // Length of the directory. mdTypeRef tr, // TypeRef to resolve. IMetaModelCommon *pCommon, // Scope in which the TypeRef is defined. REFIID riid, IUnknown **ppIScope, mdTypeDef *ptd) // [OUT] typedef { WCHAR *temp; // Used as a parsing temp. int iTmp; bool bContinue; // Flag to check if the for loop should end. LPWSTR wzSaveClassname = NULL; // Saved offset into the class name string. int iSaveLen = 0; // Saved length of the dir string. PREFIX_ASSUME(iLen >= 0); // Process the class name appending each segment of the name to the // directory until we find a DLL. for(;;) { bContinue = false; if ((temp = wcschr(wzClassname, NAMESPACE_SEPARATOR_WCHAR)) != NULL) { iTmp = (int) (temp - wzClassname); // Check for buffer overflow with correct integer overflow check. // "if (iLen + 5 + iTmp >= _MAX_PATH)" if (ovadd_ge(iLen, iTmp, (_MAX_PATH - 5))) break; // Append the next segment from the class spec to the directory. dir[iLen++] = W('\\'); wcsncpy_s(dir+iLen, iTmp+1, wzClassname, iTmp); iLen += iTmp; dir[iLen] = W('\0'); wzClassname = temp+1; // Check if a directory by this name exists. DWORD iAttrs = WszGetFileAttributes(dir); if (iAttrs != 0xffffffff && (iAttrs & FILE_ATTRIBUTE_DIRECTORY)) { // Next element in the class spec. bContinue = true; iSaveLen = iLen; wzSaveClassname = wzClassname; } } else { iTmp = (int)wcslen(wzClassname); // Check for buffer overflow with correct integer overflow check. // "if (iLen + 5 + iTmp >= _MAX_PATH)" if (ovadd_ge(iLen, iTmp, (_MAX_PATH - 5))) break; dir[iLen++] = W('\\'); wcscpy_s(dir+iLen, iTmp+1, wzClassname); // Advance past the class name. iLen += iTmp; wzClassname += iTmp; } // Try to load the image. wcscpy_s(dir+iLen, 5, W(".dll")); // OpenScope given the dll name and make sure that the class is defined in the module. if ( SUCCEEDED( CORPATHService::FindTypeDef(dir, tr, pCommon, riid, ppIScope, ptd) ) ) { return (S_OK); } // If we didn't find the dll, try some more. while (*wzClassname != W('\0')) { // Find the length of the next class name element. if ((temp = wcschr(wzClassname, NAMESPACE_SEPARATOR_WCHAR)) == NULL) temp = wzClassname + wcslen(wzClassname); iTmp = (int) (temp - wzClassname); // Check for buffer overflow. if ((iLen + 5 + iTmp) >= _MAX_PATH) break; // Tack on ".element.dll" dir[iLen++] = W('.'); wcsncpy_s(dir+iLen, iTmp+1, wzClassname, iTmp); iLen += iTmp; // Try to load the image. wcscpy_s(dir+iLen, 5, W(".dll")); // OpenScope given the dll name and make sure that the class is defined in the module. if ( SUCCEEDED( CORPATHService::FindTypeDef(dir, tr, pCommon, riid, ppIScope, ptd) ) ) { return (S_OK); } // Advance to the next class name element. wzClassname = temp; if (*wzClassname != '\0') ++wzClassname; } if (bContinue) { iLen = iSaveLen; wzClassname = wzSaveClassname; } else { break; } } return S_FALSE; } // CORPATHService::GetClassFromDir
//***************************************************************************** // Walk up to the containing tree and // mark the transitive closure of the root token //***************************************************************************** HRESULT FilterManager::Mark(mdToken tk) { HRESULT hr = NOERROR; mdTypeDef td; // We hard coded System.Object as mdTypeDefNil // The backing Field of property can be NULL as well. if (RidFromToken(tk) == mdTokenNil) goto ErrExit; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); switch ( TypeFromToken(tk) ) { case mdtTypeDef: IfFailGo( MarkTypeDef(tk) ); break; case mdtMethodDef: // Get the typedef containing the MethodDef and mark the whole type IfFailGo( m_pMiniMd->FindParentOfMethodHelper(tk, &td) ); // Global function so only mark the function itself and the typedef. // Don't call MarkTypeDef. That will trigger all of the global methods/fields // marked. // if (IsGlobalTypeDef(td)) { IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef(td) ); IfFailGo( MarkMethod(tk) ); } else { IfFailGo( MarkTypeDef(td) ); } break; case mdtFieldDef: // Get the typedef containing the FieldDef and mark the whole type IfFailGo( m_pMiniMd->FindParentOfFieldHelper(tk, &td) ); if (IsGlobalTypeDef(td)) { IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef(td) ); IfFailGo( MarkField(tk) ); } else { IfFailGo( MarkTypeDef(td) ); } break; case mdtMemberRef: IfFailGo( MarkMemberRef(tk) ); break; case mdtTypeRef: IfFailGo( MarkTypeRef(tk) ); break; case mdtTypeSpec: IfFailGo( MarkTypeSpec(tk) ); break; case mdtSignature: IfFailGo( MarkStandAloneSig(tk) ); break; case mdtModuleRef: IfFailGo( MarkModuleRef(tk) ); break; case mdtAssemblyRef: IfFailGo( MarkAssemblyRef(tk) ); break; case mdtModule: IfFailGo( MarkModule(tk) ); break; case mdtString: IfFailGo( MarkUserString(tk) ); break; case mdtBaseType: // don't need to mark any base type. break; case mdtAssembly: IfFailGo( MarkAssembly(tk) ); break; case mdtMethodSpec: IfFailGo( MarkMethodSpec(tk) ); break; case mdtProperty: case mdtEvent: case mdtParamDef: case mdtInterfaceImpl: default: _ASSERTE(!" unknown type!"); hr = E_INVALIDARG; break; } ErrExit: return hr; } // HRESULT FilterManager::Mark()
//***************************************************************************** // cascading Mark of a method token //***************************************************************************** HRESULT FilterManager::MarkMethod(mdMethodDef md) { HRESULT hr = NOERROR; MethodRec *pRec; ULONG cbSize; ULONG cbUsed; PCCOR_SIGNATURE pbSig; ULONG i, iCount; ImplMapRec *pImplMapRec = NULL; mdMethodDef mdImp; mdModuleRef mrImp; IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); // if MethodDef is already marked, just return if (m_pMiniMd->GetFilterTable()->IsMethodMarked(md)) goto ErrExit; IfFailGo( m_pMiniMd->GetFilterTable()->MarkMethod( md ) ); if (pFilter) pFilter->MarkToken(md); IfFailGo( MarkParamsWithParentToken(md) ); // mark any GenericParam of this Method IfFailGo( MarkGenericParamWithParentToken(md) ); // Walk the signature and mark all of the embedded types IfFailGo(m_pMiniMd->GetMethodRecord(RidFromToken(md), &pRec)); IfFailGo(m_pMiniMd->getSignatureOfMethod(pRec, &pbSig, &cbSize)); IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); iCount = m_pMiniMd->getCountImplMaps(); // loop through all ImplMaps and find the Impl map associated with this method def tokens // and mark the Module Ref tokens in the entries // for (i = 1; i <= iCount; i++) { IfFailGo(m_pMiniMd->GetImplMapRecord(i, &pImplMapRec)); // Get the MethodDef that the impl map is associated with mdImp = m_pMiniMd->getMemberForwardedOfImplMap(pImplMapRec); if (mdImp != md) { // Impl Map entry does not associated with the method def that we are marking continue; } // Get the ModuleRef token mrImp = m_pMiniMd->getImportScopeOfImplMap(pImplMapRec); IfFailGo( Mark(mrImp) ); } // We should not mark all of the memberref with the parent of this methoddef token. // Because not all of the call sites are needed. // // IfFailGo( MarkMemberRefsWithParentToken(md) ); IfFailGo( MarkCustomAttributesWithParentToken(md) ); IfFailGo( MarkDeclSecuritiesWithParentToken(md) ); ErrExit: return hr; } // HRESULT FilterManager::MarkMethod()