Beispiel #1
0
    // will return exact size which will match the size returned by Emit
    unsigned __stdcall SectEH_SizeExact(unsigned ehCount, IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* clauses)
    {
        if (ehCount == 0)
            return(0);

        unsigned smallSize = COR_ILMETHOD_SECT_EH_SMALL::Size(ehCount);
        if (smallSize > COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE)
            return(COR_ILMETHOD_SECT_EH_FAT::Size(ehCount));
        for (unsigned i = 0; i < ehCount; i++) {
            COR_ILMETHOD_SECT_EH_CLAUSE_FAT* fatClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)&clauses[i];
            if (fatClause->GetTryOffset() > 0xFFFF ||
                    fatClause->GetTryLength() > 0xFF ||
                    fatClause->GetHandlerOffset() > 0xFFFF ||
                    fatClause->GetHandlerLength() > 0xFF) {
                return(COR_ILMETHOD_SECT_EH_FAT::Size(ehCount));
            }
        }
        return smallSize;
    }
Beispiel #2
0
// This method computes the same result as COR_ILMETHOD_SECT_EH::Size(...) but
// does so in a way that detects overflow if the number of exception clauses is
// too great (in which case an OOM exception is thrown). We do this rather than
// modifying COR_ILMETHOD_SECT_EH::Size because that routine is published in the
// SDK and can't take breaking changes and because the overflow support (and
// exception mechanism) we're using is only available to the VM.
UINT32 ExceptionHandlingSize(unsigned uNumExceptions, COR_ILMETHOD_SECT_EH_CLAUSE_FAT* pClauses)
{
    STANDARD_VM_CONTRACT;

    if (uNumExceptions == 0)
        return 0;

    // Speculatively compute the size for the slim version of the header.
    S_UINT32 uSmallSize = S_UINT32(sizeof(COR_ILMETHOD_SECT_EH_SMALL)) +
        (S_UINT32(sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL)) * (S_UINT32(uNumExceptions - 1)));

    if (uSmallSize.IsOverflow())
        COMPlusThrowOM();

    if (uSmallSize.Value() > COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE)
        goto FatCase;

    // Check whether any of the clauses won't fit in the slim case.
    for (UINT32 i = 0; i < uNumExceptions; i++) {
        COR_ILMETHOD_SECT_EH_CLAUSE_FAT* pFatClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)&pClauses[i];
        if (pFatClause->GetTryOffset() > 0xFFFF ||
            pFatClause->GetTryLength() > 0xFF ||
            pFatClause->GetHandlerOffset() > 0xFFFF ||
            pFatClause->GetHandlerLength() > 0xFF) {
            goto FatCase;
        }
    }

    _ASSERTE(uSmallSize.Value() == COR_ILMETHOD_SECT_EH::Size(uNumExceptions, pClauses));
    return uSmallSize.Value();

 FatCase:
    S_UINT32 uFatSize = S_UINT32(sizeof(COR_ILMETHOD_SECT_EH_FAT)) +
        (S_UINT32(sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT)) * (S_UINT32(uNumExceptions - 1)));

    if (uFatSize.IsOverflow())
        COMPlusThrowOM();

    _ASSERTE(uFatSize.Value() == COR_ILMETHOD_SECT_EH::Size(uNumExceptions, pClauses));
    return uFatSize.Value();
}
Beispiel #3
0
    /* static */
    IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* __stdcall SectEH_EHClause(void *pSectEH, unsigned idx, IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* buff)
    {
        if (((COR_ILMETHOD_SECT_EH *)pSectEH)->IsFat())
            return(&(((COR_ILMETHOD_SECT_EH *)pSectEH)->Fat.Clauses[idx]));

        COR_ILMETHOD_SECT_EH_CLAUSE_FAT* fatClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)buff;
        COR_ILMETHOD_SECT_EH_CLAUSE_SMALL* smallClause = (COR_ILMETHOD_SECT_EH_CLAUSE_SMALL*)&((COR_ILMETHOD_SECT_EH *)pSectEH)->Small.Clauses[idx];

        // mask to remove sign extension - cast just wouldn't work
        fatClause->SetFlags((CorExceptionFlag)(smallClause->GetFlags()&0x0000ffff));
        fatClause->SetClassToken(smallClause->GetClassToken());
        fatClause->SetTryOffset(smallClause->GetTryOffset());
        fatClause->SetTryLength(smallClause->GetTryLength());
        fatClause->SetHandlerLength(smallClause->GetHandlerLength());
        fatClause->SetHandlerOffset(smallClause->GetHandlerOffset());
        return(buff);
    }
