Exemple #1
0
FieldDesc *Binder::LookupField(BinderFieldID id)
{
    _ASSERTE(m_pModule != NULL);
    _ASSERTE(id != FIELD__NIL);
    _ASSERTE(id <= m_cFieldRIDs);

    THROWSCOMPLUSEXCEPTION();

    const FieldDescription *d = m_fieldDescriptions + id - 1;

    MethodTable *pMT = FetchClass(d->classID);

    FieldDesc *pFD;

    pFD = pMT->GetClass()->FindField(d->name, d->sig);

    _ASSERTE(pFD != NULL || !"EE expects field to exist");
    _ASSERTE(pFD - pMT->GetClass()->GetFieldDescListRaw() >= 0);
    _ASSERTE(pFD - pMT->GetClass()->GetFieldDescListRaw() < (pMT->GetClass()->GetNumStaticFields() 
                                                             + pMT->GetClass()->GetNumIntroducedInstanceFields()));
    _ASSERTE(pFD - pMT->GetClass()->GetFieldDescListRaw() + 1 < USHRT_MAX);

    USHORT index = (USHORT)(pFD - pMT->GetClass()->GetFieldDescListRaw());

    m_pFieldRIDs[id-1] = index+1;

    // Go ahead and fill in the rid map since we're here anyway
    m_pModule->StoreFieldDef(pFD->GetMemberDef(), pFD);

    return pFD;
}
Exemple #2
0
MethodTable *Binder::LookupClass(BinderClassID id, BOOL fLoad)
{
    _ASSERTE(m_pModule != NULL);
    _ASSERTE(id != CLASS__NIL);
    _ASSERTE(id <= m_cClassRIDs);

    MethodTable *pMT;

    const ClassDescription *d = m_classDescriptions + id - 1;

    NameHandle nh(d->name);

    if (!fLoad)
    {
        nh.SetTokenNotToLoad(tdAllTypes);
        pMT = m_pModule->GetClassLoader()->FindTypeHandle(&nh).AsMethodTable();
        if (pMT == NULL)
            return NULL;
    }
    else
    {
        THROWSCOMPLUSEXCEPTION();

        BEGIN_ENSURE_COOPERATIVE_GC();
        OBJECTREF pThrowable = NULL;
        GCPROTECT_BEGIN(pThrowable);

        pMT = m_pModule->GetClassLoader()->FindTypeHandle(&nh, &pThrowable).AsMethodTable();
        if (pMT == NULL)
        {
            _ASSERTE(!"EE expects class to exist");
            COMPlusThrow(pThrowable);
        }
        GCPROTECT_END();
        END_ENSURE_COOPERATIVE_GC();
    }

    _ASSERTE(pMT->GetModule() == m_pModule);

    mdTypeDef td = pMT->GetClass()->GetCl();

    _ASSERTE(!IsNilToken(td));

    _ASSERTE(RidFromToken(td) <= USHRT_MAX);
    m_pClassRIDs[id-1] = (USHORT) RidFromToken(td);

    m_pModule->StoreTypeDef(td, pMT);

    return pMT;
}
Exemple #3
0
FieldDesc *Binder::RawGetField(BinderFieldID id)
{
    CANNOTTHROWCOMPLUSEXCEPTION();
    _ASSERTE(m_pModule != NULL);
    _ASSERTE(id != FIELD__NIL);
    _ASSERTE(id <= m_cFieldRIDs);
    const FieldDescription *f = m_fieldDescriptions + id - 1;
    MethodTable *pMT = RawGetClass(f->classID);
    _ASSERTE(pMT != NULL);

    // Can't do this because the class may not be restored yet.
    // _ASSERTE(m_pFieldRIDs[id-1]-1 < (pMT->GetClass()->GetNumStaticFields() 
    //                                  + pMT->GetClass()->GetNumIntroducedInstanceFields()));

    FieldDesc *pFD = pMT->GetClass()->GetFieldDescListRaw() + m_pFieldRIDs[id-1]-1;
    _ASSERTE(pFD != NULL);
    return pFD;
}
Exemple #4
0
MethodDesc *Binder::LookupMethod(BinderMethodID id)
{
    _ASSERTE(m_pModule != NULL);
    _ASSERTE(id != METHOD__NIL);
    _ASSERTE(id <= m_cMethodRIDs);

    THROWSCOMPLUSEXCEPTION();

    const MethodDescription *d = m_methodDescriptions + id - 1;

    MethodTable *pMT = FetchClass(d->classID);

    MethodDesc *pMD = pMT->GetClass()->FindMethod(d->name, d->sig);

    _ASSERTE(pMD != NULL || !"EE expects method to exist");

    _ASSERTE(pMD->GetSlot()+1 <= USHRT_MAX);
    m_pMethodRIDs[id-1] = (USHORT) pMD->GetSlot()+1;

    // Go ahead and fill in the rid map since we're here anyway
    m_pModule->StoreMethodDef(pMD->GetMemberDef(), pMD);

    return pMD;
}
Exemple #5
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));
}
Exemple #6
0
HRESULT STDMETHODCALLTYPE ICorDBPrivHelperImpl::CreateManagedObject(
    /*in*/  WCHAR *wszAssemblyName,
    /*in*/  WCHAR *wszModuleName,
    /*in*/  mdTypeDef classToken,
    /*in*/  void *rawData,
    /*out*/ IUnknown **ppUnk)
{
    _ASSERTE(TypeFromToken((mdTypeDef)classToken) == mdtTypeDef);
    _ASSERTE(wszAssemblyName && wszModuleName && ppUnk);

    if (!wszAssemblyName || !wszModuleName || classToken == mdTokenNil) 
        return E_INVALIDARG;

    if (!ppUnk) 
        return E_POINTER;

    HRESULT hr = S_OK;

    BEGINCANNOTTHROWCOMPLUSEXCEPTION();

    // This will set up a managed thread object if one does not already exist
    // for this particular thread.
    Thread* pThread = SetupThread();

    if (pThread == NULL) {
        hr = E_OUTOFMEMORY;
        goto Exit;
    }
    
    // Start up COM Interop
    if (FAILED(hr = QuickCOMStartup()))
        goto Exit;

    {
    // Don't want to be interrupted...
    BOOL fWasGCEnabled = !pThread->PreemptiveGCDisabled();

    if (fWasGCEnabled)
        pThread->DisablePreemptiveGC();
    
    Assembly  *pAssembly;
    Module    *pModule;
     
    if (GetAppDomain() == NULL)
        hr = E_INVALIDARG;
    else
    {
        // Try and load the assembly, given the name provided.
        OBJECTREF pThrowable = NULL;
        GCPROTECT_BEGIN(pThrowable);

        hr = AssemblySpec::LoadAssembly(wszAssemblyName, &pAssembly, &pThrowable);

        GCPROTECT_END();

        if (SUCCEEDED(hr))
        {
            _ASSERTE(pAssembly);

            // Try and load the module, given the name provided.
            hr = pAssembly->GetModuleFromFilename(wszModuleName, &pModule);

            if (SUCCEEDED(hr))
            {
                _ASSERTE(pModule);

                // If the class isn't known,then don't try and create it.
                if (!pModule->GetMDImport()->IsValidToken(classToken))
                    hr = E_INVALIDARG;
                else
                {                    
                    COMPLUS_TRY
                    {
                        OBJECTREF obj = NULL;
                        GCPROTECT_BEGIN(obj);

                        // Now try and get the TypeHandle for the given token
                        NameHandle nameHandle(pModule, classToken);
                        TypeHandle typeHandle =
                            pAssembly->LoadTypeHandle(&nameHandle, &obj);

                        // If an exception was thrown at some point, convert
                        // it to an HRESULT
                        if (obj != NULL)
                            hr = SecurityHelper::MapToHR(obj);

                        // No longer need the object, can be GC'd if desired
                        obj = NULL;

                        if (SUCCEEDED(hr))
                        {
                            _ASSERTE(typeHandle.AsMethodTable());
                            MethodTable *pMT = typeHandle.AsMethodTable();
        
                            if (!pMT->GetClass()->IsValueClass() ||
                                pMT->ContainsPointers())
                                hr = CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS;

                            if (SUCCEEDED(hr))
                            {
                                // Now run the class initialiser
                                if (!pMT->CheckRunClassInit(&obj))
                                    hr = SecurityHelper::MapToHR(obj);

                                // No longer need the object, can be GC'd if
                                // desired
                                obj = NULL;

                                if (SUCCEEDED(hr))
                                {
                                    // If successful, allocate an instance of
                                    // the class
                                    
                                    // This may throw an
                                    // OutOfMemoryException, but the below
                                    // COMPLUS_CATCH should handle it.  If
                                    // the class is a ValueClass, the
                                    // created object will be a boxed
                                    // ValueClass.
                                    obj = AllocateObject(pMT);

                                    // Now create a COM wrapper around
                                    // this object.  Note that this can
                                    // also throw.
                                    *ppUnk = GetComIPFromObjectRef(&obj);
                                    _ASSERTE(ppUnk);

                                    // This is the nasty part. We're gonna
                                    // copy the raw data we're given over
                                    // the new instance of the value
                                    // class...
                                    CopyValueClass(obj->UnBox(), rawData, pMT, obj->GetAppDomain());

                                    // No longer need the object, can be GC'd
                                    // if desired
                                    obj = NULL;
                                }
                            }
                        }

                        GCPROTECT_END();  // obj
                    }
                    COMPLUS_CATCH
                    {
                        // If there's an exception, convert it to an HR
                        hr = SecurityHelper::MapToHR(GETTHROWABLE());
                    }
                    COMPLUS_END_CATCH
                }
            }
        }
    }
    
    if (fWasGCEnabled)
        pThread->EnablePreemptiveGC();

    }
Exit:
    ENDCANNOTTHROWCOMPLUSEXCEPTION();
    return (hr);
}
Exemple #7
0
HRESULT STDMETHODCALLTYPE ICorDBPrivHelperImpl::GetManagedObjectContents(
        /* in */ IUnknown *pObject,
        /* in */ void *rawData,
        /* in */ ULONG32 dataSize)
{
    if (!pObject || !rawData)
        return E_POINTER;

    if (dataSize == 0)
        return E_INVALIDARG;

    HRESULT hr = S_OK;

    BEGINCANNOTTHROWCOMPLUSEXCEPTION();

    // This will set up a managed thread object if one does not already exist
    // for this particular thread.
    Thread* pThread = SetupThread();

    if (pThread == NULL) {
        hr = E_OUTOFMEMORY;
        goto Exit;
    }
    
    {
    // Don't want to be interrupted...
    BOOL fWasGCEnabled = !pThread->PreemptiveGCDisabled();

    if (fWasGCEnabled)
        pThread->DisablePreemptiveGC();
    
    OBJECTREF obj = NULL;
    GCPROTECT_BEGIN(obj);

    COMPLUS_TRY
    {
        // Get the Object out of the IUnknown.
        obj = GetObjectRefFromComIP(pObject);
        
        MethodTable *pMT = obj->GetMethodTable();
    
        if (!pMT->GetClass()->IsValueClass() ||
            pMT->ContainsPointers() ||
            (pMT->GetClass()->GetNumInstanceFieldBytes() != dataSize))
            hr = CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS;

        // This is the nasty part. We're gonna copy the raw data out
        // of the object and pass it out.
        if (SUCCEEDED(hr))
        {
            memcpy(rawData, obj->UnBox(), dataSize);
        }
    }
    COMPLUS_CATCH
    {
        // If there's an exception, convert it to an HR
        hr = SecurityHelper::MapToHR(GETTHROWABLE());
    }
    COMPLUS_END_CATCH

    obj = NULL;
    GCPROTECT_END();  // obj
    
    if (fWasGCEnabled)
        pThread->EnablePreemptiveGC();

    }
Exit:
    ENDCANNOTTHROWCOMPLUSEXCEPTION();
    return (hr);
}