Пример #1
0
HRESULT CeeFileGenWriter::MapTokens(
    CeeGenTokenMapper *pMapper,
    IMetaDataImport *pImport)
{
    mdTypeDef   td;
    mdMethodDef md;
    ULONG       count;
    ULONG       MethodRVA;
    ULONG       codeOffset;
    ULONG       BaseRVA;
    DWORD       dwFlags;
    DWORD       iFlags;
    HCORENUM    hTypeDefs = 0, hEnum = 0;
    WCHAR       rcwName[MAX_CLASSNAME_LENGTH];
    HRESULT     hr;
    CeeSection  TextSection = getTextSection();

    // Ask for the base RVA of the first method in the stream.  All other
    // method RVA's are >= that value, and will give us the raw offset required.

    hr = getMethodRVA(0, &BaseRVA);
    _ASSERTE(SUCCEEDED(hr));
    // do globals first
    while ((hr = pImport->EnumMethods(&hEnum, mdTokenNil, &md, 1, &count)) == S_OK)
    {
        hr = pImport->GetMethodProps(md, NULL,
                    rcwName, lengthof(rcwName), NULL,
                    &dwFlags, NULL, NULL,
                    &MethodRVA, &iFlags);
        _ASSERTE(SUCCEEDED(hr));

        if (MethodRVA == 0 || ((IsMdAbstract(dwFlags) || IsMiInternalCall(iFlags)) ||
                                   (! IsMiIL(iFlags) && ! IsMiOPTIL(iFlags))))
            continue;

        // The raw offset of the method is the RVA in the image minus
        // the first method in the text section.
        codeOffset = MethodRVA - BaseRVA;
        hr = MapTokensForMethod(pMapper,
                    (BYTE *) TextSection.computePointer(codeOffset),
                    rcwName);
        if (FAILED(hr))
            goto ErrExit;
    }
    if (hEnum) pImport->CloseEnum(hEnum);
    hEnum = 0;

    while ((hr = pImport->EnumTypeDefs(&hTypeDefs, &td, 1, &count)) == S_OK)
    {
        while ((hr = pImport->EnumMethods(&hEnum, td, &md, 1, &count)) == S_OK)
        {
            hr = pImport->GetMethodProps(md, NULL,
                        rcwName, lengthof(rcwName), NULL,
                        &dwFlags, NULL, NULL,
                        &MethodRVA, &iFlags);
            _ASSERTE(SUCCEEDED(hr));

            if (MethodRVA == 0 || ((IsMdAbstract(dwFlags) || IsMiInternalCall(iFlags)) ||
                                   (! IsMiIL(iFlags) && ! IsMiOPTIL(iFlags))))
                continue;


            // The raw offset of the method is the RVA in the image minus
            // the first method in the text section.
            codeOffset = MethodRVA - BaseRVA;
            hr = MapTokensForMethod(pMapper,
                        (BYTE *) TextSection.computePointer(codeOffset),
                        rcwName);
            if (FAILED(hr))
                goto ErrExit;
        }

        if (hEnum) pImport->CloseEnum(hEnum);
        hEnum = 0;
    }

ErrExit:
    if (hTypeDefs) pImport->CloseEnum(hTypeDefs);
    if (hEnum) pImport->CloseEnum(hEnum);
    return (hr);
}
Пример #2
0
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));
}