-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathInstrumentationEngine.idl
1668 lines (1387 loc) · 65.5 KB
/
InstrumentationEngine.idl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Header files for the instrumentation engine
// This is used to generate header files
// but not to generate proxy stubs, tlb, or registration
import "ocidl.idl";
import "oleidl.idl";
import "corprof.idl";
[
uuid(54DD4A02-1C02-43FF-8EC8-FA4244B52E60)
]
library MicrosoftInstrumentationEngine
{
interface IProfilerManager;
interface IProfilerManagerHost;
interface IProfilerManagerLogging;
interface IProfilerManagerLoggingHost;
interface IInstrumentationMethodHost;
interface IInstrumentationMethod;
interface IDataContainer;
interface IInstruction;
interface IExceptionSection;
interface IExceptionClause;
interface IEnumExceptionClauses;
interface IOperandInstruction;
interface IBranchInstruction;
interface ISwitchInstruction;
interface IInstructionGraph;
interface IMethodInfo;
interface IMethodInfo2;
interface IAssemblyInfo;
interface IEnumAssemblyInfo;
interface IModuleInfo;
interface IModuleInfo2;
interface IModuleInfo3;
interface IEnumModuleInfo;
interface IAppDomainInfo;
interface IEnumAppDomainInfo;
interface IInstrumentationMethod;
interface IInstructionGraph;
interface ILocalVariableCollection;
interface IType;
interface IAppDomainCollection;
interface ISignatureBuilder;
interface ITypeCreator;
interface IMethodLocal;
interface IMethodParameter;
interface IEnumMethodLocals;
interface IEnumMethodParameters;
interface ISingleRetDefaultInstrumentation;
// Api version level. This must be updated every time any change is made in any API definition.
// If IProfilerManager3::GetApiVersion returns a number greater than or equal to this number,
// the client can be guaranteed that at least every interface and enumeration defined in
// the api that the client is compiled against exists in the linked version.
const DWORD CLR_INSTRUMENTATION_ENGINE_API_VER = 7;
[
object,
uuid(3A09AD0A-25C6-4093-93E1-3F64EB160A9D),
pointer_default(unique)
]
interface IProfilerManager : IUnknown
{
// manipulating xml configuration files is hard from setup.
// So this lets the host push in a collection of config paths
// instead of a single file.
HRESULT SetupProfilingEnvironment([in] BSTR bstrConfigPath[], [in] UINT numConfigPaths);
// Allow hosts and instrumentation methods to get access to the raw profiler callback
// events (ICorProfilerCallback, ICorProfilerCallback2...).
// The events are multiplexed to each implementation and they fire AFTER
// the normal instrumentation methods have performed instrumentation etc..
//
// The initialize method will be called on each instance passing a wrapped
// ICorProfilerInfo instance which allows the host to add to the cor profiler event
// flags.
//
// NOTE: raw profiler hooks will need to be added during initialize if any changes
// to the profiler events are to be supported.
HRESULT AddRawProfilerHook([in]IUnknown* pUnkProfilerCallback);
HRESULT RemoveRawProfilerHook();
// Return the wrapped ICorProfilerInfo Instance
HRESULT GetCorProfilerInfo([out]IUnknown** ppCorProfiler);
// return the profiler host instance
[helpstring("This method is deprecated as of 1.0.32 and will return E_NOTIMPL when called.")]
HRESULT GetProfilerHost([out]IProfilerManagerHost** ppProfilerManagerHost);
// Returns an instance of IProfilerManagerLogging which instrumentation methods can use
// to log to the profiler manager or optionally to the profiler host.
HRESULT GetLoggingInstance([out] IProfilerManagerLogging** ppLogging);
// By default, logging messages are written to the debug output port. However,
// hosts can optionally signup to receive them through an instance of IProfilerManagerLoggingHost
HRESULT SetLoggingHost([in] IProfilerManagerLoggingHost* pLoggingHost);
// Return the appdomain collection
HRESULT GetAppDomainCollection([out] IAppDomainCollection** ppAppDomainCollection);
// Creates a general purpose signature builder
HRESULT CreateSignatureBuilder([out] ISignatureBuilder** ppSignatureBuilder);
// Query the profiler manager for a pointer to another instrumentation method.
// Consumers can call QueryInterface to obtain an interface specific to that
// instrumentation method
HRESULT GetInstrumentationMethod([in]REFGUID cslid, [out]IUnknown** ppUnknown);
HRESULT RemoveInstrumentationMethod([in] IInstrumentationMethod* pInstrumentationMethod);
// Registers a new instrumentation method in the profiler manager. Also calls its Initialize() method.
HRESULT AddInstrumentationMethod([in]BSTR bstrModulePath, [in]BSTR bstrName, [in]BSTR bstrDescription, [in]BSTR bstrModule, [in]BSTR bstrClassGuid, [in]DWORD dwPriority, [out]IInstrumentationMethod** pInstrumentationMethod);
HRESULT GetRuntimeType([out]COR_PRF_RUNTIME_TYPE* pRuntimeType);
};
[
object,
uuid(DCB0764D-E18F-4F9A-91E8-6A40FCFE6775),
pointer_default(unique)
]
interface IProfilerManager2 : IUnknown
{
// An instrumentation method may disable profiling of a process by calling this method.
// This will result in the instrumentation engine returning CORPROF_E_PROFILER_CANCEL_ACTIVATION
// from initialize, effectively disabling the profiler in the process.
HRESULT DisableProfiling();
// If metadata is modified outside of a module load callback. Call this method
// to get the clr to apply the changes.
HRESULT ApplyMetadata([in] IModuleInfo* pMethodInfo);
};
[
object,
uuid(0B097E56-55EE-4EC4-B2F4-380B82448B63),
pointer_default(unique)
]
interface IProfilerManager3 : IUnknown
{
// Sets the value of pSupported to true if and only if this version of IProfilerManager
// will supports the interface with the given iid. Used to ensure that the linked version
// of the api is at least as new as the one that the client compiled against.
HRESULT GetApiVersion([out] DWORD* pApiVer);
};
[
object,
uuid(24100BD8-58F2-483A-948A-5B0B8186E451),
pointer_default(unique)
]
interface IProfilerManager4 : IUnknown
{
// Returns an instance of IProfilerManagerLogging which instrumentation methods can use
// to log to the logging service independently of the profiler manager. This instance is
// guaranteed to not depend on the lifetime of the profiler manager from which it is acquired.
HRESULT GetGlobalLoggingInstance([out] IProfilerManagerLogging** ppLogging);
};
[
object,
uuid(AF78C11D-385A-47B1-A4FB-8D6BA7FE9B2D),
pointer_default(unique)
]
interface IProfilerManager5 : IUnknown
{
// Returns a value indicating whether the profiler manager is aware of the specified
// instrumentation method class ID, regardless of the state of initialization of the
// corresponding instrumentation method.
HRESULT IsInstrumentationMethodRegistered([in] REFGUID cslid, [out] BOOL* pfRegistered);
};
[
object,
uuid(D7EAEC8F-C4BB-4F5D-99B9-7215FEB0ED57),
pointer_default(unique)
]
interface IProfilerStringManager : IUnknown
{
// Frees the string that was allocated by one of the Clr Instrumentation Engine functions.
// This is a shortcut to the exported function InstrumentationEngineFreeString.
HRESULT FreeString([in, optional] BSTR bstr);
};
// The profiler manager host is created by the profiler manager during the call to initialize after the clr
// The profiler manager host should call SetupProfilingEnvironment to enable registered instrumentation methods and
// call AddRawProfilerHook to get access to the raw ICorProfiler events.
// InstrumentationEngine solely uses a default ExtensionsHost implementation
[
object,
uuid(BA9193B4-287F-4BF4-8E1B-00FCE33862EB),
pointer_default(unique)
]
interface IProfilerManagerHost : IUnknown
{
HRESULT Initialize([in] IProfilerManager* pProfilerManager);
};
// logging levels in the instrumentation engine.
enum LoggingFlags
{
LoggingFlags_None = 0x0, // No logging
LoggingFlags_Errors = 0x1, // Log error messages
LoggingFlags_Trace = 0x2, // Log verbose trace messages
LoggingFlags_InstrumentationResults = 0x4 // Log full dumping of il results.
};
// Interface implemented by the profiler manager that is used by instrumentation methods to send logging messages to the instrumentation engine.
[
object,
uuid(9CFECED7-2123-4115-BF06-3693D1D19E22),
pointer_default(unique)
]
interface IProfilerManagerLogging : IUnknown
{
// If trace logging in enabled in the profiler manager, trace messages are sent to the
// profiler manager through this function.
HRESULT LogMessage([in] const WCHAR* wszMessage);
// Errors detected during profiling will be sent to the host through this method
HRESULT LogError([in] const WCHAR* wszError);
// If instrumentation result tracing is enabled, the detailed results of each instrumented
// method will be sent to the profiler manager host through this method.
HRESULT LogDumpMessage([in] const WCHAR* wszMessage);
// Called to cause logging to be written to the debug output port (via DebugOutputString) as well
// as to the host.
HRESULT EnableDiagnosticLogToDebugPort([in] BOOL enable);
// Allows instrumentation methods and hosts to ask for the current logging level
HRESULT GetLoggingFlags([out] enum LoggingFlags* pLoggingFlags);
// Allows instrumentation methods and hosts to modify the current logging level
HRESULT SetLoggingFlags([in] enum LoggingFlags loggingFlags);
};
// Profiler manager hosts can implement this to receive and manage all tracing from the instrumentation engine.
// and instrumentation methods
[
object,
uuid(99F828EE-EA00-473C-A829-D400235C11C1),
pointer_default(unique)
]
interface IProfilerManagerLoggingHost : IUnknown
{
// If trace logging in enabled in the profiler manager, trace messages are sent to the
// profiler manager through this function.
HRESULT LogMessage([in] const WCHAR* wszMessage);
// Errors detected during profiling will be sent to the host through this method
HRESULT LogError([in] const WCHAR* wszError);
// If instrumentation result tracing is enabled, the detailed results of each instrumented
// method will be sent to the profiler manager host through this method.
HRESULT LogDumpMessage([in] const WCHAR* wszMessage);
}
[
object,
uuid(0D92A8D9-6645-4803-B94B-06A1C4F4E633),
pointer_default(unique)
]
interface IInstrumentationMethod : IUnknown
{
HRESULT Initialize([in] IProfilerManager* pProfilerManager);
HRESULT OnAppDomainCreated([in] IAppDomainInfo* pAppDomainInfo);
HRESULT OnAppDomainShutdown([in] IAppDomainInfo* pAppDomainInfo);
HRESULT OnAssemblyLoaded([in] IAssemblyInfo* pAssemblyInfo);
HRESULT OnAssemblyUnloaded([in] IAssemblyInfo* pAssemblyInfo);
HRESULT OnModuleLoaded([in] IModuleInfo* pModuleInfo);
HRESULT OnModuleUnloaded([in] IModuleInfo* pModuleInfo);
HRESULT OnShutdown();
// Instrumentation methods should return true if they want to instrument the method pointed to by IMethodInfo
HRESULT ShouldInstrumentMethod([in] IMethodInfo* pMethodInfo, [in] BOOL isRejit, [out] BOOL* pbInstrument);
// Called on instrumentation methods that return true to ShouldInstrumentMethod. This gives them the opportunity
// to replace the method body using the CreateBaseline api on the instruction graph. Only one instrumentation
// method can create the baseline. BeforeInstrumentMethod is called on instrumentation methods in priority order.
// Instrumentation methods should not perform any other instrumentation in this callback as a lower priority instrumentation
// method may replace the method body later
HRESULT BeforeInstrumentMethod([in] IMethodInfo* pMethodInfo, [in] BOOL isRejit);
// Called for methods where the instrumentation method returned true during ShouldInstrumentMethod.
// InstrumentMethod is called on instrumentation methods in priority order
HRESULT InstrumentMethod([in] IMethodInfo* pMethodInfo, [in] BOOL isRejit);
// Fires after all instrumentation is complete. This allows instrumentation methods to perform final
// bookkeeping such as recording local variable signatures which are not known until the final process
// is complete.
HRESULT OnInstrumentationComplete([in] IMethodInfo* pMethodInfo, [in] BOOL isRejit);
// Instrumentation engine asks each instrumentation method if inlining should be allowed
HRESULT AllowInlineSite([in] IMethodInfo* pMethodInfoInlinee, [in] IMethodInfo* pMethodInfoCaller, [out] BOOL* pbAllowInline);
};
// Interface implemented by instrumentation methods that want events about exceptions. The instrumentation engine
// must also set the COR_PRF_MONITOR_EXCEPTIONS flags on the instrumentation flags during initialize as the
// exception callbacks are not enabled by default.
[
object,
uuid(8310B758-6642-46AD-9423-DDA5F9E278AE),
pointer_default(unique)
]
interface IInstrumentationMethodExceptionEvents : IUnknown
{
HRESULT ExceptionCatcherEnter(
[in] IMethodInfo* pMethodInfo,
[in] UINT_PTR objectId
);
HRESULT ExceptionCatcherLeave();
HRESULT ExceptionSearchCatcherFound(
[in] IMethodInfo* pMethodInfo
);
HRESULT ExceptionSearchFilterEnter(
[in] IMethodInfo* pMethodInfo
);
HRESULT ExceptionSearchFilterLeave();
HRESULT ExceptionSearchFunctionEnter(
[in] IMethodInfo* pMethodInfo
);
HRESULT ExceptionSearchFunctionLeave();
HRESULT ExceptionThrown(
[in] UINT_PTR thrownObjectId
);
HRESULT ExceptionUnwindFinallyEnter(
[in] IMethodInfo* pMethodInfo
);
HRESULT ExceptionUnwindFinallyLeave();
HRESULT ExceptionUnwindFunctionEnter(
[in] IMethodInfo* pMethodInfo
);
HRESULT ExceptionUnwindFunctionLeave();
}
[
object,
uuid(2A4FDF66-FC5B-442D-8FAA-4137F023A4EA),
pointer_default(unique)
]
interface IDataContainer : IUnknown
{
// Set an instance of a data item for a component. This object will be add-ref'd and
// continue to exist until someone sets it again passing null, or the data container
// is destroyed
HRESULT SetDataItem([in] const GUID* componentId, [in] const GUID* objectGuid, [in] IUnknown* pDataItem);
// return an addref'd pointer to a data item previously stored with SetDataItem.
// componentId is the guid of the object storing the item (i.e. the CoClass of instrumentation method or raw callback)
// objectGuid is a class guid of the object being stored returns the data item if it exists
HRESULT GetDataItem([in] const GUID* componentId, [in] const GUID* objectGuid, [out] IUnknown** ppDataItem);
};
// Drag the opcodes in from opcode.def
enum ILOrdinalOpcode
{
#define OPDEF(ord, code, name, opcodeLen, operandLen, type, alt, flags, pop, push) code = ord,
#include "ILOpcodes.h"
#undef OPDEF
};
// These are all possible the operand types, NOT all the built-in CLR types
enum ILOperandType
{
ILOperandType_None,
ILOperandType_Byte,
ILOperandType_Int,
ILOperandType_UShort,
ILOperandType_Long,
ILOperandType_Single,
ILOperandType_Double,
ILOperandType_Token,
ILOperandType_Switch
};
enum ILOpcodeFlags
{
ILOpcodeFlag_None = 0x0000,
ILOpcodeFlag_Meta = 0x0001,
ILOpcodeFlag_Unused = 0x0002,
ILOpcodeFlag_Branch = 0x0004
};
enum InstructionGeneration
{
Generation_Original = 0x1,
Generation_Baseline = 0x2,
Generation_New = 0x3,
};
enum InstructionTerminationType
{
TerminationType_FallThrough, // Next instruction to execute in normal control flow is the next instruction in stream
TerminationType_Branch, // Next instruction is branch target. (Cee_Br_S, Cee_Br, Cee_Leave, Cee_Leave_S)
TerminationType_ConditionalBranch, // Next instruction is conditional branch target.
TerminationType_Throw, // Next instruction is unknown due to throw/rethrow. Same as BranchIndirect in msdis
TerminationType_Switch, // Next instruction is a switch target
TerminationType_Call, // Next instruction is a call target (Cee_Call, Cee_Jmp, Cee_NewObj)
TerminationType_IndirectCall, // Next instruction is a dynamic call target (Cee_CALLI, Cee_JMPI, Cee_CALLVIRT)
TerminationType_Return, // Next instruction return address. (Cee_Ret, Cee_Endfinally, Cee_Endfilter)
TerminationType_Trap // Next instruction is post switch (Cee_Break)
};
[
object,
uuid(E80D8434-2976-4242-8F3B-0C837C343F6C),
pointer_default(unique)
]
interface IInstruction : IUnknown
{
HRESULT GetOffset([out] DWORD* pdwOffset);
HRESULT GetOriginalOffset([out] DWORD* pdwOffset);
// Gets the name of the opcode as a newly allocated string.
// For safe cleanup, use IProfilerStringManager::FreeString or InstrumentationEngineFreeString
HRESULT GetOpCodeName([out] BSTR* pbstrName);
HRESULT GetOpCode([out] enum ILOrdinalOpcode* pOpCode);
// Only single byte opcodes have short and long forms
HRESULT GetAlternateOrdinalOpcode([out] enum ILOrdinalOpcode* pOpCode);
HRESULT GetInstructionLength([out] DWORD* pdwLength);
HRESULT GetOpcodeFlags([out] enum ILOpcodeFlags* pFlags);
HRESULT GetOpcodeLength([out] DWORD* pdwLength);
HRESULT GetOperandType([out] enum ILOperandType* pType);
HRESULT GetOperandLength([out] DWORD* pdwLength);
// set to true if this instruction did not exist in the original instruction stream.
HRESULT GetIsNew([out] BOOL* pbValue);
// set to true of this instruction has been removed from the instruction stream.
HRESULT GetIsRemoved([out] BOOL* pbValue);
HRESULT GetIsBranch([out] BOOL* pbValue);
HRESULT GetIsSwitch([out] BOOL* pbValue);
HRESULT GetIsCallInstruction([out] BOOL* pbValue);
HRESULT GetTerminationType([out] enum InstructionTerminationType* pTerminationType);
HRESULT GetIsFallThrough([out] BOOL* pbIsFallThrough);
// Get the current next and previous instructions reflecting changes that instrumentation methods have made
HRESULT GetNextInstruction([out] IInstruction** ppNextInstruction);
HRESULT GetPreviousInstruction([out] IInstruction** ppPrevInstruction);
// Get the original instructions from the graph before any instrumentation method made chanages to it.
HRESULT GetOriginalNextInstruction([out] IInstruction** ppNextInstruction);
HRESULT GetOriginalPreviousInstruction([out] IInstruction** ppPrevInstruction);
HRESULT GetInstructionGeneration([out] enum InstructionGeneration* pInstructionGeneration);
};
[
object,
uuid(1F014299-F383-46CE-B7A6-1982C85F9FEA),
pointer_default(unique)
]
interface IOperandInstruction : IUnknown
{
HRESULT GetOperandType([out] enum ILOperandType* pType);
// Operand length is available on IInstruction
HRESULT GetOperandValue(
[in] DWORD dwSize,
[out, size_is(dwSize), length_is(dwSize)] BYTE* pBytes
);
// Size of operand must match expected size from operand type
HRESULT SetOperandValue(
[in] DWORD dwSize,
[in, size_is(dwSize), length_is(dwSize)] BYTE* pBytes
);
};
[
object,
uuid(73728F9D-B4B5-4149-8396-A79C4726636E),
pointer_default(unique)
]
interface IBranchInstruction : IUnknown
{
HRESULT IsShortBranch([out] BOOL* pbValue);
//Expand the branch to the long form
HRESULT ExpandBranch();
HRESULT GetBranchTarget([out] IInstruction** ppTarget);
HRESULT GetTargetOffset([out] DWORD* pOffset);
HRESULT SetBranchTarget([in] IInstruction* pTarget);
};
[
object,
uuid(66B79035-4F18-4689-A16D-95AF469460A3),
pointer_default(unique)
]
interface ISwitchInstruction : IUnknown
{
HRESULT GetBranchTarget([in] DWORD index, [out] IInstruction** ppTarget);
HRESULT SetBranchTarget([in] DWORD index, [in] IInstruction* pTarget);
HRESULT RemoveBranchTargetAt([in] DWORD index);
HRESULT RemoveBranchTarget([in] IInstruction* pTarget);
HRESULT ReplaceBranchTarget([in] IInstruction* pOriginal, [in] IInstruction *pNew);
HRESULT GetBranchCount([out] DWORD* pBranchCount);
HRESULT GetBranchOffset([in] DWORD index, [out] DWORD* pdwOffset);
};
[
object,
uuid(2A4A827A-046D-4927-BD90-CE9607607280),
pointer_default(unique)
]
interface IEnumInstructions : IUnknown
{
HRESULT Next(
[in] ULONG celt,
[out, size_is(celt), length_is(celt)] IInstruction** rgelt,
[in] ULONG* pceltFetched
);
HRESULT Skip(
[in] ULONG celt
);
HRESULT Reset(void);
HRESULT Clone(
[out]IEnumInstructions** ppenum
);
HRESULT GetCount(
[out] DWORD* pLength
);
};
[
object,
uuid(9165F2D1-2D6D-4B89-B2AB-2CACA66CAA48),
pointer_default(unique)
]
interface IInstructionGraph : IUnknown
{
HRESULT GetMethodInfo([out] IMethodInfo** ppMethodInfo);
// Get the current first and last instructions reflecting changes that instrumentation methods have made
HRESULT GetFirstInstruction([out] IInstruction** ppInstruction);
HRESULT GetLastInstruction([out] IInstruction** ppInstruction);
HRESULT GetOriginalFirstInstruction([out] IInstruction** ppInstruction);
HRESULT GetOriginalLastInstruction([out] IInstruction** ppInstruction);
HRESULT GetUninstrumentedFirstInstruction([out] IInstruction** ppInstruction);
HRESULT GetUninstrumentedLastInstruction([out] IInstruction** ppInstruction);
HRESULT GetInstructionAtOffset([in] DWORD offset, [out] IInstruction** ppInstruction);
HRESULT GetInstructionAtOriginalOffset([in] DWORD offset, [out] IInstruction** ppInstruction);
HRESULT GetInstructionAtUninstrumentedOffset([in] DWORD dwOffset, [out] IInstruction** ppInstruction);
// Insert an instruction before another instruction. jmp offsets that point to the original instruction
// are not updated to reflect this change
HRESULT InsertBefore([in] IInstruction* pInstructionOrig, [in] IInstruction* pInstructionNew);
// Insert an instruction after another instruction. jmp offsets that point to the next instruction after
// the other instruction are not updated to reflect this change
HRESULT InsertAfter([in] IInstruction* pInstructionOrig, [in] IInstruction* pInstructionNew);
// Insert an instruction before another instruction AND update jmp targets and exception ranges that used
// to point to the old instruction to point to the new instruction.
HRESULT InsertBeforeAndRetargetOffsets([in] IInstruction* pInstructionOrig, [in] IInstruction* pInstructionNew);
// Replace an instruction with another instruction. The old instruction continues to live in the original graph but is marked replaced
HRESULT Replace([in] IInstruction* pInstructionOrig, [in] IInstruction *pInstructionNew);
// Remove an instruction. The old instruction continues to live in the original graph but is marked deleted
HRESULT Remove([in] IInstruction *pInstructionOrig);
// Remove all instructions from the current graph. The original instructions are still accessible from the original first and original last
// methods. These are all marked deleted and their original next fields are still set.
HRESULT RemoveAll();
// Removes all existing instructions from the graph and replaces them with a complete method body. The original instructions are preserved in a disjoint
// graph. Note that this changes the behavior of API's such as GetInstructionAtOriginalOffset; these will now retrieve the baseline instruction instead.
// This can only be called during the BeforeInstrumentMethod phase of the instrumentation and can only be called once
HRESULT CreateBaseline(
[in] LPCBYTE pCodeBase,
[in] LPCBYTE pEndOfCode,
[in] DWORD originalToBaselineCorIlMapSize,
[in, size_is(originalToBaselineCorIlMapSize)] COR_IL_MAP originalToBaselineCorIlMap[],
[in] DWORD baselineSequencePointSize,
[in, size_is(baselineSequencePointSize)] DWORD baselineSequencePointList[]
);
// true if CreateBaseline has previously been called.
HRESULT HasBaselineBeenSet([out] BOOL* pHasBaselineBeenSet);
HRESULT ExpandBranches();
};
[
object,
uuid(85B0B99F-73D7-4C69-8659-BF6196F5264F),
pointer_default(unique)
]
interface IEnumExceptionClauses : IUnknown
{
HRESULT Next(
[in] ULONG celt,
[out, size_is(celt), length_is(celt)] IExceptionClause** rgelt,
[in] ULONG* pceltFetched
);
HRESULT Skip(
[in] ULONG celt
);
HRESULT Reset(void);
HRESULT Clone(
[out]IEnumExceptionClauses** ppenum
);
HRESULT GetCount(
[out] DWORD* pLength
);
};
[
object,
uuid(1D57EAF6-FCFE-4874-AA0E-C9D1DF714950),
pointer_default(unique)
]
interface IExceptionClause : IUnknown
{
// flags is CorExceptionFlag
HRESULT GetFlags([out] DWORD* pFlags);
HRESULT GetTryFirstInstruction([out] IInstruction** ppInstruction);
HRESULT GetTryLastInstruction([out] IInstruction** ppInstruction);
HRESULT GetHandlerFirstInstruction([out] IInstruction** ppInstruction);
HRESULT GetHandlerLastInstruction([out] IInstruction** ppInstruction);
HRESULT GetFilterFirstInstruction([out] IInstruction** ppInstruction);
// The token of the type in the catch block
HRESULT GetExceptionHandlerType([out] mdToken* pToken);
// flags is CorExceptionFlag
HRESULT SetFlags([in] DWORD flags);
HRESULT SetTryFirstInstruction([in] IInstruction* pInstruction);
HRESULT SetTryLastInstruction([in] IInstruction* pInstruction);
HRESULT SetHandlerFirstInstruction([in] IInstruction* pInstruction);
HRESULT SetHandlerLastInstruction([in] IInstruction* pInstruction);
HRESULT SetFilterFirstInstruction([in] IInstruction* pInstruction);
// The token of the type in the catch block
HRESULT SetExceptionHandlerType([in] mdToken token);
};
[
object,
uuid(42CE95A2-F814-4DCD-952F-68CE9801FDD3),
pointer_default(unique)
]
interface IExceptionSection : IUnknown
{
HRESULT GetMethodInfo([out] IMethodInfo** ppMethodInfo);
HRESULT GetExceptionClauses([out] IEnumExceptionClauses** ppEnumExceptionClauses);
HRESULT AddExceptionClause([in] IExceptionClause* pExceptionClause);
HRESULT RemoveExceptionClause([in] IExceptionClause* pExceptionClause);
HRESULT RemoveAllExceptionClauses();
HRESULT AddNewExceptionClause(
[in] DWORD flags, /*CorExceptionFlag*/
[in] IInstruction* pTryFirstInstruction,
[in] IInstruction* pTryLastInstruction,
[in] IInstruction* pHandlerFirstInstruction,
[in] IInstruction* pHandlerLastInstruction,
[in] IInstruction* pFilterLastInstruction,
[in] mdToken handlerTypeToken,
[out] IExceptionClause** ppExceptionClause
);
};
[
object,
uuid(CF059876-C5CA-4EBF-ACB9-9C58009CE31A),
pointer_default(unique)
]
interface IInstructionFactory : IUnknown
{
// Create an instance of an instruction that takes no operands
HRESULT CreateInstruction([in] enum ILOrdinalOpcode opcode, [out] IInstruction** ppInstruction);
// Create an instance of an instruction that takes a byte operand
HRESULT CreateByteOperandInstruction([in] enum ILOrdinalOpcode opcode, [in] BYTE operand, [out] IInstruction** ppInstruction);
// Create an instance of an instruction that takes a USHORT operand
HRESULT CreateUShortOperandInstruction([in] enum ILOrdinalOpcode opcode, [in] USHORT operand, [out] IInstruction** ppInstruction);
// Create an instance of an instruction that takes a ULONG operand
HRESULT CreateIntOperandInstruction([in] enum ILOrdinalOpcode opcode, [in] INT32 operand, [out] IInstruction** ppInstruction);
// Create an instance of an instruction that takes a 64 bit operand. The name "Long" in this case comes from the msil definition
// of a 64 bit value
HRESULT CreateLongOperandInstruction([in] enum ILOrdinalOpcode opcode, [in] INT64 operand, [out] IInstruction** ppInstruction);
// Create an instance of an instruction that takes a float operand
HRESULT CreateFloatOperandInstruction([in] enum ILOrdinalOpcode opcode, [in] float operand, [out] IInstruction** ppInstruction);
// Create an instance of an instruction that takes a double operand
HRESULT CreateDoubleOperandInstruction([in] enum ILOrdinalOpcode opcode, [in] double operand, [out] IInstruction** ppInstruction);
// Create an instance of an instruction that takes a metadata token operand
HRESULT CreateTokenOperandInstruction([in] enum ILOrdinalOpcode opcode, [in] mdToken operand, [out] IInstruction** ppInstruction);
// Create a branch instruction
HRESULT CreateBranchInstruction([in] enum ILOrdinalOpcode opcode, [in] IInstruction* pBranchTarget, [out] IInstruction** ppInstruction);
// Create a switch instruction
HRESULT CreateSwitchInstruction([in] enum ILOrdinalOpcode opcode, [in] DWORD cBranchTargets, [in, size_is(cBranchTargets), length_is(cBranchTargets)] IInstruction** ppBranchTargets, [out] IInstruction** ppInstruction);
// Helpers that adjust the opcode to match the operand size
// Creates an operand instruction of type Cee_Ldc_I4, or Cee_Ldc_I4_S, Cee_Ldc_I4_0, Cee_Ldc_I4_1, Cee_Ldc_I4_2...
HRESULT CreateLoadConstInstruction([in] int value, [out] IInstruction** ppInstruction);
// Creates an operand instruction of type Cee_Ldloc, or (Cee_Ldloc_S, (Cee_Ldloc_0, Cee_Ldloc_1, Cee_Ldloc_1...
HRESULT CreateLoadLocalInstruction([in] USHORT index, [out] IInstruction** ppInstruction);
// Creates an operand instruction of type Cee_Ldloca, or Cee_Ldloca_S
HRESULT CreateLoadLocalAddressInstruction([in] USHORT index, [out] IInstruction** ppInstruction);
// Creates an operand instruction of type Cee_Stloc, or Cee_Stloc_S, Cee_Stloc_0, Cee_Stloc_1, Cee_Stloc_2...
HRESULT CreateStoreLocalInstruction([in] USHORT index, [out] IInstruction** ppInstruction);
// Creates an operand instruction of type Cee_Ldarg, or Cee_Ldarg_S, Cee_Ldarg_0, Cee_Ldarg_1, Cee_Ldarg_2...
HRESULT CreateLoadArgInstruction([in] USHORT index, [out] IInstruction** ppInstruction);
// Creates an operand instruction of type Cee_Ldarga or Cee_Ldarga_S
HRESULT CreateLoadArgAddressInstruction([in] USHORT index, [out] IInstruction** ppInstruction);
// Given a byte stream that points to MSIL, create new graph of IInstructions that represents
// that stream.
//
// 1) Each instruction in this stream will be marked as "New" and will not have the original
// next and original previous fields set.
//
// 2) This graph will not have a method info set and cannot create exception sections or handlers.
HRESULT DecodeInstructionByteStream([in] DWORD cbMethod, [in, size_is(cbMethod)] LPCBYTE instructionBytes, [out] IInstructionGraph** ppInstructionGraph);
}
[
object,
uuid(541A45B7-D194-47EE-9231-AB69D27D1D59),
pointer_default(unique)
]
interface IEnumAppMethodInfo : IUnknown
{
HRESULT Next(
[in] ULONG celt,
[out, size_is(celt), length_is(celt)] IEnumAppMethodInfo** rgelt,
[in] ULONG* pceltFetched
);
HRESULT Skip(
[in] ULONG celt
);
HRESULT Reset(void);
HRESULT Clone(
[out]IEnumAppMethodInfo** ppenum
);
HRESULT GetCount(
[out] DWORD* pLength
);
};
[
object,
uuid(CC21A894-F4DF-4726-8318-D6C24C4985B1),
pointer_default(unique)
]
interface IMethodInfo : IUnknown
{
HRESULT GetModuleInfo([out] IModuleInfo** ppModuleInfo);
// Gets the simple name of the method as a newly allocated string.
// For safe cleanup, use IProfilerStringManager::FreeString or InstrumentationEngineFreeString
HRESULT GetName([out]BSTR* pbstrName);
// Gets the fully qualified name of the method (if available).
// For safe cleanup, use IProfilerStringManager::FreeString or InstrumentationEngineFreeString
HRESULT GetFullName([out] BSTR* pbstrFullName);
// Obtain the graph of instructions. Manipulating this graph will result in changes to the code
// a the end of jit or rejit.
HRESULT GetInstructions([out] IInstructionGraph** ppInstructionGraph);
// Create a local variable builder. Can be used to add new locals.
HRESULT GetLocalVariables([out] ILocalVariableCollection** ppLocalVariables);
HRESULT GetClassId([out] ClassID* pClassId);
HRESULT GetFunctionId([out] FunctionID* pFunctionID);
HRESULT GetMethodToken([out] mdToken* pToken);
HRESULT GetGenericParameterCount([out] DWORD* pCount);
HRESULT GetIsStatic([out] BOOL* pbValue);
HRESULT GetIsPublic([out] BOOL* pbValue);
HRESULT GetIsPrivate([out] BOOL* pbValue);
HRESULT GetIsPropertyGetter([out] BOOL* pbValue);
HRESULT GetIsPropertySetter([out] BOOL* pbValue);
HRESULT GetIsFinalizer([out] BOOL* pbValue);
HRESULT GetIsConstructor([out] BOOL* pbValue);
HRESULT GetIsStaticConstructor([out] BOOL* pbValue);
HRESULT GetParameters([out] IEnumMethodParameters** pMethodArgs);
HRESULT GetDeclaringType([out] IType** ppType);
HRESULT GetReturnType([out] IType** ppType);
// Get the cor signature for the method. Passing NULL for corSignature will return the required
// buffer size in pcbSignature
HRESULT GetCorSignature([in] DWORD cbBuffer, [out, length_is(cbBuffer), size_is(cbBuffer)] BYTE* pCorSignature, [out] DWORD* pcbSignature);
HRESULT GetLocalVarSigToken([out] mdToken* pToken);
HRESULT SetLocalVarSigToken([in] mdToken token);
HRESULT GetAttributes([out] /*CorMethodAttr*/ DWORD* pCorMethodAttr);
HRESULT GetRejitCodeGenFlags([out] DWORD* pRefitFlags);
HRESULT GetCodeRva([out] DWORD* pRva);
HRESULT MethodImplFlags([out] /*CorMethodImpl*/ UINT* pCorMethodImpl);
// Allow callers to adjust optimizations during a rejit. For instance, disable all optimizations against a method
HRESULT SetRejitCodeGenFlags([in] DWORD dwFlags);
HRESULT GetExceptionSection([out] IExceptionSection** ppExceptionSection);
HRESULT GetInstructionFactory([out] IInstructionFactory** ppInstructionFactory);
// Return the running count of the number of rejits for this methodinfo
HRESULT GetRejitCount([out] DWORD* pdwRejitCount);
// Obtain the max stack value for the method. This is calculated using the instruction graph
HRESULT GetMaxStack([out] DWORD* pMaxStack);
// Get an instance of single return default transformation.
// Ieally we need to have a generic method that will intantiate this class - it actually independent from the specific method
HRESULT GetSingleRetDefaultInstrumentation([out]ISingleRetDefaultInstrumentation** ppSingleRetDefaultInstrumentation);
}
[
object,
uuid(CDF098F7-D04A-4B58-B46E-184C4F223E5F),
pointer_default(unique)
]
interface IMethodInfo2 : IMethodInfo
{
// Get the original local variables for the function.
// This is a read-only collection.
HRESULT GetOriginalLocalVariables([out] ILocalVariableCollection** ppLocalVariables);
}
[
object,
uuid(0BD963B1-FD87-4492-A417-152F3D0C9CBC),
pointer_default(unique)
]
interface IModuleInfo : IUnknown
{
// Gets the module name of the method as a newly allocated string
// For safe cleanup, use IProfilerStringManager::FreeString or InstrumentationEngineFreeString
HRESULT GetModuleName([out] BSTR* pbstrModuleName);
// Gets the path from where the module was loaded as a newly
// allocated string.
// For safe cleanup, use IProfilerStringManager::FreeString or InstrumentationEngineFreeString
HRESULT GetFullPath([out] BSTR* pbstrFullPath);
// Get info about the assembly that contains this module
HRESULT GetAssemblyInfo([out] IAssemblyInfo** ppAssemblyInfo);
HRESULT GetAppDomainInfo([out] IAppDomainInfo** ppAppDomainInfo);
HRESULT GetMetaDataImport([out] IUnknown** ppMetaDataImport);
HRESULT GetMetaDataAssemblyImport([out] IUnknown** ppMetaDataAssemblyImport);
// NOTE: It is expected that these fail for winmd files which do not support
// metadata emit.
HRESULT GetMetaDataEmit([out] IUnknown** ppMetaDataEmit);
HRESULT GetMetaDataAssemblyEmit([out] IUnknown** ppMetaDataAssemblyEmit);
HRESULT GetModuleID([out] ModuleID* pModuleId);
// Get the managed module version id
HRESULT GetMVID([out] GUID* pguidMvid);
HRESULT GetIsILOnly([out] BOOL* pbValue);
HRESULT GetIsMscorlib([out] BOOL* pbValue);
// Gets a value indicating whether or not this module is a dynamic modules.
// Note, dynamic modules have a base load address of 0, and any attempts
// to resolve an address to an RVA in this module will result in an
// error.
HRESULT GetIsDynamic([out] BOOL* pbValue);
HRESULT GetIsNgen([out] BOOL* pbValue);
HRESULT GetIsWinRT([out] BOOL* pbValue);
HRESULT GetIs64bit([out] BOOL* pbValue);
// Returns the image base for the loaded module. Note, if this module represents a dynamic module,
// then the image base will be 0.
HRESULT GetImageBase([out] LPCBYTE* pbValue);
// Return the IMAGE_COR20_HEADER structure
HRESULT GetCorHeader([in] DWORD cbValue, [out, size_is(cbValue), length_is(cbValue)] BYTE* pbValue);
// Returns the modules entrypoint token. If the module has no entrypoint token, returns E_FAIL;
HRESULT GetEntrypointToken([out]DWORD* pdwEntrypointToken);
// Returns the VS_FIXEDFILEINFO for this module.
HRESULT GetModuleVersion([in] DWORD cbValue, [out, size_is(cbValue), length_is(cbValue)] BYTE* pbValue);
HRESULT RequestRejit([in] mdToken methodToken);
// Creates a type factory associated with this module.
HRESULT CreateTypeFactory([out] ITypeCreator** ppTypeFactory);
// Allow instrumentation methods to receive an instance of IMethodInfo for a FunctionID.
// This method info is only for obtaining information about the method and cannot be used
// for instrumenation.
HRESULT GetMethodInfoById([in] FunctionID functionID, [out] IMethodInfo** ppMethodInfo);
// Allow instrumentation methods to receive an instance of IMethodInfo for a token.
// This method info is only for obtaining information about the method and cannot be used
// for instrumenation.
HRESULT GetMethodInfoByToken([in] mdToken token, [out] IMethodInfo** ppMethodInfo);
HRESULT ImportModule(
[in] IUnknown* pSourceModuleMetadataImport,
[in] LPCBYTE* pSourceImage
);
};
[
object,
uuid(4200c448-7ede-4e61-ae67-b017d3021f12),
pointer_default(unique)
]
interface IModuleInfo2 : IModuleInfo
{
HRESULT GetIsFlatLayout([out] BOOL* pbValue);
// Attempts to resolve the rva relative to this module. Note,
// this method is not implemented for dynamic modules, which
// do not have a module base address. In such cases, ResolveRva will return
// E_NOT_IMPL. Clients should call GetImageBase(), or GetIsDynamic() first
// to ensure that the module base address is not 0.
HRESULT ResolveRva([in] DWORD rva, [out] LPCBYTE* ppbResolvedAddress);
};
[
object,
uuid(B4C10B86-E3D3-4514-91B9-B2BAA84E7D8B),
pointer_default(unique)
]
interface IModuleInfo3 : IModuleInfo2
{
// Gets a value indicating whether or not this module was loaded from disk.