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