Beispiel #4
0
    // emit the section (best format);
    unsigned __stdcall SectEH_Emit(unsigned size, unsigned ehCount,
                                   IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* clauses,
                                   BOOL moreSections, BYTE* outBuff,
                                   ULONG* ehTypeOffsets)
    {
        if (size == 0)
            return(0);

        _ASSERTE((((size_t) outBuff) & 3) == 0);               // header is dword aligned
        BYTE* origBuff = outBuff;
        if (ehCount <= 0)
            return 0;

        // Initialize the ehTypeOffsets array.
        if (ehTypeOffsets)
        {
            for (unsigned int i = 0; i < ehCount; i++)
                ehTypeOffsets[i] = (ULONG) -1;
        }

        if (COR_ILMETHOD_SECT_EH_SMALL::Size(ehCount) < COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE) {
            COR_ILMETHOD_SECT_EH_SMALL* EHSect = (COR_ILMETHOD_SECT_EH_SMALL*) outBuff;
            unsigned i;
            for (i = 0; i < ehCount; i++) {
                COR_ILMETHOD_SECT_EH_CLAUSE_FAT* fatClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)&clauses[i];
                if (fatClause->GetTryOffset() > 0xFFFF ||
                        fatClause->GetTryLength() > 0xFF ||
                        fatClause->GetHandlerOffset() > 0xFFFF ||
                        fatClause->GetHandlerLength() > 0xFF) {
                    break;  // fall through and generate as FAT
                }
                _ASSERTE((fatClause->GetFlags() & ~0xFFFF) == 0);
                _ASSERTE((fatClause->GetTryOffset() & ~0xFFFF) == 0);
                _ASSERTE((fatClause->GetTryLength() & ~0xFF) == 0);
                _ASSERTE((fatClause->GetHandlerOffset() & ~0xFFFF) == 0);
                _ASSERTE((fatClause->GetHandlerLength() & ~0xFF) == 0);

                COR_ILMETHOD_SECT_EH_CLAUSE_SMALL* smallClause = (COR_ILMETHOD_SECT_EH_CLAUSE_SMALL*)&EHSect->Clauses[i];
                smallClause->SetFlags((CorExceptionFlag) fatClause->GetFlags());
                smallClause->SetTryOffset(fatClause->GetTryOffset());
                smallClause->SetTryLength(fatClause->GetTryLength());
                smallClause->SetHandlerOffset(fatClause->GetHandlerOffset());
                smallClause->SetHandlerLength(fatClause->GetHandlerLength());
                smallClause->SetClassToken(fatClause->GetClassToken());
            }
            if (i >= ehCount) {
                // if actually got through all the clauses and they are small enough
                EHSect->Kind = CorILMethod_Sect_EHTable;
                if (moreSections)
                    EHSect->Kind |= CorILMethod_Sect_MoreSects;
                EHSect->DataSize = EHSect->Size(ehCount);
                EHSect->Reserved = 0;
                _ASSERTE(EHSect->DataSize == EHSect->Size(ehCount)); // make sure didn't overflow
                outBuff = (BYTE*) &EHSect->Clauses[ehCount];
                // Set the offsets for the exception type tokens.
                if (ehTypeOffsets)
                {
                    for (i = 0; i < ehCount; i++) {
                        COR_ILMETHOD_SECT_EH_CLAUSE_SMALL* smallClause = (COR_ILMETHOD_SECT_EH_CLAUSE_SMALL*)&EHSect->Clauses[i];
                        if (smallClause->GetFlags() == COR_ILEXCEPTION_CLAUSE_NONE)
                        {
                            _ASSERTE(! IsNilToken(smallClause->GetClassToken()));
                            ehTypeOffsets[i] = (ULONG)((BYTE *)&smallClause->ClassToken - origBuff);
                        }
                    }
                }
                return(size);
            }
        }
        // either total size too big or one of constituent elements too big (eg. offset or length)
        COR_ILMETHOD_SECT_EH_FAT* EHSect = (COR_ILMETHOD_SECT_EH_FAT*) outBuff;
        EHSect->SetKind(CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat);
        if (moreSections)
            EHSect->SetKind(EHSect->GetKind() | CorILMethod_Sect_MoreSects);

        EHSect->SetDataSize(EHSect->Size(ehCount));
        memcpy(EHSect->Clauses, clauses, ehCount * sizeof(COR_ILMETHOD_SECT_EH_CLAUSE_FAT));
        outBuff = (BYTE*) &EHSect->Clauses[ehCount];
        _ASSERTE(&origBuff[size] == outBuff);
        // Set the offsets for the exception type tokens.
        if (ehTypeOffsets)
        {
            for (unsigned int i = 0; i < ehCount; i++) {
                COR_ILMETHOD_SECT_EH_CLAUSE_FAT* fatClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)&EHSect->Clauses[i];
                if (fatClause->GetFlags() == COR_ILEXCEPTION_CLAUSE_NONE)
                {
                    _ASSERTE(! IsNilToken(fatClause->GetClassToken()));
                    ehTypeOffsets[i] = (ULONG)((BYTE *)&fatClause->ClassToken - origBuff);
                }
            }
        }
        return(size);
    }