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
/// <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. 3
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();
}