HRESULT ProfilerInfoShim::GetILFunctionBody(ModuleID moduleId, mdMethodDef methodId, LPCBYTE *ppMethodHeader, ULONG *pcbMethodSize)
{
	HRESULT result = m_wrappedInfo->GetILFunctionBody(moduleId, methodId, ppMethodHeader, pcbMethodSize);
	if (result != S_OK)
		return result;

	IMAGE_COR_ILMETHOD *method = (IMAGE_COR_ILMETHOD *)*ppMethodHeader;
	COR_ILMETHOD_FAT *fatImage = (COR_ILMETHOD_FAT *)&method->Fat;
	UINT codeSize = 0;
	BYTE *codeBytes = NULL;
	if (fatImage->IsFat())
	{
		codeSize = fatImage->GetCodeSize();
		codeBytes = fatImage->GetCode();
	}
	else
	{
		COR_ILMETHOD_TINY *tinyImage = (COR_ILMETHOD_TINY *)&method->Tiny;
		codeSize = tinyImage->GetCodeSize();
		codeBytes = tinyImage->GetCode();
	}

	fprintf(m_stream, "Getting IL for ");
	IMetaDataImport2 *metadata = NULL;
	PrintMethodInfo(m_wrappedInfo, moduleId, methodId, m_stream, &metadata);

	if (codeBytes != NULL)
		PrintILMethodBody(m_wrappedInfo, metadata, moduleId, m_stream, codeBytes, codeSize);
	fflush(m_stream);

	metadata->Release();

	return result;
}
Esempio n. 2
0
    // emit the header (bestFormat) return amount emitted
    unsigned __stdcall IlmethodEmit(unsigned size, COR_ILMETHOD_FAT* header,
                                    BOOL moreSections, BYTE* outBuff)
    {
#ifdef _DEBUG
        BYTE* origBuff = outBuff;
#endif
        if (size == 1) {
            // Tiny format
            *outBuff++ = (BYTE) (CorILMethod_TinyFormat | (header->GetCodeSize() << 2));
        }
        else {
            // Fat format
            _ASSERTE((((size_t) outBuff) & 3) == 0);               // header is dword aligned
            COR_ILMETHOD_FAT* fatHeader = (COR_ILMETHOD_FAT*) outBuff;
            outBuff += sizeof(COR_ILMETHOD_FAT);
            *fatHeader = *header;
            fatHeader->SetFlags(fatHeader->GetFlags() | CorILMethod_FatFormat);
            _ASSERTE((fatHeader->GetFlags() & CorILMethod_FormatMask) == CorILMethod_FatFormat);
            if (moreSections)
                fatHeader->SetFlags(fatHeader->GetFlags() | CorILMethod_MoreSects);
            fatHeader->SetSize(sizeof(COR_ILMETHOD_FAT) / 4);
        }
        _ASSERTE(&origBuff[size] == outBuff);
        return(size);
    }
