Make dumpmd work with tiered jitting. Now displays previous code addresses (#13805)
[platform/upstream/coreclr.git] / src / inc / dacprivate.h
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 // Internal data access functionality.
7 //
8 //*****************************************************************************
9
10 #ifndef _DACPRIVATE_H_
11 #define _DACPRIVATE_H_
12
13 #include <cor.h>
14 #include <clrdata.h>
15 #include <xclrdata.h>
16 #include <sospriv.h>
17
18 #ifndef FEATURE_PAL
19 // It is unfortunate having to include this header just to get the definition of GenericModeBlock
20 #include <msodw.h>
21 #endif // FEATURE_PAL
22
23 //
24 // Whenever a structure is marshalled between different platforms, we need to ensure the
25 // layout is the same in both cases.  We tell GCC to use the MSVC-style packing with
26 // the following attribute.  The main thing this appears to control is whether
27 // 8-byte values are aligned at 4-bytes (GCC default) or 8-bytes (MSVC default).
28 // This attribute affects only the immediate struct it is applied to, you must also apply
29 // it to any nested structs if you want their layout affected as well.  You also must
30 // apply this to unions embedded in other structures, since it can influence the starting
31 // alignment.
32 //
33 // Note that there doesn't appear to be any disadvantage to applying this a little
34 // more agressively than necessary, so we generally use it on all classes / structures
35 // defined in a file that defines marshalled data types (eg. DacDbiStructures.h)
36 // The -mms-bitfields compiler option also does this for the whole file, but we don't
37 // want to go changing the layout of, for example, structures defined in OS header files
38 // so we explicitly opt-in with this attribute.
39 //
40 #ifdef __GNUC__
41 #define MSLAYOUT __attribute__((__ms_struct__))
42 #else
43 #define MSLAYOUT
44 #endif
45
46 //----------------------------------------------------------------------------
47 //
48 // Utility class to allow for zero initialization of our Dacp- structs.
49 //
50 //----------------------------------------------------------------------------
51
52 template <class T>
53 struct ZeroInit
54 {
55     ZeroInit()
56     { memset(static_cast<T*>(this), 0, sizeof(T)); }
57 };
58
59     
60 #include <livedatatarget.h>
61
62 //----------------------------------------------------------------------------
63 //
64 // Internal CLRData requests.
65 //
66 //----------------------------------------------------------------------------
67
68
69 // Private requests for DataModules
70 enum
71 {
72     DACDATAMODULEPRIV_REQUEST_GET_MODULEPTR = 0xf0000000,
73     DACDATAMODULEPRIV_REQUEST_GET_MODULEDATA = 0xf0000001
74 };
75
76
77 // Private requests for stack walkers.
78 enum
79 {
80     DACSTACKPRIV_REQUEST_FRAME_DATA = 0xf0000000
81 };
82
83 enum DacpObjectType { OBJ_STRING=0,OBJ_FREE,OBJ_OBJECT,OBJ_ARRAY,OBJ_OTHER };
84 struct MSLAYOUT DacpObjectData : ZeroInit<DacpObjectData>
85 {
86     CLRDATA_ADDRESS MethodTable;
87     DacpObjectType ObjectType;
88     ULONG64 Size;
89     CLRDATA_ADDRESS ElementTypeHandle;
90     CorElementType ElementType;
91     DWORD dwRank;
92     ULONG64 dwNumComponents;
93     ULONG64 dwComponentSize;
94     CLRDATA_ADDRESS ArrayDataPtr;
95     CLRDATA_ADDRESS ArrayBoundsPtr;
96     CLRDATA_ADDRESS ArrayLowerBoundsPtr;
97
98     CLRDATA_ADDRESS RCW;
99     CLRDATA_ADDRESS CCW;
100     
101     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
102     {
103         return sos->GetObjectData(addr, this);
104     }
105 };
106
107 struct MSLAYOUT DacpExceptionObjectData : ZeroInit<DacpExceptionObjectData>
108 {
109     CLRDATA_ADDRESS   Message;
110     CLRDATA_ADDRESS   InnerException;
111     CLRDATA_ADDRESS   StackTrace;
112     CLRDATA_ADDRESS   WatsonBuckets;
113     CLRDATA_ADDRESS   StackTraceString;
114     CLRDATA_ADDRESS   RemoteStackTraceString;
115     INT32             HResult;
116     INT32             XCode;
117
118     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
119     {
120         HRESULT hr;
121         ISOSDacInterface2 *psos2 = NULL;
122         if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface2), (void**) &psos2)))
123         {
124             hr = psos2->GetObjectExceptionData(addr, this);
125             psos2->Release();
126         }
127         return hr;
128     }
129 };
130
131 struct MSLAYOUT DacpUsefulGlobalsData : ZeroInit<DacpUsefulGlobalsData>
132 {
133     CLRDATA_ADDRESS ArrayMethodTable;
134     CLRDATA_ADDRESS StringMethodTable;
135     CLRDATA_ADDRESS ObjectMethodTable;
136     CLRDATA_ADDRESS ExceptionMethodTable;
137     CLRDATA_ADDRESS FreeMethodTable;
138 };
139
140 struct MSLAYOUT DacpFieldDescData : ZeroInit<DacpFieldDescData>
141 {
142     CorElementType Type;
143     CorElementType sigType;     // ELEMENT_TYPE_XXX from signature. We need this to disply pretty name for String in minidump's case
144     CLRDATA_ADDRESS MTOfType; // NULL if Type is not loaded
145     
146     CLRDATA_ADDRESS ModuleOfType;
147     mdTypeDef TokenOfType;
148     
149     mdFieldDef mb;
150     CLRDATA_ADDRESS MTOfEnclosingClass;
151     DWORD dwOffset;
152     BOOL bIsThreadLocal;
153     BOOL bIsContextLocal;
154     BOOL bIsStatic;
155     CLRDATA_ADDRESS NextField;
156
157     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
158     {
159         return sos->GetFieldDescData(addr, this);
160     }
161 };
162
163 struct MSLAYOUT DacpMethodTableFieldData : ZeroInit<DacpMethodTableFieldData>
164 {
165     WORD wNumInstanceFields;
166     WORD wNumStaticFields;
167     WORD wNumThreadStaticFields;
168
169     CLRDATA_ADDRESS FirstField; // If non-null, you can retrieve more
170     
171     WORD wContextStaticOffset;
172     WORD wContextStaticsSize;
173     
174     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
175     {
176         return sos->GetMethodTableFieldData(addr, this);
177     }
178 };
179
180 struct MSLAYOUT DacpMethodTableTransparencyData : ZeroInit<DacpMethodTableTransparencyData>
181 {
182     BOOL bHasCriticalTransparentInfo;
183     BOOL bIsCritical;
184     BOOL bIsTreatAsSafe;
185
186     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
187     {
188         return sos->GetMethodTableTransparencyData(addr, this);
189     }
190 };
191
192 struct MSLAYOUT DacpDomainLocalModuleData : ZeroInit<DacpDomainLocalModuleData>
193 {
194     // These two parameters are used as input params when calling the
195     // no-argument form of Request below.
196     CLRDATA_ADDRESS appDomainAddr;
197     ULONG64  ModuleID;
198     
199     CLRDATA_ADDRESS pClassData;   
200     CLRDATA_ADDRESS pDynamicClassTable;   
201     CLRDATA_ADDRESS pGCStaticDataStart;
202     CLRDATA_ADDRESS pNonGCStaticDataStart; 
203
204     // Called when you have a pointer to the DomainLocalModule
205     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
206     {
207         return sos->GetDomainLocalModuleData(addr, this);
208     }
209 };
210
211
212 struct MSLAYOUT DacpThreadLocalModuleData : ZeroInit<DacpThreadLocalModuleData>
213 {
214     // These two parameters are used as input params when calling the
215     // no-argument form of Request below.
216     CLRDATA_ADDRESS threadAddr;
217     ULONG64 ModuleIndex;
218     
219     CLRDATA_ADDRESS pClassData;   
220     CLRDATA_ADDRESS pDynamicClassTable;   
221     CLRDATA_ADDRESS pGCStaticDataStart;
222     CLRDATA_ADDRESS pNonGCStaticDataStart;
223 };
224
225
226 struct MSLAYOUT DacpModuleData : ZeroInit<DacpModuleData>
227 {
228     CLRDATA_ADDRESS Address;
229     CLRDATA_ADDRESS File; // A PEFile addr
230     CLRDATA_ADDRESS  ilBase;
231     CLRDATA_ADDRESS metadataStart;
232     ULONG64 metadataSize;
233     CLRDATA_ADDRESS Assembly; // Assembly pointer
234     BOOL bIsReflection;
235     BOOL bIsPEFile;
236     ULONG64 dwBaseClassIndex;
237     ULONG64 dwModuleID;
238
239     DWORD dwTransientFlags;
240     
241     CLRDATA_ADDRESS TypeDefToMethodTableMap;
242     CLRDATA_ADDRESS TypeRefToMethodTableMap;
243     CLRDATA_ADDRESS MethodDefToDescMap;
244     CLRDATA_ADDRESS FieldDefToDescMap;
245     CLRDATA_ADDRESS MemberRefToDescMap;
246     CLRDATA_ADDRESS FileReferencesMap;
247     CLRDATA_ADDRESS ManifestModuleReferencesMap;
248
249     CLRDATA_ADDRESS pLookupTableHeap;
250     CLRDATA_ADDRESS pThunkHeap;
251
252     ULONG64 dwModuleIndex;
253
254     DacpModuleData()
255     {
256     }
257     
258     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
259     {
260         return sos->GetModuleData(addr, this);
261     }
262
263 private:
264     // Ensure that this data structure is not copied.
265     DacpModuleData(const DacpModuleData&);
266     void operator=(const DacpModuleData&);
267 };
268
269 struct MSLAYOUT DacpMethodTableData : ZeroInit<DacpMethodTableData>
270 {
271     BOOL bIsFree; // everything else is NULL if this is true.
272     CLRDATA_ADDRESS Module;
273     CLRDATA_ADDRESS Class;
274     CLRDATA_ADDRESS ParentMethodTable;
275     WORD wNumInterfaces;
276     WORD wNumMethods;
277     WORD wNumVtableSlots;
278     WORD wNumVirtuals;
279     DWORD BaseSize;
280     DWORD ComponentSize;
281     mdTypeDef cl; // Metadata token    
282     DWORD dwAttrClass; // cached metadata
283     BOOL bIsShared; // flags & enum_flag_DomainNeutral
284     BOOL bIsDynamic;
285     BOOL bContainsPointers;
286
287     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
288     {
289         return sos->GetMethodTableData(addr, this);
290     }
291 };
292
293
294 // Copied from util.hpp, for DacpThreadStoreData.fHostConfig below.
295 #define CLRMEMORYHOSTED                             0x1
296 #define CLRTASKHOSTED                               0x2
297 #define CLRSYNCHOSTED                               0x4
298 #define CLRTHREADPOOLHOSTED                         0x8
299 #define CLRIOCOMPLETIONHOSTED                       0x10
300 #define CLRASSEMBLYHOSTED                           0x20
301 #define CLRGCHOSTED                                 0x40
302 #define CLRSECURITYHOSTED                           0x80
303 #define CLRHOSTED           0x80000000
304
305 struct MSLAYOUT DacpThreadStoreData : ZeroInit<DacpThreadStoreData>
306 {
307     LONG threadCount;
308     LONG unstartedThreadCount;
309     LONG backgroundThreadCount;
310     LONG pendingThreadCount;
311     LONG deadThreadCount;
312     CLRDATA_ADDRESS firstThread;
313     CLRDATA_ADDRESS finalizerThread;
314     CLRDATA_ADDRESS gcThread;
315     DWORD fHostConfig;          // Uses hosting flags defined above
316
317     HRESULT Request(ISOSDacInterface *sos)
318     {
319         return sos->GetThreadStoreData(this);
320     }
321 };
322
323 struct MSLAYOUT DacpAppDomainStoreData : ZeroInit<DacpAppDomainStoreData>
324 {
325     CLRDATA_ADDRESS sharedDomain;
326     CLRDATA_ADDRESS systemDomain;
327     LONG DomainCount;
328
329     HRESULT Request(ISOSDacInterface *sos)
330     {
331         return sos->GetAppDomainStoreData(this);
332     }
333 };
334
335 struct MSLAYOUT DacpCOMInterfacePointerData : ZeroInit<DacpCOMInterfacePointerData>
336 {
337     CLRDATA_ADDRESS methodTable;
338     CLRDATA_ADDRESS interfacePtr;
339     CLRDATA_ADDRESS comContext;
340 };
341
342 struct MSLAYOUT DacpRCWData : ZeroInit<DacpRCWData>
343 {
344     CLRDATA_ADDRESS identityPointer;
345     CLRDATA_ADDRESS unknownPointer;
346     CLRDATA_ADDRESS managedObject;
347     CLRDATA_ADDRESS jupiterObject;
348     CLRDATA_ADDRESS vtablePtr;
349     CLRDATA_ADDRESS creatorThread;
350     CLRDATA_ADDRESS ctxCookie;
351     
352     LONG refCount;
353     LONG interfaceCount;
354
355     BOOL isJupiterObject;
356     BOOL supportsIInspectable;
357     BOOL isAggregated;
358     BOOL isContained;
359     BOOL isFreeThreaded;
360     BOOL isDisconnected;
361     
362     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS rcw)
363     {
364         return sos->GetRCWData(rcw, this);
365     }
366
367     HRESULT IsDCOMProxy(ISOSDacInterface *sos, CLRDATA_ADDRESS rcw, BOOL* isDCOMProxy)
368     {
369         ISOSDacInterface2 *pSOS2 = nullptr;
370         HRESULT hr = sos->QueryInterface(__uuidof(ISOSDacInterface2), reinterpret_cast<LPVOID*>(&pSOS2));
371         if (SUCCEEDED(hr))
372         {
373             hr = pSOS2->IsRCWDCOMProxy(rcw, isDCOMProxy);
374             pSOS2->Release();
375         }
376
377         return hr;
378     }
379 };
380
381 struct MSLAYOUT DacpCCWData : ZeroInit<DacpCCWData>
382 {
383     CLRDATA_ADDRESS outerIUnknown;
384     CLRDATA_ADDRESS managedObject;
385     CLRDATA_ADDRESS handle;
386     CLRDATA_ADDRESS ccwAddress;
387
388     LONG refCount;
389     LONG interfaceCount;
390     BOOL isNeutered;
391
392     LONG jupiterRefCount;
393     BOOL isPegged;
394     BOOL isGlobalPegged;
395     BOOL hasStrongRef;
396     BOOL isExtendsCOMObject;
397     BOOL isAggregated;
398     
399     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS ccw)
400     {
401         return sos->GetCCWData(ccw, this);
402     }
403 };
404
405 enum DacpAppDomainDataStage {
406     STAGE_CREATING,
407     STAGE_READYFORMANAGEDCODE,
408     STAGE_ACTIVE,
409     STAGE_OPEN,
410     STAGE_UNLOAD_REQUESTED,
411     STAGE_EXITING,
412     STAGE_EXITED,
413     STAGE_FINALIZING,
414     STAGE_FINALIZED,
415     STAGE_HANDLETABLE_NOACCESS,
416     STAGE_CLEARED,
417     STAGE_COLLECTED,
418     STAGE_CLOSED
419 };
420
421 // Information about a BaseDomain (AppDomain, SharedDomain or SystemDomain).
422 // For types other than AppDomain, some fields (like dwID, DomainLocalBlock, etc.) will be 0/null. 
423 struct MSLAYOUT DacpAppDomainData : ZeroInit<DacpAppDomainData>
424 {
425     // The pointer to the BaseDomain (not necessarily an AppDomain).  
426     // It's useful to keep this around in the structure
427     CLRDATA_ADDRESS AppDomainPtr; 
428     CLRDATA_ADDRESS AppSecDesc;
429     CLRDATA_ADDRESS pLowFrequencyHeap;
430     CLRDATA_ADDRESS pHighFrequencyHeap;
431     CLRDATA_ADDRESS pStubHeap;
432     CLRDATA_ADDRESS DomainLocalBlock;
433     CLRDATA_ADDRESS pDomainLocalModules;    
434     // The creation sequence number of this app domain (starting from 1)
435     DWORD dwId;
436     LONG AssemblyCount;
437     LONG FailedAssemblyCount;
438     DacpAppDomainDataStage appDomainStage; 
439     
440     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
441     {
442         return sos->GetAppDomainData(addr, this);
443     }
444 };
445
446 struct MSLAYOUT DacpAssemblyData : ZeroInit<DacpAssemblyData>
447 {
448     CLRDATA_ADDRESS AssemblyPtr; //useful to have
449     CLRDATA_ADDRESS ClassLoader;
450     CLRDATA_ADDRESS ParentDomain;
451     CLRDATA_ADDRESS BaseDomainPtr;
452     CLRDATA_ADDRESS AssemblySecDesc;
453     BOOL isDynamic;
454     UINT ModuleCount;
455     UINT LoadContext;
456     BOOL isDomainNeutral;
457     DWORD dwLocationFlags;
458
459     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr, CLRDATA_ADDRESS baseDomainPtr)
460     {
461         return sos->GetAssemblyData(baseDomainPtr, addr, this);
462     }
463
464     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
465     {
466         return Request(sos, addr, NULL);
467     }
468 };
469
470
471 struct MSLAYOUT DacpThreadData : ZeroInit<DacpThreadData>
472 {
473     DWORD corThreadId;
474     DWORD osThreadId;
475     int state;
476     ULONG preemptiveGCDisabled;
477     CLRDATA_ADDRESS allocContextPtr;
478     CLRDATA_ADDRESS allocContextLimit;
479     CLRDATA_ADDRESS context;
480     CLRDATA_ADDRESS domain;
481     CLRDATA_ADDRESS pFrame;
482     DWORD lockCount;
483     CLRDATA_ADDRESS firstNestedException; // Pass this pointer to DacpNestedExceptionInfo
484     CLRDATA_ADDRESS teb;
485     CLRDATA_ADDRESS fiberData;
486     CLRDATA_ADDRESS lastThrownObjectHandle;
487     CLRDATA_ADDRESS nextThread;
488
489     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
490     {
491         return sos->GetThreadData(addr, this);
492     }
493 };
494
495
496 struct MSLAYOUT DacpReJitData : ZeroInit<DacpReJitData>
497 {
498     enum Flags
499     {
500         kUnknown,
501         kRequested,
502         kActive,
503         kReverted,
504     };
505
506     CLRDATA_ADDRESS                 rejitID;
507     Flags                           flags;
508     CLRDATA_ADDRESS                 NativeCodeAddr;
509 };
510
511
512 struct MSLAYOUT DacpMethodDescData : ZeroInit<DacpMethodDescData>
513 {
514     BOOL            bHasNativeCode;
515     BOOL            bIsDynamic;
516     WORD            wSlotNumber;
517     CLRDATA_ADDRESS NativeCodeAddr;
518     // Useful for breaking when a method is jitted.
519     CLRDATA_ADDRESS AddressOfNativeCodeSlot;
520     
521     CLRDATA_ADDRESS MethodDescPtr;
522     CLRDATA_ADDRESS MethodTablePtr;
523     CLRDATA_ADDRESS ModulePtr;
524     
525     mdToken                  MDToken;
526     CLRDATA_ADDRESS GCInfo;
527     CLRDATA_ADDRESS GCStressCodeCopy;
528
529     // This is only valid if bIsDynamic is true
530     CLRDATA_ADDRESS managedDynamicMethodObject;
531
532     CLRDATA_ADDRESS requestedIP;
533
534     // Gives info for the single currently active version of a method
535     DacpReJitData       rejitDataCurrent;
536
537     // Gives info corresponding to requestedIP (for !ip2md)
538     DacpReJitData       rejitDataRequested;
539     
540     // Total number of rejit versions that have been jitted
541     ULONG               cJittedRejitVersions;
542
543     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
544     {
545         return sos->GetMethodDescData(
546             addr, 
547             NULL,   // IP address
548             this,
549             0,      // cRejitData
550             NULL,   // rejitData[]
551             NULL    // pcNeededRejitData
552             );
553     }
554 };
555
556
557 struct MSLAYOUT DacpMethodDescTransparencyData : ZeroInit<DacpMethodDescTransparencyData>
558 {
559     BOOL            bHasCriticalTransparentInfo;
560     BOOL            bIsCritical;
561     BOOL            bIsTreatAsSafe;
562
563     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
564     {
565         return sos->GetMethodDescTransparencyData(addr, this);
566     }
567 };
568
569 struct MSLAYOUT DacpTieredVersionData
570 {
571     enum TieredState 
572     {
573         NON_TIERED,
574         TIERED_0,
575         TIERED_1,
576         TIERED_UNKNOWN
577     };
578     
579     CLRDATA_ADDRESS NativeCodeAddr;
580     TieredState     TieredInfo;
581     CLRDATA_ADDRESS NativeCodeVersionNodePtr;
582 };
583
584 // for JITType
585 enum JITTypes {TYPE_UNKNOWN=0,TYPE_JIT,TYPE_PJIT};
586
587 struct MSLAYOUT DacpCodeHeaderData : ZeroInit<DacpCodeHeaderData>
588 {        
589     CLRDATA_ADDRESS GCInfo;
590     JITTypes                   JITType;
591     CLRDATA_ADDRESS MethodDescPtr;
592     CLRDATA_ADDRESS MethodStart;
593     DWORD                    MethodSize;
594     CLRDATA_ADDRESS ColdRegionStart;
595     DWORD           ColdRegionSize;
596     DWORD           HotRegionSize;
597     
598     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS IPAddr)
599     {
600         return sos->GetCodeHeaderData(IPAddr, this);
601     }
602 };
603
604 struct MSLAYOUT DacpWorkRequestData : ZeroInit<DacpWorkRequestData>
605 {
606     CLRDATA_ADDRESS Function;
607     CLRDATA_ADDRESS Context;
608     CLRDATA_ADDRESS NextWorkRequest;
609         
610     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
611     {
612         return sos->GetWorkRequestData(addr, this);
613     }
614 };
615
616 struct MSLAYOUT DacpHillClimbingLogEntry : ZeroInit<DacpHillClimbingLogEntry>
617 {
618     DWORD TickCount;
619     int Transition;
620     int NewControlSetting;
621     int LastHistoryCount;
622     double LastHistoryMean;
623     
624     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS entry)
625     {
626         return sos->GetHillClimbingLogEntry(entry, this);   
627     }
628 };
629
630
631 // Used for CLR versions >= 4.0
632 struct MSLAYOUT DacpThreadpoolData : ZeroInit<DacpThreadpoolData>
633 {
634     LONG cpuUtilization;    
635     int NumIdleWorkerThreads;
636     int NumWorkingWorkerThreads;
637     int NumRetiredWorkerThreads;
638     LONG MinLimitTotalWorkerThreads;
639     LONG MaxLimitTotalWorkerThreads;
640
641     CLRDATA_ADDRESS FirstUnmanagedWorkRequest;
642
643     CLRDATA_ADDRESS HillClimbingLog;
644     int HillClimbingLogFirstIndex;
645     int HillClimbingLogSize;
646
647     DWORD NumTimers;
648     // TODO: Add support to enumerate timers too.
649
650     LONG   NumCPThreads;
651     LONG   NumFreeCPThreads;
652     LONG   MaxFreeCPThreads; 
653     LONG   NumRetiredCPThreads;
654     LONG   MaxLimitTotalCPThreads;
655     LONG   CurrentLimitTotalCPThreads;
656     LONG   MinLimitTotalCPThreads;
657
658     CLRDATA_ADDRESS AsyncTimerCallbackCompletionFPtr;
659     
660     HRESULT Request(ISOSDacInterface *sos)
661     {
662         return sos->GetThreadpoolData(this);
663     }
664 };
665
666 struct MSLAYOUT DacpGenerationData : ZeroInit<DacpGenerationData>
667 {    
668     CLRDATA_ADDRESS start_segment;
669     CLRDATA_ADDRESS allocation_start;
670
671     // These are examined only for generation 0, otherwise NULL
672     CLRDATA_ADDRESS allocContextPtr;
673     CLRDATA_ADDRESS allocContextLimit;
674 };
675
676 #define DAC_NUMBERGENERATIONS 4
677
678
679 struct MSLAYOUT DacpAllocData : ZeroInit<DacpAllocData>
680 {
681     CLRDATA_ADDRESS allocBytes;
682     CLRDATA_ADDRESS allocBytesLoh;
683 };
684
685 struct MSLAYOUT DacpGenerationAllocData : ZeroInit<DacpGenerationAllocData>
686 {
687     DacpAllocData allocData[DAC_NUMBERGENERATIONS]; 
688 };
689
690 struct MSLAYOUT DacpGcHeapDetails : ZeroInit<DacpGcHeapDetails>
691 {
692     CLRDATA_ADDRESS heapAddr; // Only filled in in server mode, otherwise NULL
693     CLRDATA_ADDRESS alloc_allocated;
694
695     CLRDATA_ADDRESS mark_array;
696     CLRDATA_ADDRESS current_c_gc_state;
697     CLRDATA_ADDRESS next_sweep_obj;
698     CLRDATA_ADDRESS saved_sweep_ephemeral_seg;
699     CLRDATA_ADDRESS saved_sweep_ephemeral_start;
700     CLRDATA_ADDRESS background_saved_lowest_address;
701     CLRDATA_ADDRESS background_saved_highest_address;
702
703     DacpGenerationData generation_table [DAC_NUMBERGENERATIONS]; 
704     CLRDATA_ADDRESS ephemeral_heap_segment;        
705     CLRDATA_ADDRESS finalization_fill_pointers [DAC_NUMBERGENERATIONS + 3];
706     CLRDATA_ADDRESS lowest_address;
707     CLRDATA_ADDRESS highest_address;
708     CLRDATA_ADDRESS card_table;
709
710     // Use this for workstation mode (DacpGcHeapDat.bServerMode==FALSE).
711     HRESULT Request(ISOSDacInterface *sos)
712     {
713         return sos->GetGCHeapStaticData(this);
714     }
715
716     // Use this for Server mode, as there are multiple heaps,
717     // and you need to pass a heap address in addr.
718     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
719     {
720         return sos->GetGCHeapDetails(addr, this);
721     }
722 };
723
724 struct MSLAYOUT DacpGcHeapData
725     : ZeroInit<DacpGcHeapData>
726 {
727     BOOL bServerMode;
728     BOOL bGcStructuresValid;
729     UINT HeapCount;
730     UINT g_max_generation;
731     
732     HRESULT Request(ISOSDacInterface *sos)
733     {
734         return sos->GetGCHeapData(this);
735     }
736 };
737
738 struct MSLAYOUT DacpHeapSegmentData
739     : ZeroInit<DacpHeapSegmentData>
740 {
741     CLRDATA_ADDRESS segmentAddr;
742     CLRDATA_ADDRESS allocated;
743     CLRDATA_ADDRESS committed;
744     CLRDATA_ADDRESS reserved;
745     CLRDATA_ADDRESS used;
746     CLRDATA_ADDRESS mem;
747     // pass this to request if non-null to get the next segments.
748     CLRDATA_ADDRESS next;
749     CLRDATA_ADDRESS gc_heap; // only filled in in server mode, otherwise NULL
750     // computed field: if this is the ephemeral segment highMark includes the ephemeral generation
751     CLRDATA_ADDRESS highAllocMark;
752
753     size_t flags;
754     CLRDATA_ADDRESS background_allocated;
755
756     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr, const DacpGcHeapDetails& heap)
757     {
758         HRESULT hr = sos->GetHeapSegmentData(addr, this);
759
760         // if this is the start segment, set highAllocMark too.
761         if (SUCCEEDED(hr))
762         {
763             // TODO:  This needs to be put on the Dac side.
764             if (this->segmentAddr == heap.generation_table[0].start_segment)
765                 highAllocMark = heap.alloc_allocated;
766             else
767                 highAllocMark = allocated;
768         }    
769         return hr;
770     }
771 };
772
773 struct MSLAYOUT DacpOomData : ZeroInit<DacpOomData>
774 {
775     int reason;
776     ULONG64 alloc_size;
777     ULONG64 available_pagefile_mb;
778     ULONG64 gc_index;
779     int fgm;
780     ULONG64 size;
781     BOOL loh_p;
782
783     HRESULT Request(ISOSDacInterface *sos)
784     {
785         return sos->GetOOMStaticData(this);
786     }
787
788     // Use this for Server mode, as there are multiple heaps,
789     // and you need to pass a heap address in addr.
790     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
791     {
792         return sos->GetOOMData(addr, this);
793     }
794 };
795
796 #define   DAC_NUM_GC_DATA_POINTS 9
797 #define   DAC_MAX_COMPACT_REASONS_COUNT 11
798 #define   DAC_MAX_EXPAND_MECHANISMS_COUNT 6
799 #define   DAC_MAX_GC_MECHANISM_BITS_COUNT 2
800 #define   DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT 6
801 struct MSLAYOUT DacpGCInterestingInfoData : ZeroInit<DacpGCInterestingInfoData>
802 {
803     size_t interestingDataPoints[DAC_NUM_GC_DATA_POINTS];
804     size_t compactReasons[DAC_MAX_COMPACT_REASONS_COUNT];
805     size_t expandMechanisms[DAC_MAX_EXPAND_MECHANISMS_COUNT];
806     size_t bitMechanisms[DAC_MAX_GC_MECHANISM_BITS_COUNT];
807     size_t globalMechanisms[DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT];
808
809     HRESULT RequestGlobal(ISOSDacInterface *sos)
810     {
811         HRESULT hr;
812         ISOSDacInterface3 *psos3 = NULL;
813         if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3)))
814         {
815             hr = psos3->GetGCGlobalMechanisms(globalMechanisms);
816             psos3->Release();
817         }
818         return hr;
819     }
820
821     HRESULT Request(ISOSDacInterface *sos)
822     {
823         HRESULT hr;
824         ISOSDacInterface3 *psos3 = NULL;
825         if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3)))
826         {
827             hr = psos3->GetGCInterestingInfoStaticData(this);
828             psos3->Release();
829         }
830         return hr;
831     }
832
833     // Use this for Server mode, as there are multiple heaps,
834     // and you need to pass a heap address in addr.
835     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
836     {
837         HRESULT hr;
838         ISOSDacInterface3 *psos3 = NULL;
839         if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3)))
840         {
841             hr = psos3->GetGCInterestingInfoData(addr, this);
842             psos3->Release();
843         }
844         return hr;
845     }
846 };
847
848 struct MSLAYOUT DacpGcHeapAnalyzeData
849     : ZeroInit<DacpGcHeapAnalyzeData>
850 {
851     CLRDATA_ADDRESS heapAddr; // Only filled in in server mode, otherwise NULL
852
853     CLRDATA_ADDRESS internal_root_array;
854     ULONG64         internal_root_array_index;
855     BOOL            heap_analyze_success;
856
857     // Use this for workstation mode (DacpGcHeapDat.bServerMode==FALSE).
858     HRESULT Request(ISOSDacInterface *sos)
859     {
860         return sos->GetHeapAnalyzeStaticData(this);   
861     }
862
863     // Use this for Server mode, as there are multiple heaps,
864     // and you need to pass a heap address in addr.
865     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
866     {
867         return sos->GetHeapAnalyzeData(addr, this);
868     }
869 };
870
871
872 #define SYNCBLOCKDATA_COMFLAGS_CCW 1
873 #define SYNCBLOCKDATA_COMFLAGS_RCW 2
874 #define SYNCBLOCKDATA_COMFLAGS_CF 4
875
876 struct MSLAYOUT DacpSyncBlockData : ZeroInit<DacpSyncBlockData>
877 {        
878     CLRDATA_ADDRESS Object;
879     BOOL            bFree; // if set, no other fields are useful
880     
881     // fields below provide data from this, so it's just for display
882     CLRDATA_ADDRESS SyncBlockPointer;
883     DWORD           COMFlags;
884     UINT            MonitorHeld;
885     UINT            Recursion;
886     CLRDATA_ADDRESS HoldingThread;
887     UINT            AdditionalThreadCount;
888     CLRDATA_ADDRESS appDomainPtr;
889     
890     // SyncBlockCount will always be filled in with the number of SyncBlocks.
891     // SyncBlocks may be requested from [1,SyncBlockCount]
892     UINT            SyncBlockCount;
893
894     // SyncBlockNumber must be from [1,SyncBlockCount]    
895     // If there are no SyncBlocks, a call to Request with SyncBlockCount = 1
896     // will return E_FAIL.
897     HRESULT Request(ISOSDacInterface *sos, UINT SyncBlockNumber)
898     {
899         return sos->GetSyncBlockData(SyncBlockNumber, this);
900     }
901 };
902
903 struct MSLAYOUT DacpSyncBlockCleanupData : ZeroInit<DacpSyncBlockCleanupData>
904 {
905     CLRDATA_ADDRESS SyncBlockPointer;
906     
907     CLRDATA_ADDRESS nextSyncBlock;
908     CLRDATA_ADDRESS blockRCW;
909     CLRDATA_ADDRESS blockClassFactory;
910     CLRDATA_ADDRESS blockCCW;
911     
912     // Pass NULL on the first request to start a traversal.
913     HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS psyncBlock)
914     {
915         return sos->GetSyncBlockCleanupData(psyncBlock, this);
916     }
917 };
918
919 ///////////////////////////////////////////////////////////////////////////
920
921 enum EHClauseType {EHFault, EHFinally, EHFilter, EHTyped, EHUnknown};
922                 
923 struct MSLAYOUT DACEHInfo : ZeroInit<DACEHInfo>
924 {
925     EHClauseType clauseType;
926     CLRDATA_ADDRESS tryStartOffset;
927     CLRDATA_ADDRESS tryEndOffset;
928     CLRDATA_ADDRESS handlerStartOffset;
929     CLRDATA_ADDRESS handlerEndOffset;
930     BOOL isDuplicateClause;
931     CLRDATA_ADDRESS filterOffset;   // valid when clauseType is EHFilter
932     BOOL isCatchAllHandler;             // valid when clauseType is EHTyped
933     CLRDATA_ADDRESS moduleAddr;    // when == 0 mtCatch contains a MethodTable, when != 0 tokCatch contains a type token
934     CLRDATA_ADDRESS mtCatch;   // the method table of the TYPED clause type
935     mdToken tokCatch;          // the type token of the TYPED clause type
936 };
937
938 struct MSLAYOUT DacpGetModuleAddress : ZeroInit<DacpGetModuleAddress>
939 {
940     CLRDATA_ADDRESS ModulePtr;
941     HRESULT Request(IXCLRDataModule* pDataModule)
942     {
943         return pDataModule->Request(DACDATAMODULEPRIV_REQUEST_GET_MODULEPTR, 0, NULL, sizeof(*this), (PBYTE) this);
944     }
945 };
946
947 struct MSLAYOUT DacpGetModuleData : ZeroInit<DacpGetModuleData>
948 {
949     BOOL IsDynamic;
950     BOOL IsInMemory;
951     BOOL IsFileLayout;
952     CLRDATA_ADDRESS PEFile;
953     CLRDATA_ADDRESS LoadedPEAddress;
954     ULONG64 LoadedPESize;
955     CLRDATA_ADDRESS InMemoryPdbAddress;
956     ULONG64 InMemoryPdbSize;
957
958     HRESULT Request(IXCLRDataModule* pDataModule)
959     {
960         return pDataModule->Request(DACDATAMODULEPRIV_REQUEST_GET_MODULEDATA, 0, NULL, sizeof(*this), (PBYTE) this);
961     }
962 };
963
964 struct MSLAYOUT DacpFrameData : ZeroInit<DacpFrameData>
965 {
966     CLRDATA_ADDRESS frameAddr;
967
968     // Could also be implemented for IXCLRDataFrame if desired.
969     HRESULT Request(IXCLRDataStackWalk* dac)
970     {
971         return dac->Request(DACSTACKPRIV_REQUEST_FRAME_DATA,
972                             0, NULL,
973                             sizeof(*this), (PBYTE)this);
974     }
975 };
976
977 struct MSLAYOUT DacpJitManagerInfo : ZeroInit<DacpJitManagerInfo>
978 {
979     CLRDATA_ADDRESS managerAddr;
980     DWORD codeType; // for union below
981     CLRDATA_ADDRESS ptrHeapList;    // A HeapList * if IsMiIL(codeType)
982 };
983
984 enum CodeHeapType {CODEHEAP_LOADER=0,CODEHEAP_HOST,CODEHEAP_UNKNOWN};
985
986 struct MSLAYOUT DacpJitCodeHeapInfo : ZeroInit<DacpJitCodeHeapInfo>
987 {
988     DWORD codeHeapType; // for union below
989
990     union
991     {
992         CLRDATA_ADDRESS LoaderHeap;    // if CODEHEAP_LOADER
993         struct MSLAYOUT
994         {
995             CLRDATA_ADDRESS baseAddr; // if CODEHEAP_HOST
996             CLRDATA_ADDRESS currentAddr;
997         } HostData;
998     };
999 };
1000
1001 #include "static_assert.h"
1002
1003 /* DAC datastructures are frozen as of dev11 shipping.  Do NOT add fields, remove fields, or change the fields of
1004  * these structs in any way.  The correct way to get new data out of the runtime is to create a new struct and
1005  * add a new function to the latest Dac<-->SOS interface to produce this data.
1006  */
1007 static_assert(sizeof(DacpAllocData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility.");
1008 static_assert(sizeof(DacpGenerationAllocData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility.");
1009 static_assert(sizeof(DacpSyncBlockCleanupData) == 0x28, "Dacp structs cannot be modified due to backwards compatibility.");
1010 static_assert(sizeof(DacpThreadStoreData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
1011 static_assert(sizeof(DacpAppDomainStoreData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1012 static_assert(sizeof(DacpAppDomainData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility.");
1013 static_assert(sizeof(DacpAssemblyData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility.");
1014 static_assert(sizeof(DacpThreadData) == 0x68, "Dacp structs cannot be modified due to backwards compatibility.");
1015 static_assert(sizeof(DacpMethodDescData) == 0x98, "Dacp structs cannot be modified due to backwards compatibility.");
1016 static_assert(sizeof(DacpCodeHeaderData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
1017 static_assert(sizeof(DacpThreadpoolData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility.");
1018 static_assert(sizeof(DacpObjectData) == 0x60, "Dacp structs cannot be modified due to backwards compatibility.");
1019 static_assert(sizeof(DacpMethodTableData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility.");
1020 static_assert(sizeof(DacpWorkRequestData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1021 static_assert(sizeof(DacpFieldDescData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility.");
1022 static_assert(sizeof(DacpModuleData) == 0xa0, "Dacp structs cannot be modified due to backwards compatibility.");
1023 static_assert(sizeof(DacpGcHeapData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility.");
1024 static_assert(sizeof(DacpJitManagerInfo) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1025 static_assert(sizeof(DacpHeapSegmentData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility.");
1026 static_assert(sizeof(DacpDomainLocalModuleData) == 0x30, "Dacp structs cannot be modified due to backwards compatibility.");
1027 static_assert(sizeof(DacpUsefulGlobalsData) == 0x28, "Dacp structs cannot be modified due to backwards compatibility.");
1028 static_assert(sizeof(DACEHInfo) == 0x58, "Dacp structs cannot be modified due to backwards compatibility.");
1029 static_assert(sizeof(DacpRCWData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility.");
1030 static_assert(sizeof(DacpCCWData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility.");
1031 static_assert(sizeof(DacpMethodTableFieldData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1032 static_assert(sizeof(DacpMethodTableTransparencyData) == 0xc, "Dacp structs cannot be modified due to backwards compatibility.");
1033 static_assert(sizeof(DacpThreadLocalModuleData) == 0x30, "Dacp structs cannot be modified due to backwards compatibility.");
1034 static_assert(sizeof(DacpCOMInterfacePointerData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1035 static_assert(sizeof(DacpMethodDescTransparencyData) == 0xc, "Dacp structs cannot be modified due to backwards compatibility.");
1036 static_assert(sizeof(DacpHillClimbingLogEntry) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1037 static_assert(sizeof(DacpGenerationData) == 0x20, "Dacp structs cannot be modified due to backwards compatibility.");
1038 static_assert(sizeof(DacpGcHeapDetails) == 0x120, "Dacp structs cannot be modified due to backwards compatibility.");
1039 static_assert(sizeof(DacpOomData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
1040 static_assert(sizeof(DacpGcHeapAnalyzeData) == 0x20, "Dacp structs cannot be modified due to backwards compatibility.");
1041 static_assert(sizeof(DacpSyncBlockData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility.");
1042 static_assert(sizeof(DacpGetModuleAddress) == 0x8, "Dacp structs cannot be modified due to backwards compatibility.");
1043 static_assert(sizeof(DacpFrameData) == 0x8, "Dacp structs cannot be modified due to backwards compatibility.");
1044 static_assert(sizeof(DacpJitCodeHeapInfo) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
1045 static_assert(sizeof(DacpExceptionObjectData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
1046
1047 #endif  // _DACPRIVATE_H_