//***************************************************************************** // Set the cached Internal interface. This function will return an Error is the // current cached internal interface is not empty and trying set a non-empty internal // interface. One RegMeta will only associated // with one Internal Object. Unless we have bugs somewhere else. It will QI on the // IUnknown for the IMDInternalImport. If this failed, error will be returned. // Note: Caller should take a write lock // // This does addref the importer (the public and private importers maintain // weak references to each other). // // Implements internal API code:IMetaDataHelper::SetCachedInternalInterface. //***************************************************************************** HRESULT RegMeta::SetCachedInternalInterface(IUnknown *pUnk) { HRESULT hr = NOERROR; IMDInternalImport *pInternal = NULL; if (pUnk) { if (m_pInternalImport) { _ASSERTE(!"Bad state!"); } IfFailRet( pUnk->QueryInterface(IID_IMDInternalImport, (void **) &pInternal) ); // Should be non-null _ASSERTE(pInternal); m_pInternalImport = pInternal; // We don't want to add ref the internal interface, so undo the AddRef() from the QI. pInternal->Release(); } else { // Internal interface is going away before the public interface. Take ownership on the // reader writer lock. m_fOwnSem = true; m_pInternalImport = NULL; } return hr; } // RegMeta::SetCachedInternalInterface
void DisassembleToken(IMetaDataImport *i, DWORD token) { HRESULT hr; switch (TypeFromToken(token)) { default: printf("<unknown token type %08x>", TypeFromToken(token)); break; case mdtTypeDef: { ULONG cLen; WCHAR szName[50]; hr = i->GetTypeDefProps(token, szName, 49, &cLen, NULL, NULL); if (FAILED(hr)) StringCchCopyW(szName, COUNTOF(szName), L"<unknown type def>"); printf("%S", szName); } break; case mdtTypeRef: { ULONG cLen; WCHAR szName[50]; hr = i->GetTypeRefProps(token, NULL, szName, 49, &cLen); if (FAILED(hr)) StringCchCopyW(szName, COUNTOF(szName), L"<unknown type ref>"); printf("%S", szName); } break; case mdtFieldDef: { ULONG cLen; WCHAR szFieldName[50]; WCHAR szClassName[50]; mdTypeDef mdClass; hr = i->GetFieldProps(token, &mdClass, szFieldName, 49, &cLen, NULL, NULL, NULL, NULL, NULL, NULL); if (FAILED(hr)) StringCchCopyW(szFieldName, COUNTOF(szFieldName), L"<unknown field def>"); hr = i->GetTypeDefProps(mdClass, szClassName, 49, &cLen, NULL, NULL); if (FAILED(hr)) StringCchCopyW(szClassName, COUNTOF(szClassName), L"<unknown type def>"); printf("%S::%S", szClassName, szFieldName); } break; case mdtMethodDef: { ULONG cLen; WCHAR szFieldName[50]; WCHAR szClassName[50]; mdTypeDef mdClass; hr = i->GetMethodProps(token, &mdClass, szFieldName, 49, &cLen, NULL, NULL, NULL, NULL, NULL); if (FAILED(hr)) StringCchCopyW(szFieldName, COUNTOF(szFieldName), L"<unknown method def>"); hr = i->GetTypeDefProps(mdClass, szClassName, 49, &cLen, NULL, NULL); if (FAILED(hr)) StringCchCopyW(szClassName, COUNTOF(szClassName), L"<unknown type def>"); printf("%S::%S", szClassName, szFieldName); } break; case mdtMemberRef: { mdTypeRef cr = mdTypeRefNil; LPWSTR pMemberName; WCHAR memberName[50]; ULONG memberNameLen; hr = i->GetMemberRefProps(token, &cr, memberName, 49, &memberNameLen, NULL, NULL); if (FAILED(hr)) { pMemberName = L"<unknown member ref>"; } else pMemberName = memberName; ULONG cLen; WCHAR szName[50]; if(TypeFromToken(cr) == mdtTypeRef) { if (FAILED(i->GetTypeRefProps(cr, NULL, szName, 50, &cLen))) { StringCchCopyW(szName, COUNTOF(szName), L"<unknown type ref>"); } } else if(TypeFromToken(cr) == mdtTypeDef) { if (FAILED(i->GetTypeDefProps(cr, szName, 49, &cLen, NULL, NULL))) { StringCchCopyW(szName, COUNTOF(szName), L"<unknown type def>"); } } else if(TypeFromToken(cr) == mdtTypeSpec) { IMDInternalImport *pIMDI = NULL; if (SUCCEEDED(GetMDInternalFromImport(i, &pIMDI))) { CQuickBytes out; ULONG cSig; PCCOR_SIGNATURE sig; if (FAILED(pIMDI->GetSigFromToken(cr, &cSig, &sig))) { StringCchCopyW(szName, COUNTOF(szName), L"<Invalid record>"); } else { PrettyPrintType(sig, &out, pIMDI); MultiByteToWideChar (CP_ACP, 0, asString(&out), -1, szName, 50); } pIMDI->Release(); } else { StringCchCopyW(szName, COUNTOF(szName), L"<unknown type spec>"); } } else { StringCchCopyW(szName, COUNTOF(szName), L"<unknown type token>"); } printf("%S::%S ", szName, pMemberName); } break; } }
void Binder::CheckMscorlib() { const FieldOffsetCheck *pOffsets = MscorlibFieldOffsets; while (pOffsets->fieldID != FIELD__NIL) { FieldDesc *pFD = g_Mscorlib.FetchField(pOffsets->fieldID); DWORD offset = pFD->GetOffset(); if (!pFD->GetMethodTableOfEnclosingClass()->IsValueClass()) offset += sizeof(ObjHeader); _ASSERTE(offset == pOffsets->expectedOffset && "Managed class field offset does not match unmanaged class field offset"); pOffsets++; } const ClassSizeCheck *pSizes = MscorlibClassSizes; while (pSizes->classID != CLASS__NIL) { MethodTable *pMT = g_Mscorlib.FetchClass(pSizes->classID); DWORD size = pMT->GetClass()->GetNumInstanceFieldBytes(); DWORD expected = pSizes->expectedSize - sizeof(void*); _ASSERTE(size == expected && "Managed object size does not match unmanaged object size"); pSizes++; } // check the consistency of BCL and VM // note: it is not enabled by default because of it is time consuming and // changes the bootstrap sequence of the EE if (!g_pConfig->GetConfigDWORD(L"ConsistencyCheck", 0)) return; // // VM referencing BCL (mscorlib.h) // for (BinderClassID cID = (BinderClassID) 1; cID <= g_Mscorlib.m_cClassRIDs; cID = (BinderClassID) (cID + 1)) { if (g_Mscorlib.GetClassName(cID) != NULL) // Allow for CorSigElement entries with no classes g_Mscorlib.FetchClass(cID); } for (BinderMethodID mID = (BinderMethodID) 1; mID <= g_Mscorlib.m_cMethodRIDs; mID = (BinderMethodID) (mID + 1)) g_Mscorlib.FetchMethod(mID); for (BinderFieldID fID = (BinderFieldID) 1; fID <= g_Mscorlib.m_cFieldRIDs; fID = (BinderFieldID) (fID + 1)) g_Mscorlib.FetchField(fID); // // BCL referencing VM (ecall.cpp) // HRESULT hr = S_OK; Module *pModule = g_Mscorlib.m_pModule; IMDInternalImport *pInternalImport = pModule->GetMDImport(); HENUMInternal hEnum; // for all methods... IfFailGo(pInternalImport->EnumAllInit(mdtMethodDef, &hEnum)); for (;;) { mdTypeDef td; mdTypeDef tdClass; DWORD dwImplFlags; if (!pInternalImport->EnumNext(&hEnum, &td)) break; pInternalImport->GetMethodImplProps(td, NULL, &dwImplFlags); // ... that are internal calls ... if (!IsMiInternalCall(dwImplFlags)) continue; IfFailGo(pInternalImport->GetParentToken(td, &tdClass)); NameHandle className(pModule, tdClass); TypeHandle type; type = pModule->GetClassLoader()->LoadTypeHandle(&className, RETURN_ON_ERROR, FALSE); if (type.IsNull()) { LPCUTF8 pszName = pInternalImport->GetNameOfMethodDef(tdClass); OutputDebugStringA(pszName); OutputDebugStringA("\n"); _ASSERTE(false); } MethodDesc *pMD = type.AsMethodTable()->GetClass()->FindMethod(td);; _ASSERTE(pMD); // ... check that the method is in the fcall table. if (GetIDForMethod(pMD) == 0xffff) { LPCUTF8 pszName = pInternalImport->GetNameOfMethodDef(td); OutputDebugStringA(pszName); OutputDebugStringA("\n"); _ASSERTE(false); } } pInternalImport->EnumClose(&hEnum); ErrExit: _ASSERTE(SUCCEEDED(hr)); }
//--------------------------------------------------------------------------------------- // COR_ILMETHOD_DECODER::COR_ILMETHOD_DECODER( COR_ILMETHOD * header, void * pInternalImport, DecoderStatus * wbStatus) { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_FORBID_FAULT; // Can't put contract because of SEH // CONTRACTL // { // NOTHROW; // GC_NOTRIGGER; // FORBID_FAULT; // } // CONTRACTL_END bool fErrorInInit = false; struct Param { COR_ILMETHOD_DECODER * pThis; COR_ILMETHOD * header; } param; param.pThis = this; param.header = header; PAL_TRY(Param *, pParam, ¶m) { // Decode the COR header into a more convenient form DecoderInit(pParam->pThis, pParam->header); } PAL_EXCEPT_FILTER(FilterAllExceptions) { fErrorInInit = true; Code = 0; SetLocalVarSigTok(0); if (wbStatus != NULL) { *wbStatus = FORMAT_ERROR; } } PAL_ENDTRY if (fErrorInInit) { return; } // If there is a local variable sig, fetch it into 'LocalVarSig' if ((GetLocalVarSigTok() != 0) && (pInternalImport != NULL)) { IMDInternalImport * pMDI = reinterpret_cast<IMDInternalImport *>(pInternalImport); if (wbStatus != NULL) { if ((!pMDI->IsValidToken(GetLocalVarSigTok())) || (TypeFromToken(GetLocalVarSigTok()) != mdtSignature) || (RidFromToken(GetLocalVarSigTok()) == 0)) { *wbStatus = FORMAT_ERROR; // failure bad local variable signature token return; } } if (FAILED(pMDI->GetSigFromToken(GetLocalVarSigTok(), &cbLocalVarSig, &LocalVarSig))) { // Failure bad local variable signature token if (wbStatus != NULL) { *wbStatus = FORMAT_ERROR; } LocalVarSig = NULL; cbLocalVarSig = 0; return; } if (wbStatus != NULL) { if (FAILED(validateTokenSig(GetLocalVarSigTok(), LocalVarSig, cbLocalVarSig, 0, pMDI)) || (*LocalVarSig != IMAGE_CEE_CS_CALLCONV_LOCAL_SIG)) { *wbStatus = VERIFICATION_ERROR; // failure validating local variable signature return; } } } if (wbStatus != NULL) { *wbStatus = SUCCESS; } } // COR_ILMETHOD_DECODER::COR_ILMETHOD_DECODER