Esempio n. 3
0
/// <summary>Read the full method from the supplied buffer.</summary>
void Method::ReadMethod(IMAGE_COR_ILMETHOD* pMethod)
{
    BYTE* pCode;
    COR_ILMETHOD_FAT* fatImage = (COR_ILMETHOD_FAT*)&pMethod->Fat;
    if(!fatImage->IsFat())
    {
        ATLTRACE(_T("TINY"));
        COR_ILMETHOD_TINY* tinyImage = (COR_ILMETHOD_TINY*)&pMethod->Tiny;
        m_header.CodeSize = tinyImage->GetCodeSize();
        pCode = tinyImage->GetCode();
        ATLTRACE(_T("TINY(%X) => (%d + 1) : %d"), m_header.CodeSize, m_header.CodeSize, m_header.MaxStack);
    }
    else
    {
        memcpy(&m_header, pMethod, fatImage->Size * sizeof(DWORD));
        pCode = fatImage->GetCode();
        ATLTRACE(_T("FAT(%X) => (%d + 12) : %d"), m_header.CodeSize, m_header.CodeSize, m_header.MaxStack);
    }
    SetBuffer(pCode);
    ReadBody();
}
Esempio n. 4
0
// SetMethodIL -- This function will create a method within the class
void QCALLTYPE COMDynamicWrite::SetMethodIL(QCall::ModuleHandle pModule,
                                            INT32 tk,
                                            BOOL fIsInitLocal,
                                            LPCBYTE pBody,
                                            INT32 cbBody,
                                            LPCBYTE pLocalSig,
                                            INT32 sigLength,
                                            UINT16 maxStackSize,                                        
                                            ExceptionInstance * pExceptions,
                                            INT32 numExceptions,
                                            INT32 * pTokenFixups,
                                            INT32 numTokenFixups)
{
    QCALL_CONTRACT;
    
    BEGIN_QCALL;    

    RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
    _ASSERTE(pRCW);

    _ASSERTE(pLocalSig);

    PCCOR_SIGNATURE pcSig = (PCCOR_SIGNATURE)pLocalSig;
    _ASSERTE(*pcSig == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG);

    mdSignature pmLocalSigToken;
    if (sigLength==2 && pcSig[0]==0 && pcSig[1]==0) 
    { 
        //This is an empty local variable sig
        pmLocalSigToken=0;
    } 
    else 
    {
        IfFailThrow(pRCW->GetEmitter()->GetTokenFromSig( pcSig, sigLength, &pmLocalSigToken));
    }

    COR_ILMETHOD_FAT fatHeader; 

    // set fatHeader.Flags to CorILMethod_InitLocals if user wants to zero init the stack frame.
    //
    fatHeader.SetFlags(fIsInitLocal ? CorILMethod_InitLocals : 0);
    fatHeader.SetMaxStack(maxStackSize);
    fatHeader.SetLocalVarSigTok(pmLocalSigToken);
    fatHeader.SetCodeSize(cbBody);  
    bool moreSections            = (numExceptions != 0);    

    unsigned codeSizeAligned     = fatHeader.GetCodeSize();  
    if (moreSections)   
        codeSizeAligned = AlignUp(codeSizeAligned, 4); // to insure EH section aligned 
    unsigned headerSize          = COR_ILMETHOD::Size(&fatHeader, numExceptions != 0);    

    //Create the exception handlers.
    CQuickArray<COR_ILMETHOD_SECT_EH_CLAUSE_FAT> clauses;
    if (numExceptions > 0) 
    {
        clauses.AllocThrows(numExceptions);

        for (int i = 0; i < numExceptions; i++)
        {
            clauses[i].SetFlags((CorExceptionFlag)(pExceptions[i].m_type));
            clauses[i].SetTryOffset(pExceptions[i].m_start);
            clauses[i].SetTryLength(pExceptions[i].m_end - pExceptions[i].m_start);
            clauses[i].SetHandlerOffset(pExceptions[i].m_handle);
            clauses[i].SetHandlerLength(pExceptions[i].m_handleEnd - pExceptions[i].m_handle);
            if (pExceptions[i].m_type == COR_ILEXCEPTION_CLAUSE_FILTER)
            {
                clauses[i].SetFilterOffset(pExceptions[i].m_filterOffset);
            }
            else if (pExceptions[i].m_type!=COR_ILEXCEPTION_CLAUSE_FINALLY)
            {
                clauses[i].SetClassToken(pExceptions[i].m_exceptionType);
            }
            else
            {
                clauses[i].SetClassToken(mdTypeRefNil);
            }
        }
    }
    
    unsigned ehSize          = ExceptionHandlingSize(numExceptions, clauses.Ptr());
    S_UINT32 totalSizeSafe   = S_UINT32(headerSize) + S_UINT32(codeSizeAligned) + S_UINT32(ehSize); 
    if (totalSizeSafe.IsOverflow())
        COMPlusThrowOM();
    UINT32 totalSize = totalSizeSafe.Value();
    ICeeGen* pGen = pRCW->GetCeeGen();
    BYTE* buf = NULL;
    ULONG methodRVA;
    pGen->AllocateMethodBuffer(totalSize, &buf, &methodRVA);    
    if (buf == NULL)
        COMPlusThrowOM();
        
    _ASSERTE(buf != NULL);
    _ASSERTE((((size_t) buf) & 3) == 0);   // header is dword aligned  

#ifdef _DEBUG
    BYTE* endbuf = &buf[totalSize];
#endif

    BYTE * startBuf = buf;

    // Emit the header  
    buf += COR_ILMETHOD::Emit(headerSize, &fatHeader, moreSections, buf);   

    //Emit the code    
    //The fatHeader.CodeSize is a workaround to see if we have an interface or an
    //abstract method.  Force enough verification in native to ensure that
    //this is true.
    if (fatHeader.GetCodeSize()!=0) {
        memcpy(buf, pBody, fatHeader.GetCodeSize());
    }
    buf += codeSizeAligned;
        
    // Emit the eh  
    CQuickArray<ULONG> ehTypeOffsets;
    if (numExceptions > 0)
    {
        // Allocate space for the the offsets to the TypeTokens in the Exception headers
        // in the IL stream.
        ehTypeOffsets.AllocThrows(numExceptions);

        // Emit the eh.  This will update the array ehTypeOffsets with offsets
        // to Exception type tokens.  The offsets are with reference to the
        // beginning of eh section.
        buf += COR_ILMETHOD_SECT_EH::Emit(ehSize, numExceptions, clauses.Ptr(),
                                          false, buf, ehTypeOffsets.Ptr());
    }   
    _ASSERTE(buf == endbuf);    

    //Get the IL Section.
    HCEESECTION ilSection;    
    IfFailThrow(pGen->GetIlSection(&ilSection));

    // Token Fixup data...
    ULONG ilOffset = methodRVA + headerSize;

    //Add all of the relocs based on the info which I saved from ILGenerator.

    //Add the Token Fixups
    for (int iTokenFixup=0; iTokenFixup<numTokenFixups; iTokenFixup++)
    {
        IfFailThrow(pGen->AddSectionReloc(ilSection, pTokenFixups[iTokenFixup] + ilOffset, ilSection, srRelocMapToken));
    }

    // Add token fixups for exception type tokens.
    for (int iException=0; iException < numExceptions; iException++)
    {
        if (ehTypeOffsets[iException] != (ULONG) -1)
        {
            IfFailThrow(pGen->AddSectionReloc(
                                             ilSection,
                                             ehTypeOffsets[iException] + codeSizeAligned + ilOffset,
                                             ilSection, srRelocMapToken));
        }
    }

    //nasty interface workaround.  What does this mean for abstract methods?
    if (fatHeader.GetCodeSize() != 0)
    {
        // add the starting address of the il blob to the il blob hash table
        // we need to find this information from out of process for debugger inspection
        // APIs so we have to store this information where we can get it later
        pModule->SetDynamicIL(mdToken(tk), TADDR(startBuf), FALSE);

        DWORD       dwImplFlags;

        //Set the RVA of the method.
        IfFailThrow(pRCW->GetMDImport()->GetMethodImplProps(tk, NULL, &dwImplFlags));
        dwImplFlags |= (miManaged | miIL);
        IfFailThrow(pRCW->GetEmitter()->SetMethodProps(tk, (DWORD) -1, methodRVA, dwImplFlags));
    }

    END_QCALL;
}
Esempio n. 5
0
/// <summary>Write the method to a supplied buffer</summary>
/// <remarks><para>The buffer must be of the size supplied by <c>GetMethodSize</c>.</para>
/// <para>Currently only write methods with 'Fat' headers and 'Fat' Sections - simpler.</para>
/// <para>The buffer will normally be allocated by a call to <c>IMethodMalloc::Alloc</c></para></remarks>
void Method::WriteMethod(IMAGE_COR_ILMETHOD* pMethod)
{
    BYTE* pCode;
    COR_ILMETHOD_FAT* fatImage = (COR_ILMETHOD_FAT*)&pMethod->Fat;

    m_header.Flags &= ~CorILMethod_MoreSects;
    if (m_exceptions.size() > 0)
    {
        m_header.Flags |= CorILMethod_MoreSects;
    }

    memcpy(fatImage, &m_header, m_header.Size * sizeof(DWORD));

    pCode = fatImage->GetCode();

    SetBuffer(pCode);

    for (auto it = m_instructions.begin(); it != m_instructions.end(); ++it)
    {
        OperationDetails &details = Operations::m_mapNameOperationDetails[(*it)->m_operation];
        if (details.op1 == REFPRE)
        {
            Write<BYTE>(details.op2);
        }
        else if (details.op1 == MOOT)
        {
            continue;
        }
        else
        {
            Write<BYTE>(details.op1);
            Write<BYTE>(details.op2);
        }

        switch(details.operandSize)
        {
        case Null:
            break;
        case Byte:
            Write<BYTE>((BYTE)(*it)->m_operand);
            break;
        case Word:
            Write<USHORT>((USHORT)(*it)->m_operand);
            break;
        case Dword:
            Write<ULONG>((ULONG)(*it)->m_operand);
            break;
        case Qword:
            Write<ULONGLONG>((*it)->m_operand);
            break;
        default:
            break;
        }

        if ((*it)->m_operation == CEE_SWITCH)
        {
            for (std::vector<long>::iterator offsetIter = (*it)->m_branchOffsets.begin(); offsetIter != (*it)->m_branchOffsets.end() ; offsetIter++)
            {
                Write<long>(*offsetIter);
            }
        }
    }

    WriteSections();
}