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; }
void PrintMethodInfo(ICorProfilerInfo3 *profilerInfo, ModuleID moduleId, mdMethodDef methodId, FILE *stream, IMetaDataImport2 **outMetadata) { if (outMetadata != NULL) *outMetadata = NULL; LPCBYTE baseLoadAddress = NULL; ULONG actualLength; WCHAR moduleName[256]; AssemblyID assemblyID = NULL; HRESULT result = profilerInfo->GetModuleInfo(moduleId, &baseLoadAddress, 256, &actualLength, moduleName, &assemblyID); if (result != S_OK) return; ULONG actualAssemblyNameLength; WCHAR assemblyName[256]; AppDomainID appDomainId = NULL; ModuleID unusedModuleId = NULL; result = profilerInfo->GetAssemblyInfo(assemblyID, 256, &actualAssemblyNameLength, assemblyName, &appDomainId, &unusedModuleId); if (result != S_OK) return; FunctionID functionId = NULL; result = profilerInfo->GetFunctionFromToken(moduleId, methodId, &functionId); if (result != S_OK) return; ClassID classId = NULL; mdTypeDef classToken = 0; mdToken unusedToken; result = profilerInfo->GetFunctionInfo(functionId, &classId, &unusedModuleId, &unusedToken); if (result != S_OK || classId == NULL) return; result = profilerInfo->GetClassIDInfo(classId, &unusedModuleId, &classToken); if (result != S_OK) return; IMetaDataImport2 *metadata = NULL; result = profilerInfo->GetModuleMetaData(moduleId, ofRead, IID_IMetaDataImport2, (IUnknown **) &metadata); if (result != S_OK || metadata == NULL) return; if (outMetadata != NULL) *outMetadata = metadata; MDUTF8CSTR className = NULL; result = metadata->GetNameFromToken(classToken, &className); if (result != S_OK || className == NULL) return; MDUTF8CSTR methodName = NULL; result = metadata->GetNameFromToken(methodId, &methodName); if (result != S_OK || methodName == NULL) return; fprintf(stream, "Assembly: %S, Module: %S, Class: %s, Method name: %s\n", assemblyName, moduleName, className, methodName); }
//***************************************************************************** // This function returns the requested public interface based on the given // internal import interface. // A common path to call this is updating the matedata for dynamic modules. //***************************************************************************** STDAPI MDReOpenMetaDataWithMemoryEx( void *pImport, // [IN] Given scope. public interfaces LPCVOID pData, // [in] Location of scope data. ULONG cbData, // [in] Size of the data pointed to by pData. DWORD dwReOpenFlags) // [in] Flags for ReOpen { HRESULT hr = S_OK; IUnknown *pUnk = (IUnknown *) pImport; IMetaDataImport2 *pMDImport = NULL; RegMeta *pRegMeta = NULL; _ASSERTE(pImport); IfFailGo( pUnk->QueryInterface(IID_IMetaDataImport2, (void **) &pMDImport) ); pRegMeta = (RegMeta*) pMDImport; IfFailGo( pRegMeta->ReOpenWithMemory(pData, cbData, dwReOpenFlags) ); ErrExit: if (pMDImport) pMDImport->Release(); return hr; } // MDReOpenMetaDataWithMemoryEx