1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 // FILE: ProfToEEInterfaceImpl.h
7 // Declaration of class that implements the ICorProfilerInfo* interfaces, which allow the
8 // Profiler to communicate with the EE. This allows the Profiler DLL to get
9 // access to private EE data structures and other things that should never be exported
15 // ======================================================================================
18 #ifndef __PROFTOEEINTERFACEIMPL_H__
19 #define __PROFTOEEINTERFACEIMPL_H__
21 #ifdef PROFILING_SUPPORTED
23 #include "eeprofinterfaces.h"
28 #include "callingconvention.h"
31 #include "profilinghelper.h"
34 class ProfilerFunctionEnum;
39 extern MethodDesc *FunctionIdToMethodDesc(FunctionID functionID);
40 extern ClassID TypeHandleToClassID(TypeHandle th);
44 // Function declarations for those functions that are platform specific.
46 extern UINT_PTR ProfileGetIPFromPlatformSpecificHandle(void * handle);
48 extern void ProfileSetFunctionIDInPlatformSpecificHandle(void * pPlatformSpecificHandle, FunctionID functionID);
51 // The following class is implemented differently on each platform, using
52 // the PlatformSpecificHandle to initialize an ArgIterator.
54 class ProfileArgIterator
58 ArgIterator m_argIterator;
61 ProfileArgIterator(MetaSig * pMetaSig, void* platformSpecificHandle);
63 ~ProfileArgIterator();
66 // Returns number of arguments returned by GetNextArgAddr
70 LIMITED_METHOD_CONTRACT;
71 return m_argIterator.NumFixedArgs();
75 // After initialization, this method is called repeatedly until it
76 // returns NULL to get the address of each arg.
78 // Note: this address could be anywhere on the stack.
80 LPVOID GetNextArgAddr();
83 // Returns argument size
87 LIMITED_METHOD_CONTRACT;
88 return m_argIterator.GetArgSize();
92 // Called after initialization, any number of times, to retrieve any
93 // hidden argument, so that resolution for Generics can be done.
95 LPVOID GetHiddenArgValue(void);
98 // Called after initialization, any number of times, to retrieve the
101 LPVOID GetThis(void);
104 // Called after initialization, any number of times, to retrieve the
105 // address of the return buffer, if there is one. NULL indicates no
108 LPVOID GetReturnBufferAddr(void);
111 //---------------------------------------------------------------------------------------
112 // This helper class wraps a loader heap which can be used to allocate
113 // memory for IL after the current module.
115 class ModuleILHeap : public IMethodMalloc
119 virtual ULONG STDMETHODCALLTYPE AddRef();
120 virtual ULONG STDMETHODCALLTYPE Release();
121 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** pp);
124 virtual void *STDMETHODCALLTYPE Alloc(ULONG cb);
126 static ModuleILHeap s_Heap;
129 typedef struct _PROFILER_STACK_WALK_DATA PROFILER_STACK_WALK_DATA;
131 //---------------------------------------------------------------------------------------
132 // One of these is allocated per EE instance. A pointer is cached to this
133 // from the profiler implementation. The profiler will call back on the v-table
134 // to get at EE internals as required.
136 class ProfToEEInterfaceImpl : public ICorProfilerInfo10
140 // Internal Housekeeping
142 static void MethodTableCallback(void* context, void* methodTable);
143 static void ObjectRefCallback(void* context, void* objectRefUNSAFE);
145 ProfToEEInterfaceImpl();
146 virtual ~ProfToEEInterfaceImpl();
150 ULONG STDMETHODCALLTYPE AddRef();
151 ULONG STDMETHODCALLTYPE Release();
152 COM_METHOD QueryInterface(REFIID id, void ** pInterface);
156 COM_METHOD GetEventMask(DWORD * pdwEvents);
157 COM_METHOD SetEventMask(DWORD dwEventMask);
159 COM_METHOD GetHandleFromThread(ThreadID threadId, HANDLE * phThread);
161 COM_METHOD GetObjectSize(ObjectID objectId, ULONG * pcSize);
163 COM_METHOD GetObjectSize2(ObjectID objectId, SIZE_T * pcSize);
165 COM_METHOD IsArrayClass(
166 /* [in] */ ClassID classId,
167 /* [out] */ CorElementType * pBaseElemType,
168 /* [out] */ ClassID * pBaseClassId,
169 /* [out] */ ULONG * pcRank);
171 COM_METHOD GetThreadInfo(ThreadID threadId, DWORD * pdwWin32ThreadId);
173 COM_METHOD GetCurrentThreadID(ThreadID * pThreadId);
175 COM_METHOD GetFunctionFromIP(LPCBYTE ip, FunctionID * pFunctionId);
177 COM_METHOD GetTokenAndMetaDataFromFunction(
178 FunctionID functionId,
183 COM_METHOD GetCodeInfo(FunctionID functionId, LPCBYTE * pStart, ULONG * pcSize);
185 COM_METHOD GetModuleInfo(
187 LPCBYTE * ppBaseLoadAddress,
190 __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[],
191 AssemblyID * pAssemblyId);
193 COM_METHOD GetModuleMetaData(
199 COM_METHOD GetILFunctionBody(
201 mdMethodDef methodid,
202 LPCBYTE * ppMethodHeader,
203 ULONG * pcbMethodSize);
205 COM_METHOD GetILFunctionBodyAllocator(
207 IMethodMalloc ** ppMalloc);
209 COM_METHOD SetILFunctionBody(
211 mdMethodDef methodid,
212 LPCBYTE pbNewILMethodHeader);
214 COM_METHOD SetILInstrumentedCodeMap(
215 FunctionID functionId,
218 COR_IL_MAP rgILMapEntries[]);
220 COM_METHOD ForceGC();
222 COM_METHOD GetClassIDInfo(
224 ModuleID * pModuleId,
225 mdTypeDef * pTypeDefToken);
227 COM_METHOD GetFunctionInfo(
228 FunctionID functionId,
230 ModuleID * pModuleId,
233 COM_METHOD GetClassFromObject(
237 COM_METHOD GetClassFromToken(
242 COM_METHOD GetFunctionFromToken(
245 FunctionID * pFunctionId);
247 COM_METHOD GetAppDomainInfo(
248 AppDomainID appDomainId,
251 __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[],
252 ProcessID * pProcessId);
254 COM_METHOD GetAssemblyInfo(
255 AssemblyID assemblyId,
258 __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[],
259 AppDomainID * pAppDomainId,
260 ModuleID * pModuleId);
262 COM_METHOD SetEnterLeaveFunctionHooks(
263 FunctionEnter * pFuncEnter,
264 FunctionLeave * pFuncLeave,
265 FunctionTailcall * pFuncTailcall);
267 COM_METHOD SetEnterLeaveFunctionHooks2(
268 FunctionEnter2 * pFuncEnter,
269 FunctionLeave2 * pFuncLeave,
270 FunctionTailcall2 * pFuncTailcall);
272 COM_METHOD SetFunctionIDMapper(
273 FunctionIDMapper * pFunc);
275 COM_METHOD GetThreadContext(
277 ContextID * pContextId);
279 COM_METHOD GetILToNativeMapping(
280 /* [in] */ FunctionID functionId,
281 /* [in] */ ULONG32 cMap,
282 /* [out] */ ULONG32 * pcMap,
283 /* [out, size_is(cMap), length_is(*pcMap)] */
284 COR_DEBUG_IL_TO_NATIVE_MAP map[]);
286 COM_METHOD GetFunctionInfo2(
287 /* in */ FunctionID funcId,
288 /* in */ COR_PRF_FRAME_INFO frameInfo,
289 /* out */ ClassID * pClassId,
290 /* out */ ModuleID * pModuleId,
291 /* out */ mdToken * pToken,
292 /* in */ ULONG32 cTypeArgs,
293 /* out */ ULONG32 * pcTypeArgs,
294 /* out */ ClassID typeArgs[]);
296 COM_METHOD GetStringLayout(
297 /* out */ ULONG * pBufferLengthOffset,
298 /* out */ ULONG * pStringLengthOffset,
299 /* out */ ULONG * pBufferOffset);
301 COM_METHOD GetClassLayout(
302 /* in */ ClassID classID,
303 /* in.out*/ COR_FIELD_OFFSET rFieldOffset[],
304 /* in */ ULONG cFieldOffset,
305 /* out */ ULONG * pcFieldOffset,
306 /* out */ ULONG * pulClassSize);
308 COM_METHOD DoStackSnapshot(
310 StackSnapshotCallback *callback,
314 ULONG32 contextSize);
316 COM_METHOD GetCodeInfo2(FunctionID functionId,
318 ULONG32 * pcCodeInfos,
319 COR_PRF_CODE_INFO codeInfos[]);
321 COM_METHOD GetArrayObjectInfo(ObjectID objectId,
322 ULONG32 cDimensionSizes,
323 ULONG32 pDimensionSizes[],
324 int pDimensionLowerBounds[],
327 COM_METHOD GetBoxClassLayout(ClassID classId,
328 ULONG32 * pBufferOffset);
330 COM_METHOD GetClassIDInfo2(ClassID classId,
331 ModuleID * pModuleId,
332 mdTypeDef * pTypeDefToken,
333 ClassID * pParentClassId,
334 ULONG32 cNumTypeArgs,
335 ULONG32 * pcNumTypeArgs,
338 COM_METHOD GetThreadAppDomain(ThreadID threadId,
339 AppDomainID * pAppDomainId);
341 COM_METHOD GetRVAStaticAddress(ClassID classId,
342 mdFieldDef fieldToken,
345 COM_METHOD GetAppDomainStaticAddress(ClassID classId,
346 mdFieldDef fieldToken,
347 AppDomainID appDomainId,
350 COM_METHOD GetThreadStaticAddress(ClassID classId,
351 mdFieldDef fieldToken,
355 COM_METHOD GetContextStaticAddress(ClassID classId,
356 mdFieldDef fieldToken,
360 COM_METHOD GetStaticFieldInfo(ClassID classId,
361 mdFieldDef fieldToken,
362 COR_PRF_STATIC_TYPE * pFieldInfo);
364 COM_METHOD GetClassFromTokenAndTypeArgs(ModuleID moduleID,
370 COM_METHOD EnumModuleFrozenObjects(ModuleID moduleID,
371 ICorProfilerObjectEnum** ppEnum);
375 COM_METHOD GetFunctionFromTokenAndTypeArgs(ModuleID moduleID,
380 FunctionID* pFunctionID);
382 COM_METHOD GetGenerationBounds(ULONG cObjectRanges,
383 ULONG * pcObjectRanges,
384 COR_PRF_GC_GENERATION_RANGE ranges[]);
386 COM_METHOD GetObjectGeneration(ObjectID objectId,
387 COR_PRF_GC_GENERATION_RANGE *range);
389 COM_METHOD GetNotifiedExceptionClauseInfo(COR_PRF_EX_CLAUSE_INFO * pinfo);
391 COM_METHOD SetFunctionReJIT(FunctionID);
392 COM_METHOD GetInprocInspectionInterface(IUnknown **);
393 COM_METHOD GetInprocInspectionIThisThread(IUnknown **);
394 COM_METHOD BeginInprocDebugging(BOOL,DWORD *);
395 COM_METHOD EndInprocDebugging(DWORD);
399 COM_METHOD EnumJITedFunctions(ICorProfilerFunctionEnum** ppEnum);
400 COM_METHOD EnumModules(ICorProfilerModuleEnum ** ppEnum);
402 COM_METHOD RequestProfilerDetach(
403 /* in */ DWORD dwExpectedCompletionMilliseconds);
405 COM_METHOD SetFunctionIDMapper2(
406 FunctionIDMapper2 * pFunc, // in
407 void * clientData); // in
409 COM_METHOD SetEnterLeaveFunctionHooks3(
410 FunctionEnter3 * pFuncEnter3, // in
411 FunctionLeave3 * pFuncLeave3, // in
412 FunctionTailcall3 * pFuncTailcall3); // in
414 COM_METHOD SetEnterLeaveFunctionHooks3WithInfo(
415 FunctionEnter3WithInfo * pFuncEnter3WithInfo, // in
416 FunctionLeave3WithInfo * pFuncLeave3WithInfo, // in
417 FunctionTailcall3WithInfo * pFuncTailcall3WithInfo); // in
419 COM_METHOD GetFunctionEnter3Info(
420 FunctionID functionId, // in
421 COR_PRF_ELT_INFO eltInfo, // in
422 COR_PRF_FRAME_INFO * pFrameInfo, // out
423 ULONG * pcbArgumentInfo, // in, out
424 COR_PRF_FUNCTION_ARGUMENT_INFO * pArgumentInfo); // out
426 COM_METHOD GetFunctionLeave3Info(
427 FunctionID functionId, // in
428 COR_PRF_ELT_INFO eltInfo, // in
429 COR_PRF_FRAME_INFO * pFrameInfo, // out
430 COR_PRF_FUNCTION_ARGUMENT_RANGE * pRetvalRange); // out
432 COM_METHOD GetFunctionTailcall3Info(
433 FunctionID functionId, // in
434 COR_PRF_ELT_INFO pFrameInfo, // in
435 COR_PRF_FRAME_INFO * pFunc); // out
437 COM_METHOD GetStringLayout2(
438 /* out */ ULONG * pStringLengthOffset,
439 /* out */ ULONG * pBufferOffset);
441 COM_METHOD GetRuntimeInformation(USHORT * pClrInstanceId, // out
442 COR_PRF_RUNTIME_TYPE * pRuntimeType, // out
443 USHORT * pMajorVersion, // out
444 USHORT * pMinorVersion, // out
445 USHORT * pBuildNumber, // out
446 USHORT * pQFEVersion, // out
447 ULONG cchVersionString, // in
448 ULONG * pcchVersionString, // out
449 __out_ecount_part_opt(cchVersionString, *pcchVersionString) WCHAR szVersionString[]); // out
451 COM_METHOD GetThreadStaticAddress2(ClassID classId, // in
452 mdFieldDef fieldToken, // in
453 AppDomainID appDomainId, // in
454 ThreadID threadId, // in
455 void ** ppAddress); // out
457 COM_METHOD GetAppDomainsContainingModule(ModuleID moduleId, // in
458 ULONG32 cAppDomainIds, // in
459 ULONG32 *pcAppDomainIds, // out
460 AppDomainID appDomainIds[]); // out
462 COM_METHOD GetModuleInfo2(
464 LPCBYTE * ppBaseLoadAddress,
467 __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[],
468 AssemblyID * pAssemblyId,
469 DWORD * pdwModuleFlags);
471 // end ICorProfilerInfo3
475 COM_METHOD EnumThreads(
476 /* out */ ICorProfilerThreadEnum ** ppEnum);
478 COM_METHOD InitializeCurrentThread();
480 // end ICorProfilerInfo4
482 COM_METHOD RequestReJIT(ULONG cFunctions, // in
483 ModuleID moduleIds[], // in
484 mdMethodDef methodIds[]); // in
486 COM_METHOD RequestRevert(ULONG cFunctions, // in
487 ModuleID moduleIds[], // in
488 mdMethodDef methodIds[], // in
489 HRESULT status[]); // out
491 COM_METHOD GetCodeInfo3(FunctionID functionID, // in
492 ReJITID reJitId, // in
493 ULONG32 cCodeInfos, // in
494 ULONG32 * pcCodeInfos, // out
495 COR_PRF_CODE_INFO codeInfos[]); // out
497 COM_METHOD GetFunctionFromIP2(LPCBYTE ip, // in
498 FunctionID * pFunctionId, // out
499 ReJITID * pReJitId); // out
501 COM_METHOD GetReJITIDs(FunctionID functionId, // in
502 ULONG cReJitIds, // in
503 ULONG * pcReJitIds, // out
504 ReJITID reJitIds[]); // out
506 COM_METHOD GetILToNativeMapping2(
507 FunctionID functionId, // in
508 ReJITID reJitId, // in
510 ULONG32 * pcMap, // out
511 COR_DEBUG_IL_TO_NATIVE_MAP map[]); // out
513 COM_METHOD EnumJITedFunctions2(ICorProfilerFunctionEnum** ppEnum);
515 // end ICorProfilerInfo4
518 // begin ICorProfilerInfo5
520 COM_METHOD SetEventMask2(
524 COM_METHOD GetEventMask2(DWORD *pdwEventsLow, DWORD *pdwEventsHigh);
526 // end ICorProfilerInfo5
528 // begin ICorProfilerInfo6
530 COM_METHOD EnumNgenModuleMethodsInliningThisMethod(
531 ModuleID inlinersModuleId,
532 ModuleID inlineeModuleId,
533 mdMethodDef inlineeMethodId,
534 BOOL *incompleteData,
535 ICorProfilerMethodEnum** ppEnum);
538 // end ICorProfilerInfo6
540 // begin ICorProfilerInfo7
542 COM_METHOD ApplyMetaData(
545 COM_METHOD GetInMemorySymbolsLength(
547 DWORD* pCountSymbolBytes);
549 COM_METHOD ReadInMemorySymbols(
551 DWORD symbolsReadOffset,
553 DWORD countSymbolBytes,
554 DWORD* pCountSymbolBytesRead);
556 // end ICorProfilerInfo7
558 // begin ICorProfilerInfo8
560 COM_METHOD IsFunctionDynamic(
561 FunctionID functionId,
564 COM_METHOD GetFunctionFromIP3(
566 FunctionID * pFunctionId, // out
567 ReJITID * pReJitId); // out
569 COM_METHOD GetDynamicFunctionInfo(
570 FunctionID functionId,
572 PCCOR_SIGNATURE* ppvSig,
578 // end ICorProfilerInfo8
580 // beging ICorProfilerInfo9
582 COM_METHOD GetNativeCodeStartAddresses(
583 FunctionID functionID,
585 ULONG32 cCodeStartAddresses,
586 ULONG32 *pcCodeStartAddresses,
587 UINT_PTR codeStartAddresses[]);
589 COM_METHOD GetILToNativeMapping3(
590 UINT_PTR pNativeCodeStartAddress,
593 COR_DEBUG_IL_TO_NATIVE_MAP map[]);
595 COM_METHOD GetCodeInfo4(
596 UINT_PTR pNativeCodeStartAddress,
598 ULONG32* pcCodeInfos,
599 COR_PRF_CODE_INFO codeInfos[]);
601 // end ICorProfilerInfo9
603 // beging ICorProfilerInfo10
605 COM_METHOD GetObjectReferences(
607 ULONG32 cNumReferences,
608 ULONG32 *pcNumReferences,
609 ObjectID references[],
612 // end ICorProfilerInfo10
616 // Internal Helper Functions
618 HRESULT GetCodeInfoHelper(FunctionID functionId,
621 ULONG32 * pcCodeInfos,
622 COR_PRF_CODE_INFO codeInfos[]);
624 HRESULT GetStringLayoutHelper(ULONG * pBufferLengthOffset,
625 ULONG * pStringLengthOffset,
626 ULONG * pBufferOffset);
628 HRESULT GetArrayObjectInfoHelper(Object * pObj,
629 ULONG32 cDimensionSizes,
630 __out_ecount(cDimensionSizes) ULONG32 pDimensionSizes[],
631 __out_ecount(cDimensionSizes) int pDimensionLowerBounds[],
634 DWORD GetModuleFlags(Module * pModule);
636 HRESULT DoStackSnapshotHelper(Thread * pThreadToSnapshot,
637 PROFILER_STACK_WALK_DATA * pData,
641 HRESULT ProfilerStackWalkFramesWrapper(Thread * pThreadToSnapshot, PROFILER_STACK_WALK_DATA * pData, unsigned flags);
643 HRESULT EnumJITedFunctionsHelper(ProfilerFunctionEnum ** ppEnum, IJitManager ** ppJitMgr);
646 HRESULT ProfilerEbpWalker(Thread * pThreadToSnapshot, LPCONTEXT pctxSeed, StackSnapshotCallback * callback, void * clientData);
647 #endif //_TARGET_X86_
650 #endif // PROFILING_SUPPORTED
652 //---------------------------------------------------------------------------------------
653 // This provides the implementations for FCALLs in managed code related to profiling
655 class ProfilingFCallHelper
658 // This is a high-efficiency way for managed profiler code to determine if
659 // profiling of remoting is active.
660 static FCDECL0(FC_BOOL_RET, FC_TrackRemoting);
662 // This is a high-efficiency way for managed profiler code to determine if
663 // profiling of remoting with RPC cookie IDs is active.
664 static FCDECL0(FC_BOOL_RET, FC_TrackRemotingCookie);
666 // This is a high-efficiency way for managed profiler code to determine if
667 // profiling of asynchronous remote calls is profiled
668 static FCDECL0(FC_BOOL_RET, FC_TrackRemotingAsync);
670 // This will let the profiler know that the client side is sending a message to
672 static FCDECL2(void, FC_RemotingClientSendingMessage, GUID * pId, CLR_BOOL fIsAsync);
674 // For __cdecl calling convention both arguments end up on
675 // the stack but the order in which the jit puts them there needs to be reversed
676 // For __fastcall calling convention the reversal has no effect because the GUID doesn't
677 // fit in a register. On IA64 the macro is different.
679 // This will let the profiler know that the client side is receiving a reply
680 // to a message that it sent
681 static FCDECL2_VI(void, FC_RemotingClientReceivingReply, GUID id, CLR_BOOL fIsAsync);
683 // This will let the profiler know that the server side is receiving a message
685 static FCDECL2_VI(void, FC_RemotingServerReceivingMessage, GUID id, CLR_BOOL fIsAsync);
687 // This will let the profiler know that the server side is sending a reply to
688 // a received message.
689 static FCDECL2(void, FC_RemotingServerSendingReply, GUID * pId, CLR_BOOL fIsAsync);
692 #endif // __PROFTOEEINTERFACEIMPL_H__