4f0cd6b961d64569f9ca00b5bbeb48454a1f2d66
[platform/upstream/coreclr.git] / src / inc / corprof.idl
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.
4
5 /**************************************************************************************
6  **                                                                                  **
7  ** Corprof.idl - CLR Profiling interfaces.                                          **
8  **                                                                                  **
9  **************************************************************************************/
10
11 /* -------------------------------------------------------------------------- *
12  * Imported types
13  * -------------------------------------------------------------------------- */
14
15 #if !DEFINITIONS_FROM_NON_IMPORTABLE_PLACES
16
17 cpp_quote("#define CorDB_CONTROL_Profiling         \"Cor_Enable_Profiling\"")
18 cpp_quote("#define CorDB_CONTROL_ProfilingL       L\"Cor_Enable_Profiling\"")
19
20 cpp_quote("#if 0")
21
22
23 import "unknwn.idl";
24
25 typedef LONG32  mdToken;
26 typedef mdToken mdModule;
27 typedef mdToken mdTypeDef;
28 typedef mdToken mdMethodDef;
29 typedef mdToken mdFieldDef;
30 typedef ULONG CorElementType;
31
32 // Forward declaration of enum in CorHdr.h
33 enum    CorElementType;
34
35 // Forward declaration of structs in Cor.h
36
37 typedef struct
38 {
39     DWORD       dwOSPlatformId;         // Operating system platform.
40     DWORD       dwOSMajorVersion;       // OS Major version.
41     DWORD       dwOSMinorVersion;       // OS Minor version.
42 } OSINFO;
43
44 typedef struct
45 {
46     USHORT      usMajorVersion;         // Major Version.
47     USHORT      usMinorVersion;         // Minor Version.
48     USHORT      usBuildNumber;          // Build Number.
49     USHORT      usRevisionNumber;       // Revision Number.
50     LPWSTR      szLocale;               // Locale.
51     ULONG       cbLocale;               // [IN/OUT] Size of the buffer in wide chars/Actual size.
52     DWORD       *rProcessor;            // Processor ID array.
53     ULONG       ulProcessor;            // [IN/OUT] Size of the Processor ID array/Actual # of entries filled in.
54     OSINFO      *rOS;                   // OSINFO array.
55     ULONG       ulOS;                   // [IN/OUT]Size of the OSINFO array/Actual # of entries filled in.
56 } ASSEMBLYMETADATA;
57
58 cpp_quote("#endif")
59
60 typedef const BYTE *LPCBYTE;
61 typedef BYTE *LPBYTE;
62
63 typedef BYTE COR_SIGNATURE;
64 typedef COR_SIGNATURE* PCOR_SIGNATURE;
65 typedef const COR_SIGNATURE* PCCOR_SIGNATURE;
66
67 #endif
68
69
70 cpp_quote("#ifndef _COR_IL_MAP")
71 cpp_quote("#define _COR_IL_MAP")
72
73 #ifdef INTERNAL_DOCS
74 // Note that this structure is also defined in CorDebug.idl - PROPAGATE CHANGES
75 // BOTH WAYS, or this'll become a really insidious bug some day.
76 #endif
77 typedef struct _COR_IL_MAP
78 {
79     ULONG32 oldOffset;        // Old IL offset relative to beginning of function
80     ULONG32 newOffset;        // New IL offset relative to beginning of function
81     BOOL    fAccurate; //put here for compatibility with the Debugger structure.
82 } COR_IL_MAP;
83
84 cpp_quote("#endif //_COR_IL_MAP")
85
86 cpp_quote("#ifndef _COR_DEBUG_IL_TO_NATIVE_MAP_")
87 cpp_quote("#define _COR_DEBUG_IL_TO_NATIVE_MAP_")
88
89 /* ICorProfilerInfo:: GetILToNativeMapping returns an array of
90  * COR_DEBUG_IL_TO_NATIVE_MAP structures.  In order to convey that certain
91  * ranges of native instructions correspond to special regions of code (for
92  * example, the prolog), an entry in the array may have it's ilOffset field set
93  * to one of these values.
94  */
95 typedef enum CorDebugIlToNativeMappingTypes
96 {
97     NO_MAPPING = -1,
98     PROLOG     = -2,
99     EPILOG     = -3
100 } CorDebugIlToNativeMappingTypes;
101
102 typedef struct COR_DEBUG_IL_TO_NATIVE_MAP
103 {
104     ULONG32 ilOffset;
105     ULONG32 nativeStartOffset;
106     ULONG32 nativeEndOffset;
107 } COR_DEBUG_IL_TO_NATIVE_MAP;
108
109 cpp_quote("#endif // _COR_DEBUG_IL_TO_NATIVE_MAP_")
110
111 cpp_quote("#ifndef _COR_FIELD_OFFSET_")
112 cpp_quote("#define _COR_FIELD_OFFSET_")
113
114 typedef struct _COR_FIELD_OFFSET
115 {
116     mdFieldDef ridOfField;  // fieldDef token of the field
117     ULONG      ulOffset;      // offset (from the ObjectID pointer) of the field
118 } COR_FIELD_OFFSET;
119
120 cpp_quote("#endif // _COR_FIELD_OFFSET_")
121
122
123 #ifndef DO_NO_IMPORTS
124 import "wtypes.idl";
125 import "unknwn.idl";
126 #endif
127
128 typedef UINT_PTR ProcessID;
129 typedef UINT_PTR AssemblyID;
130 typedef UINT_PTR AppDomainID;
131 typedef UINT_PTR ModuleID;
132 typedef UINT_PTR ClassID;
133 typedef UINT_PTR ThreadID;
134 typedef UINT_PTR ContextID;
135 typedef UINT_PTR FunctionID;
136 typedef UINT_PTR ObjectID;
137 typedef UINT_PTR GCHandleID;
138 typedef UINT_PTR COR_PRF_ELT_INFO;
139 typedef UINT_PTR ReJITID;
140
141 typedef union {FunctionID functionID; UINT_PTR clientID;} FunctionIDOrClientID;
142
143 /*
144  * The FunctionIDMapper type definition is used by the
145  * ICorProfilerInfo::SetFunctionIDMapper method to specify
146  * a function that will be called to map FunctionIDs to alternative
147  * values that will be passed to the function entry and function exit
148  * callbacks supplied to the ICorProfilerInfo::SetEnterLeaveFunctionHooks
149  * method. The mapper can be set only once and it is recommended to do so
150  * in the Initialize callback.
151  *
152  * NOTE: There is a known bug in this API that must be worked around.
153  * The return value of FunctionIDMapper cannot be NULL (unless the boolean
154  * value in pbHookTheFunction is FALSE).  All other values are treated as
155  * opaque data to be passed to the entry/exit callback functions.  The use
156  * of a NULL return value will produce unpredictable results, including
157  * possibly halting the process.
158  *
159  * NOTE: Profilers should be tolerant of cases where multiple threads of
160  * a profiled app are calling the same method simultaneously.  In such
161  * cases, the profiler may receive multiple FunctionIDMapper callbacks
162  * for the same functionId.  The profiler should be certain to return
163  * the same values from this callback when it is called multiple times
164  * with the same functionId.
165  * 
166  */
167 typedef UINT_PTR __stdcall FunctionIDMapper(
168                 FunctionID funcId, 
169                 BOOL *pbHookFunction);
170
171 typedef UINT_PTR __stdcall FunctionIDMapper2(
172                 FunctionID funcId, 
173                 void *clientData,
174                 BOOL *pbHookFunction);
175
176 /*
177  * Enum for specifying how much data to pass back with a stack snapshot
178  */
179 typedef enum _COR_PRF_SNAPSHOT_INFO
180 {
181     COR_PRF_SNAPSHOT_DEFAULT            = 0x0,
182
183     // Return a register context for each frame
184     COR_PRF_SNAPSHOT_REGISTER_CONTEXT   = 0x1,
185
186     // Use a quicker stack walk algorithm based on the EBP frame chain. This is available
187     // on x86 only.
188     COR_PRF_SNAPSHOT_X86_OPTIMIZED      = 0x2,
189 } COR_PRF_SNAPSHOT_INFO;
190
191 /*
192  * Opaque handle that represents information about a given stack frame. It is only
193  * valid during the callback to which it is passed.
194  */
195 typedef UINT_PTR COR_PRF_FRAME_INFO;
196
197 /*
198  * Describes a range of function arguments stored contiguously in left-to-right
199  * order in memory.
200  */
201 typedef struct _COR_PRF_FUNCTION_ARGUMENT_RANGE
202 {
203     UINT_PTR startAddress;          // start address of the range
204     ULONG length;                         // contiguous length of the range
205 } COR_PRF_FUNCTION_ARGUMENT_RANGE;
206
207 /*
208  * Describes the locations in memory of a function's arguments, in
209  * left-to-right order. Note that arguments stored in registers are
210  * spilled to memory to build these structures.
211  */
212 typedef struct _COR_PRF_FUNCTION_ARGUMENT_INFO
213 {
214     ULONG numRanges;                // number of chunks of arguments
215     ULONG totalArgumentSize;    // total size of arguments
216     COR_PRF_FUNCTION_ARGUMENT_RANGE ranges[1];  // chunks
217 } COR_PRF_FUNCTION_ARGUMENT_INFO;
218
219 /*
220  * Represents one contiguous chunk of native code
221  */
222 typedef struct _COR_PRF_CODE_INFO
223 {
224     UINT_PTR startAddress;
225     SIZE_T size;
226 } COR_PRF_CODE_INFO;
227
228 /*
229  * Enum for describing the type of static a field is.  These may be bit-wise
230  * or'ed with each other if the field is multiple types.
231  */
232 typedef enum
233 {
234     COR_PRF_FIELD_NOT_A_STATIC = 0x0,
235     COR_PRF_FIELD_APP_DOMAIN_STATIC = 0x1,
236     COR_PRF_FIELD_THREAD_STATIC = 0x2,
237     COR_PRF_FIELD_CONTEXT_STATIC = 0x4,
238     COR_PRF_FIELD_RVA_STATIC = 0x8
239 } COR_PRF_STATIC_TYPE;
240
241 /*
242  * Represents a function uniquely by combining the FunctionID
243  * with a ReJITID.
244  */
245 typedef struct _COR_PRF_FUNCTION
246 {
247     FunctionID functionId;
248     ReJITID    reJitId;
249 } COR_PRF_FUNCTION;
250
251
252 /*
253  * Structure populated by profiler when declaring additional assembly references
254  * that the CLR should consider when performing an assembly reference closure
255  * walk.  See ICorProfilerCallback6::GetAssemblyReferences and
256  * ICorProfilerAssemblyReferenceProvider::AddAssemblyReference
257  */
258 typedef struct _COR_PRF_ASSEMBLY_REFERENCE_INFO
259 {
260     void  *pbPublicKeyOrToken;          // Public key or token of the assembly.
261     ULONG       cbPublicKeyOrToken;     // Count of bytes in the public key or token.
262     LPCWSTR     szName;                 // Name of the assembly being referenced.
263     ASSEMBLYMETADATA * pMetaData;       // Assembly MetaData, as defined in cor.h
264     void  *pbHashValue;                 // Hash Blob.
265     ULONG       cbHashValue;            // Count of bytes in the Hash Blob.
266     DWORD       dwAssemblyRefFlags;     // Flags.
267 } COR_PRF_ASSEMBLY_REFERENCE_INFO;
268
269
270 /*
271  * Represents a IL methods uniquely by combining the module ID and method token.
272  */
273 typedef struct _COR_PRF_METHOD
274 {
275     ModuleID    moduleId;
276     mdMethodDef methodId;
277 } COR_PRF_METHOD;
278
279 /*
280  * NOTE!!!
281  *
282  * The following applies to ALL FunctionEnter[2,3], FunctionLeave[2,3],
283  * FunctionTailcall[2,3] hooks below:
284  *
285  * It is VERY IMPORTANT to note that these function implementations must be
286  * __declspec(naked), since the EE is not saving any registers before calling
287  * any of them.  YOU MUST SAVE ALL REGISTERS YOU USE, INCLUDING FPU REGISTERS
288  * IF THE FPU STACK IS NOT EMPTY AND YOU INTEND TO USE IT.
289  *
290  * NOTE: The profiler should not block here, since the stack may not be in a
291  *       GC-friendly state and so preemptive GC cannot be enabled.  If the
292  *       profiler blocks here and a GC is attempted, the runtime will block
293  *       until this callback returns.  Also, the profiler may NOT call into
294  *       managed code or in any way cause a managed memory allocation.
295  */
296
297  /*
298  * NOTE: DEPRECATED IN V2
299  *
300  * These functions are considered deprecated in V2 and higher.  They will
301  * continue to work, but incur a performance penalty for usage.  For equivalent
302  * functionality, use the FunctionEnter3/Leave3/Tailcall3 callbacks with
303  * bits cleared for COR_PRF_ENABLE_FRAME_INFO, COR_PRF_ENABLE_FUNCTION_RETVAL
304  * and COR_PRF_ENABLE_FUNCTION_ARGS.
305  */
306 typedef void __stdcall FunctionEnter(
307                 FunctionID funcID);
308                 
309 typedef void __stdcall FunctionLeave(
310                 FunctionID funcID);
311                 
312 typedef void __stdcall FunctionTailcall(
313                 FunctionID funcID);
314
315 /*
316  * NOTE: DEPRECATED IN V4
317  *
318  * These functions are considered deprecated in V4 and higher.  They will
319  * continue to work, but incur a performance penalty for usage.  For equivalent
320  * functionality, use the FunctionEnter3/Leave3/Tailcall3 callbacks.
321  */
322
323 typedef void __stdcall FunctionEnter2(
324                 FunctionID funcId, 
325                 UINT_PTR clientData, 
326                 COR_PRF_FRAME_INFO func, 
327                 COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo);
328                 
329 typedef void __stdcall FunctionLeave2(
330                 FunctionID funcId, 
331                 UINT_PTR clientData, 
332                 COR_PRF_FRAME_INFO func, 
333                 COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange);
334                 
335 typedef void __stdcall FunctionTailcall2(
336                 FunctionID funcId, 
337                 UINT_PTR clientData, 
338                 COR_PRF_FRAME_INFO func);
339
340 /*
341  * When you are not interested in inspecting arguments or return values, then
342  * use these to be notified as functions are called and return.  Use
343  * SetEnterLeaveFunctionHooks3 to register your implementations of these
344  * functions.
345  *
346  * functionIDOrClientID: if the profiler returned a remapped value from
347  * FunctionIDMapper[2], then this is that remapped value; else it is the
348  * true FunctionID of the function.
349  */
350
351 typedef void __stdcall FunctionEnter3(
352                 FunctionIDOrClientID functionIDOrClientID);
353  
354 typedef void __stdcall FunctionLeave3(
355                 FunctionIDOrClientID functionIDOrClientID);
356  
357 typedef void __stdcall FunctionTailcall3(
358                 FunctionIDOrClientID functionIDOrClientID);
359
360 /*
361  * When you are interested in inspecting arguments and return values, then
362  * use these to be notified as functions are called and return.  Use
363  * SetEnterLeaveFunctionHooks3WithInfo to register your implementations of these
364  * functions.
365  *
366  * functionIDOrClientID: if the profiler returned a remapped value from
367  * FunctionIDMapper[2], then this is that remapped value; else it is the
368  * true FunctionID of the function.
369  *
370  * eltInfo is an opaque handle that represents information about a given stack frame. 
371  * It is only valid during the callback to which it is passed.
372  */
373
374 typedef void __stdcall FunctionEnter3WithInfo(
375                 FunctionIDOrClientID functionIDOrClientID,
376                 COR_PRF_ELT_INFO eltInfo);
377  
378 typedef void __stdcall FunctionLeave3WithInfo(
379                 FunctionIDOrClientID functionIDOrClientID,
380                 COR_PRF_ELT_INFO eltInfo);
381  
382 typedef void __stdcall FunctionTailcall3WithInfo(
383                 FunctionIDOrClientID functionIDOrClientID,
384                 COR_PRF_ELT_INFO eltInfo);
385
386 /*
387  * Stack snapshot callback definition.
388  *
389  * This callback is called once per managed frame or run of unmanaged frames.
390  *
391  * funcID is the FunctionID of the managed function. If funcID == 0, the callback is
392  * for a run of unmanaged frames. The profiler may either ignore the frame, or use
393  * the register context to perform its own unmanaged stackwalk.
394  *
395  * ip is the native IP in the frame
396  *
397  * frameInfo is the COR_PRF_FRAME_INFO for this frame. It is only valid for
398  * use during this callback.
399  *
400  * context is a Win32 CONTEXT struct for the current platform (size given in
401  * contextSize). It will only be valid if the COR_PRF_SNAPSHOT_CONTEXT flag
402  * was passed to DoStackSnapshot.
403  *
404  * clientData is a void* passed straight through from DoStackSnapshot
405  *
406  * NOTE: One must limit the complexity of work done in StackSnapshotCallback. 
407  * For example, particularly when using DoStackSnapshot in an asynchronous manner, 
408  * the target thread may be holding locks. Executing code within StackSnapshotCallback 
409  * that requires the same locks could lead to deadlock.
410  */
411 typedef HRESULT __stdcall StackSnapshotCallback(
412                 FunctionID funcId,
413                 UINT_PTR ip,
414                 COR_PRF_FRAME_INFO frameInfo,
415                 ULONG32 contextSize,
416                 BYTE context[],
417                 void *clientData);
418
419 typedef enum
420 {
421     // These flags represent classes of callback events
422     COR_PRF_MONITOR_NONE                = 0x00000000,
423
424     // MONITOR_FUNCTION_UNLOADS controls the
425     // FunctionUnloadStarted callback.
426     COR_PRF_MONITOR_FUNCTION_UNLOADS    = 0x00000001,
427
428     // MONITOR_CLASS_LOADS controls the ClassLoad*
429     // and ClassUnload* callbacks.
430     // See the comments on those callbacks for important
431     // behavior changes in V2.
432     COR_PRF_MONITOR_CLASS_LOADS         = 0x00000002,
433
434     // MONITOR_MODULE_LOADS controls the 
435     // ModuleLoad*, ModuleUnload*, and ModuleAttachedToAssembly
436     // callbacks.
437     COR_PRF_MONITOR_MODULE_LOADS        = 0x00000004,
438
439     // MONITOR_ASSEMBLY_LOADS controls the
440     // AssemblyLoad* and AssemblyUnload* callbacks
441     COR_PRF_MONITOR_ASSEMBLY_LOADS      = 0x00000008,
442
443     // MONITOR_APPDOMAIN_LOADS controls the
444     // AppDomainCreation* and AppDomainShutdown* callbacks
445     COR_PRF_MONITOR_APPDOMAIN_LOADS     = 0x00000010,
446
447     // MONITOR_JIT_COMPILATION controls the
448     // JITCompilation*, JITFunctionPitched, and JITInlining 
449     // callbacks.
450     COR_PRF_MONITOR_JIT_COMPILATION     = 0x00000020,
451
452
453     // MONITOR_EXCEPTIONS controls the ExceptionThrown,
454     // ExceptionSearch*, ExceptionOSHandler*, ExceptionUnwind*,
455     // and ExceptionCatcher* callbacks.
456     COR_PRF_MONITOR_EXCEPTIONS          = 0x00000040,
457
458     // MONITOR_GC controls the GarbageCollectionStarted/Finished,
459     // MovedReferences, SurvivingReferences,
460     // ObjectReferences, ObjectsAllocatedByClass,
461     // RootReferences*, HandleCreated/Destroyed, and FinalizeableObjectQueued
462     // callbacks.
463     COR_PRF_MONITOR_GC                  = 0x00000080,
464
465     // MONITOR_OBJECT_ALLOCATED controls the
466     // ObjectAllocated callback.
467     COR_PRF_MONITOR_OBJECT_ALLOCATED    = 0x00000100,
468
469     // MONITOR_THREADS controls the ThreadCreated,
470     // ThreadDestroyed, ThreadAssignedToOSThread, 
471     // and ThreadNameChanged callbacks.
472     COR_PRF_MONITOR_THREADS             = 0x00000200,
473
474     // MONITOR_REMOTING controls the Remoting*
475     // callbacks.
476     COR_PRF_MONITOR_REMOTING            = 0x00000400,
477
478     // MONITOR_CODE_TRANSITIONS controls the
479     // UnmanagedToManagedTransition and 
480     // ManagedToUnmanagedTransition callbacks.
481     COR_PRF_MONITOR_CODE_TRANSITIONS    = 0x00000800,
482
483     // MONITOR_ENTERLEAVE controls the 
484     // FunctionEnter*/Leave*/Tailcall* callbacks
485     COR_PRF_MONITOR_ENTERLEAVE          = 0x00001000,
486
487     // MONITOR_CCW controls the COMClassicVTable*
488     // callbacks.
489     COR_PRF_MONITOR_CCW                 = 0x00002000,
490
491     // MONITOR_REMOTING_COOKIE controls whether
492     // a cookie will be passed to the Remoting* callbacks
493     COR_PRF_MONITOR_REMOTING_COOKIE     = 0x00004000 | COR_PRF_MONITOR_REMOTING,
494
495     // MONITOR_REMOTING_ASYNC controls whether
496     // the Remoting* callbacks will monitor async events
497     COR_PRF_MONITOR_REMOTING_ASYNC      = 0x00008000 | COR_PRF_MONITOR_REMOTING,
498
499     // MONITOR_SUSPENDS controls the RuntimeSuspend*,
500     // RuntimeResume*, RuntimeThreadSuspended, and 
501     // RuntimeThreadResumed callbacks.
502     COR_PRF_MONITOR_SUSPENDS            = 0x00010000,
503
504     // MONITOR_CACHE_SEARCHES controls the
505     // JITCachedFunctionSearch* callbacks.
506     // See the comments on those callbacks for important
507     // behavior changes in V2.
508     COR_PRF_MONITOR_CACHE_SEARCHES      = 0x00020000,
509
510     // NOTE: ReJIT is now supported again.  The profiler must set this flag on
511     // startup in order to use RequestReJIT or RequestRevert.  If the profiler specifies
512     // this flag, then the profiler must also specify COR_PRF_DISABLE_ALL_NGEN_IMAGES
513     COR_PRF_ENABLE_REJIT                = 0x00040000,
514
515     // V2 MIGRATION WARNING: DEPRECATED
516     // Inproc debugging is no longer supported. ENABLE_INPROC_DEBUGGING
517     // has no effect.
518     COR_PRF_ENABLE_INPROC_DEBUGGING     = 0x00080000,
519
520     // V2 MIGRATION NOTE: DEPRECATED
521     // The runtime now always tracks IL-native maps; this flag is thus always
522     // considered to be set.
523     COR_PRF_ENABLE_JIT_MAPS             = 0x00100000,
524
525     // DISABLE_INLINING tells the runtime to disable all inlining
526     COR_PRF_DISABLE_INLINING            = 0x00200000,
527
528     // DISABLE_OPTIMIZATIONS tells the runtime to disable all code optimizations
529     COR_PRF_DISABLE_OPTIMIZATIONS       = 0x00400000,
530
531     // ENABLE_OBJECT_ALLOCATED tells the runtime that the profiler may want
532     // object allocation notifications.  This must be set during initialization if the profiler
533     // ever wants object notifications (using COR_PRF_MONITOR_OBJECT_ALLOCATED)
534     COR_PRF_ENABLE_OBJECT_ALLOCATED     = 0x00800000,
535
536     // MONITOR_CLR_EXCEPTIONS controls the ExceptionCLRCatcher*
537     // callbacks.
538     COR_PRF_MONITOR_CLR_EXCEPTIONS      = 0x01000000,
539
540     // All callback events are enabled with this flag
541     COR_PRF_MONITOR_ALL                 = 0x0107FFFF,
542
543     // ENABLE_FUNCTION_ARGS enables argument tracing through FunctionEnter2.
544     COR_PRF_ENABLE_FUNCTION_ARGS        = 0X02000000,
545
546     // ENABLE_FUNCTION_RETVAL enables retval tracing through FunctionLeave2.
547     COR_PRF_ENABLE_FUNCTION_RETVAL      = 0X04000000,
548
549     // ENABLE_FRAME_INFO enables retrieval of exact ClassIDs for generic functions using
550     // GetFunctionInfo2 with a COR_PRF_FRAME_INFO obtained from FunctionEnter2.
551     COR_PRF_ENABLE_FRAME_INFO           = 0X08000000,
552
553     // ENABLE_STACK_SNAPSHOT enables the used of DoStackSnapshot calls.
554     COR_PRF_ENABLE_STACK_SNAPSHOT       = 0X10000000,
555
556     // USE_PROFILE_IMAGES causes the native image search to look for profiler-enhanced
557     // images.  If no profiler-enhanced image is found for a given assembly the
558     // runtime will fallback to JIT for that assembly.
559     COR_PRF_USE_PROFILE_IMAGES          = 0x20000000,
560
561     // COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST will disable security
562     // transparency checks normally done during JIT compilation and class loading for
563     // full trust assemblies. This can make some instrumentation easier to perform.
564     COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST
565                                         = 0x40000000,
566
567     // Prevents all NGEN images (including profiler-enhanced images) from loading.  If
568     // this and COR_PRF_USE_PROFILE_IMAGES are both specified,
569     // COR_PRF_DISABLE_ALL_NGEN_IMAGES wins.
570     COR_PRF_DISABLE_ALL_NGEN_IMAGES     = 0x80000000,
571
572     // The mask for valid mask bits
573     COR_PRF_ALL                         = 0x8FFFFFFF,
574
575     // COR_PRF_REQUIRE_PROFILE_IMAGE represents all flags that require profiler-enhanced
576     // images.
577     COR_PRF_REQUIRE_PROFILE_IMAGE       = COR_PRF_USE_PROFILE_IMAGES | 
578                                           COR_PRF_MONITOR_CODE_TRANSITIONS | 
579                                           COR_PRF_MONITOR_ENTERLEAVE,
580
581     COR_PRF_ALLOWABLE_AFTER_ATTACH      = COR_PRF_MONITOR_THREADS |
582                                           COR_PRF_MONITOR_MODULE_LOADS |
583                                           COR_PRF_MONITOR_ASSEMBLY_LOADS |
584                                           COR_PRF_MONITOR_APPDOMAIN_LOADS |
585                                           COR_PRF_ENABLE_STACK_SNAPSHOT |
586                                           COR_PRF_MONITOR_GC |
587                                           COR_PRF_MONITOR_SUSPENDS |
588                                           COR_PRF_MONITOR_CLASS_LOADS |
589                                           COR_PRF_MONITOR_EXCEPTIONS |
590                                           COR_PRF_MONITOR_JIT_COMPILATION,
591
592     // MONITOR_IMMUTABLE represents all flags that may only be set during initialization.
593     // Trying to change any of these flags elsewhere will result in a
594     // failed HRESULT.
595     COR_PRF_MONITOR_IMMUTABLE           = COR_PRF_MONITOR_CODE_TRANSITIONS |
596                                           COR_PRF_MONITOR_REMOTING |
597                                           COR_PRF_MONITOR_REMOTING_COOKIE |
598                                           COR_PRF_MONITOR_REMOTING_ASYNC |
599                                           COR_PRF_ENABLE_REJIT |
600                                           COR_PRF_ENABLE_INPROC_DEBUGGING |
601                                           COR_PRF_ENABLE_JIT_MAPS |
602                                           COR_PRF_DISABLE_OPTIMIZATIONS |
603                                           COR_PRF_DISABLE_INLINING |
604                                           COR_PRF_ENABLE_OBJECT_ALLOCATED |
605                                           COR_PRF_ENABLE_FUNCTION_ARGS |
606                                           COR_PRF_ENABLE_FUNCTION_RETVAL |
607                                           COR_PRF_ENABLE_FRAME_INFO |
608                                           COR_PRF_USE_PROFILE_IMAGES |
609                                           COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST |
610                                           COR_PRF_DISABLE_ALL_NGEN_IMAGES
611 } COR_PRF_MONITOR;
612
613 /*
614  * Additional flags the profiler can specify via SetEventMask2 when loading
615  */
616 typedef enum
617 {
618     COR_PRF_HIGH_MONITOR_NONE                       = 0x00000000,
619
620     COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES            = 0x00000001,
621
622     COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED          = 0x00000002,
623
624     COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS   = 0x00000004,
625
626     COR_PRF_HIGH_DISABLE_TIERED_COMPILATION         = 0x00000008,
627
628     COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE              = 0,
629
630     COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH             = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS,
631
632     // MONITOR_IMMUTABLE represents all flags that may only be set during initialization.
633     // Trying to change any of these flags elsewhere will result in a
634     // failed HRESULT.
635     COR_PRF_HIGH_MONITOR_IMMUTABLE                  = COR_PRF_HIGH_DISABLE_TIERED_COMPILATION,
636
637 } COR_PRF_HIGH_MONITOR;
638
639 /*
640  * COR_PRF_MISC contains miscellaneous constant ID's used for special
641  * purposes.
642  */
643 typedef enum
644 {
645     // PROFILER_PARENT_UNKNOWN is the AssemblyID used by GetModuleInfo
646     // when a module has not yet been attached to an assembly.
647     PROFILER_PARENT_UNKNOWN             = 0xFFFFFFFD,
648
649     // PROFILER_GLOBAL_CLASS is a ClassID used for globals that belong to no class
650     PROFILER_GLOBAL_CLASS               = 0xFFFFFFFE,
651
652     // PROFILER_GLOBAL_MODULE is a ModuleID used for globals that belong
653     // to no module in particular
654     PROFILER_GLOBAL_MODULE              = 0xFFFFFFFF
655 } COR_PRF_MISC;
656
657 /*
658  * COR_PRF_JIT_CACHE contains values used to express the result of a
659  * cached function search. Note that FOUND is 0, and thus this is not truly
660  * a boolean.
661  */
662 typedef enum
663 {
664     COR_PRF_CACHED_FUNCTION_FOUND,
665     COR_PRF_CACHED_FUNCTION_NOT_FOUND
666 } COR_PRF_JIT_CACHE;
667
668 /*
669  * COR_PRF_TRANSITION_REASON contains values used to describe
670  * the reason for a ManagedToUnmanaged or UnmanagedToManagedTransition
671  * callback.
672  */
673 typedef enum
674 {
675     COR_PRF_TRANSITION_CALL,
676     COR_PRF_TRANSITION_RETURN
677 } COR_PRF_TRANSITION_REASON;
678
679 /*
680  * COR_PRF_SUSPEND_REASON contains values used to describe the
681  * reason for suspending the runtime. See the RuntimeSuspension*
682  * callbacks for detailed descriptions of each.
683  */
684 typedef enum
685 {
686     COR_PRF_SUSPEND_OTHER                   = 0,
687     COR_PRF_SUSPEND_FOR_GC                  = 1,
688     COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN  = 2,
689     COR_PRF_SUSPEND_FOR_CODE_PITCHING       = 3,
690     COR_PRF_SUSPEND_FOR_SHUTDOWN            = 4,
691     COR_PRF_SUSPEND_FOR_INPROC_DEBUGGER     = 6,
692     COR_PRF_SUSPEND_FOR_GC_PREP             = 7,
693     COR_PRF_SUSPEND_FOR_REJIT               = 8,
694 } COR_PRF_SUSPEND_REASON;
695
696 /*
697  * COR_PRF_RUNTIME_TYPE contains values used to indicate the
698  * type of runtime.
699  */
700 typedef enum
701 {
702     COR_PRF_DESKTOP_CLR = 0x1,
703     COR_PRF_CORE_CLR    = 0x2,
704 } COR_PRF_RUNTIME_TYPE;
705
706
707 /* -------------------------------------------------------------------------- *
708  * Forward declarations
709  * -------------------------------------------------------------------------- */
710
711 interface ICorProfilerCallback;
712 interface ICorProfilerCallback2;
713 interface ICorProfilerCallback3;
714 interface ICorProfilerCallback4;
715 interface ICorProfilerInfo;
716 interface ICorProfilerInfo2;
717 interface ICorProfilerInfo3;
718 interface ICorProfilerInfo4;
719 interface ICorProfilerObjectEnum;
720 interface ICorProfilerFunctionEnum;
721 interface ICorProfilerModuleEnum;
722 interface ICorProfilerThreadEnum;
723 interface ICorProfilerMethodEnum;
724 interface IMethodMalloc;
725 interface ICorProfilerFunctionControl;
726 interface ICorProfilerAssemblyReferenceProvider;
727 /* -------------------------------------------------------------------------- *
728  * User Callback interface
729  * -------------------------------------------------------------------------- */
730
731 /*
732  * The ICorProfilerCallback interface is used by the CLR to notify a
733  * code profiler when events have occurred that the code profiler has registered
734  * an in interest in receiving. This is the primary callback interface through
735  * which the CLR communicates with the code profiler. A code profiler
736  * must register this callback interface in the Win32 registry. This object has
737  * several methods that receive notification from the runtime when an event is
738  * about to occur in an executing runtime process.
739  *
740  * The methods implemented on this interface return S_OK on success, or E_FAIL
741  * on failure.
742  */
743
744 [
745     object,
746     uuid(176FBED1-A55C-4796-98CA-A9DA0EF883E7),
747     pointer_default(unique),
748     local
749 ]
750 interface ICorProfilerCallback : IUnknown
751 {
752
753     /*
754      *
755      * STARTUP/SHUTDOWN EVENTS
756      *
757      */
758
759     /*
760      * The CLR calls Initialize to setup the code profiler
761      * whenever a new CLR application is started. The call provides
762      * an IUnknown interface pointer that should be QI'd for an ICorProfilerInfo
763      * interface pointer.
764      *
765      * NOTE: this is the only opportunity to enable callbacks that are a part
766      * of COR_PRF_MONITOR_IMMUTABLE, since they can no longer be changed after
767      * returning from this function.  This is done through SetEventMask on the
768      * ICorProfilerInfo object.
769      */
770     HRESULT Initialize(
771                 [in] IUnknown     *pICorProfilerInfoUnk);
772
773     /*
774      * The CLR calls Shutdown to notify the code profiler that
775      * the application is exiting.  This is the profiler's last opportunity to
776      * safely call functions on the ICorProfilerInfo interface.  After returning
777      * from this function the runtime will proceed to unravel its internal data
778      * structures and any calls to ICorProfilerInfo are undefined in their
779      * behaviour.
780      *
781      * NOTE: Certain IMMUTABLE events may still occur after Shutdown.
782      *
783      * NOTE: Shutdown will only fire where the managed application that is being
784      * profiled was started running managed code (i.e., the initial frame on the
785      * process' stack is managed).  If the application being profiled started
786      * life as unmanaged code, which later 'jumped into' managed code (thereby
787      * creating an instance of the CLR), then Shutdown will not fire.  In these
788      * cases, the profiler should include a DllMain routine in their library that
789      * uses Win32's DLL_PROCESS_DETACH call to free any resources and perform tidy-up
790      * processing of its data (flush traces to disk, etc)
791      *
792      * NOTE: The profiler must in general cope with unexpected shutdowns, such as
793      * when the process is "killed" by Win32's TerminateProcess.
794      *
795      * NOTE: Sometimes the CLR will violently kill certain managed threads
796      * (background threads) without delivering orderly destruction messages for them.
797      */
798     HRESULT Shutdown();
799
800
801     /*
802      *
803      * APPLICATION DOMAIN EVENTS
804      *
805      */
806
807     /*
808      * Called when an application domain creation has begun and ended.
809      * The ID is not valid for any information request until the Finished
810      * event is called.
811      *
812      * Some parts of app domain loading may take place lazily at some time
813      * after the Finished callback. Therefore, while a failure HRESULT in
814      * hrStatus definitely indicates a failure, a success HRESULT only indicates
815      * that the first part of app domain creation succeeded.
816      */
817     HRESULT AppDomainCreationStarted(
818                 [in] AppDomainID appDomainId);
819
820     HRESULT AppDomainCreationFinished(
821                 [in] AppDomainID appDomainId,
822                 [in] HRESULT     hrStatus);
823
824     /*
825      * Called before and after an app domain is unloaded from a process.
826      * The ID is no longer valid after the Started event returns.
827      *
828      * Some parts of app domain unloading may take place lazily at some time
829      * after the Finished callback. Therefore, while a failure HRESULT in
830      * hrStatus definitely indicates a failure, a success HRESULT only indicates
831      * that the first part of app domain unloading succeeded.
832      */
833     HRESULT AppDomainShutdownStarted(
834                 [in] AppDomainID appDomainId);
835
836     HRESULT AppDomainShutdownFinished(
837                 [in] AppDomainID appDomainId,
838                 [in] HRESULT     hrStatus);
839
840     /*
841      *
842      * ASSEMBLY EVENTS
843      *
844      */
845
846     /*
847      * Called when an Assembly load has begun and ended. The ID is not valid
848      * for any information request until the Finished event is called.
849      *
850      * Some parts of assembly loading may take place lazily at some time
851      * after the Finished callback. Therefore, while a failure HRESULT in
852      * hrStatus definitely indicates a failure, a success HRESULT only indicates
853      * that the first part of assembly loading succeeded.
854      */
855     HRESULT AssemblyLoadStarted(
856                 [in] AssemblyID assemblyId);
857
858     HRESULT AssemblyLoadFinished(
859                 [in] AssemblyID assemblyId,
860                 [in] HRESULT    hrStatus);
861
862     /*
863      * Called before and after an assembly is unloaded.
864      * The ID is no longer valid after the Started event returns.
865      *
866      * Some parts of assembly unloading may take place lazily at some time
867      * after the Finished callback. Therefore, while a failure HRESULT in
868      * hrStatus definitely indicates a failure, a success HRESULT only indicates
869      * that the first part of assembly unloading succeeded.
870      */
871     HRESULT AssemblyUnloadStarted(
872                 [in] AssemblyID assemblyId);
873
874     HRESULT AssemblyUnloadFinished(
875                 [in] AssemblyID assemblyId,
876                 [in] HRESULT    hrStatus);
877
878
879     /*
880      *
881      * MODULE EVENTS
882      *
883      */
884
885     /*
886      * Called when a module load has begun and ended. The ID is not valid
887      * for any information request until the Finished event is called.
888      *
889      * Some parts of module loading may take place lazily at some time
890      * after the Finished callback. Therefore, while a failure HRESULT in
891      * hrStatus definitely indicates a failure, a success HRESULT only indicates
892      * that the first part of module loading succeeded.
893      *
894      * Note that when a module load is reported as finished this indicates
895      * that the load has completed but it has not yet returned to the caller.
896      * This is the opportunity for the profiler to note that other notifications regarding
897      * this module may start coming afterwards however internal safeguards
898      * protecting the runtime from recursive loading are still present and so it is
899      * a bad time to begin inquiries on this module.  The notification is informational
900      * only.  
901      *
902      * Note: ModuleLoadFinished is a reasonable time to interrogate MetaData via API's 
903      * like GetModuleMetadata, however APIs that create (e.g. ClassID's and FunctionID's)
904      * are not safe to use here.  Profiler writers are advised to stay in the universe of
905      * tokens.
906      *
907      */
908     HRESULT ModuleLoadStarted(
909                 [in] ModuleID moduleId);
910
911     HRESULT ModuleLoadFinished(
912                 [in] ModuleID moduleId,
913                 [in] HRESULT  hrStatus);
914
915     /*
916      * Called before and after a module is unloaded.
917      * The ID is no longer valid after the Started event returns.
918      *
919      * Some parts of module unloading may take place lazily at some time
920      * after the Finished callback. Therefore, while a failure HRESULT in
921      * hrStatus definitely indicates a failure, a success HRESULT only indicates
922      * that the first part of module unloading succeeded.
923      */
924     HRESULT ModuleUnloadStarted(
925                 [in] ModuleID moduleId);
926
927     HRESULT ModuleUnloadFinished(
928                 [in] ModuleID moduleId,
929                 [in] HRESULT  hrStatus);
930
931     /*
932      * A module can get loaded through legacy means (ie: IAT or LoadLibrary) or
933      * through a metadata reference.  The CLR loader therefore has many code
934      * paths for determining what assembly a module lives in.  It is therefore
935      * possible that after a ModuleLoadFinished event, the module does not
936      * know what assembly it is in and getting the parent AssemblyID is not possible.
937      * This event is fired when the module is officially attached to its parent
938      * assembly.  Calling GetModuleInfo after this function is called will return the
939      * proper parent assembly.
940      */
941     HRESULT ModuleAttachedToAssembly(
942                 [in] ModuleID   moduleId,
943                 [in] AssemblyID AssemblyId);
944
945
946     /*
947      *
948      *  CLASS EVENTS
949      *
950      */
951
952     /*
953      * Called when a class load has begun and ended. The ID is not valid
954      * for any information request until the Finished event is called.
955      *
956      * Some parts of class loading may take place lazily at some time
957      * after the Finished callback. Therefore, while a failure HRESULT in
958      * hrStatus definitely indicates a failure, a success HRESULT only indicates
959      * that the first part of class loading succeeded.
960      *
961      * Note that when a class load is reported as finished this indicates
962      * that the load has completed but it has not yet returned to the caller.
963      * This is the opportunity for the profiler to note that other notifications regarding
964      * this class may start coming afterwards however internal safeguards
965      * protecting the runtime from recursive loading are still present and so it is
966      * a bad time to begin inquiries on this class.  The notification is informational
967      * only.  
968      *
969      */
970     HRESULT ClassLoadStarted(
971                 [in] ClassID classId);
972
973     HRESULT ClassLoadFinished(
974                 [in] ClassID classId,
975                 [in] HRESULT hrStatus);
976
977     /*
978      * Called before and after a class is unloaded.
979      * The ID is no longer valid after the Started event returns.
980      *
981      * Some parts of class unloading may take place lazily at some time
982      * after the Finished callback. Therefore, while a failure HRESULT in
983      * hrStatus definitely indicates a failure, a success HRESULT only indicates
984      * that the first part of class unloading succeeded.
985      */
986     HRESULT ClassUnloadStarted(
987                 [in] ClassID classId);
988
989     HRESULT ClassUnloadFinished(
990                 [in] ClassID classId,
991                 [in] HRESULT hrStatus);
992
993     /*
994      *
995      * JIT EVENTS
996      *
997      */
998
999     /*
1000      * The CLR calls FunctionUnloadStarted to notify the code
1001      * profiler that a function is being unloaded.  After returning from this
1002      * call, the FunctionID is no longer valid.
1003      */
1004     HRESULT FunctionUnloadStarted(
1005                 [in] FunctionID functionId);
1006
1007
1008     /*
1009      * The CLR calls JITCompilationStarted to notify the code
1010      * profiler that the JIT compiler is starting to compile a function.
1011      *
1012      * The fIsSafeToBlock argument tells the profiler whether or not blocking
1013      * will affect the operation of the runtime.  If true, blocking may cause
1014      * the runtime to wait for the calling thread to return from this callback.
1015      * Although this will not harm the runtime, it will skew the profiling
1016      * results.
1017      *
1018      * NOTE: It is possible to receive more than one JITCompilationStarted/
1019      * JITCompilationFinished pair for each method.  This is because of how
1020      * the runtime handles class constructors: method A starts to be JIT'd,
1021      * then realizes that the class ctor for class B needs to be run, so
1022      * JIT's it and runs it, and while it's running makes a call to original
1023      * method A, which causes it to be JIT'd again, and causes the original
1024      * (incomplete) JIT'ing of A to be aborted.  However, both attempts to
1025      * JIT A are reported with JIT compilation events.  If the profiler is
1026      * going to replace IL code for this method with SetILFunctionBody, then
1027      * it must do so for both JITCompilationStarted events, but may use the
1028      * same IL block for both.
1029      *
1030      * NOTE: A profiler should be tolerant of the sequence of JIT callbacks
1031      * received in cases where two threads are simultaneously calling a
1032      * method.  For example, thread A receives JITCompilationStarted.
1033      * But before thread A receives JITCompilationFinished, thread B
1034      * receives FunctionEnter with the functionId from thread A's
1035      * JITCompilationStarted callback.  It may appear that functionId should
1036      * not yet be valid because JITCompilationFinished had not yet been
1037      * received.  But it is indeed valid in such a case.
1038      */
1039     HRESULT JITCompilationStarted(
1040                 [in] FunctionID functionId,
1041                 [in] BOOL       fIsSafeToBlock);
1042
1043     /*
1044      * The CLR calls JITCompilationFinished to notify the code
1045      * profiler that the JIT compiler has finished compiling a function.
1046      *
1047      * The fIsSafeToBlock argument tells the profiler whether or not blocking
1048      * will affect the operation of the runtime.  If true, blocking may cause
1049      * the runtime to wait for the calling thread to return from this callback.
1050      * Although this will not harm the runtime, it will skew the profiling
1051      * results.
1052      *
1053      * The FunctionID is now valid in ICorProfilerInfo APIs.
1054      *
1055      * The hrStatus provides the success or failure of the operation
1056      */
1057     HRESULT JITCompilationFinished(
1058                 [in] FunctionID functionId,
1059                 [in] HRESULT    hrStatus,
1060                 [in] BOOL       fIsSafeToBlock);
1061
1062     /*
1063      * V2 MIGRATION WARNING: DOES NOT ALWAYS OCCUR
1064      * The JITCachedFunctionSearchStarted/Finished callbacks
1065      * will now occur only for some functions in regular NGEN images;
1066      * only profiler-optimized NGEN images will generate callbacks for
1067      * all functions in the image. Profilers which do not use these callbacks 
1068      * to force a function to be JIT-compiled should move to using a lazy
1069      * strategy for gathering function information.
1070      *
1071      * This notifies the profiler when a search for a prejitted function is
1072      * starting.
1073      *
1074      *    functionId: the function for which the search is being performed.
1075      *    bUseCachedFunction: if true, the EE uses the cached function (if applicable)
1076      *                        if false, the EE jits the function instead of
1077      *                        using a pre-jitted version.
1078      *
1079      * NOTE: Profilers should be tolerant of cases where multiple threads of
1080      * a profiled app are calling the same method simultaneously.  For example,
1081      * thread A may receive JITCachedFunctionSearchStarted (and the
1082      * profiler sets *pbUseCachedFunction=FALSE to force a JIT), thread A
1083      * then receives JITCompilationStarted/JITCompilationFinished, then
1084      * thread B receives another JITCachedFunctionSearchStarted for the same
1085      * method.  It might appear odd to receive this final callback, since the
1086      * profiler already stated its intention to JIT the method.  But this is
1087      * occurring because the CLR in thread B decided to send this callback
1088      * before thread A responded to JITCachedFunctionSearchStarted
1089      * with *pbUseCachedFunction=FALSE, and the thread B callback
1090      * hadn't actually been sent until now due how the threads
1091      * happened to be scheduled.  In such cases where the profiler
1092      * receives duplicate JITCachedFunctionSearchStarted callbacks for
1093      * the same functionId, the profiler should be certain to set
1094      * *pbUseCachedFunction to the same value from this callback
1095      * when it is called multiple times with the same functionId.
1096      */
1097     HRESULT JITCachedFunctionSearchStarted(
1098                 [in] FunctionID functionId,
1099                 [out] BOOL      *pbUseCachedFunction);
1100
1101     /*
1102      * V2 MIGRATION WARNING: DOES NOT ALWAYS OCCUR
1103      * The JITCachedFunctionSearchStarted/Finished callbacks
1104      * will now occur only for some functions in regular NGEN images;
1105      * only profiler-optimized NGEN images will generate callbacks for
1106      * all functions in the image. Profilers which do not use these callbacks 
1107      * to force a function to be JIT-compiled should move to using a lazy
1108      * strategy for gathering function information.
1109      *
1110      * This notifies the profiler when a search for a cached function has been
1111      * performed.
1112      *
1113      *    functionId: the function for which the search has been performed.
1114      *    result: the result of the search.  There are two possible results:
1115      *        COR_PRF_CACHED_FUNCTION_FOUND
1116      *        COR_PRF_CACHED_FUNCTION_NOT_FOUND
1117      *
1118      */
1119     HRESULT JITCachedFunctionSearchFinished(
1120                 [in] FunctionID        functionId,
1121                 [in] COR_PRF_JIT_CACHE result);
1122
1123     /*
1124      * The CLR calls JITFunctionPitched to notify the profiler
1125      * that a jitted function was removed from memory.  If the pitched
1126      * function is called in the future, the profiler will receive new
1127      * JIT compilation events as it is re-jitted.
1128      *
1129      * Currently the CLR JIT does not pitch functions, so this callback
1130      * will not be received.
1131      *
1132      * NOTE: the FunctionID is not valid until it is re-jitted.  When it is
1133      * re-jitted, it will use the same FunctionID value.
1134      */
1135     HRESULT JITFunctionPitched(
1136                 [in] FunctionID functionId);
1137
1138     /*
1139      * The CLR calls JITInlining to notify the profiler that the jitter
1140      * is about to inline calleeId into callerId.  Set pfShouldInline to FALSE
1141      * to prevent the callee from being inlined into the caller, and set to
1142      * TRUE to allow the inline to occur.
1143      *
1144      * NOTE: Inlined functions do not provide Enter/Leave events, so if you desire
1145      *       an accurate callgraph, you should set FALSE.  Be aware that
1146      *       setting FALSE will affect performance, since inlining typically
1147      *       increases speed and reduces separate jitting events for the inlined
1148      *       method.
1149      *
1150      * NOTE: It is also possible to globally disable inlining by setting the
1151      *       COR_PRF_DISABLE_INLINING flag.
1152      */
1153     HRESULT JITInlining(
1154                 [in] FunctionID callerId,
1155                 [in] FunctionID calleeId,
1156                 [out] BOOL      *pfShouldInline);
1157
1158     /*
1159      *
1160      * THREAD EVENTS
1161      *
1162      */
1163
1164     /*
1165      * The CLR calls ThreadCreated to notify the code profiler
1166      * that a thread has been created.  The ThreadID is valid immediately.
1167      */
1168     HRESULT ThreadCreated(
1169                 [in] ThreadID threadId);
1170
1171     /*
1172      * The CLR calls ThreadDestroyed to notify the code profiler
1173      * that a thread has been destroyed.  The ThreadID is no longer valid
1174      * at the time of this call.
1175      */
1176     HRESULT ThreadDestroyed(
1177                 [in] ThreadID threadId);
1178
1179     /*
1180      * The CLR calls ThreadAssignedToOSThread to tell the profiler
1181      * that a managed thread is being implemented via a particualr OS thread.
1182      * This callback exists so that the profiler can maintain an accurate
1183      * OS to Managed thread mapping across fibres.
1184      */
1185     HRESULT ThreadAssignedToOSThread(
1186                 [in] ThreadID managedThreadId,
1187                 [in] DWORD    osThreadId);
1188
1189     /*
1190      *
1191      * REMOTING EVENTS
1192      *
1193      */
1194
1195     //
1196     // Client-side events
1197     //
1198
1199     /*
1200      * NOTE: each of the following pairs of callbacks will occur on the same
1201      *       thread
1202      *   RemotingClientInvocationStarted  & RemotingClientSendingMessage
1203      *   RemotingClientReceivingReply     & RemotingClientInvocationFinished
1204      *   RemotingServerInvocationReturned & RemotingServerSendingReply
1205      *
1206      * There are a few issues with the remoting callbacks that should be outlined.
1207      * First, remoting function execution is not reflected by the profiler API, so
1208      * the notifications for functions that are called from the client and executed
1209      * to the server are not properly received. The actual invocation happens via a
1210      * proxy object. That creates the illusion to the profiler that certain
1211      * functions get jit-compiled but they never get used. Second, the profiler does
1212      * not receive accurate notifications for asynchronous remoting events.
1213      */
1214
1215     /*
1216      * The CLR calls RemotingClientInvocationStarted to notify the profiler that
1217      * a remoting call has begun.  This event is the same for synchronous and
1218      * asynchronous calls.
1219      */
1220     HRESULT RemotingClientInvocationStarted();
1221
1222     /*
1223      * The CLR calls RemotingClientSendingMessage to notify the profiler that
1224      * a remoting call is requiring the the caller to send an invocation request through
1225      * a remoting channel.
1226      *
1227      * pCookie  - if remoting GUID cookies are active, this value will correspond with the
1228      *            the value provided in RemotingServerReceivingMessage, if the channel
1229      *            succeeds in transmitting the message, and if GUID cookies are active on
1230      *            the server-side process.  This allows easy pairing of remoting calls,
1231      *            and the creation of a logical call stack.
1232      * fIsAsync - is true if the call is asynchronous.
1233      */
1234     HRESULT RemotingClientSendingMessage(
1235                 [in] GUID *pCookie,
1236                 [in] BOOL fIsAsync);
1237
1238     /*
1239      * The CLR calls RemotingClientReceivingReply to notify the profiler that
1240      * the server-side portion of a remoting call has completed and that the client is
1241      * now receiving and about to process the reply.
1242      *
1243      * pCookie  - if remoting GUID cookies are active, this value will correspond with the
1244      *            the value provided in RemotingServerSendingReply, if the channel
1245      *            succeeds in transmitting the message, and if GUID cookies are active on
1246      *            the server-side process.  This allows easy pairing of remoting calls.
1247      * fIsAsync - is true if the call is asynchronous.
1248      */
1249     HRESULT RemotingClientReceivingReply(
1250                 [in] GUID *pCookie,
1251                 [in] BOOL fIsAsync);
1252
1253     /*
1254      * The CLR calls RemotingClientInvocationFinished to notify the profiler that
1255      * a remoting invocation has run to completion on the client side.  If the call was
1256      * synchronous, this means that it has also run to completion on the server side.  If
1257      * the call was asynchronous, a reply may still be expected when the call is handled.
1258      * If the call is asynchronous, and a reply is expected, then the reply will occur in
1259      * the form of a call to RemotingClientReceivingReply and an additional call to
1260      * RemotingClientInvocationFinished to indicate the required secondary processing of
1261      * an asynchronous call.
1262      */
1263     HRESULT RemotingClientInvocationFinished();
1264
1265     //
1266     // Server-side events
1267     //
1268
1269     /*
1270      * The CLR calls RemotingServerReceivingMessage to notify the profiler that
1271      * the process has received a remote method invocation (or activation) request.  If
1272      * the message request is asynchronous, then the request may be serviced by any
1273      * arbitrary thread.
1274      *
1275      * pCookie  - if remoting GUID cookies are active, this value will correspond with the
1276      *            the value provided in RemotingClientSendingMessage, if the channel
1277      *            succeeds in transmitting the message, and if GUID cookies are active on
1278      *            the client-side process.  This allows easy pairing of remoting calls.
1279      * fIsAsync - is true if the call is asynchronous.
1280      */
1281     HRESULT RemotingServerReceivingMessage(
1282                 [in] GUID *pCookie,
1283                 [in] BOOL fIsAsync);
1284
1285     /*
1286      * The CLR calls RemotingServerInvocationStarted to notify the profiler that
1287      * the process is invoking a method due to a remote method invocation request.
1288      */
1289     HRESULT RemotingServerInvocationStarted();
1290
1291     /*
1292      * The CLR calls RemotingServerInvocationReturned to notify the profiler that
1293      * the process has finished invoking a method due to a remote method invocation request.
1294      */
1295     HRESULT RemotingServerInvocationReturned();
1296
1297     /*
1298      * The CLR calls RemotingServerSendingReply to notify the profiler that
1299      * the process has finished processing a remote method invocation request and is
1300      * about to transmit the reply through a channel.
1301      *
1302      * pCookie  - if remoting GUID cookies are active, this value will correspond with the
1303      *            the value provided in RemotingClientReceivingReply, if the channel
1304      *            succeeds in transmitting the message, and if GUID cookies are active on
1305      *            the client-side process.  This allows easy pairing of remoting calls.
1306      * fIsAsync - is true if the call is asynchronous.
1307      */
1308     HRESULT RemotingServerSendingReply(
1309                 [in] GUID *pCookie,
1310                 [in] BOOL fIsAsync);
1311
1312     /*
1313      *
1314      * TRANSITION EVENTS
1315      *
1316      */
1317
1318     /*
1319      * The CLR calls UnmanagedToManagedTransition to notify the
1320      * code profiler that a transition from unmanaged code to managed code has
1321      * occurred. functionId is always the ID of the callee, and reason
1322      * indicates whether the transition was due to a call into managed code from
1323      * unmanaged, or a return from an unmanaged function called by a managed one.
1324      *
1325      * Note that if the reason is COR_PRF_TRANSITION_RETURN and the functionId is
1326      * non-NULL, then the functionId is that of the unmanaged function, and will
1327      * never have been jitted. Unmanaged functions still have some basic
1328      * information associated with them, such as a name, and some metadata.
1329      *
1330      * Note that if the reason is COR_PRF_TRANSITION_RETURN and the callee was
1331      * a PInvoke call indirect, then the runtime does not know the destination
1332      * of the call and functionId will be NULL.
1333      *
1334      * Note that if the reason is COR_PRF_TRANSITION_CALL then it may be possible
1335      * that the callee has not yet been JIT-compiled.
1336      */
1337     HRESULT UnmanagedToManagedTransition(
1338                 [in] FunctionID                functionId,
1339                 [in] COR_PRF_TRANSITION_REASON reason);
1340
1341
1342     /*
1343      * The CLR calls ManagedToUnmanagedTransition to notify the
1344      * code profiler that a transition from managed code to unmanaged code has
1345      * occurred. functionId is always the ID of the callee, and reason
1346      * indicates whether the transition was due to a call into unmanaged code from
1347      * managed, or a return from an managed function called by an unmanaged one.
1348      *
1349      * Note that if the reason is COR_PRF_TRANSITION_CALL, then the functionId
1350      * is that of the unmanaged function, and will never have been jitted.
1351      * Unmanaged functions still have some basic information associated with
1352      * them, such as a name, and some metadata.
1353      *
1354      * Note that if the reason is COR_PRF_TRANSITION_CALL and the callee is
1355      * a PInvoke call indirect, then the runtime does not know the destination
1356      * of the call and functionId will be NULL.
1357      */
1358     HRESULT ManagedToUnmanagedTransition(
1359                 [in] FunctionID                functionId,
1360                 [in] COR_PRF_TRANSITION_REASON reason);
1361
1362
1363     /*
1364      *
1365      * RUNTIME SUSPENSION EVENTS
1366      *
1367      */
1368
1369     /*
1370      * The CLR calls RuntimeSuspendStarted to notify the code profiler
1371      * that the runtime is about to suspend all of the runtime threads.
1372      * All runtime threads that are in unmanaged code are permitted to continue
1373      * running until they try to re-enter the runtime, at which point they will
1374      * also suspend until the runtime resumes.  This also applies to new threads
1375      * that enter the runtime.  All threads within the runtime are either
1376      * suspended immediately if they are in interruptible code, or asked to
1377      * suspend when they do reach interruptible code.
1378      *
1379      * suspendReason make be any of the following values:
1380      *  COR_PRF_SUSPEND_FOR_GC
1381      *      the runtime is suspending to service a GC request.  The GC-related
1382      *      callbacks will occur between the RuntimeSuspendFinished and
1383      *      RuntimeResumeStarted events.
1384      *  COR_PRF_SUSPEND_FOR_CODE_PITCHING
1385      *      the runtime is suspending so that code pitching may occur.  This
1386      *      only occurs when the EJit is active with code pitching enabled.
1387      *      Code pitching callbacks will occur between the
1388      *      RuntimeSuspendFinished and RuntimeResumeStarted events.
1389      *  COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN
1390      *      the runtime is suspending so that an AppDomain can be shut down.
1391      *      While the runtime is suspended, the runtime will determine which
1392      *      threads are in the AppDomain that is being shut down, set them to
1393      *      abort when they resume, and then resumes the runtime.  There are
1394      *      no AppDomain-specific callbacks during this suspension.
1395      *  COR_PRF_SUSPEND_FOR_SHUTDOWN
1396      *      the runtime is shutting down, and it must suspend all threads to
1397      *      complete the operation.
1398      *  COR_PRF_SUSPEND_FOR_GC_PREP
1399      *      the runtime is preparing for a GC.
1400      *  COR_PRF_SUSPEND_FOR_INPROC_DEBUGGER
1401      *      the runtime is suspending for in-process debugging.
1402      *  COR_PRF_SUSPEND_OTHER
1403      *      the runtime is suspending for a reason other than those above.
1404      */
1405     HRESULT RuntimeSuspendStarted(
1406             [in] COR_PRF_SUSPEND_REASON suspendReason);
1407
1408     /*
1409      * The CLR calls RuntimeSuspendFinished to notify the code profiler
1410      * that the runtime has suspended all threads needed for a runtime
1411      * suspension.  Note that not all runtime threads are required to be
1412      * suspended, as described in the comment for RuntimeSuspendStarted.
1413      *
1414      * NOTE: It is guaranteed that this event will occur on the same ThreadID
1415      * as RuntimeSuspendStarted occurred on.
1416      */
1417     HRESULT RuntimeSuspendFinished();
1418
1419     /*
1420      * The CLR calls RuntimeSuspendAborted to notify the code profiler
1421      * that the runtime is aborting the runtime suspension that was occurring.
1422      * This may occur if two threads simultaneously attempt to suspend the
1423      * runtime.
1424      *
1425      * NOTE: It is guaranteed that this event will occur on the same ThreadID
1426      * as the RuntimeSuspendStarted occurred on, and that only one of
1427      * RuntimeSuspendFinished and RuntimeSuspendAborted may occur on a single
1428      * thread following a RuntimeSuspendStarted event.
1429      */
1430     HRESULT RuntimeSuspendAborted();
1431
1432     /*
1433      * The CLR calls RuntimeResumeStarted to notify the code profiler
1434      * that the runtime is about to resume all of the runtime threads.
1435      */
1436     HRESULT RuntimeResumeStarted();
1437
1438     /*
1439      * The CLR calls RuntimeResumeFinished to notify the code profiler
1440      * that the runtime has finished resuming all of it's threads and is now
1441      * back in normal operation.
1442      *
1443      * NOTE: It is *NOT* guaranteed that this event will occur on the same
1444      * ThreadID as the RuntimeSuspendStarted occurred on, but is guaranteed
1445      * to occur on the same ThreadID as the RuntimeResumeStarted occurred on.
1446      */
1447     HRESULT RuntimeResumeFinished();
1448
1449     /*
1450      * The CLR calls RuntimeThreadSuspended to notify the code profiler
1451      * that a particular thread has been suspended. 
1452      *
1453      * This notification may occur any time between the RuntimeSuspendStarted
1454      * and the associated RuntimeResumeStarted. Notifications that occur
1455      * between RuntimeSuspendFinished and RuntimeResumeStarted are for
1456      * threads that had been running in unmanaged code and were suspended
1457      * upon entry to the runtime.
1458      */
1459     HRESULT RuntimeThreadSuspended(
1460                     [in] ThreadID threadId);
1461
1462     /*
1463      * The CLR calls RuntimeThreadResumed to notify the code profiler
1464      * that a particular thread has been resumed after being suspended due to
1465      * a runtime suspension.
1466      */
1467     HRESULT RuntimeThreadResumed(
1468                     [in] ThreadID threadId);
1469
1470     /*
1471      *
1472      * GC EVENTS
1473      *
1474      * NOTE: All of these callbacks (except ObjectAllocated) are made while the
1475      *       runtime is suspended, so none of the ObjectID values can change until
1476      *       the runtime resumes and another GC occurs.
1477      *
1478      * NOTE: The profiler will receive GC-related events (except ObjectAllocated)
1479      *       when the profiler has been suspended for COR_PRF_SUSPEND_FOR_GC *except*
1480      *       for one special case.  When the runtime is shutting down, there is a
1481      *       stage where it is suspended for COR_PRF_SUSPEND_FOR_SHUTDOWN reason and
1482      *       is never resumed.  But after this suspension a garbage collection may
1483      *       occur without a COR_PRF_SUSPEND_FOR_GC suspension notification, and
1484      *       the profiler will thus receive GC-related callbacks.
1485      *
1486      * NOTE: All of these callbacks (except ObjectAllocated) may be called more than
1487      *       once during the same GC. These calls should be considered multiple parts of
1488      *       one long report; the profiler should simply aggregate the information provided
1489      *       in all of them.
1490      */
1491
1492     /*
1493      * The CLR calls MovedReferences with information about
1494      * object references that moved as a result of garbage collection.
1495      *
1496      * cMovedObjectIDRanges is a count of the number of ObjectID ranges that
1497      *      were moved.
1498      * oldObjectIDRangeStart is an array of elements, each of which is the start
1499      *      value of a range of ObjectID values before being moved.
1500      * newObjectIDRangeStart is an array of elements, each of which is the start
1501      *      value of a range of ObjectID values after being moved.
1502      * cObjectIDRangeLength is an array of elements, each of which states the
1503      *      size of the moved ObjectID value range.
1504      *
1505      * The last three arguments of this function are parallel arrays.
1506      *
1507      * In other words, if an ObjectID value lies within the range
1508      *      oldObjectIDRangeStart[i] <= ObjectID < oldObjectIDRangeStart[i] + cObjectIDRangeLength[i]
1509      * for 0 <= i < cMovedObjectIDRanges, then the ObjectID value has changed to
1510      *      ObjectID - oldObjectIDRangeStart[i] + newObjectIDRangeStart[i]
1511      *
1512      * NOTE: None of the objectIDs returned by MovedReferences are valid during the callback
1513      * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
1514      * should not attempt to inspect objects during a MovedReferences call. At 
1515      * GarbageCollectionFinished, all objects have been moved to their new locations, and
1516      * inspection may be done.
1517      *
1518      * THIS CALLBACK IS OBSOLETE. It reports ranges for objects >4GB as ULONG_MAX 
1519      * on 64-bit platforms. Use ICorProfilerCallback4::MovedReferences2 instead.
1520      */
1521     HRESULT MovedReferences(
1522                 [in]                                ULONG    cMovedObjectIDRanges,
1523                 [in, size_is(cMovedObjectIDRanges)] ObjectID oldObjectIDRangeStart[] ,
1524                 [in, size_is(cMovedObjectIDRanges)] ObjectID newObjectIDRangeStart[] ,
1525                 [in, size_is(cMovedObjectIDRanges)] ULONG    cObjectIDRangeLength[] );
1526
1527     /*
1528      * The CLR calls ObjectAllocated to notify the code profiler
1529      * an object was allocated on the heap. This notification does not fire
1530      * for allocations from the stack, nor from unmanaged memory.
1531      *
1532      * It is possible to receive a classId that corresponds to a regular class
1533      * that has not been loaded yet. The profiler will receive a class load
1534      * callback for that class immediately after the object creation callback.
1535      */
1536     HRESULT ObjectAllocated(
1537                 [in] ObjectID objectId,
1538                 [in] ClassID classId);
1539
1540     /*
1541      * The CLR calls ObjectsAllocatedByClass to notify the code
1542      * profiler about the number of objects of a particular class that were
1543      * allocated since the previous garbage collection. The classes and the
1544      * counts are passed in parallel arrays. (Classes for which no instances
1545      * have been allocated since the previous GC are omitted entirely.)
1546      *
1547      * NOTE: This callback will not report objects allocated in the large
1548      *       object heap.
1549      *
1550      * NOTE: The numbers here are only estimates. Use ObjectAllocated for
1551      *       exact counts.
1552      */
1553     HRESULT ObjectsAllocatedByClass(
1554                 [in]                       ULONG   cClassCount,
1555                 [in, size_is(cClassCount)] ClassID classIds[] ,
1556                 [in, size_is(cClassCount)] ULONG   cObjects[] );
1557
1558     /*
1559      * The CLR calls ObjectReferences to provide information
1560      * about objects in memory referenced by a given object.  This function
1561      * is called for each object remaining in the GC heap after a collection
1562      * has completed.  If the profiler returns an error from this callback,
1563      * the profiling services will discontinue invoking this callback until the
1564      * next GC.  This callback can be used in conjunction with the
1565      * RootReferences callback to create a complete object reference graph for
1566      * the runtime.
1567      *
1568      * NOTE: The CLR will ensure that each object reference is reported only
1569      * once by this function.
1570      *
1571      * NOTE: None of the objectIDs returned by ObjectReferences are valid during the callback
1572      * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
1573      * should not attempt to inspect objects during an ObjectReferences call. At 
1574      * GarbageCollectionFinished, all objects have been moved to their new locations, and
1575      * inspection may be done.
1576      */
1577     HRESULT ObjectReferences(
1578                 [in]                       ObjectID objectId,
1579                 [in]                       ClassID  classId,
1580                 [in]                       ULONG    cObjectRefs,
1581                 [in, size_is(cObjectRefs)] ObjectID objectRefIds[] );
1582
1583     /*
1584      * The CLR calls RootReferences with information about root
1585      * references after a garbage collection has occurred. Static object
1586      * references and references to objects on a stack are co-mingled in the
1587      * arrays.
1588      *
1589      * NOTE: It is possible to get NULL ObjectIDs in the RootReferences callback.
1590      * For example, all object references declared on the stack are treated as
1591      * roots by the GC, and will always be reported.
1592      *
1593      * NOTE: None of the objectIDs returned by RootReferences are valid during the callback
1594      * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
1595      * should not attempt to inspect objects during a RootReferences call. At 
1596      * GarbageCollectionFinished, all objects have been moved to their new locations, and
1597      * inspection may be done.
1598      */
1599     HRESULT RootReferences(
1600                 [in]                     ULONG    cRootRefs,
1601                 [in, size_is(cRootRefs)] ObjectID rootRefIds[] );
1602
1603
1604     /*
1605      *
1606      * EXCEPTION EVENTS
1607      *
1608      */
1609
1610     //
1611     // Exception creation
1612     //
1613
1614     /*
1615      * The CLR calls ExceptionThrown to notify the code
1616      * profiler that an exception has been thrown.
1617      *
1618      * NOTE: This function is only called if the exception reaches
1619      *       managed code.
1620      *
1621      * NOTE: The profiler should not block here, since the stack may not be in a
1622      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1623      *       profiler blocks here and a GC is attempted, the runtime will block
1624      *       until this callback returns.  Also, the profiler may NOT call into
1625      *       managed code or in any way cause a managed memory allocation.
1626      */
1627     HRESULT ExceptionThrown(
1628                 [in] ObjectID thrownObjectId);
1629
1630     //
1631     // Search phase
1632     //
1633
1634     /*
1635      * The CLR calls ExceptionSearchFunctionEnter to notify the profiler
1636      * that the search phase of exception handling has entered a function.
1637      */
1638     HRESULT ExceptionSearchFunctionEnter(
1639                 [in] FunctionID functionId);
1640
1641     /*
1642      * The CLR calls ExceptionSearchFunctionLeave to notify the profiler
1643      * that the search phase of exception handling has left a function.
1644      */
1645     HRESULT ExceptionSearchFunctionLeave();
1646
1647     /*
1648      * The CLR will call ExceptionSearchFilterEnter just before excecuting
1649      * a user filter.  The functionID is that of the function containing the filter.
1650      */
1651     HRESULT ExceptionSearchFilterEnter(
1652                 [in] FunctionID functionId);
1653
1654     /*
1655      * The CLR will call ExceptionSearchFilterLeave immediately after
1656      * executing a user filter.
1657      */
1658     HRESULT ExceptionSearchFilterLeave();
1659
1660     /*
1661      * The CLR will call ExceptionSearchCatcherFound when the search
1662      * phase of exception handling has located a handler for the exception that
1663      * was thrown.
1664      */
1665     HRESULT ExceptionSearchCatcherFound(
1666                 [in] FunctionID functionId);
1667
1668     /*
1669      * DEPRECATED. It is the job of the unmanaged profiler to detect OS
1670      * handling of exceptions.
1671      */
1672     HRESULT ExceptionOSHandlerEnter(
1673                 [in] UINT_PTR __unused);
1674
1675     /*
1676      * DEPRECATED. It is the job of the unmanaged profiler to detect OS
1677      * handling of exceptions.
1678      */
1679     HRESULT ExceptionOSHandlerLeave(
1680                 [in] UINT_PTR __unused);
1681
1682     //
1683     // Unwind phase
1684     //
1685
1686     /*
1687      * The CLR calls ExceptionUnwindFunctionEnter to notify the profiler
1688      * that the unwind phase of exception handling has entered a function.
1689      *
1690      * NOTE: The profiler should not block here, since the stack may not be in a
1691      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1692      *       profiler blocks here and a GC is attempted, the runtime will block
1693      *       until this callback returns.  Also, the profiler may NOT call into
1694      *       managed code or in any way cause a managed memory allocation.
1695      */
1696     HRESULT ExceptionUnwindFunctionEnter(
1697                 [in] FunctionID functionId);
1698
1699     /*
1700      * The CLR calls ExceptionUnwindFunctionLeave to notify the profiler
1701      * that the unwind phase of exception handling has left a function.  The
1702      * function instance and it's stack data has now been removed from the stack.
1703      *
1704      * NOTE: The profiler should not block here, since the stack may not be in a
1705      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1706      *       profiler blocks here and a GC is attempted, the runtime will block
1707      *       until this callback returns.  Also, the profiler may NOT call into
1708      *       managed code or in any way cause a managed memory allocation.
1709      */
1710     HRESULT ExceptionUnwindFunctionLeave();
1711
1712     /*
1713      * The CLR calls ExceptionUnwindFinallyEnter to notify the profiler
1714      * that the unwind phase of exception is entering a finally clause contained
1715      * in the specified function.
1716      *
1717      * NOTE: The profiler should not block here, since the stack may not be in a
1718      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1719      *       profiler blocks here and a GC is attempted, the runtime will block
1720      *       until this callback returns.  Also, the profiler may NOT call into
1721      *       managed code or in any way cause a managed memory allocation.
1722      */
1723     HRESULT ExceptionUnwindFinallyEnter(
1724                 [in] FunctionID functionId);
1725
1726     /*
1727      * The CLR calls ExceptionUnwindFinallyLeave to notify the profiler
1728      * that the unwind phase of exception is leaving a finally clause.
1729      *
1730      * NOTE: The profiler should not block here, since the stack may not be in a
1731      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1732      *       profiler blocks here and a GC is attempted, the runtime will block
1733      *       until this callback returns.  Also, the profiler may NOT call into
1734      *       managed code or in any way cause a managed memory allocation.
1735      */
1736     HRESULT ExceptionUnwindFinallyLeave();
1737
1738     /*
1739      * The CLR calls this function just before passing control to
1740      * the appropriate catch block.  Note that this is called only if the
1741      * catch point is in JIT'ed code.  An exception that is caught in
1742      * unmanaged code, or in the internal code of the CLR will
1743      * not generate this notification.  The ObjectID is passed again since
1744      * a GC could have moved the object since the ExceptionThrown
1745      * notification.
1746      *
1747      * NOTE: The profiler should not block here, since the stack may not be in a
1748      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1749      *       profiler blocks here and a GC is attempted, the runtime will block
1750      *       until this callback returns.  Also, the profiler may NOT call into
1751      *       managed code or in any way cause a managed memory allocation.
1752      */
1753     HRESULT ExceptionCatcherEnter(
1754                 [in] FunctionID functionId,
1755                 [in] ObjectID   objectId);
1756
1757     /*
1758      * The CLR calls ExceptionCatcherLeave when the runtime leaves
1759      * the catcher's code.
1760      *
1761      * NOTE: The profiler should not block here, since the stack may not be in a
1762      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1763      *       profiler blocks here and a GC is attempted, the runtime will block
1764      *       until this callback returns.  Also, the profiler may NOT call into
1765      *       managed code or in any way cause a managed memory allocation.
1766      */
1767     HRESULT ExceptionCatcherLeave();
1768
1769     /*
1770      *  CLR<->COM interop vtable creation/destruction.
1771      */
1772
1773     /*
1774      * The CLR calls this function when an CLR<->COM interop vtable
1775      * for a particular IID and for a particular class has been created.
1776      * This provides the ClassID of the class for which this vtable has been
1777      * created, the IID it implements, the start of the vtable and how many
1778      * slots are in it.
1779      *
1780      * NOTE: The profiler should not block here, since the stack may not be in a
1781      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1782      *       profiler blocks here and a GC is attempted, the runtime will block
1783      *       until this callback returns.  Also, the profiler may NOT call into
1784      *       managed code or in any way cause a managed memory allocation.
1785      *
1786      * NOTE: It is possible to receive a NULL GUID if the interface is
1787      *       internal only.
1788      */
1789     HRESULT COMClassicVTableCreated(
1790                [in] ClassID wrappedClassId,
1791                [in] REFGUID implementedIID,
1792                [in] void    *pVTable,
1793                [in] ULONG   cSlots);
1794
1795     /*
1796      * The CLR calls this function when a CLR<->COM interop vtable is
1797      * being destroyed.  Provided are the ClassID, IID and vtable pointer for
1798      * the destroyed vtable.
1799      *
1800      * NOTE: The profiler should not block here, since the stack may not be in a
1801      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
1802      *       profiler blocks here and a GC is attempted, the runtime will block
1803      *       until this callback returns.  Also, the profiler may NOT call into
1804      *       managed code or in any way cause a managed memory allocation.
1805      *
1806      * NOTE: It is possible to receive a NULL GUID if the interface is
1807      *       internal only.
1808      *
1809      * NOTE: This callback is likely never to occur, since the destruction of
1810      *       vtables occurs very close to Shutdown.
1811      */
1812     HRESULT COMClassicVTableDestroyed(
1813                [in] ClassID wrappedClassId,
1814                [in] REFGUID implementedIID,
1815                [in] void    *pVTable);
1816
1817     /*
1818      * DEPRECATED. These callbacks are no longer delivered.
1819      */
1820     HRESULT ExceptionCLRCatcherFound();
1821
1822     HRESULT ExceptionCLRCatcherExecute();
1823 }
1824
1825 /*
1826  * COR_PRF_GC_ROOT_KIND describes the kind of GC root exposed by
1827  * the RootReferences2 callback.
1828  */
1829
1830 typedef enum
1831 {
1832     COR_PRF_GC_ROOT_STACK = 1,        // Variables on the stack
1833     COR_PRF_GC_ROOT_FINALIZER = 2,    // Entry in the finalizer queue
1834     COR_PRF_GC_ROOT_HANDLE = 3,        // GC Handle
1835     COR_PRF_GC_ROOT_OTHER = 0        //Misc. roots
1836 }   COR_PRF_GC_ROOT_KIND;
1837
1838
1839 /*
1840  * COR_PRF_GC_ROOT_FLAGS describes properties of a GC root
1841  * exposed by the RootReferences callback.
1842  */
1843
1844 typedef enum
1845 {  
1846     COR_PRF_GC_ROOT_PINNING = 0x1,    // Prevents GC from moving the object
1847     COR_PRF_GC_ROOT_WEAKREF = 0x2,    // Does not prevent collection
1848     COR_PRF_GC_ROOT_INTERIOR = 0x4,   // Refers to a field of the object rather than the object itself
1849     COR_PRF_GC_ROOT_REFCOUNTED = 0x8, // Whether it prevents collection depends on a refcount - if not,
1850                                       // COR_PRF_GC_ROOT_WEAKREF will be set also
1851 }   COR_PRF_GC_ROOT_FLAGS;
1852
1853  
1854 /*
1855  * COR_PRF_FINALIZER_FLAGS is used by FinalizableObjectQueued to describe
1856  * the finalizer for the object.
1857  */
1858
1859 typedef enum
1860 {
1861     COR_PRF_FINALIZER_CRITICAL = 0x1    // Critical finalizer
1862 }   COR_PRF_FINALIZER_FLAGS;
1863
1864  
1865 /*
1866  * COR_PRF_GC_GENERATION contains the numbers used to represent each GC generation
1867  * in the GetGenerationBounds and GetObjectGeneration functions.
1868  */
1869
1870 typedef enum
1871 {
1872     COR_PRF_GC_GEN_0 = 0,
1873     COR_PRF_GC_GEN_1 = 1,
1874     COR_PRF_GC_GEN_2 = 2,
1875     COR_PRF_GC_LARGE_OBJECT_HEAP = 3
1876 }   COR_PRF_GC_GENERATION;
1877
1878
1879 /*
1880  * COR_PRF_GC_GENERATION_RANGE describes a range of memory in the GetGenerationBounds and GetObjectGeneration functions.
1881  * Note that the rangeLength member is only guaranteed to be accurate if GetGenerationBounds or GetObjectGeneration are
1882  * called from a GarbageCollectionStarted or GarbageCollectionFinished notification
1883  */
1884 typedef struct COR_PRF_GC_GENERATION_RANGE
1885 {
1886     COR_PRF_GC_GENERATION   generation;             // what generation the range of memory belongs to
1887     ObjectID                rangeStart;             // the start of the range
1888     UINT_PTR                rangeLength;            // the used length of the range
1889     UINT_PTR                rangeLengthReserved;    // the amount of memory reserved for the range (including rangeLength)
1890
1891 }   COR_PRF_GC_GENERATION_RANGE;
1892
1893
1894
1895 /*
1896  * COR_PRF_CLAUSE_TYPE defines the various clause codes for the EX clauses
1897  */
1898 typedef enum
1899 {
1900     COR_PRF_CLAUSE_NONE = 0,  // not a real clause (only used in error cases)
1901     COR_PRF_CLAUSE_FILTER = 1,  
1902     COR_PRF_CLAUSE_CATCH = 2,  
1903     COR_PRF_CLAUSE_FINALLY = 3, 
1904 }   COR_PRF_CLAUSE_TYPE;
1905
1906 /*
1907  * COR_PRF_EX_CLAUSE_INFO identifies a specific exception clause instance and its associated frame. 
1908  * When an exception notification is received, GetNotifiedExceptionClauseInfo() may be used to get the 
1909  * native address and frame information for the exception clause (catch/finally/filter) that is 
1910  * about to be run (ExceptionCatchEnter, ExceptionUnwindFinallyEnter, ExceptionFilterEnter) or has just 
1911  * been run (ExceptionCatchLeave, ExceptionUnwindFinallyLeave, ExceptionFilterLeave).  
1912  */
1913 typedef struct COR_PRF_EX_CLAUSE_INFO 
1914 {
1915     COR_PRF_CLAUSE_TYPE  clauseType; // the type of clause we just entered or left
1916     UINT_PTR  programCounter;   // the native entry point of the clause handler (e.g. EIP)
1917     UINT_PTR framePointer;    // the logical frame pointer (e.g. EBP) for that clause handler
1918     UINT_PTR shadowStackPointer;  // the shadow stack pointer (IA64 only, BSP)
1919 }   COR_PRF_EX_CLAUSE_INFO;
1920
1921 /*
1922  * COR_PRF_GC_REASON describes the reason for a given GC.
1923  */
1924 typedef enum
1925 {
1926     COR_PRF_GC_INDUCED = 1,     // Induced by GC.Collect
1927     COR_PRF_GC_OTHER = 0        // Anything else
1928 }   COR_PRF_GC_REASON;
1929
1930 /*
1931  * Bits from COR_PRF_MODULE_FLAGS are returned to the profiler in GetModuleInfo2's
1932  * pdwModuleFlags output parameter. Some combinations of 2 or more flags are possible,
1933  * though not all combinations are possible.
1934  */ 
1935 typedef enum
1936 {
1937     // The module was loaded from disk
1938     COR_PRF_MODULE_DISK             = 0x00000001,
1939     
1940     // The module had been generated via NGEN
1941     COR_PRF_MODULE_NGEN             = 0x00000002,
1942     
1943     // The module was created via methods in the Reflection.Emit namespace
1944     COR_PRF_MODULE_DYNAMIC          = 0x00000004,
1945     
1946     // The module's lifetime is managed by the garbage collector.
1947     COR_PRF_MODULE_COLLECTIBLE      = 0x00000008,
1948     
1949     // The module contains no metadata and is used strictly as a resource.  The managed
1950     // equivalent of this bit is the System.Reflection.Module.IsResource() method.
1951     COR_PRF_MODULE_RESOURCE         = 0x00000010,
1952     
1953     // The module's layout in memory is flat, as opposed to mapped. For modules that have
1954     // this bit set, profilers that directly read information out of the PE header will
1955     // need to be careful when interpreting RVAs present in the PE header.
1956     COR_PRF_MODULE_FLAT_LAYOUT      = 0x00000020,
1957
1958     // The Windows Runtime content type flag is set in the metadata for this module's
1959     // assembly
1960     COR_PRF_MODULE_WINDOWS_RUNTIME  = 0x00000040,
1961 }   COR_PRF_MODULE_FLAGS;
1962 /*
1963  * The ICorProfilerCallback2 interface is used by the CLR to notify a
1964  * code profiler when events have occurred that the code profiler has registered
1965  * an in interest in receiving.  These are new callbacks implemented in V2.0
1966  * of the runtime.
1967  *
1968  * The methods implemented on this interface return S_OK on success, or E_FAIL
1969  * on failure.
1970  */
1971
1972 [
1973     object,
1974     uuid(8A8CC829-CCF2-49fe-BBAE-0F022228071A),
1975     pointer_default(unique),
1976     local
1977 ]
1978 interface ICorProfilerCallback2 : ICorProfilerCallback
1979 {
1980
1981     /*
1982      *
1983      * THREAD EVENTS
1984      *
1985      */
1986
1987     /*
1988      * The CLR calls ThreadNameChanged to notify the code profiler
1989      * that a thread's name has changed.
1990      *
1991      * name is not NULL terminated.
1992      *
1993      */
1994     HRESULT ThreadNameChanged(
1995                 [in] ThreadID threadId,
1996                 [in] ULONG cchName,
1997                 [in, annotation("_In_reads_opt_(cchName)")] WCHAR name[]);
1998
1999     /*
2000      *
2001      * GARBAGE COLLECTION EVENTS
2002      *
2003      */
2004
2005     /*
2006      * The CLR calls GarbageCollectionStarted before beginning a 
2007      * garbage collection. All GC callbacks pertaining to this
2008      * collection will occur between the GarbageCollectionStarted
2009      * callback and the corresponding GarbageCollectionFinished
2010      * callback. Corresponding GarbageCollectionStarted and 
2011      * GarbageCollectionFinished callbacks need not occur on the same thread.
2012      *
2013      *          cGenerations indicates the total number of entries in
2014      *                the generationCollected array
2015      *          generationCollected is an array of booleans, indexed
2016      *                by COR_PRF_GC_GENERATIONS, indicating which
2017      *                generations are being collected in this collection
2018      *          reason indicates whether this GC was induced
2019      *                by the application calling GC.Collect().
2020      *
2021      * NOTE: It is safe to inspect objects in their original locations
2022      * during this callback. The GC will begin moving objects after
2023      * the profiler returns from this callback. Therefore, after 
2024      * returning, the profiler should consider all ObjectIDs to be invalid
2025      * until it receives a GarbageCollectionFinished callback.
2026      */
2027     HRESULT GarbageCollectionStarted(
2028                 [in] int cGenerations,
2029                 [in, size_is(cGenerations)] BOOL generationCollected[],
2030                 [in] COR_PRF_GC_REASON reason);
2031
2032     /*
2033      * The CLR calls SurvivingReferences with information about
2034      * object references that survived a garbage collection.
2035      *
2036      * Generally, the CLR calls SurvivingReferences for non-compacting garbage collections.
2037      * For compacting garbage collections, MovedReferences is called instead.
2038      *
2039      * The exception to this rule is that the CLR always calls SurvivingReferences for objects
2040      * in the large object heap, which is not compacted.
2041      *
2042      * Multiple calls to SurvivingReferences may be received during a particular
2043      * garbage collection, due to limited internal buffering, multiple threads reporting
2044      * in the case of server gc, and other reasons.
2045      * In the case of multiple calls, the information is cumulative - all of the references
2046      * reported in any SurvivingReferences call survive this collection.
2047      *
2048      * cSurvivingObjectIDRanges is a count of the number of ObjectID ranges that
2049      *      survived.
2050      * objectIDRangeStart is an array of elements, each of which is the start
2051      *      value of a range of ObjectID values that survived the collection.
2052      * cObjectIDRangeLength is an array of elements, each of which states the
2053      *      size of the surviving ObjectID value range.
2054      *
2055      * The last two arguments of this function are parallel arrays.
2056      *
2057      * In other words, if an ObjectID value lies within the range
2058      *      objectIDRangeStart[i] <= ObjectID < objectIDRangeStart[i] + cObjectIDRangeLength[i]
2059      * for 0 <= i < cMovedObjectIDRanges, then the ObjectID has survived the collection
2060      *
2061      * THIS CALLBACK IS OBSOLETE. It reports ranges for objects >4GB as ULONG_MAX 
2062      * on 64-bit platforms. Use ICorProfilerCallback4::SurvivingReferences2 instead.
2063      */
2064     HRESULT SurvivingReferences(
2065                 [in]                                    ULONG    cSurvivingObjectIDRanges,
2066                 [in, size_is(cSurvivingObjectIDRanges)] ObjectID objectIDRangeStart[] ,
2067                 [in, size_is(cSurvivingObjectIDRanges)] ULONG    cObjectIDRangeLength[] );
2068     /*
2069      * The CLR calls GarbageCollectionFinished after a garbage
2070      * collection has completed and all GC callbacks have been
2071      * issued for it.
2072      *
2073      * NOTE: It is now safe to inspect objects in their
2074      * final locations.
2075      */
2076     HRESULT GarbageCollectionFinished();
2077
2078     /*
2079      * The CLR calls FinalizeableObjectQueued to notify the code profiler
2080      * that an object with a finalizer (destructor in C# parlance) has
2081      * just been queued to the finalizer thread for execution of its
2082      * Finalize method.
2083      *
2084      * finalizerFlags describes aspects of the finalizer, and takes its
2085      *     value from COR_PRF_FINALIZER_FLAGS.
2086      *
2087      */
2088
2089     HRESULT FinalizeableObjectQueued(
2090                 [in] DWORD finalizerFlags,
2091                 [in] ObjectID objectID);
2092
2093     /*
2094      * The CLR calls RootReferences2 with information about root
2095      * references after a garbage collection has occurred.
2096      * For each root reference in rootRefIds, there is information in
2097      * rootClassifications to classify it. Depending on the classification,
2098      * rootsIds may contain additional information. The information in
2099      * rootKinds and rootFlags contains information about the location and
2100      * properties of the reference.
2101      *
2102      * If the profiler implements ICorProfilerCallback2, both
2103      * ICorProfilerCallback::RootReferences and ICorProfilerCallback2::RootReferences2
2104      * are called. As the information passed to RootReferences2 is a superset
2105      * of the one passed to RootReferences, profilers will normally implement
2106      * one or the other, but not both.
2107      *
2108      * If the root kind is STACK, the ID is the FunctionID of the
2109      * function containing the variable. If the FunctionID is 0, the function
2110      * is an unnamed function internal to the CLR.
2111      *
2112      * If the root kind is HANDLE, the ID is the GCHandleID.
2113      *
2114      * For the other root kinds, the ID is an opaque value and should
2115      * be ignored.
2116      *
2117      * It's possible for entries in rootRefIds to be 0 - this just
2118      * implies the corresponding root reference was null and thus did not
2119      * refer to an object on the managed heap.
2120      *
2121      * NOTE: None of the objectIDs returned by RootReferences2 are valid during the callback
2122      * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
2123      * should not attempt to inspect objects during a RootReferences2 call. At 
2124      * GarbageCollectionFinished, all objects have been moved to their new locations, and
2125      * inspection may be done.
2126      */
2127
2128     HRESULT RootReferences2(
2129                 [in]                     ULONG    cRootRefs,
2130                 [in, size_is(cRootRefs)] ObjectID rootRefIds[],
2131                 [in, size_is(cRootRefs)] COR_PRF_GC_ROOT_KIND rootKinds[],
2132                 [in, size_is(cRootRefs)] COR_PRF_GC_ROOT_FLAGS rootFlags[],
2133                 [in, size_is(cRootRefs)] UINT_PTR rootIds[]);
2134
2135     /*
2136      * The CLR calls HandleCreated when a gc handle has been created.
2137      *
2138      */
2139
2140     HRESULT HandleCreated(
2141                 [in] GCHandleID handleId,
2142                 [in] ObjectID initialObjectId);
2143
2144     /*
2145      * The CLR calls HandleDestroyed when a gc handle has been destroyed.
2146      *
2147      */
2148
2149     HRESULT HandleDestroyed(
2150                 [in] GCHandleID handleId);
2151 }
2152
2153 [
2154     object,
2155     uuid(4FD2ED52-7731-4b8d-9469-03D2CC3086C5),
2156     pointer_default(unique),
2157     local
2158 ]
2159 interface ICorProfilerCallback3 : ICorProfilerCallback2
2160 {
2161     HRESULT InitializeForAttach(
2162                 [in] IUnknown * pCorProfilerInfoUnk,
2163                 [in] void * pvClientData,
2164                 [in] UINT cbClientData);
2165
2166     HRESULT ProfilerAttachComplete();
2167
2168     HRESULT ProfilerDetachSucceeded();
2169 };
2170
2171 [
2172     object,
2173     uuid(7B63B2E3-107D-4d48-B2F6-F61E229470D2),
2174     pointer_default(unique),
2175     local
2176 ]
2177 interface ICorProfilerCallback4 : ICorProfilerCallback3
2178 {
2179     /*
2180      * Similar to JITCompilationStarted, except called when rejitting a method
2181      */
2182     HRESULT ReJITCompilationStarted(
2183                 [in] FunctionID functionId,
2184                 [in] ReJITID rejitId,
2185                 [in] BOOL fIsSafeToBlock);
2186
2187     /*
2188      * This is called exactly once per method (which may represent more than
2189      * one function id), to allow the code profiler to set alternate code
2190      * generation flags or a new method body.
2191      */
2192     HRESULT GetReJITParameters(
2193                 [in] ModuleID moduleId,
2194                 [in] mdMethodDef methodId,
2195                 [in] ICorProfilerFunctionControl *pFunctionControl);
2196
2197     /*
2198      * Similar to JITCompilationFinished, except called when rejitting a method
2199      */
2200     HRESULT ReJITCompilationFinished(
2201                 [in] FunctionID functionId,
2202                 [in] ReJITID rejitId,
2203                 [in] HRESULT hrStatus,
2204                 [in] BOOL fIsSafeToBlock);
2205
2206     /*
2207      * This is called to report an error encountered while processing a ReJIT request.
2208      * This may either be called from within the RequestReJIT call itself, or called after 
2209      * RequestReJIT returns, if the error was encountered later on.
2210      */
2211     HRESULT ReJITError(
2212                 [in] ModuleID moduleId,
2213                 [in] mdMethodDef methodId,
2214                 [in] FunctionID functionId,
2215                 [in] HRESULT hrStatus);
2216
2217     /*
2218      * The CLR calls MovedReferences with information about
2219      * object references that moved as a result of garbage collection.
2220      *
2221      * cMovedObjectIDRanges is a count of the number of ObjectID ranges that
2222      *      were moved.
2223      * oldObjectIDRangeStart is an array of elements, each of which is the start
2224      *      value of a range of ObjectID values before being moved.
2225      * newObjectIDRangeStart is an array of elements, each of which is the start
2226      *      value of a range of ObjectID values after being moved.
2227      * cObjectIDRangeLength is an array of elements, each of which states the
2228      *      size of the moved ObjectID value range.
2229      *
2230      * The last three arguments of this function are parallel arrays.
2231      *
2232      * In other words, if an ObjectID value lies within the range
2233      *      oldObjectIDRangeStart[i] <= ObjectID < oldObjectIDRangeStart[i] + cObjectIDRangeLength[i]
2234      * for 0 <= i < cMovedObjectIDRanges, then the ObjectID value has changed to
2235      *      ObjectID - oldObjectIDRangeStart[i] + newObjectIDRangeStart[i]
2236      *
2237      * NOTE: None of the objectIDs returned by MovedReferences are valid during the callback
2238      * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
2239      * should not attempt to inspect objects during a MovedReferences call. At 
2240      * GarbageCollectionFinished, all objects have been moved to their new locations, and
2241      * inspection may be done.
2242      *
2243      * If the profiler implements ICorProfilerCallback4, ICorProfilerCallback4::MovedReferences2 
2244      * is called first and ICorProfilerCallback::MovedReferences is called second but only if 
2245      * ICorProfilerCallback4::MovedReferences2 returned success. Profilers can return failure 
2246      * from ICorProfilerCallback4::MovedReferences2 to save some chattiness.
2247      */
2248     HRESULT MovedReferences2(
2249                 [in]                                ULONG    cMovedObjectIDRanges,
2250                 [in, size_is(cMovedObjectIDRanges)] ObjectID oldObjectIDRangeStart[] ,
2251                 [in, size_is(cMovedObjectIDRanges)] ObjectID newObjectIDRangeStart[] ,
2252                 [in, size_is(cMovedObjectIDRanges)] SIZE_T   cObjectIDRangeLength[] );
2253
2254     /*
2255      * The CLR calls SurvivingReferences with information about
2256      * object references that survived a garbage collection.
2257      *
2258      * Generally, the CLR calls SurvivingReferences for non-compacting garbage collections.
2259      * For compacting garbage collections, MovedReferences is called instead.
2260      *
2261      * The exception to this rule is that the CLR always calls SurvivingReferences for objects
2262      * in the large object heap, which is not compacted.
2263      *
2264      * Multiple calls to SurvivingReferences may be received during a particular
2265      * garbage collection, due to limited internal buffering, multiple threads reporting
2266      * in the case of server gc, and other reasons.
2267      * In the case of multiple calls, the information is cumulative - all of the references
2268      * reported in any SurvivingReferences call survive this collection.
2269      *
2270      * cSurvivingObjectIDRanges is a count of the number of ObjectID ranges that
2271      *      survived.
2272      * objectIDRangeStart is an array of elements, each of which is the start
2273      *      value of a range of ObjectID values that survived the collection.
2274      * cObjectIDRangeLength is an array of elements, each of which states the
2275      *      size of the surviving ObjectID value range.
2276      *
2277      * The last two arguments of this function are parallel arrays.
2278      *
2279      * In other words, if an ObjectID value lies within the range
2280      *      objectIDRangeStart[i] <= ObjectID < objectIDRangeStart[i] + cObjectIDRangeLength[i]
2281      * for 0 <= i < cMovedObjectIDRanges, then the ObjectID has survived the collection
2282      *
2283      * If the profiler implements ICorProfilerCallback4, ICorProfilerCallback4::SurvivingReferences2 
2284      * is called first and ICorProfilerCallback2::SurvivingReferences is called second but only if 
2285      * ICorProfilerCallback4::SurvivingReferences2 returned success. Profilers can return failure 
2286      * from ICorProfilerCallback4::SurvivingReferences2 to save some chattiness.
2287      */
2288     HRESULT SurvivingReferences2(
2289                 [in]                                    ULONG    cSurvivingObjectIDRanges,
2290                 [in, size_is(cSurvivingObjectIDRanges)] ObjectID objectIDRangeStart[] ,
2291                 [in, size_is(cSurvivingObjectIDRanges)] SIZE_T   cObjectIDRangeLength[] );
2292
2293 };
2294
2295
2296 [
2297     object,
2298     uuid(8DFBA405-8C9F-45F8-BFFA-83B14CEF78B5),
2299     pointer_default(unique),
2300     local
2301 ]
2302 interface ICorProfilerCallback5 : ICorProfilerCallback4
2303 {
2304     /*
2305      * The CLR calls ConditionalWeakTableElementReferences with information 
2306      * about dependent handles after a garbage collection has occurred.
2307      *
2308      * For each root ID in rootIds, keyRefIds will contain the ObjectID for 
2309      * the primary element in the dependent handle pair, and valueRefIds will
2310      * contain the ObjectID for the secondary element (keyRefIds[i] keeps 
2311      * valueRefIds[i] alive).
2312      *
2313      * NOTE: None of the objectIDs returned by ConditionalWeakTableElementReferences
2314      * are valid during the callback itself, as the GC may be in the middle 
2315      * of moving objects from old to new. Thus profilers should not attempt 
2316      * to inspect objects during a ConditionalWeakTableElementReferences call.
2317      * At GarbageCollectionFinished, all objects have been moved to their new
2318      * locations, and inspection may be done.
2319      */
2320     HRESULT ConditionalWeakTableElementReferences(
2321                 [in]                     ULONG    cRootRefs,
2322                 [in, size_is(cRootRefs)] ObjectID keyRefIds[],
2323                 [in, size_is(cRootRefs)] ObjectID valueRefIds[],
2324                 [in, size_is(cRootRefs)] GCHandleID rootIds[]);
2325 };
2326
2327
2328 [
2329     object,
2330     uuid(FC13DF4B-4448-4F4F-950C-BA8D19D00C36),
2331     pointer_default(unique),
2332     local
2333 ]
2334 interface ICorProfilerCallback6 : ICorProfilerCallback5
2335 {
2336     // Controlled by the COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES event mask flag.
2337     // Notifies the profiler of a very early stage in the loading of an Assembly, where the CLR
2338     // performs an assembly reference closure walk.  This is useful ONLY if the profiler will need
2339     // to modify the metadata of the Assembly to add AssemblyRefs (later, in ModuleLoadFinished).  In
2340     // such a case, the profiler should implement this callback as well, to inform the CLR that assembly references
2341     // will be added once the module has loaded.  This is useful to ensure that assembly sharing decisions
2342     // made by the CLR during this early stage remain valid even though the profiler plans to modify the metadata
2343     // assembly references later on.  This can be used to avoid some instances where profiler metadata
2344     // modifications can cause the SECURITY_E_INCOMPATIBLE_SHARE error to be thrown.
2345     //
2346     // The profiler uses the ICorProfilerAssemblyReferenceProvider provided to add assembly references
2347     // to the CLR assembly reference closure walker.  The ICorProfilerAssemblyReferenceProvider
2348     // should only be used from within this callback. The profiler will still need to explicitly add assembly 
2349     // references via IMetaDataAssemblyEmit, from within the ModuleLoadFinished callback for the referencing assembly,
2350     // even though the profiler implements this GetAssemblyReferences callback.  This callback does not result in
2351     // modified metadata; only in a modified assembly reference closure walk.
2352     // 
2353     // The profiler should be prepared to receive duplicate calls to this callback for the same assembly,
2354     // and should respond identically for each such duplicate call (by making the same set of
2355     // ICorProfilerAssemblyReferenceProvider::AddAssemblyReference calls).
2356     HRESULT GetAssemblyReferences(
2357         [in, string] const WCHAR * wszAssemblyPath,
2358         [in] ICorProfilerAssemblyReferenceProvider * pAsmRefProvider);
2359 };
2360
2361
2362 [
2363     object,
2364     uuid(F76A2DBA-1D52-4539-866C-2AA518F9EFC3),
2365     pointer_default(unique),
2366     local
2367 ]
2368 interface ICorProfilerCallback7 : ICorProfilerCallback6
2369 {
2370     // This event is triggered whenever the symbol stream associated with an
2371     // in-memory module is updated. Even when symbols are provided up-front in
2372     // a call to the managed API Assembly.Load(byte[], byte[], ...) the runtime
2373     // may not actually associate the symbolic data with the module until after
2374     // the ModuleLoadFinished callback has occured. This event provides a later
2375     // opportunity to collect symbols for such modules.
2376     //
2377     // This event is controlled by the COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED
2378     // event mask flag.
2379     //
2380     // Note: This event is not currently raised for symbols implicitly created or
2381     // modified via Reflection.Emit APIs.
2382     HRESULT ModuleInMemorySymbolsUpdated(ModuleID moduleId);
2383 }
2384
2385
2386 [
2387     object,
2388     uuid(5BED9B15-C079-4D47-BFE2-215A140C07E0),
2389     pointer_default(unique),
2390     local
2391 ]
2392 interface ICorProfilerCallback8 : ICorProfilerCallback7
2393 {
2394     // This event is triggered whenever a dynamic method is jit compiled.
2395     // These include various IL Stubs and LCG Methods.
2396     // The goal is to provide profiler writers with enough information to identify
2397     // it to users as beyond unknown code addresses.
2398     // Note: FunctionID's provided here cannot be used to resolve to their metadata
2399     //       tokens since dynamic methods have no metadata.
2400     //
2401     // Documentation Note: pILHeader is only valid during the callback
2402
2403     HRESULT DynamicMethodJITCompilationStarted(
2404         [in] FunctionID functionId,
2405         [in] BOOL       fIsSafeToBlock,
2406         [in] LPCBYTE    pILHeader,
2407         [in] ULONG      cbILHeader);
2408
2409     HRESULT DynamicMethodJITCompilationFinished(
2410         [in] FunctionID functionId,
2411         [in] HRESULT    hrStatus,
2412         [in] BOOL       fIsSafeToBlock);
2413 }
2414
2415 [
2416     object,
2417     uuid(27583EC3-C8F5-482F-8052-194B8CE4705A),
2418     pointer_default(unique),
2419     local
2420 ]
2421 interface ICorProfilerCallback9 : ICorProfilerCallback8
2422 {
2423     // This event is triggered whenever a dynamic method is garbage collected
2424     // and subsequently unloaded.
2425
2426     HRESULT DynamicMethodUnloaded([in] FunctionID functionId);
2427 }
2428
2429
2430 /*
2431  * COR_PRF_CODEGEN_FLAGS controls various flags and hooks for a specific
2432  * method.  A combination of COR_PRF_CODEGEN_FLAGS is provided by the
2433  * profiler in its call to ICorProfilerFunctionControl::SetCodegenFlags()
2434  * when rejitting a method.
2435  */
2436 typedef enum
2437 {
2438     COR_PRF_CODEGEN_DISABLE_INLINING =          0x0001,
2439     COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS = 0x0002,
2440 } COR_PRF_CODEGEN_FLAGS;
2441
2442
2443 /*
2444  * The CLR implements the ICorProfilerInfo interface. This interface is
2445  * used by a code profiler to communicate with the CLR to control event
2446  * monitoring and request information. The CLR passes an
2447  * ICorProfilerInfo interface to each code profiler during initialization.
2448  *
2449  * A code profiler can call methods on the ICorProfilerInfo interface to get
2450  * information about managed code being executed under the control of the CLR
2451  *
2452  * The ICorProfilerInfo interface implemented by the CLR uses the free
2453  * threaded model.
2454  *
2455  * The methods implemented on this interface return S_OK on success, or E_FAIL
2456  * on failure.
2457  *
2458  */
2459
2460 [
2461     object,
2462     uuid(28B5557D-3F3F-48b4-90B2-5F9EEA2F6C48),
2463     pointer_default(unique),
2464     local
2465 ]
2466 interface ICorProfilerInfo : IUnknown
2467 {
2468     /*
2469      * The code profiler calls GetClassFromObject to obtain the ClassID of an
2470      * object given its ObjectID.
2471      */
2472     HRESULT GetClassFromObject(
2473                 [in]  ObjectID objectId,
2474                 [out] ClassID *pClassId);
2475
2476     /*
2477      * V2 MIGRATION WARNING - DOES NOT WORK FOR GENERIC TYPES
2478      *
2479      * This function will be removed in a future release, so
2480      * use GetClassFromTokenAndTypeArgs for all types.
2481      */
2482     HRESULT GetClassFromToken(
2483                 [in]  ModuleID  moduleId,
2484                 [in]  mdTypeDef typeDef,
2485                 [out] ClassID   *pClassId);
2486
2487     /*
2488      * V2 MIGRATION WARNING - WILL NOT WORK WITH .NET FRAMEWORK
2489      * FUNCTIONS
2490      *
2491      * This function will be removed in a future release; use GetCodeInfo2
2492      * in all cases.
2493      */
2494     HRESULT GetCodeInfo(
2495                 [in]  FunctionID functionId,
2496                 [out] LPCBYTE    *pStart,
2497                 [out] ULONG      *pcSize);
2498
2499     /*
2500      * RECOMMENDATION: USE GetEventMask2 INSTEAD.  WHILE THIS METHOD CONTINUES TO
2501      * TO WORK, GetEventMask2 PROVIDES MORE FUNCTIONALITY.
2502      *
2503      * The code profiler calls GetEventMask to obtain the current event
2504      * categories for which it is to receive event notifications from the COM+
2505      * Runtime.
2506      */
2507     HRESULT GetEventMask(
2508                 [out] DWORD *pdwEvents);
2509
2510     /*
2511      * The code profiler calls GetFunctionFromIP to map an instruction pointer
2512      * in managed code to a FunctionID.
2513      */
2514     HRESULT GetFunctionFromIP(
2515                 [in]  LPCBYTE    ip,
2516                 [out] FunctionID *pFunctionId);
2517
2518     /*
2519      * V2 MIGRATION WARNING - WILL NOT WORK FOR GENERIC FUNCTIONS OR
2520      * FUNCTIONS ON GENERIC TYPES
2521      *
2522      * This function will be removed in a future release, so use
2523      * GetFunctionFromTokenAndTypeArgs for all functions.
2524      */
2525     HRESULT GetFunctionFromToken(
2526                 [in]  ModuleID   moduleId,
2527                 [in]  mdToken    token,
2528                 [out] FunctionID *pFunctionId);
2529
2530     /*
2531      * The code profiler calls GetHandleFromThread to map a ThreadID to a Win32
2532      * thread handle. The profiler must call DuplicateHandle on the handle
2533      * before using it.
2534      */
2535     HRESULT GetHandleFromThread(
2536                 [in]  ThreadID threadId,
2537                 [out] HANDLE  *phThread);
2538
2539     /*
2540      * The code profiler calls GetObjectSize to obtain the size of an object.
2541      * Note that types like arrays and strings may have a different size for each object.
2542      *
2543      * THIS API IS OBSOLETE. It does not work for objects >4GB on 64-bit platforms.
2544      * Use ICorProfilerInfo4::GetObjectSize2 instead.
2545      */
2546     HRESULT GetObjectSize(
2547                 [in]  ObjectID objectId,
2548                 [out] ULONG  *pcSize);
2549
2550     /*
2551      * This will return S_OK if the ClassID provided is an array class, and will
2552      * fill out the information for any non-null out params.  S_FALSE will be
2553      * returned if the ClassID is not an array.
2554      *
2555      * classId       : the ClassID to return information about
2556      * pBaseElemType : the array's base element type
2557      * pBaseClassId  : the base ClassID if the element type == ELEMENT_TYPE_CLASS
2558      * pcRank        : the number of dimensions of the array
2559      */
2560     HRESULT IsArrayClass(
2561                 [in]  ClassID        classId,
2562                 [out] CorElementType *pBaseElemType,
2563                 [out] ClassID        *pBaseClassId,
2564                 [out] ULONG          *pcRank);
2565
2566     /*
2567      * The code profiler calls GetThreadInfo to obtain the current Win32 thread ID for
2568      * the specified thread.
2569      */
2570     HRESULT GetThreadInfo(
2571                 [in]  ThreadID threadId,
2572                 [out] DWORD    *pdwWin32ThreadId);
2573
2574     /*
2575      * The code profiler calls GetCurrentThreadID to get the managed thread ID
2576      * for the current thread.
2577      *
2578      * NOTE: GetCurrentThreadID may return CORPROF_E_NOT_MANAGED_THREAD if the
2579      * current thread is an internal runtime thread, and the returned value of
2580      * pThreadId will be NULL.
2581      */
2582     HRESULT GetCurrentThreadID(
2583                 [out] ThreadID *pThreadId);
2584
2585     /*
2586      * V2 MIGRATION NOTE - More information is available for generic types
2587      * from GetClassIDInfo2.
2588      *
2589      * Returns the parent module a class is defined in, along with the
2590      * metadata token for the class.  One can call GetModuleMetaData
2591      * to obtain the metadata interface for a given module.  The token
2592      * can then be used to access the metadata for this class.
2593      */
2594     HRESULT GetClassIDInfo(
2595                 [in]  ClassID   classId,
2596                 [out] ModuleID  *pModuleId,
2597                 [out] mdTypeDef *pTypeDefToken);
2598
2599     /*
2600      * Return the parent class for a given function.  Also return the metadata
2601      * token which can be used to read the metadata.
2602      *
2603      * V2 MIGRATION WARNING - LESS INFORMATION FOR GENERIC CLASSES
2604      * The ClassID of a function on a generic class may not be obtainable without
2605      * more context about the use of the function. In this case, *pClassId will be 0;
2606      * try using GetFunctionInfo2 with a COR_PRF_FRAME_INFO to give more context.
2607      */
2608     HRESULT GetFunctionInfo(
2609                 [in]  FunctionID functionId,
2610                 [out] ClassID    *pClassId,
2611                 [out] ModuleID   *pModuleId,
2612                 [out] mdToken    *pToken);
2613
2614     /*
2615      * RECOMMENDATION: USE SetEventMask2 INSTEAD.  WHILE THIS METHOD CONTINUES TO
2616      * TO WORK, SetEventMask2 PROVIDES MORE FUNCTIONALITY.
2617      *
2618      * The code profiler calls SetEventMask to set the event categories for
2619      * which it is set to receive notification from the CLR.
2620      */
2621     HRESULT SetEventMask(
2622                 [in] DWORD dwEvents);
2623
2624     /*
2625      * The code profiler calls SetFunctionHooks to specify handlers
2626      * for FunctionEnter, FunctionLeave, and FunctionTailcall.
2627      *
2628      * Note that only one set of callbacks may be active at a time. Thus,
2629      * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
2630      * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
2631      * wins.  SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
2632      * when both are set.
2633      *
2634      * Each function pointer may be null to disable that callback.
2635      *
2636      * SetEnterLeaveFunctionHooks may only be called from the
2637      * profiler's Initialize() callback.
2638      */
2639     HRESULT SetEnterLeaveFunctionHooks(
2640                 [in] FunctionEnter    *pFuncEnter,
2641                 [in] FunctionLeave    *pFuncLeave,
2642                 [in] FunctionTailcall *pFuncTailcall);
2643
2644     /*
2645      * This is used for mapping FunctionIDs to alternative values that will be
2646      * passed to the callbacks
2647      */
2648     HRESULT SetFunctionIDMapper(
2649                 [in] FunctionIDMapper *pFunc);
2650
2651     /*
2652      * For a given function, retrieve the token value and an instance of the
2653      * meta data interface which can be used against this token.
2654      */
2655     HRESULT GetTokenAndMetaDataFromFunction(
2656                 [in]  FunctionID functionId,
2657                 [in]  REFIID     riid,
2658                 [out] IUnknown   **ppImport,
2659                 [out] mdToken    *pToken);
2660
2661     /*
2662      * Retrieve information about a given module.
2663      *
2664      * When the module is loaded from disk, the name returned will be the filename;
2665      * otherwise, the name will be the name from the metadata Module table (i.e., 
2666      * the same as the managed System.Reflection.Module.ScopeName).
2667      *
2668      * NOTE: While this function may be called as soon as the moduleId is alive,
2669      * the AssemblyID of the containing assembly will not be available until the
2670      * ModuleAttachedToAssembly callback.
2671      *
2672      * NOTE: More information is available by using ICorProfilerInfo3::GetModuleInfo2 instead.
2673      */
2674     HRESULT GetModuleInfo(
2675                 [in]  ModuleID   moduleId,
2676                 [out] LPCBYTE    *ppBaseLoadAddress,
2677                 [in]  ULONG      cchName,
2678                 [out] ULONG      *pcchName,
2679                 [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
2680                       WCHAR      szName[] ,
2681                 [out] AssemblyID *pAssemblyId);
2682
2683     /*
2684      * Get a metadata interface instance which maps to the given module.
2685      * One may ask for the metadata to be opened in read+write mode, but
2686      * this will result in slower metadata execution of the program, because
2687      * changes made to the metadata cannot be optimized as they were from
2688      * the compiler.
2689      *
2690      * NOTE: Some modules (such as resource modules) have no metadata. In
2691      * those cases, GetModuleMetaData will return S_FALSE, and a NULL
2692      * IUnknown.
2693      *
2694      * NOTE: the only values valid for dwOpenFlags are ofRead and ofWrite.
2695      */
2696     HRESULT GetModuleMetaData(
2697                 [in]  ModuleID moduleId,
2698                 [in]  DWORD    dwOpenFlags,
2699                 [in]  REFIID   riid,
2700                 [out] IUnknown **ppOut);
2701
2702     /*
2703      * Retrieve a pointer to the body of a method starting at it's header.
2704      * A method is scoped by the module it lives in.  Because this function
2705      * is designed to give a tool access to IL before it has been loaded
2706      * by the Runtime, it uses the metadata token of the method to find
2707      * the instance desired.
2708      *
2709      * GetILFunctionBody can return CORPROF_E_FUNCTION_NOT_IL if the methodId
2710      * points to a method without any IL (such as an abstract method, or a
2711      * P/Invoke method).
2712      */
2713     HRESULT GetILFunctionBody(
2714                 [in]  ModuleID    moduleId,
2715                 [in]  mdMethodDef methodId,
2716                 [out] LPCBYTE     *ppMethodHeader,
2717                 [out] ULONG       *pcbMethodSize);
2718
2719     /*
2720      * IL method bodies must be located as RVA's to the loaded module, which
2721      * means they come after the module within 4 gb.  In order to make it
2722      * easier for a tool to swap out the body of a method, this allocator
2723      * will ensure memory is allocated within that range.
2724      */
2725     HRESULT GetILFunctionBodyAllocator(
2726                 [in]  ModuleID      moduleId,
2727                 [out] IMethodMalloc **ppMalloc);
2728
2729     /*
2730      * Replaces the method body for a function in a module.  This will replace
2731      * the RVA of the method in the metadata to point to this new method body,
2732      * and adjust any internal data structures as required.  This function can
2733      * only be called on those methods which have never been compiled by a JITTER.
2734      * Please use the GetILFunctionAllocator to allocate space for the new method to
2735      * ensure the buffer is compatible.
2736      */
2737     HRESULT SetILFunctionBody(
2738                 [in] ModuleID    moduleId,
2739                 [in] mdMethodDef methodid,
2740                 [in] LPCBYTE     pbNewILMethodHeader);
2741
2742     /*
2743      * Retrieve app domain information given its id.
2744      */
2745     HRESULT GetAppDomainInfo(
2746                 [in]  AppDomainID appDomainId,
2747                 [in]  ULONG       cchName,
2748                 [out] ULONG       *pcchName,
2749                 [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
2750                       WCHAR       szName[] ,
2751                 [out] ProcessID   *pProcessId);
2752
2753     /*
2754      * Retrieve information about an assembly given its ID.
2755      */
2756     HRESULT GetAssemblyInfo(
2757                 [in]  AssemblyID  assemblyId,
2758                 [in]  ULONG       cchName,
2759                 [out] ULONG       *pcchName,
2760                 [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
2761                       WCHAR       szName[] ,
2762                 [out] AppDomainID *pAppDomainId,
2763                 [out] ModuleID    *pModuleId);
2764
2765
2766     /*
2767      * V2 MIGRATION WARNING: DEPRECATED.  Returns E_NOTIMPL always.
2768      *
2769      * See ICorProfilerInfo4::RequestReJIT instead
2770      *
2771      */
2772     HRESULT SetFunctionReJIT(
2773                 [in] FunctionID functionId);
2774
2775     /*
2776      * ForceGC forces a GC to occur within the runtime.
2777      *
2778      * NOTE: This method needs to be called from a thread that does not have any
2779      * profiler callbacks on its stack. The most convenient way to implement this is
2780      * to create a separate thread within the profiler and have it call ForceGC when
2781      * signalled.
2782      */
2783     HRESULT ForceGC();
2784
2785     /*
2786      *
2787      * V2 MIGRATION NOTE - Calling SetILInstrumentedCodeMap on any one
2788      * of the multiple FunctionIDs that represent a generic function in a given
2789      * AppDomain will affect all instantiations of that function in the AppDomain.
2790      *
2791      * fStartJit should be set to true the first time this function is called for
2792      * a given FunctionID, and false thereafter.
2793      *
2794      * The format of the map is as follows:
2795      *      The debugger will assume that each oldOffset refers to an IL offset
2796      *  within the original, unmodified IL code.  newOffset refers to the corresponding
2797      *  IL offset within the new, instrumented code.
2798      *
2799      * The map should be sorted in increasing order. For stepping to work properly:
2800      * - Instrumented IL should not be reordered (so both old & new are sorted)
2801      * - original IL should not be removed
2802      * - the map should include entries to map all of the sequence points from the pdb.
2803      *
2804      * The map does not interpolate missing entries. So given the following map:
2805      * (0 old, 0  new)
2806      * (5 old, 10 new)
2807      * (9 old, 20 new)
2808      * - An old offset of 0,1,2,3,4 will be mapped to a new offset of 0
2809      * - An old offset of 5,6,7, or 8 will be mapped to new offset 10.
2810      * - An old offset of 9 or higher will be mapped to new offset 20.
2811      * - A new offset of 0, 1,...8,9 will be mapped to old offset 0
2812      * - A new offset of 10,11,...18,19 will be mapped to old offset 5.
2813      * - A new offset of 20 or higher will be mapped to old offset 9.
2814      *
2815      */
2816     HRESULT SetILInstrumentedCodeMap(
2817                 [in]                         FunctionID functionId,
2818                 [in]                         BOOL       fStartJit,
2819                 [in]                         ULONG      cILMapEntries,
2820                 [in, size_is(cILMapEntries)] COR_IL_MAP rgILMapEntries[] );
2821
2822     /*
2823      * DEPRECATED.
2824      */
2825     HRESULT GetInprocInspectionInterface(
2826                 [out] IUnknown **ppicd);
2827
2828     /*
2829      * DEPRECATED.
2830      */
2831     HRESULT GetInprocInspectionIThisThread(
2832                 [out] IUnknown **ppicd);
2833
2834     /*
2835      * This will return the ContextID currently associated with the calling
2836      * runtime thread.  This will set pContextId to NULL if the calling thread
2837      * is not a runtime thread.
2838      */
2839     HRESULT GetThreadContext(
2840                 [in]  ThreadID  threadId,
2841                 [out] ContextID *pContextId);
2842
2843     /*
2844      * DEPRECATED.
2845      */
2846     HRESULT BeginInprocDebugging(
2847                 [in]  BOOL   fThisThreadOnly,
2848                 [out] DWORD *pdwProfilerContext);
2849
2850     /*
2851      * DEPRECATED.
2852      */
2853     HRESULT EndInprocDebugging(
2854                 [in]  DWORD dwProfilerContext);
2855
2856     /*
2857      * GetILToNativeMapping returns a map from IL offsets to native
2858      * offsets for this code. An array of COR_PROF_IL_TO_NATIVE_MAP
2859      * structs will be returned, and some of the ilOffsets in this array
2860      * may be the values specified in CorDebugIlToNativeMappingTypes.
2861      */
2862     HRESULT GetILToNativeMapping(
2863                 [in] FunctionID functionId,
2864                 [in] ULONG32 cMap,
2865                 [out] ULONG32 *pcMap,
2866                 [out, size_is(cMap), length_is(*pcMap)]
2867                     COR_DEBUG_IL_TO_NATIVE_MAP map[]);
2868 }
2869
2870 /*
2871  * The CLR implements the ICorProfilerInfo2 interface. This interface is
2872  * used by a code profiler to communicate with the CLR to control event
2873  * monitoring and request information. The CLR passes an
2874  * ICorProfilerInfo2 interface to each code profiler during initialization.
2875  *
2876  * A code profiler can call methods on the ICorProfilerInfo2 interface to get
2877   * information about managed code being executed under the control of the CLR
2878  *
2879  * The ICorProfilerInfo2 interface implemented by the CLR uses the free
2880  * threaded model.
2881  *
2882  * The methods implemented on this interface return S_OK on success, or E_FAIL
2883  * on failure.
2884  *
2885  */
2886
2887 [
2888     object,
2889     uuid(CC0935CD-A518-487d-B0BB-A93214E65478),
2890     pointer_default(unique),
2891     local
2892 ]
2893 interface ICorProfilerInfo2 : ICorProfilerInfo
2894 {
2895     /*
2896      * The code profiler calls DoStackSnapshot to do sparse one-off stack snapshots.
2897      *
2898      * Passing NULL for thread yields a snapshot of the current thread. If a ThreadID
2899      * of a different thread is passed, the runtime will suspend that thread, perform
2900      * the snapshot, and resume.
2901      *
2902      * infoFlags come from the COR_PRF_SNAPSHOT_INFO enum.
2903      *
2904      * context is a platform-dependent CONTEXT structure, representing the complete
2905      * register context that the profiling API will use to seed the stack walk.  If this
2906      * is non-NULL, it must point to JITd or NGENd code, or else DoStackSnapshot
2907      * will return CORPROF_E_STACKSNAPSHOT_UNMANAGED_CTX.  Contexts are
2908      * only provided by profilers that hijack threads to force them to walk their
2909      * own stacks; profilers should not attempt to provide a context when walking
2910      * another thread's stack. If context is NULL, the stack walk will begin at the 
2911      * last available managed frame for the target thread.
2912      *
2913      * See the definition of StackSnapshotCallback for more information.
2914      */
2915     HRESULT DoStackSnapshot(
2916                 [in] ThreadID thread,
2917                 [in] StackSnapshotCallback *callback,
2918                 [in] ULONG32 infoFlags,
2919                 [in] void *clientData,
2920                 [in, size_is(contextSize)] BYTE context[],
2921                 [in] ULONG32 contextSize);
2922
2923     /*
2924      * The code profiler calls SetFunctionHooks2 to specify handlers
2925      * for FunctionEnter2, FunctionLeave2, and FunctionTailcall2
2926      * callbacks.
2927      *
2928      * Note that only one set of callbacks may be active at a time. Thus,
2929      * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
2930      * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
2931      * wins.  SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
2932      * when both are set.
2933      *
2934      * Each pointer may be null to disable that particular callback.
2935      *
2936      * SetEnterLeaveFunctionHooks2 may only be called from the
2937      * profiler's Initialize() callback.
2938      */
2939     HRESULT SetEnterLeaveFunctionHooks2(
2940                 [in] FunctionEnter2    *pFuncEnter,
2941                 [in] FunctionLeave2    *pFuncLeave,
2942                 [in] FunctionTailcall2 *pFuncTailcall);
2943
2944     /*
2945      * GetFunctionInfo2 returns the parent class of a function, plus the
2946      * function's metadata token and the ClassIDs of its type arguments
2947      * (if any). 
2948      *
2949      * When a COR_PRF_FRAME_INFO obtained from a FunctionEnter2
2950      * callback is passed, the ClassID and all type arguments will be exact.
2951      *
2952      * When a COR_PRF_FRAME_INFO from any other source is passed, or 
2953      * when 0 is passed as the frameInfo argument, exact ClassID and type 
2954      * arguments cannot always be determined.  The value returned in pClassId 
2955      * may be NULL and some type args will come back as System.Object.
2956      *
2957      */
2958     HRESULT GetFunctionInfo2(
2959                 [in] FunctionID funcId,
2960                 [in] COR_PRF_FRAME_INFO frameInfo,
2961                 [out] ClassID *pClassId,
2962                 [out] ModuleID *pModuleId,
2963                 [out] mdToken *pToken,
2964                 [in] ULONG32 cTypeArgs,
2965                 [out] ULONG32 *pcTypeArgs,
2966                 [out] ClassID typeArgs[]);
2967
2968     /*
2969      * GetStringLayout returns detailed information about how string objects are stored.
2970      *
2971      * *pBufferLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
2972      * stores the length of the string's buffer
2973      *
2974      * *pStringLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
2975      * stores the length of the string itself
2976      *
2977      * *pBufferOffset is the offset (from the ObjectID pointer) to the actual buffer
2978      * of wide characters
2979      *
2980      * Strings may or may not be null-terminated.
2981      */
2982     HRESULT GetStringLayout(
2983                 [out] ULONG *pBufferLengthOffset,
2984                 [out] ULONG *pStringLengthOffset,
2985                 [out] ULONG *pBufferOffset);
2986
2987     /*
2988      * GetClassLayout returns detailed information how a specific class is stored.
2989      * It only returns the fields defined by the class itself; if the parent class
2990      * defined fields as well, the profiler must call GetClassLayout on the parent class
2991      * to obtain those fields.
2992      *
2993      * It will fail with E_INVALIDARG for string and array classes.
2994      */
2995     HRESULT GetClassLayout(
2996                 [in]  ClassID classID,
2997                 [in, out] COR_FIELD_OFFSET rFieldOffset[],
2998                 [in] ULONG cFieldOffset,
2999                 [out] ULONG *pcFieldOffset,
3000                 [out] ULONG *pulClassSize);
3001
3002     /*
3003      * Returns the parent module a class is defined in, along with the
3004      * metadata token for the class, the ClassID of its parent class, and the
3005      * ClassIDs of its type arguments (if any).
3006      *
3007      * One can call GetModuleMetaData to obtain the metadata interface for
3008      * a given module.  The token can then be used to access the metadata for this
3009      * class.
3010      */
3011     HRESULT GetClassIDInfo2(
3012                 [in] ClassID classId,
3013                 [out] ModuleID *pModuleId,
3014                 [out] mdTypeDef *pTypeDefToken,
3015                 [out] ClassID *pParentClassId,
3016                 [in] ULONG32 cNumTypeArgs,
3017                 [out] ULONG32 *pcNumTypeArgs,
3018                 [out] ClassID typeArgs[]);
3019
3020     /*
3021      * GetCodeInfo2 returns the extents of native code associated with the
3022      * given FunctionID. These extents are returned sorted in order of increasing
3023      * IL offset.
3024      */
3025     HRESULT GetCodeInfo2(
3026                 [in] FunctionID functionID,
3027                 [in] ULONG32 cCodeInfos,
3028                 [out] ULONG32 *pcCodeInfos,
3029                 [out, size_is(cCodeInfos), length_is(*pcCodeInfos)]
3030                 COR_PRF_CODE_INFO codeInfos[]);
3031
3032     /*
3033      * GetClassFromTokenAndTypeArgs returns the ClassID of a type given its metadata
3034      * token (typedef) and the ClassIDs of its type arguments (if any).
3035      *
3036      *      cTypeArgs must be equal to the number of type parameters for the given type
3037      *          (0 for non-generic types)
3038      *      typeArgs may be NULL if cTypeArgs == 0
3039      *
3040      * Calling this function with a TypeRef token can have unpredictable results; callers
3041      * should resolve the TypeRef to a TypeDef and use that.
3042      *
3043      * If the type is not already loaded, calling this function will cause it to be. 
3044      * Loading is a dangerous operation in many contexts. For example, calling
3045      * this function during loading of modules or other types could lead to an infinite
3046      * loop as the runtime attempts to circularly load things.
3047      *
3048      * In general, use of this function is discouraged. If profilers are interested in
3049      * events for a particular type, they should store the ModuleID and TypeDef of that type,
3050      * and use GetClassIDInfo2 to check whether a given ClassID is the desired type.
3051      */
3052     HRESULT GetClassFromTokenAndTypeArgs(
3053                     [in] ModuleID moduleID,
3054                     [in] mdTypeDef typeDef,
3055                     [in] ULONG32 cTypeArgs,
3056                     [in, size_is(cTypeArgs)] ClassID typeArgs[],
3057                     [out] ClassID* pClassID);
3058
3059     /*
3060      * GetFunctionFromTokenAndTypeArgs returns the FunctionID of a function given
3061      * its metadata token (methoddef), containing class, and type args (if any).
3062      *
3063      *      classID may be 0 if the containing class is not generic
3064      *      typeArgs may be NULL if cTypeArgs == 0
3065      *
3066      * Calling this function with a MethodRef token can have unpredictable results; callers
3067      * should resolve the MethodRef to a MethodDef and use that.
3068      *
3069      * If the function is not already loaded, calling this function will cause it to be. 
3070      * Loading is a dangerous operation in many contexts. For example, calling
3071      * this function during loading of modules or types could lead to an infinite
3072      * loop as the runtime attempts to circularly load things.
3073      *
3074      * In general, use of this function is discouraged. If profilers are interested in
3075      * events for a particular function, they should store the ModuleID and MethodDef of that function,
3076      * and use GetFunctionInfo2 to check whether a given FunctionID is the desired function.
3077      */
3078     HRESULT GetFunctionFromTokenAndTypeArgs(
3079                     [in] ModuleID moduleID,
3080                     [in] mdMethodDef funcDef,
3081                     [in] ClassID classId,
3082                     [in] ULONG32 cTypeArgs,
3083                     [in, size_is(cTypeArgs)] ClassID typeArgs[],
3084                     [out] FunctionID* pFunctionID);
3085
3086     /*
3087      * Returns an enumerator over all frozen objects in the given module.
3088      */
3089     HRESULT EnumModuleFrozenObjects(
3090                 [in] ModuleID moduleID,
3091                 [out] ICorProfilerObjectEnum** ppEnum);
3092
3093
3094
3095     /*
3096      * GetArrayObjectInfo returns detailed information about an array object.
3097      * objectId is a valid array object.
3098      * cDimensions is the rank (# of dimensions).
3099      * On success:
3100      *   pDimensionSizes, pDimensionLowerBounds are parallel arrays describing the size and lower bound for each dimension.
3101      *   (*ppData) is a pointer to the raw buffer for the array, which is laid out according to the C++
3102      *   convention
3103      */
3104     HRESULT GetArrayObjectInfo(
3105                     [in] ObjectID objectId,
3106                     [in] ULONG32 cDimensions,
3107                     [out, size_is(cDimensions)] ULONG32 pDimensionSizes[],
3108                     [out, size_is(cDimensions)] int pDimensionLowerBounds[],
3109                     [out] BYTE **ppData);
3110
3111     /*
3112      * GetBoxClassLayout returns information about how a particular value type is laid out
3113      * when boxed.
3114      *
3115      *  *pBufferOffset is the offset (from the ObjectID pointer) to where the value type
3116      *  is stored within the box. The value type's class layout may then be used to
3117      *  interpret it.
3118      */
3119     HRESULT GetBoxClassLayout(
3120                     [in] ClassID classId,
3121                     [out] ULONG32 *pBufferOffset);
3122
3123
3124     /*
3125      * GetThreadAppDomain returns the AppDomainID currently associated with\
3126      * the given ThreadID
3127      */
3128     HRESULT GetThreadAppDomain(
3129                     [in] ThreadID threadId,
3130                     [out] AppDomainID *pAppDomainId);
3131
3132
3133     /*
3134      * GetRVAStaticAddress gets the address of the home for the given
3135      * RVA static. It must be called from a managed thread.  Otherwise, 
3136      * it will return CORPROF_E_NOT_MANAGED_THREAD.
3137      */
3138     HRESULT GetRVAStaticAddress(
3139                     [in] ClassID classId,
3140                     [in] mdFieldDef fieldToken,
3141                     [out] void **ppAddress);
3142
3143     /*
3144      * GetAppDomainStaticAddress gets the address of the home for the given
3145      * AppDomain static in the given AppDomain.
3146      *
3147      * This function may return CORPROF_E_DATAINCOMPLETE if the given static
3148      * has not been assigned a home in the given AppDomain.
3149      */
3150     HRESULT GetAppDomainStaticAddress(
3151                     [in] ClassID classId,
3152                     [in] mdFieldDef fieldToken,
3153                     [in] AppDomainID appDomainId,
3154                     [out] void **ppAddress);
3155
3156     /*
3157      * GetThreadStaticAddress gets the address of the home for the given
3158      * Thread static in the given Thread. threadId must be the current thread
3159      * ID or NULL, which means using curernt thread ID.
3160      *
3161      * This function may return CORPROF_E_DATAINCOMPLETE if the given static
3162      * has not been assigned a home in the given Thread.
3163      */
3164     HRESULT GetThreadStaticAddress(
3165                     [in] ClassID classId,
3166                     [in] mdFieldDef fieldToken,
3167                     [in] ThreadID threadId,
3168                     [out] void **ppAddress);
3169
3170     /*
3171      * GetContextStaticAddress gets the address of the home for the given
3172      * Context static in the given context.  It must be called from a managed 
3173      * thread.  Otherwise, it will return CORPROF_E_NOT_MANAGED_THREAD.
3174      *
3175      * This function may return CORPROF_E_DATAINCOMPLETE if the given static
3176      * has not been assigned a home in the given Context.  
3177      */
3178     HRESULT GetContextStaticAddress(
3179                     [in] ClassID classId,
3180                     [in] mdFieldDef fieldToken,
3181                     [in] ContextID contextId,
3182                     [out] void **ppAddress);
3183
3184     /*
3185      * GetStaticFieldInfo gets COR_PRF_STATIC_TYPE for a specific
3186      * field in a class. This information can be used to decide which
3187      * function to call to get the address of the static.
3188      *
3189      * NOTE: One should still check the metadata for a static to ensure
3190      * it is actually going to have an address. Statics that are literals
3191      * (aka constants) exist only in the metadata and do not have an address.
3192      *
3193      */
3194     HRESULT GetStaticFieldInfo(
3195                     [in] ClassID classId,
3196                     [in] mdFieldDef fieldToken,
3197                     [out] COR_PRF_STATIC_TYPE *pFieldInfo);
3198
3199     /*
3200      * GetGenerationBounds returns the memory regions that make up a given
3201      * GC generation in memory. It may be called from any profiler callback as long
3202      * as a GC is not in progress. (To be exact, it may be called from any callback
3203      * except for those that occur between GarbageCollectionStarted and GarbageCollectionFinished.)
3204      *
3205      * Most shifting of generations takes place during garbage collections; between
3206      * collections generations may grow, but generally do not move around. Therefore
3207      * the most interesting places to call this function are in GarbageCollectionStarted
3208      * and Finished.
3209      *
3210      * During program startup, some objects are allocated by the CLR itself, generally
3211      * in generations 3 and 0. So by the time managed code starts executing, these
3212      * generations will already contain objects. Generations 1 and 2 will be normally
3213      * empty, except for dummy objects generated by the garbage collector (of size 12
3214      * bytes in 32-bit implementations of the CLR, larger in 64-bit implementaions).
3215      * You may also see generation 2 ranges that are inside modules generated by ngen.
3216      * These are "frozen objects" generated at ngen time rather than allocated by the
3217      * garbage collector.
3218      *
3219      * cObjectRanges is a count of the number of elements allocated by the caller for
3220      *      the ranges array
3221      * pcObjectRanges is an out param for the number of ranges in the given generation
3222      * ranges is an array of elements of type COR_PRF_GC_GENERATION_RANGE, each of which
3223      *      describes a range of memory used by the garbage collector
3224      */
3225
3226     HRESULT GetGenerationBounds(
3227                     [in] ULONG cObjectRanges,
3228                     [out] ULONG *pcObjectRanges,
3229                     [out, size_is(cObjectRanges), length_is(*pcObjectRanges)] COR_PRF_GC_GENERATION_RANGE ranges[]);
3230  
3231     /*
3232      * GetObjectGeneration returns which generation the given object is currently in, along
3233      * with the start and length of the segment containing the object. It may be called
3234      * at any time as long as a GC is not in progress.
3235      */
3236
3237     HRESULT GetObjectGeneration(
3238                     [in] ObjectID objectId,
3239                     [out] COR_PRF_GC_GENERATION_RANGE *range);
3240
3241
3242    /*
3243      * When an exception notification is received, GetNotifiedExceptionClauseInfo() may be used 
3244      * to get the native address and frame information for the exception clause (catch/finally/filter)
3245      * that is about to be run (ExceptionCatchEnter, ExceptionUnwindFinallyEnter, ExceptionFilterEnter)
3246      * or has just been run (ExceptionCatchLeave, ExceptionUnwindFinallyLeave, ExceptionFilterLeave).  
3247      *
3248      * This call may be made at any time after one of the Enter calls above until either the matching
3249      * Leave call is received or until a nested exception throws out of the current clause in which case
3250      * there will be no Leave notification for that clause.  Note it is not possible for a throw to escape 
3251      * a Filter so there is always a Leave in that case.
3252      *
3253      * Return values:
3254      *   S_OK indicates success
3255      *   S_FALSE indicates that no exception clause is active   
3256      *   CORPROF_E_NOT_MANAGED_THREAD indicates an unmanaged thread.    
3257      */
3258
3259     HRESULT GetNotifiedExceptionClauseInfo(
3260                     [out] COR_PRF_EX_CLAUSE_INFO *pinfo);                 
3261 }
3262
3263 /*
3264  * The CLR implements the ICorProfilerInfo3 interface. This interface is
3265  * used by a code profiler to communicate with the CLR to control event
3266  * monitoring and request information. The CLR passes an
3267  * ICorProfilerInfo3 interface to each code profiler during initialization.
3268  *
3269  * A code profiler can call methods on the ICorProfilerInfo3 interface to get
3270   * information about managed code being executed under the control of the CLR
3271  *
3272  * The ICorProfilerInfo3 interface implemented by the CLR uses the free
3273  * threaded model.
3274  *
3275  * The methods implemented on this interface return S_OK on success, or E_FAIL
3276  * on failure.
3277  *
3278  */
3279
3280 [
3281     object,
3282     uuid(B555ED4F-452A-4E54-8B39-B5360BAD32A0),
3283     pointer_default(unique),
3284     local
3285 ]
3286 interface ICorProfilerInfo3 : ICorProfilerInfo2
3287 {  
3288     /*
3289      * Returns an enumerator for all previously jitted functions. May overlap with
3290      * functions previously reported via CompilationStarted callbacks.
3291      * NOTE: The returned enumeration will only include '0' for the value of the
3292      * COR_PRF_FUNCTION::reJitId field.  If you require valid COR_PRF_FUNCTION::reJitId values, use
3293      * ICorProfilerInfo4::EnumJITedFunctions2.
3294      */
3295     HRESULT EnumJITedFunctions([out] ICorProfilerFunctionEnum** ppEnum);
3296
3297     HRESULT RequestProfilerDetach([in] DWORD dwExpectedCompletionMilliseconds);
3298
3299     HRESULT SetFunctionIDMapper2(
3300                 [in] FunctionIDMapper2 *pFunc,
3301                 [in] void *clientData);
3302
3303     /*
3304      * GetStringLayout2 returns detailed information about how string objects are stored.
3305      *
3306      * *pStringLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
3307      * stores the length of the string itself
3308      *
3309      * *pBufferOffset is the offset (from the ObjectID pointer) to the actual buffer
3310      * of wide characters
3311      *
3312      * Strings may or may not be null-terminated.
3313      */
3314     HRESULT GetStringLayout2(
3315                 [out] ULONG *pStringLengthOffset,
3316                 [out] ULONG *pBufferOffset);
3317
3318     /*
3319      * The code profiler calls SetFunctionHooks3 to specify handlers
3320      * for FunctionEnter3, FunctionLeave3, and FunctionTailcall3, and calls 
3321      * SetFunctionHooks3WithInfo to specify handlers for FunctionEnter3WithInfo, 
3322      * FunctionLeave3WithInfo, and FunctionTailcall3WithInfo.
3323      *
3324      * Note that only one set of callbacks may be active at a time. Thus,
3325      * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
3326      * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
3327      * wins.  SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
3328      * when both are set.
3329      *
3330      * Each function pointer may be null to disable that callback.
3331      *
3332      * SetEnterLeaveFunctionHooks3(WithInfo) may only be called from the
3333      * profiler's Initialize() callback.
3334      */
3335     HRESULT SetEnterLeaveFunctionHooks3(
3336                 [in] FunctionEnter3    *pFuncEnter3,
3337                 [in] FunctionLeave3    *pFuncLeave3,
3338                 [in] FunctionTailcall3 *pFuncTailcall3);
3339
3340
3341     HRESULT SetEnterLeaveFunctionHooks3WithInfo(
3342                 [in] FunctionEnter3WithInfo    *pFuncEnter3WithInfo,
3343                 [in] FunctionLeave3WithInfo    *pFuncLeave3WithInfo,
3344                 [in] FunctionTailcall3WithInfo *pFuncTailcall3WithInfo);
3345
3346     /*
3347      * The profiler can call GetFunctionEnter3Info to gather frame info and argument info 
3348      * in FunctionEnter3WithInfo callback. The profiler needs to allocate sufficient space 
3349      * for COR_PRF_FUNCTION_ARGUMENT_INFO of the function it's inspecting and indicate the 
3350      * size in a ULONG pointed by pcbArgumentInfo.
3351      */
3352     HRESULT GetFunctionEnter3Info( 
3353                 [in]  FunctionID functionId, 
3354                 [in]  COR_PRF_ELT_INFO eltInfo,
3355                 [out] COR_PRF_FRAME_INFO *pFrameInfo,
3356                 [in, out] ULONG *pcbArgumentInfo,
3357                 [out, size_is(*pcbArgumentInfo)] COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo);
3358                 
3359     /*
3360      * The profiler can call GetFunctionLeave3Info to gather frame info and return value 
3361      * in FunctionLeave3WithInfo callback. 
3362      */
3363     HRESULT GetFunctionLeave3Info( 
3364                 [in]  FunctionID functionId, 
3365                 [in]  COR_PRF_ELT_INFO eltInfo,
3366                 [out] COR_PRF_FRAME_INFO *pFrameInfo,
3367                 [out] COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange);
3368                
3369     /*
3370      * The profiler can call GetFunctionTailcall3Info to gather frame info in 
3371      * FunctionTailcall3WithInfo callback. 
3372      */
3373     HRESULT GetFunctionTailcall3Info( 
3374                 [in]  FunctionID functionId, 
3375                 [in]  COR_PRF_ELT_INFO eltInfo,
3376                 [out] COR_PRF_FRAME_INFO *pFrameInfo);
3377
3378     HRESULT EnumModules([out] ICorProfilerModuleEnum** ppEnum);
3379
3380     /*
3381      * The profiler can call GetRuntimeInformation to query CLR version information.
3382      * Passing NULL to any parameter is acceptable except pcchVersionString cannot 
3383      * be NULL if szVersionString is not NULL.
3384      */
3385     HRESULT GetRuntimeInformation([out] USHORT *pClrInstanceId,
3386                                   [out] COR_PRF_RUNTIME_TYPE *pRuntimeType,
3387                                   [out] USHORT *pMajorVersion,
3388                                   [out] USHORT *pMinorVersion,
3389                                   [out] USHORT *pBuildNumber,
3390                                   [out] USHORT *pQFEVersion,
3391                                   [in]  ULONG  cchVersionString,
3392                                   [out] ULONG  *pcchVersionString,
3393                                   [out, annotation("_Out_writes_to_(cchVersionString, *pcchVersionString)")]
3394                                         WCHAR  szVersionString[]);
3395
3396     /*
3397      * GetThreadStaticAddress2 gets the address of the home for the given
3398      * Thread static in the given Thread.
3399      *
3400      * This function may return CORPROF_E_DATAINCOMPLETE if the given static
3401      * has not been assigned a home in the given Thread.
3402      */
3403     HRESULT GetThreadStaticAddress2(
3404                     [in] ClassID classId,
3405                     [in] mdFieldDef fieldToken,
3406                     [in] AppDomainID appDomainId,
3407                     [in] ThreadID threadId,
3408                     [out] void **ppAddress);
3409
3410     /*
3411      * GetAppDomainsContainingModule returns the AppDomainIDs in which the
3412      * given module has been loaded
3413      */
3414     HRESULT GetAppDomainsContainingModule(
3415                 [in] ModuleID moduleId,
3416                 [in] ULONG32 cAppDomainIds,
3417                 [out] ULONG32 *pcAppDomainIds,
3418                 [out, size_is(cAppDomainIds), length_is(*pcAppDomainIds)] AppDomainID appDomainIds[]);
3419
3420
3421     /*
3422      * Retrieve information about a given module.
3423      *
3424      * When the module is loaded from disk, the name returned will be the filename;
3425      * otherwise, the name will be the name from the metadata Module table (i.e., 
3426      * the same as the managed System.Reflection.Module.ScopeName).
3427      * 
3428      * *pdwModuleFlags will be filled in with a bitmask of values from COR_PRF_MODULE_FLAGS
3429      * that specify some properties of the module.
3430      * 
3431      * NOTE: While this function may be called as soon as the moduleId is alive,
3432      * the AssemblyID of the containing assembly will not be available until the
3433      * ModuleAttachedToAssembly callback.
3434      *
3435      */
3436     HRESULT GetModuleInfo2(
3437                 [in]  ModuleID              moduleId,
3438                 [out] LPCBYTE               *ppBaseLoadAddress,
3439                 [in]  ULONG                 cchName,
3440                 [out] ULONG                 *pcchName,
3441                 [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
3442                       WCHAR                 szName[],
3443                 [out] AssemblyID            *pAssemblyId,
3444                 [out] DWORD                 *pdwModuleFlags);
3445
3446
3447 }
3448
3449
3450 /*
3451  * This interface lets you iterate over the frozen objects from ngen images.
3452  */
3453
3454 [
3455     object,
3456     uuid(2C6269BD-2D13-4321-AE12-6686365FD6AF),
3457     pointer_default(unique),
3458     local
3459 ]
3460 interface ICorProfilerObjectEnum : IUnknown
3461 {
3462     HRESULT Skip(
3463                 [in] ULONG celt);
3464         
3465     HRESULT Reset();
3466     
3467     HRESULT Clone(
3468                     [out] ICorProfilerObjectEnum **ppEnum);
3469                     
3470     HRESULT GetCount(
3471                     [out] ULONG *pcelt);
3472
3473     HRESULT Next(
3474                     [in] ULONG celt,
3475                     [out, size_is(celt), length_is(*pceltFetched)]  ObjectID objects[],
3476                     [out] ULONG *pceltFetched);
3477 }
3478
3479
3480 /*
3481  * This interface lets you iterate over functions in the runtime.
3482  */
3483
3484 [
3485     object,
3486     uuid(FF71301A-B994-429D-A10B-B345A65280EF),
3487     pointer_default(unique),
3488     local
3489 ]
3490 interface ICorProfilerFunctionEnum : IUnknown
3491 {
3492     HRESULT Skip([in] ULONG celt);
3493         
3494     HRESULT Reset();
3495     
3496     HRESULT Clone([out] ICorProfilerFunctionEnum **ppEnum);
3497                     
3498     HRESULT GetCount([out] ULONG *pcelt);
3499
3500     HRESULT Next([in]  ULONG            celt,
3501                  [out, size_is(celt), length_is(*pceltFetched)]
3502                        COR_PRF_FUNCTION ids[],
3503                  [out] ULONG *          pceltFetched);
3504 };
3505
3506 /*
3507  * This interface lets you iterate over modules in the runtime.
3508  */
3509
3510 [
3511     object,
3512     uuid(b0266d75-2081-4493-af7f-028ba34db891),
3513     pointer_default(unique),
3514     local
3515 ]
3516 interface ICorProfilerModuleEnum : IUnknown
3517 {
3518     HRESULT Skip([in] ULONG celt);
3519         
3520     HRESULT Reset();
3521     
3522     HRESULT Clone([out] ICorProfilerModuleEnum **ppEnum);
3523                     
3524     HRESULT GetCount([out] ULONG *pcelt);
3525
3526     HRESULT Next([in]  ULONG            celt,
3527                  [out, size_is(celt), length_is(*pceltFetched)]
3528                        ModuleID         ids[],
3529                  [out] ULONG *          pceltFetched);
3530 };
3531
3532 /*
3533  * NOTE: DEPRECATED, now you can use your any allocator.
3534  *
3535  * This is simple allocator that only allows you to allocate memory.
3536  * You may not free it.  This was used in conjunction with
3537  * ICorProfilerInfo::SetILFunctionBody.
3538  */
3539 [
3540     object,
3541     uuid(A0EFB28B-6EE2-4d7b-B983-A75EF7BEEDB8),
3542     pointer_default(unique),
3543     local
3544 ]
3545 interface IMethodMalloc : IUnknown
3546 {
3547     /*
3548      * Tries to allocate memory above the start address of the module from
3549      * which it was created.  It is important to note that this method may
3550      * fail to allocate the memory specified above the start address, and
3551      * may as a result return NULL.
3552      */
3553     PVOID Alloc(
3554                     [in] ULONG cb);
3555 }
3556
3557 /*
3558  * The CLR implements the ICorProfilerFunctionControl interface. This interface
3559  * is used by a code profiler to communicate with the CLR to control how the 
3560  * JIT should generate code when rejitting a specific method.
3561  *
3562  * The ICorProfilerFunctionControl interface implemented by the CLR uses the
3563  * free threaded model.
3564  */
3565
3566 [
3567     object,
3568     uuid(F0963021-E1EA-4732-8581-E01B0BD3C0C6),
3569     pointer_default(unique),
3570     local
3571 ]
3572 interface ICorProfilerFunctionControl : IUnknown
3573 {
3574     /*
3575      * Set one or more flags from COR_PRF_CODEGEN_FLAGS to control code
3576      * generation just for this method.
3577      */
3578     HRESULT SetCodegenFlags(
3579                 [in] DWORD flags);
3580
3581     /*
3582      * Override the method body.
3583      */
3584     HRESULT SetILFunctionBody(
3585                 [in]                               ULONG   cbNewILMethodHeader,
3586                 [in, size_is(cbNewILMethodHeader)] LPCBYTE pbNewILMethodHeader);
3587
3588     /*
3589      * This is not currently implemented, and will return E_NOTIMPL
3590      */
3591     HRESULT SetILInstrumentedCodeMap(
3592                 [in]                         ULONG      cILMapEntries,
3593                 [in, size_is(cILMapEntries)] COR_IL_MAP rgILMapEntries[]);
3594
3595 }
3596
3597 /*
3598  * The CLR implements the ICorProfilerInfo4 interface. This interface is
3599  * used by a code profiler to communicate with the CLR to control event
3600  * monitoring and request information. The CLR passes an
3601  * ICorProfilerInfo4 interface to each code profiler during initialization.
3602  *
3603  * A code profiler can call methods on the ICorProfilerInfo4 interface to get
3604   * information about managed code being executed under the control of the CLR
3605  *
3606  * The ICorProfilerInfo4 interface implemented by the CLR uses the free
3607  * threaded model.
3608  *
3609  * The methods implemented on this interface return S_OK on success, or E_FAIL
3610  * on failure.
3611  *
3612  */
3613
3614 [
3615     object,
3616     uuid(0d8fdcaa-6257-47bf-b1bf-94dac88466ee),
3617     pointer_default(unique),
3618     local
3619 ]
3620 interface ICorProfilerInfo4 : ICorProfilerInfo3
3621 {  
3622     HRESULT EnumThreads([out] ICorProfilerThreadEnum **ppEnum);
3623     HRESULT InitializeCurrentThread();
3624
3625     /*
3626      * Call RequestReJIT to have the runtime re-JIT a particular set of methods.
3627      * A code profiler can then adjust the code generated when the method is
3628      * re-JITed through the ICorProfilerFunctionControl interface.  This does
3629      * not impact currently executing methods, only future invocations.
3630      *
3631      * A return code of S_OK indicates that all of the requested methods were
3632      * attempted to be rejitted.   However, the profiler must implement
3633      * ICorProfilerCallback4::ReJITError to determine which of the methods were
3634      * successfully re-JITed.
3635      *
3636      * A failure return value (E_*) indicates some failure that prevents any
3637      * re-JITs.
3638      */
3639     HRESULT RequestReJIT(
3640                 [in]                       ULONG       cFunctions,
3641                 [in, size_is(cFunctions)]  ModuleID    moduleIds[],
3642                 [in, size_is(cFunctions)]  mdMethodDef methodIds[]);
3643
3644     /*
3645      * RequestRevert will instruct the runtime to revert to using/calling the
3646      * original method (original IL and flags) rather than whatever was
3647      * ReJITed.  This does not change any currently active methods, only future
3648      * invocations.
3649      *
3650      */
3651     HRESULT RequestRevert(
3652                 [in]                       ULONG       cFunctions,
3653                 [in, size_is(cFunctions)]  ModuleID    moduleIds[],
3654                 [in, size_is(cFunctions)]  mdMethodDef methodIds[],
3655                 [out, size_is(cFunctions)] HRESULT     status[]);
3656
3657     /*
3658      * Same as GetCodeInfo2, except instead of always returning the code info
3659      * associated with the original IL/function, you can request the code info
3660      * for a particular re-JITed version of a function.
3661      */
3662     HRESULT GetCodeInfo3(
3663                 [in]  FunctionID           functionID,
3664                 [in]  ReJITID              reJitId,
3665                 [in]  ULONG32              cCodeInfos,
3666                 [out] ULONG32 *            pcCodeInfos,
3667                 [out, size_is(cCodeInfos), length_is(*pcCodeInfos)]
3668                       COR_PRF_CODE_INFO    codeInfos[]);
3669
3670     /*
3671      * Same as GetFunctionFromIP, but also returns which re-JITed version is
3672      * associated with the IP address.
3673      */
3674     HRESULT GetFunctionFromIP2(
3675                 [in]  LPCBYTE      ip,
3676                 [out] FunctionID * pFunctionId,
3677                 [out] ReJITID *    pReJitId);
3678
3679     /*
3680      * GetReJITIDs can be used to find all of the re-JITed versions of the
3681      * given function.
3682      */
3683     HRESULT GetReJITIDs(
3684                 [in]  FunctionID          functionId,
3685                 [in]  ULONG               cReJitIds,
3686                 [out] ULONG *             pcReJitIds,
3687                 [out, size_is(cReJitIds), length_is(*pcReJitIds)] 
3688                       ReJITID             reJitIds[]);
3689
3690     /*
3691      * Same as GetILToNativeMapping, but allows the code profiler to specify
3692      * which re-JITed version it applies to.
3693      */
3694     HRESULT GetILToNativeMapping2(
3695                 [in]  FunctionID                       functionId,
3696                 [in]  ReJITID                          reJitId,
3697                 [in]  ULONG32                          cMap,
3698                 [out] ULONG32 *                        pcMap,
3699                 [out, size_is(cMap),length_is(*pcMap)]
3700                       COR_DEBUG_IL_TO_NATIVE_MAP       map[]);
3701
3702     /*
3703      * Returns an enumerator for all previously jitted functions. May overlap with
3704      * functions previously reported via CompilationStarted callbacks.  The returned
3705      * enumeration will include values for the COR_PRF_FUNCTION::reJitId field 
3706      */
3707     HRESULT EnumJITedFunctions2([out] ICorProfilerFunctionEnum** ppEnum);
3708
3709     /*
3710      * The code profiler calls GetObjectSize to obtain the size of an object.
3711      * Note that types like arrays and strings may have a different size for each object.
3712      */
3713     HRESULT GetObjectSize2(
3714                 [in]  ObjectID objectId,
3715                 [out] SIZE_T *pcSize);
3716
3717 }
3718
3719 [
3720     object,
3721     uuid(07602928-CE38-4B83-81E7-74ADAF781214),
3722     pointer_default(unique),
3723     local
3724 ]
3725 interface ICorProfilerInfo5 : ICorProfilerInfo4
3726 {
3727     /*
3728      * The code profiler calls GetEventMask2 to obtain the current event
3729      * categories for which it is to receive event notifications from the CLR
3730      *
3731      * *pdwEventsLow is a bitwise combination of values from COR_PRF_MONITOR
3732      * *pdwEventsHigh is a bitwise combination of values from COR_PRF_HIGH_MONITOR
3733      */
3734     HRESULT GetEventMask2(
3735             [out] DWORD *pdwEventsLow,
3736             [out] DWORD *pdwEventsHigh);
3737
3738     /*
3739      * The code profiler calls SetEventMask2 to set the event categories for
3740      * which it is set to receive notification from the CLR.
3741      *
3742      * dwEventsLow is a bitwise combination of values from COR_PRF_MONITOR
3743      * dwEventsHigh is a bitwise combination of values from COR_PRF_HIGH_MONITOR
3744      */
3745     HRESULT SetEventMask2(
3746             [in] DWORD dwEventsLow,
3747             [in] DWORD dwEventsHigh);
3748 };
3749
3750
3751 [
3752     object,
3753     uuid(F30A070D-BFFB-46A7-B1D8-8781EF7B698A),
3754     pointer_default(unique),
3755     local
3756 ]
3757 interface ICorProfilerInfo6 : ICorProfilerInfo5
3758 {
3759     /*
3760     * Returns an enumerator for all methods that 
3761     * - belong to a given NGen or R2R module (inlinersModuleId) and 
3762     * - inlined a body of a given method (inlineeModuleId / inlineeMethodId). 
3763     *
3764     * If incompleteData is set to TRUE after function is called, it means that the methods enumerator 
3765     * doesn't contain all methods inlining a given method. 
3766     * It can happen when one or more direct or indirect dependencies of inliners module haven't been loaded yet.
3767     * If profiler needs accurate data it should retry later when more modules are loaded (preferably on each module load).
3768     *
3769     * It can be used to lift limitation on inlining for ReJIT.
3770     *
3771     * NOTE: If the inlinee method is decorated with the System.Runtime.Versioning.NonVersionable attribute then
3772     * then some inliners may not ever be reported. If you need to get a full accounting you can avoid the issue
3773     * by disabling the use of all native images.
3774     * 
3775     */
3776     HRESULT EnumNgenModuleMethodsInliningThisMethod(
3777         [in] ModuleID    inlinersModuleId,
3778         [in] ModuleID    inlineeModuleId,
3779         [in] mdMethodDef inlineeMethodId,
3780         [out] BOOL        *incompleteData,
3781         [out] ICorProfilerMethodEnum** ppEnum);
3782 };
3783
3784 [
3785     object,
3786     uuid(9AEECC0D-63E0-4187-8C00-E312F503F663),
3787     pointer_default(unique),
3788     local
3789 ]
3790 interface ICorProfilerInfo7 : ICorProfilerInfo6
3791 {
3792     /*
3793     * Applies the newly emitted Metadata.
3794     *
3795     * This method can be used to apply the newly defined metadata by IMetadataEmit::Define* methods
3796     * to the module.
3797     *
3798     * If metadata changes are made after ModuleLoadFinished callback,
3799     * it is required to call this method before using the new metadata
3800     */
3801     HRESULT ApplyMetaData(
3802         [in] ModuleID    moduleId);
3803
3804     /* Returns the length of an in-memory symbol stream
3805     *
3806     * If the module has in-memory symbols the length of the stream will
3807     * be placed in pCountSymbolBytes. If the module doesn't have in-memory
3808     * symbols, *pCountSymbolBytes = 0
3809     *
3810     * Returns S_OK if the length could be determined (even if it is 0)
3811     *
3812     * Note: The current implementation does not support reflection.emit. 
3813     * CORPROF_E_MODULE_IS_DYNAMIC will be returned in that case. 
3814     */
3815     HRESULT GetInMemorySymbolsLength(
3816         [in] ModuleID moduleId,
3817         [out] DWORD* pCountSymbolBytes);
3818
3819     /* Reads bytes from an in-memory symbol stream
3820     *
3821     * This function attempts to read countSymbolBytes of data starting at offset 
3822     * symbolsReadOffset within the in-memory stream. The data will be copied into
3823     * pSymbolBytes which is expected to have countSymbolBytes of space available.
3824     * pCountSymbolsBytesRead contains the actual number of bytes read which
3825     * may be less than countSymbolBytes if the end of the stream is reached.
3826     *
3827     * Returns S_OK if a non-zero number of bytes were read.
3828     *
3829     * Note: The current implementation does not support reflection.emit.
3830     * CORPROF_E_MODULE_IS_DYNAMIC will be returned in that case.
3831     */
3832     HRESULT ReadInMemorySymbols(
3833         [in] ModuleID moduleId,
3834         [in] DWORD symbolsReadOffset,
3835         [out] BYTE* pSymbolBytes,
3836         [in] DWORD countSymbolBytes,
3837         [out] DWORD* pCountSymbolBytesRead);
3838
3839 };
3840
3841 [
3842     object,
3843     uuid(C5AC80A6-782E-4716-8044-39598C60CFBF),
3844     pointer_default(unique),
3845     local
3846 ]
3847 interface ICorProfilerInfo8 : ICorProfilerInfo7
3848 {
3849     /*
3850     * Determines if a function has associated metadata 
3851     *
3852     * Certain methods like IL Stubs or LCG Methods do not have
3853     * associated metadata that can be retrieved using the IMetaDataImport APIs.
3854     *
3855     * Such methods can be encountered by profilers through instruction pointers
3856     * or by listening to ICorProfilerCallback::DynamicMethodJITCompilationStarted
3857     *
3858     * This API can be used to determine whether a FunctionID is dynamic.
3859     */
3860     HRESULT IsFunctionDynamic( [in]  FunctionID  functionId,
3861                                [out] BOOL        *isDynamic);
3862
3863     /*
3864     * Maps a managed code instruction pointer to a FunctionID.
3865     *
3866     * GetFunctionFromIP2 fails for dynamic methods, this method works for
3867     * both dynamic and non-dynamic methods. It is a superset of GetFunctionFromIP2
3868     */
3869     HRESULT GetFunctionFromIP3([in] LPCBYTE ip,
3870                                [out] FunctionID *functionId,
3871                                [out] ReJITID * pReJitId);
3872
3873     /*
3874     * Retrieves informaiton about dynamic methods
3875     *
3876     * Certain methods like IL Stubs or LCG do not have
3877     * associated metadata that can be retrieved using the IMetaDataImport APIs.
3878     *
3879     * Such methods can be encountered by profilers through instruction pointers
3880     * or by listening to ICorProfilerCallback::DynamicMethodJITCompilationStarted
3881     *
3882     * This API can be used to retrieve information about dynamic methods
3883     * including a friendly name if available.
3884     */
3885     HRESULT GetDynamicFunctionInfo( [in]  FunctionID              functionId,
3886                                     [out] ModuleID                *moduleId,
3887                                     [out] PCCOR_SIGNATURE         *ppvSig,
3888                                     [out] ULONG                   *pbSig,
3889                                     [in]  ULONG                   cchName,
3890                                     [out] ULONG                   *pcchName,
3891                                     [out] WCHAR                    wszName[]);
3892 };
3893
3894 [
3895     object,
3896     uuid(008170DB-F8CC-4796-9A51-DC8AA0B47012),
3897     pointer_default(unique),
3898     local
3899 ]
3900 interface ICorProfilerInfo9 : ICorProfilerInfo8
3901 {
3902     //Given functionId + rejitId, enumerate the native code start address of all jitted versions of this code that currently exist
3903     HRESULT GetNativeCodeStartAddresses(FunctionID functionID, ReJITID reJitId, ULONG32 cCodeStartAddresses, ULONG32 *pcCodeStartAddresses, UINT_PTR codeStartAddresses[]);
3904
3905     //Given the native code start address, return the native->IL mapping information for this jitted version of the code
3906     HRESULT GetILToNativeMapping3(UINT_PTR pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[]);
3907
3908     //Given the native code start address, return the the blocks of virtual memory that store this code (method code is not necessarily stored in a single contiguous memory region)
3909     HRESULT GetCodeInfo4(UINT_PTR pNativeCodeStartAddress, ULONG32 cCodeInfos, ULONG32* pcCodeInfos, COR_PRF_CODE_INFO codeInfos[]);
3910 }
3911
3912 /*
3913 * This interface lets you iterate over methods in the runtime.
3914 */
3915
3916 [
3917     object,
3918     uuid(FCCEE788-0088-454B-A811-C99F298D1942),
3919     pointer_default(unique),
3920     local
3921 ]
3922 interface ICorProfilerMethodEnum : IUnknown
3923 {
3924     HRESULT Skip([in] ULONG celt);
3925
3926     HRESULT Reset();
3927
3928     HRESULT Clone([out] ICorProfilerMethodEnum **ppEnum);
3929
3930     HRESULT GetCount([out] ULONG *pcelt);
3931
3932     HRESULT Next([in]  ULONG   celt,
3933         [out, size_is(celt), length_is(*pceltFetched)]
3934         COR_PRF_METHOD         elements[],
3935         [out] ULONG *          pceltFetched);
3936 }
3937
3938 /*
3939  * This interface lets you iterate over threads in the runtime.
3940  */
3941
3942 [
3943     object,
3944     uuid(571194f7-25ed-419f-aa8b-7016b3159701),
3945     pointer_default(unique),
3946     local
3947 ]
3948 interface ICorProfilerThreadEnum : IUnknown
3949 {
3950     HRESULT Skip([in] ULONG celt);
3951         
3952     HRESULT Reset();
3953     
3954     HRESULT Clone([out] ICorProfilerThreadEnum **ppEnum);
3955                     
3956     HRESULT GetCount([out] ULONG *pcelt);
3957
3958     HRESULT Next([in]  ULONG            celt,
3959                  [out, size_is(celt), length_is(*pceltFetched)]
3960                        ThreadID         ids[],
3961                  [out] ULONG *          pceltFetched);
3962 }
3963
3964
3965 /*
3966  * This interface is given to the profiler in the GetAssemblyReferences() callback, to
3967  * allow the profiler to inform the CLR of assembly references that the profiler plans to
3968  * add later on during ModuleLoadFinished.  This improves the accuracy of the CLR assembly
3969  * reference closure walker, and its algorithms for determining whether assemblies may be shared
3970  *
3971  * This interface is valid for use only within the GetAssemblyReferences callback that passed
3972  * this interface to the profiler
3973  */
3974 [
3975     object,
3976     uuid(66A78C24-2EEF-4F65-B45F-DD1D8038BF3C),
3977     pointer_default(unique),
3978     local
3979 ]
3980 interface ICorProfilerAssemblyReferenceProvider : IUnknown
3981 {
3982     // The profiler calls this for each target assembly it plans to reference from the
3983     // assembly specified in the wszAssemblyPath argument of the GetAssemblyReferences callback.
3984     HRESULT AddAssemblyReference(const COR_PRF_ASSEMBLY_REFERENCE_INFO * pAssemblyRefInfo);
3985 };
3986
3987
3988 /***************************************************************************************
3989 ** ICLRProfiling                                                                     **
3990 ** Activated using mscoree!CLRCreateInstance. Export AttachProfiler API to profilers **
3991 ***************************************************************************************/
3992 [
3993     uuid(B349ABE3-B56F-4689-BFCD-76BF39D888EA),
3994     version(1.0),
3995     helpstring("CoreCLR profiling interface for profiler attach"),
3996     local
3997 ]
3998 interface ICLRProfiling : IUnknown
3999 {
4000     HRESULT AttachProfiler(
4001         [in] DWORD dwProfileeProcessID,
4002         [in] DWORD dwMillisecondsMax,                        // optional
4003         [in] const CLSID * pClsidProfiler,
4004         [in] LPCWSTR wszProfilerPath,                        // optional
4005         [in, size_is(cbClientData)] void * pvClientData,     // optional
4006         [in] UINT cbClientData);                             // optional
4007 }