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 DacpMethodTableCollectibleData : ZeroInit<DacpMethodTableCollectibleData> |
181 | { |
182 | CLRDATA_ADDRESS LoaderAllocatorObjectHandle; |
183 | BOOL bCollectible; |
184 | |
185 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
186 | { |
187 | HRESULT hr; |
188 | ISOSDacInterface6 *pSOS6 = NULL; |
189 | if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface6), (void**)&pSOS6))) |
190 | { |
191 | hr = pSOS6->GetMethodTableCollectibleData(addr, this); |
192 | pSOS6->Release(); |
193 | } |
194 | |
195 | return hr; |
196 | } |
197 | }; |
198 | |
199 | struct MSLAYOUT DacpMethodTableTransparencyData : ZeroInit<DacpMethodTableTransparencyData> |
200 | { |
201 | BOOL bHasCriticalTransparentInfo; |
202 | BOOL bIsCritical; |
203 | BOOL bIsTreatAsSafe; |
204 | |
205 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
206 | { |
207 | return sos->GetMethodTableTransparencyData(addr, this); |
208 | } |
209 | }; |
210 | |
211 | struct MSLAYOUT DacpDomainLocalModuleData : ZeroInit<DacpDomainLocalModuleData> |
212 | { |
213 | // These two parameters are used as input params when calling the |
214 | // no-argument form of Request below. |
215 | CLRDATA_ADDRESS appDomainAddr; |
216 | ULONG64 ModuleID; |
217 | |
218 | CLRDATA_ADDRESS pClassData; |
219 | CLRDATA_ADDRESS pDynamicClassTable; |
220 | CLRDATA_ADDRESS pGCStaticDataStart; |
221 | CLRDATA_ADDRESS pNonGCStaticDataStart; |
222 | |
223 | // Called when you have a pointer to the DomainLocalModule |
224 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
225 | { |
226 | return sos->GetDomainLocalModuleData(addr, this); |
227 | } |
228 | }; |
229 | |
230 | |
231 | struct MSLAYOUT DacpThreadLocalModuleData : ZeroInit<DacpThreadLocalModuleData> |
232 | { |
233 | // These two parameters are used as input params when calling the |
234 | // no-argument form of Request below. |
235 | CLRDATA_ADDRESS threadAddr; |
236 | ULONG64 ModuleIndex; |
237 | |
238 | CLRDATA_ADDRESS pClassData; |
239 | CLRDATA_ADDRESS pDynamicClassTable; |
240 | CLRDATA_ADDRESS pGCStaticDataStart; |
241 | CLRDATA_ADDRESS pNonGCStaticDataStart; |
242 | }; |
243 | |
244 | |
245 | struct MSLAYOUT DacpModuleData : ZeroInit<DacpModuleData> |
246 | { |
247 | CLRDATA_ADDRESS Address; |
248 | CLRDATA_ADDRESS File; // A PEFile addr |
249 | CLRDATA_ADDRESS ilBase; |
250 | CLRDATA_ADDRESS metadataStart; |
251 | ULONG64 metadataSize; |
252 | CLRDATA_ADDRESS Assembly; // Assembly pointer |
253 | BOOL bIsReflection; |
254 | BOOL bIsPEFile; |
255 | ULONG64 dwBaseClassIndex; |
256 | ULONG64 dwModuleID; |
257 | |
258 | DWORD dwTransientFlags; |
259 | |
260 | CLRDATA_ADDRESS TypeDefToMethodTableMap; |
261 | CLRDATA_ADDRESS TypeRefToMethodTableMap; |
262 | CLRDATA_ADDRESS MethodDefToDescMap; |
263 | CLRDATA_ADDRESS FieldDefToDescMap; |
264 | CLRDATA_ADDRESS MemberRefToDescMap; |
265 | CLRDATA_ADDRESS FileReferencesMap; |
266 | CLRDATA_ADDRESS ManifestModuleReferencesMap; |
267 | |
268 | CLRDATA_ADDRESS pLookupTableHeap; |
269 | CLRDATA_ADDRESS pThunkHeap; |
270 | |
271 | ULONG64 dwModuleIndex; |
272 | |
273 | DacpModuleData() |
274 | { |
275 | } |
276 | |
277 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
278 | { |
279 | return sos->GetModuleData(addr, this); |
280 | } |
281 | |
282 | private: |
283 | // Ensure that this data structure is not copied. |
284 | DacpModuleData(const DacpModuleData&); |
285 | void operator=(const DacpModuleData&); |
286 | }; |
287 | |
288 | struct MSLAYOUT DacpMethodTableData : ZeroInit<DacpMethodTableData> |
289 | { |
290 | BOOL bIsFree; // everything else is NULL if this is true. |
291 | CLRDATA_ADDRESS Module; |
292 | CLRDATA_ADDRESS Class; |
293 | CLRDATA_ADDRESS ParentMethodTable; |
294 | WORD wNumInterfaces; |
295 | WORD wNumMethods; |
296 | WORD wNumVtableSlots; |
297 | WORD wNumVirtuals; |
298 | DWORD BaseSize; |
299 | DWORD ComponentSize; |
300 | mdTypeDef cl; // Metadata token |
301 | DWORD dwAttrClass; // cached metadata |
302 | BOOL bIsShared; // Always false, preserved for backward compatibility |
303 | BOOL bIsDynamic; |
304 | BOOL bContainsPointers; |
305 | |
306 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
307 | { |
308 | return sos->GetMethodTableData(addr, this); |
309 | } |
310 | }; |
311 | |
312 | |
313 | // Copied from util.hpp, for DacpThreadStoreData.fHostConfig below. |
314 | #define CLRMEMORYHOSTED 0x1 |
315 | #define CLRTASKHOSTED 0x2 |
316 | #define CLRSYNCHOSTED 0x4 |
317 | #define CLRTHREADPOOLHOSTED 0x8 |
318 | #define CLRIOCOMPLETIONHOSTED 0x10 |
319 | #define CLRASSEMBLYHOSTED 0x20 |
320 | #define CLRGCHOSTED 0x40 |
321 | #define CLRSECURITYHOSTED 0x80 |
322 | #define CLRHOSTED 0x80000000 |
323 | |
324 | struct MSLAYOUT DacpThreadStoreData : ZeroInit<DacpThreadStoreData> |
325 | { |
326 | LONG threadCount; |
327 | LONG unstartedThreadCount; |
328 | LONG backgroundThreadCount; |
329 | LONG pendingThreadCount; |
330 | LONG deadThreadCount; |
331 | CLRDATA_ADDRESS firstThread; |
332 | CLRDATA_ADDRESS finalizerThread; |
333 | CLRDATA_ADDRESS gcThread; |
334 | DWORD fHostConfig; // Uses hosting flags defined above |
335 | |
336 | HRESULT Request(ISOSDacInterface *sos) |
337 | { |
338 | return sos->GetThreadStoreData(this); |
339 | } |
340 | }; |
341 | |
342 | struct MSLAYOUT DacpAppDomainStoreData : ZeroInit<DacpAppDomainStoreData> |
343 | { |
344 | CLRDATA_ADDRESS sharedDomain; |
345 | CLRDATA_ADDRESS systemDomain; |
346 | LONG DomainCount; |
347 | |
348 | HRESULT Request(ISOSDacInterface *sos) |
349 | { |
350 | return sos->GetAppDomainStoreData(this); |
351 | } |
352 | }; |
353 | |
354 | struct MSLAYOUT DacpCOMInterfacePointerData : ZeroInit<DacpCOMInterfacePointerData> |
355 | { |
356 | CLRDATA_ADDRESS methodTable; |
357 | CLRDATA_ADDRESS interfacePtr; |
358 | CLRDATA_ADDRESS comContext; |
359 | }; |
360 | |
361 | struct MSLAYOUT DacpRCWData : ZeroInit<DacpRCWData> |
362 | { |
363 | CLRDATA_ADDRESS identityPointer; |
364 | CLRDATA_ADDRESS unknownPointer; |
365 | CLRDATA_ADDRESS managedObject; |
366 | CLRDATA_ADDRESS jupiterObject; |
367 | CLRDATA_ADDRESS vtablePtr; |
368 | CLRDATA_ADDRESS creatorThread; |
369 | CLRDATA_ADDRESS ctxCookie; |
370 | |
371 | LONG refCount; |
372 | LONG interfaceCount; |
373 | |
374 | BOOL isJupiterObject; |
375 | BOOL supportsIInspectable; |
376 | BOOL isAggregated; |
377 | BOOL isContained; |
378 | BOOL isFreeThreaded; |
379 | BOOL isDisconnected; |
380 | |
381 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS rcw) |
382 | { |
383 | return sos->GetRCWData(rcw, this); |
384 | } |
385 | |
386 | HRESULT IsDCOMProxy(ISOSDacInterface *sos, CLRDATA_ADDRESS rcw, BOOL* isDCOMProxy) |
387 | { |
388 | ISOSDacInterface2 *pSOS2 = nullptr; |
389 | HRESULT hr = sos->QueryInterface(__uuidof(ISOSDacInterface2), reinterpret_cast<LPVOID*>(&pSOS2)); |
390 | if (SUCCEEDED(hr)) |
391 | { |
392 | hr = pSOS2->IsRCWDCOMProxy(rcw, isDCOMProxy); |
393 | pSOS2->Release(); |
394 | } |
395 | |
396 | return hr; |
397 | } |
398 | }; |
399 | |
400 | struct MSLAYOUT DacpCCWData : ZeroInit<DacpCCWData> |
401 | { |
402 | CLRDATA_ADDRESS outerIUnknown; |
403 | CLRDATA_ADDRESS managedObject; |
404 | CLRDATA_ADDRESS handle; |
405 | CLRDATA_ADDRESS ccwAddress; |
406 | |
407 | LONG refCount; |
408 | LONG interfaceCount; |
409 | BOOL isNeutered; |
410 | |
411 | LONG jupiterRefCount; |
412 | BOOL isPegged; |
413 | BOOL isGlobalPegged; |
414 | BOOL hasStrongRef; |
415 | BOOL isExtendsCOMObject; |
416 | BOOL isAggregated; |
417 | |
418 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS ccw) |
419 | { |
420 | return sos->GetCCWData(ccw, this); |
421 | } |
422 | }; |
423 | |
424 | enum DacpAppDomainDataStage { |
425 | STAGE_CREATING, |
426 | STAGE_READYFORMANAGEDCODE, |
427 | STAGE_ACTIVE, |
428 | STAGE_OPEN, |
429 | STAGE_UNLOAD_REQUESTED, |
430 | STAGE_EXITING, |
431 | STAGE_EXITED, |
432 | STAGE_FINALIZING, |
433 | STAGE_FINALIZED, |
434 | STAGE_HANDLETABLE_NOACCESS, |
435 | STAGE_CLEARED, |
436 | STAGE_COLLECTED, |
437 | STAGE_CLOSED |
438 | }; |
439 | |
440 | // Information about a BaseDomain (AppDomain, SharedDomain or SystemDomain). |
441 | // For types other than AppDomain, some fields (like dwID, DomainLocalBlock, etc.) will be 0/null. |
442 | struct MSLAYOUT DacpAppDomainData : ZeroInit<DacpAppDomainData> |
443 | { |
444 | // The pointer to the BaseDomain (not necessarily an AppDomain). |
445 | // It's useful to keep this around in the structure |
446 | CLRDATA_ADDRESS AppDomainPtr; |
447 | CLRDATA_ADDRESS AppSecDesc; |
448 | CLRDATA_ADDRESS pLowFrequencyHeap; |
449 | CLRDATA_ADDRESS pHighFrequencyHeap; |
450 | CLRDATA_ADDRESS pStubHeap; |
451 | CLRDATA_ADDRESS DomainLocalBlock; |
452 | CLRDATA_ADDRESS pDomainLocalModules; |
453 | // The creation sequence number of this app domain (starting from 1) |
454 | DWORD dwId; |
455 | LONG AssemblyCount; |
456 | LONG FailedAssemblyCount; |
457 | DacpAppDomainDataStage appDomainStage; |
458 | |
459 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
460 | { |
461 | return sos->GetAppDomainData(addr, this); |
462 | } |
463 | }; |
464 | |
465 | struct MSLAYOUT DacpAssemblyData : ZeroInit<DacpAssemblyData> |
466 | { |
467 | CLRDATA_ADDRESS AssemblyPtr; //useful to have |
468 | CLRDATA_ADDRESS ClassLoader; |
469 | CLRDATA_ADDRESS ParentDomain; |
470 | CLRDATA_ADDRESS BaseDomainPtr; |
471 | CLRDATA_ADDRESS AssemblySecDesc; |
472 | BOOL isDynamic; |
473 | UINT ModuleCount; |
474 | UINT LoadContext; |
475 | BOOL isDomainNeutral; // Always false, preserved for backward compatibility |
476 | DWORD dwLocationFlags; |
477 | |
478 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr, CLRDATA_ADDRESS baseDomainPtr) |
479 | { |
480 | return sos->GetAssemblyData(baseDomainPtr, addr, this); |
481 | } |
482 | |
483 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
484 | { |
485 | return Request(sos, addr, NULL); |
486 | } |
487 | }; |
488 | |
489 | |
490 | struct MSLAYOUT DacpThreadData : ZeroInit<DacpThreadData> |
491 | { |
492 | DWORD corThreadId; |
493 | DWORD osThreadId; |
494 | int state; |
495 | ULONG preemptiveGCDisabled; |
496 | CLRDATA_ADDRESS allocContextPtr; |
497 | CLRDATA_ADDRESS allocContextLimit; |
498 | CLRDATA_ADDRESS context; |
499 | CLRDATA_ADDRESS domain; |
500 | CLRDATA_ADDRESS pFrame; |
501 | DWORD lockCount; |
502 | CLRDATA_ADDRESS firstNestedException; // Pass this pointer to DacpNestedExceptionInfo |
503 | CLRDATA_ADDRESS teb; |
504 | CLRDATA_ADDRESS fiberData; |
505 | CLRDATA_ADDRESS lastThrownObjectHandle; |
506 | CLRDATA_ADDRESS nextThread; |
507 | |
508 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
509 | { |
510 | return sos->GetThreadData(addr, this); |
511 | } |
512 | }; |
513 | |
514 | |
515 | struct MSLAYOUT DacpReJitData : ZeroInit<DacpReJitData> |
516 | { |
517 | enum Flags |
518 | { |
519 | kUnknown, |
520 | kRequested, |
521 | kActive, |
522 | kReverted, |
523 | }; |
524 | |
525 | CLRDATA_ADDRESS rejitID; |
526 | Flags flags; |
527 | CLRDATA_ADDRESS NativeCodeAddr; |
528 | }; |
529 | |
530 | |
531 | struct MSLAYOUT DacpMethodDescData : ZeroInit<DacpMethodDescData> |
532 | { |
533 | BOOL bHasNativeCode; |
534 | BOOL bIsDynamic; |
535 | WORD wSlotNumber; |
536 | CLRDATA_ADDRESS NativeCodeAddr; |
537 | // Useful for breaking when a method is jitted. |
538 | CLRDATA_ADDRESS AddressOfNativeCodeSlot; |
539 | |
540 | CLRDATA_ADDRESS MethodDescPtr; |
541 | CLRDATA_ADDRESS MethodTablePtr; |
542 | CLRDATA_ADDRESS ModulePtr; |
543 | |
544 | mdToken MDToken; |
545 | CLRDATA_ADDRESS GCInfo; |
546 | CLRDATA_ADDRESS GCStressCodeCopy; |
547 | |
548 | // This is only valid if bIsDynamic is true |
549 | CLRDATA_ADDRESS managedDynamicMethodObject; |
550 | |
551 | CLRDATA_ADDRESS requestedIP; |
552 | |
553 | // Gives info for the single currently active version of a method |
554 | DacpReJitData rejitDataCurrent; |
555 | |
556 | // Gives info corresponding to requestedIP (for !ip2md) |
557 | DacpReJitData rejitDataRequested; |
558 | |
559 | // Total number of rejit versions that have been jitted |
560 | ULONG cJittedRejitVersions; |
561 | |
562 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
563 | { |
564 | return sos->GetMethodDescData( |
565 | addr, |
566 | NULL, // IP address |
567 | this, |
568 | 0, // cRejitData |
569 | NULL, // rejitData[] |
570 | NULL // pcNeededRejitData |
571 | ); |
572 | } |
573 | }; |
574 | |
575 | |
576 | struct MSLAYOUT DacpMethodDescTransparencyData : ZeroInit<DacpMethodDescTransparencyData> |
577 | { |
578 | BOOL bHasCriticalTransparentInfo; |
579 | BOOL bIsCritical; |
580 | BOOL bIsTreatAsSafe; |
581 | |
582 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
583 | { |
584 | return sos->GetMethodDescTransparencyData(addr, this); |
585 | } |
586 | }; |
587 | |
588 | struct MSLAYOUT DacpTieredVersionData |
589 | { |
590 | enum TieredState |
591 | { |
592 | NON_TIERED, |
593 | TIERED_0, |
594 | TIERED_1, |
595 | TIERED_UNKNOWN |
596 | }; |
597 | |
598 | CLRDATA_ADDRESS NativeCodeAddr; |
599 | TieredState TieredInfo; |
600 | CLRDATA_ADDRESS NativeCodeVersionNodePtr; |
601 | }; |
602 | |
603 | // for JITType |
604 | enum JITTypes {TYPE_UNKNOWN=0,TYPE_JIT,TYPE_PJIT}; |
605 | |
606 | struct MSLAYOUT : ZeroInit<DacpCodeHeaderData> |
607 | { |
608 | CLRDATA_ADDRESS ; |
609 | JITTypes ; |
610 | CLRDATA_ADDRESS ; |
611 | CLRDATA_ADDRESS ; |
612 | DWORD ; |
613 | CLRDATA_ADDRESS ; |
614 | DWORD ; |
615 | DWORD ; |
616 | |
617 | HRESULT (ISOSDacInterface *sos, CLRDATA_ADDRESS IPAddr) |
618 | { |
619 | return sos->GetCodeHeaderData(IPAddr, this); |
620 | } |
621 | }; |
622 | |
623 | struct MSLAYOUT DacpWorkRequestData : ZeroInit<DacpWorkRequestData> |
624 | { |
625 | CLRDATA_ADDRESS Function; |
626 | CLRDATA_ADDRESS Context; |
627 | CLRDATA_ADDRESS NextWorkRequest; |
628 | |
629 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
630 | { |
631 | return sos->GetWorkRequestData(addr, this); |
632 | } |
633 | }; |
634 | |
635 | struct MSLAYOUT DacpHillClimbingLogEntry : ZeroInit<DacpHillClimbingLogEntry> |
636 | { |
637 | DWORD TickCount; |
638 | int Transition; |
639 | int NewControlSetting; |
640 | int LastHistoryCount; |
641 | double LastHistoryMean; |
642 | |
643 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS entry) |
644 | { |
645 | return sos->GetHillClimbingLogEntry(entry, this); |
646 | } |
647 | }; |
648 | |
649 | |
650 | // Used for CLR versions >= 4.0 |
651 | struct MSLAYOUT DacpThreadpoolData : ZeroInit<DacpThreadpoolData> |
652 | { |
653 | LONG cpuUtilization; |
654 | int NumIdleWorkerThreads; |
655 | int NumWorkingWorkerThreads; |
656 | int NumRetiredWorkerThreads; |
657 | LONG MinLimitTotalWorkerThreads; |
658 | LONG MaxLimitTotalWorkerThreads; |
659 | |
660 | CLRDATA_ADDRESS FirstUnmanagedWorkRequest; |
661 | |
662 | CLRDATA_ADDRESS HillClimbingLog; |
663 | int HillClimbingLogFirstIndex; |
664 | int HillClimbingLogSize; |
665 | |
666 | DWORD NumTimers; |
667 | // TODO: Add support to enumerate timers too. |
668 | |
669 | LONG NumCPThreads; |
670 | LONG NumFreeCPThreads; |
671 | LONG MaxFreeCPThreads; |
672 | LONG NumRetiredCPThreads; |
673 | LONG MaxLimitTotalCPThreads; |
674 | LONG CurrentLimitTotalCPThreads; |
675 | LONG MinLimitTotalCPThreads; |
676 | |
677 | CLRDATA_ADDRESS AsyncTimerCallbackCompletionFPtr; |
678 | |
679 | HRESULT Request(ISOSDacInterface *sos) |
680 | { |
681 | return sos->GetThreadpoolData(this); |
682 | } |
683 | }; |
684 | |
685 | struct MSLAYOUT DacpGenerationData : ZeroInit<DacpGenerationData> |
686 | { |
687 | CLRDATA_ADDRESS start_segment; |
688 | CLRDATA_ADDRESS allocation_start; |
689 | |
690 | // These are examined only for generation 0, otherwise NULL |
691 | CLRDATA_ADDRESS allocContextPtr; |
692 | CLRDATA_ADDRESS allocContextLimit; |
693 | }; |
694 | |
695 | #define DAC_NUMBERGENERATIONS 4 |
696 | |
697 | |
698 | struct MSLAYOUT DacpAllocData : ZeroInit<DacpAllocData> |
699 | { |
700 | CLRDATA_ADDRESS allocBytes; |
701 | CLRDATA_ADDRESS allocBytesLoh; |
702 | }; |
703 | |
704 | struct MSLAYOUT DacpGenerationAllocData : ZeroInit<DacpGenerationAllocData> |
705 | { |
706 | DacpAllocData allocData[DAC_NUMBERGENERATIONS]; |
707 | }; |
708 | |
709 | struct MSLAYOUT DacpGcHeapDetails : ZeroInit<DacpGcHeapDetails> |
710 | { |
711 | CLRDATA_ADDRESS heapAddr; // Only filled in in server mode, otherwise NULL |
712 | CLRDATA_ADDRESS alloc_allocated; |
713 | |
714 | CLRDATA_ADDRESS mark_array; |
715 | CLRDATA_ADDRESS current_c_gc_state; |
716 | CLRDATA_ADDRESS next_sweep_obj; |
717 | CLRDATA_ADDRESS saved_sweep_ephemeral_seg; |
718 | CLRDATA_ADDRESS saved_sweep_ephemeral_start; |
719 | CLRDATA_ADDRESS background_saved_lowest_address; |
720 | CLRDATA_ADDRESS background_saved_highest_address; |
721 | |
722 | DacpGenerationData generation_table [DAC_NUMBERGENERATIONS]; |
723 | CLRDATA_ADDRESS ephemeral_heap_segment; |
724 | CLRDATA_ADDRESS finalization_fill_pointers [DAC_NUMBERGENERATIONS + 3]; |
725 | CLRDATA_ADDRESS lowest_address; |
726 | CLRDATA_ADDRESS highest_address; |
727 | CLRDATA_ADDRESS card_table; |
728 | |
729 | // Use this for workstation mode (DacpGcHeapDat.bServerMode==FALSE). |
730 | HRESULT Request(ISOSDacInterface *sos) |
731 | { |
732 | return sos->GetGCHeapStaticData(this); |
733 | } |
734 | |
735 | // Use this for Server mode, as there are multiple heaps, |
736 | // and you need to pass a heap address in addr. |
737 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
738 | { |
739 | return sos->GetGCHeapDetails(addr, this); |
740 | } |
741 | }; |
742 | |
743 | struct MSLAYOUT DacpGcHeapData |
744 | : ZeroInit<DacpGcHeapData> |
745 | { |
746 | BOOL bServerMode; |
747 | BOOL bGcStructuresValid; |
748 | UINT HeapCount; |
749 | UINT g_max_generation; |
750 | |
751 | HRESULT Request(ISOSDacInterface *sos) |
752 | { |
753 | return sos->GetGCHeapData(this); |
754 | } |
755 | }; |
756 | |
757 | struct MSLAYOUT DacpHeapSegmentData |
758 | : ZeroInit<DacpHeapSegmentData> |
759 | { |
760 | CLRDATA_ADDRESS segmentAddr; |
761 | CLRDATA_ADDRESS allocated; |
762 | CLRDATA_ADDRESS committed; |
763 | CLRDATA_ADDRESS reserved; |
764 | CLRDATA_ADDRESS used; |
765 | CLRDATA_ADDRESS mem; |
766 | // pass this to request if non-null to get the next segments. |
767 | CLRDATA_ADDRESS next; |
768 | CLRDATA_ADDRESS gc_heap; // only filled in in server mode, otherwise NULL |
769 | // computed field: if this is the ephemeral segment highMark includes the ephemeral generation |
770 | CLRDATA_ADDRESS highAllocMark; |
771 | |
772 | size_t flags; |
773 | CLRDATA_ADDRESS background_allocated; |
774 | |
775 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr, const DacpGcHeapDetails& heap) |
776 | { |
777 | HRESULT hr = sos->GetHeapSegmentData(addr, this); |
778 | |
779 | // if this is the start segment, set highAllocMark too. |
780 | if (SUCCEEDED(hr)) |
781 | { |
782 | // TODO: This needs to be put on the Dac side. |
783 | if (this->segmentAddr == heap.generation_table[0].start_segment) |
784 | highAllocMark = heap.alloc_allocated; |
785 | else |
786 | highAllocMark = allocated; |
787 | } |
788 | return hr; |
789 | } |
790 | }; |
791 | |
792 | struct MSLAYOUT DacpOomData : ZeroInit<DacpOomData> |
793 | { |
794 | int reason; |
795 | ULONG64 alloc_size; |
796 | ULONG64 available_pagefile_mb; |
797 | ULONG64 gc_index; |
798 | int fgm; |
799 | ULONG64 size; |
800 | BOOL loh_p; |
801 | |
802 | HRESULT Request(ISOSDacInterface *sos) |
803 | { |
804 | return sos->GetOOMStaticData(this); |
805 | } |
806 | |
807 | // Use this for Server mode, as there are multiple heaps, |
808 | // and you need to pass a heap address in addr. |
809 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
810 | { |
811 | return sos->GetOOMData(addr, this); |
812 | } |
813 | }; |
814 | |
815 | #define DAC_NUM_GC_DATA_POINTS 9 |
816 | #define DAC_MAX_COMPACT_REASONS_COUNT 11 |
817 | #define DAC_MAX_EXPAND_MECHANISMS_COUNT 6 |
818 | #define DAC_MAX_GC_MECHANISM_BITS_COUNT 2 |
819 | #define DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT 6 |
820 | struct MSLAYOUT DacpGCInterestingInfoData : ZeroInit<DacpGCInterestingInfoData> |
821 | { |
822 | size_t interestingDataPoints[DAC_NUM_GC_DATA_POINTS]; |
823 | size_t compactReasons[DAC_MAX_COMPACT_REASONS_COUNT]; |
824 | size_t expandMechanisms[DAC_MAX_EXPAND_MECHANISMS_COUNT]; |
825 | size_t bitMechanisms[DAC_MAX_GC_MECHANISM_BITS_COUNT]; |
826 | size_t globalMechanisms[DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT]; |
827 | |
828 | HRESULT RequestGlobal(ISOSDacInterface *sos) |
829 | { |
830 | HRESULT hr; |
831 | ISOSDacInterface3 *psos3 = NULL; |
832 | if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3))) |
833 | { |
834 | hr = psos3->GetGCGlobalMechanisms(globalMechanisms); |
835 | psos3->Release(); |
836 | } |
837 | return hr; |
838 | } |
839 | |
840 | HRESULT Request(ISOSDacInterface *sos) |
841 | { |
842 | HRESULT hr; |
843 | ISOSDacInterface3 *psos3 = NULL; |
844 | if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3))) |
845 | { |
846 | hr = psos3->GetGCInterestingInfoStaticData(this); |
847 | psos3->Release(); |
848 | } |
849 | return hr; |
850 | } |
851 | |
852 | // Use this for Server mode, as there are multiple heaps, |
853 | // and you need to pass a heap address in addr. |
854 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
855 | { |
856 | HRESULT hr; |
857 | ISOSDacInterface3 *psos3 = NULL; |
858 | if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3))) |
859 | { |
860 | hr = psos3->GetGCInterestingInfoData(addr, this); |
861 | psos3->Release(); |
862 | } |
863 | return hr; |
864 | } |
865 | }; |
866 | |
867 | struct MSLAYOUT DacpGcHeapAnalyzeData |
868 | : ZeroInit<DacpGcHeapAnalyzeData> |
869 | { |
870 | CLRDATA_ADDRESS heapAddr; // Only filled in in server mode, otherwise NULL |
871 | |
872 | CLRDATA_ADDRESS internal_root_array; |
873 | ULONG64 internal_root_array_index; |
874 | BOOL heap_analyze_success; |
875 | |
876 | // Use this for workstation mode (DacpGcHeapDat.bServerMode==FALSE). |
877 | HRESULT Request(ISOSDacInterface *sos) |
878 | { |
879 | return sos->GetHeapAnalyzeStaticData(this); |
880 | } |
881 | |
882 | // Use this for Server mode, as there are multiple heaps, |
883 | // and you need to pass a heap address in addr. |
884 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) |
885 | { |
886 | return sos->GetHeapAnalyzeData(addr, this); |
887 | } |
888 | }; |
889 | |
890 | |
891 | #define SYNCBLOCKDATA_COMFLAGS_CCW 1 |
892 | #define SYNCBLOCKDATA_COMFLAGS_RCW 2 |
893 | #define SYNCBLOCKDATA_COMFLAGS_CF 4 |
894 | |
895 | struct MSLAYOUT DacpSyncBlockData : ZeroInit<DacpSyncBlockData> |
896 | { |
897 | CLRDATA_ADDRESS Object; |
898 | BOOL bFree; // if set, no other fields are useful |
899 | |
900 | // fields below provide data from this, so it's just for display |
901 | CLRDATA_ADDRESS SyncBlockPointer; |
902 | DWORD COMFlags; |
903 | UINT MonitorHeld; |
904 | UINT Recursion; |
905 | CLRDATA_ADDRESS HoldingThread; |
906 | UINT AdditionalThreadCount; |
907 | CLRDATA_ADDRESS appDomainPtr; |
908 | |
909 | // SyncBlockCount will always be filled in with the number of SyncBlocks. |
910 | // SyncBlocks may be requested from [1,SyncBlockCount] |
911 | UINT SyncBlockCount; |
912 | |
913 | // SyncBlockNumber must be from [1,SyncBlockCount] |
914 | // If there are no SyncBlocks, a call to Request with SyncBlockCount = 1 |
915 | // will return E_FAIL. |
916 | HRESULT Request(ISOSDacInterface *sos, UINT SyncBlockNumber) |
917 | { |
918 | return sos->GetSyncBlockData(SyncBlockNumber, this); |
919 | } |
920 | }; |
921 | |
922 | struct MSLAYOUT DacpSyncBlockCleanupData : ZeroInit<DacpSyncBlockCleanupData> |
923 | { |
924 | CLRDATA_ADDRESS SyncBlockPointer; |
925 | |
926 | CLRDATA_ADDRESS nextSyncBlock; |
927 | CLRDATA_ADDRESS blockRCW; |
928 | CLRDATA_ADDRESS blockClassFactory; |
929 | CLRDATA_ADDRESS blockCCW; |
930 | |
931 | // Pass NULL on the first request to start a traversal. |
932 | HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS psyncBlock) |
933 | { |
934 | return sos->GetSyncBlockCleanupData(psyncBlock, this); |
935 | } |
936 | }; |
937 | |
938 | /////////////////////////////////////////////////////////////////////////// |
939 | |
940 | enum EHClauseType {EHFault, EHFinally, EHFilter, EHTyped, EHUnknown}; |
941 | |
942 | struct MSLAYOUT DACEHInfo : ZeroInit<DACEHInfo> |
943 | { |
944 | EHClauseType clauseType; |
945 | CLRDATA_ADDRESS tryStartOffset; |
946 | CLRDATA_ADDRESS tryEndOffset; |
947 | CLRDATA_ADDRESS handlerStartOffset; |
948 | CLRDATA_ADDRESS handlerEndOffset; |
949 | BOOL isDuplicateClause; |
950 | CLRDATA_ADDRESS filterOffset; // valid when clauseType is EHFilter |
951 | BOOL isCatchAllHandler; // valid when clauseType is EHTyped |
952 | CLRDATA_ADDRESS moduleAddr; // when == 0 mtCatch contains a MethodTable, when != 0 tokCatch contains a type token |
953 | CLRDATA_ADDRESS mtCatch; // the method table of the TYPED clause type |
954 | mdToken tokCatch; // the type token of the TYPED clause type |
955 | }; |
956 | |
957 | struct MSLAYOUT DacpGetModuleAddress : ZeroInit<DacpGetModuleAddress> |
958 | { |
959 | CLRDATA_ADDRESS ModulePtr; |
960 | HRESULT Request(IXCLRDataModule* pDataModule) |
961 | { |
962 | return pDataModule->Request(DACDATAMODULEPRIV_REQUEST_GET_MODULEPTR, 0, NULL, sizeof(*this), (PBYTE) this); |
963 | } |
964 | }; |
965 | |
966 | struct MSLAYOUT DacpGetModuleData : ZeroInit<DacpGetModuleData> |
967 | { |
968 | BOOL IsDynamic; |
969 | BOOL IsInMemory; |
970 | BOOL IsFileLayout; |
971 | CLRDATA_ADDRESS PEFile; |
972 | CLRDATA_ADDRESS LoadedPEAddress; |
973 | ULONG64 LoadedPESize; |
974 | CLRDATA_ADDRESS InMemoryPdbAddress; |
975 | ULONG64 InMemoryPdbSize; |
976 | |
977 | HRESULT Request(IXCLRDataModule* pDataModule) |
978 | { |
979 | return pDataModule->Request(DACDATAMODULEPRIV_REQUEST_GET_MODULEDATA, 0, NULL, sizeof(*this), (PBYTE) this); |
980 | } |
981 | }; |
982 | |
983 | struct MSLAYOUT DacpFrameData : ZeroInit<DacpFrameData> |
984 | { |
985 | CLRDATA_ADDRESS frameAddr; |
986 | |
987 | // Could also be implemented for IXCLRDataFrame if desired. |
988 | HRESULT Request(IXCLRDataStackWalk* dac) |
989 | { |
990 | return dac->Request(DACSTACKPRIV_REQUEST_FRAME_DATA, |
991 | 0, NULL, |
992 | sizeof(*this), (PBYTE)this); |
993 | } |
994 | }; |
995 | |
996 | struct MSLAYOUT DacpJitManagerInfo : ZeroInit<DacpJitManagerInfo> |
997 | { |
998 | CLRDATA_ADDRESS managerAddr; |
999 | DWORD codeType; // for union below |
1000 | CLRDATA_ADDRESS ptrHeapList; // A HeapList * if IsMiIL(codeType) |
1001 | }; |
1002 | |
1003 | enum CodeHeapType {CODEHEAP_LOADER=0,CODEHEAP_HOST,CODEHEAP_UNKNOWN}; |
1004 | |
1005 | struct MSLAYOUT DacpJitCodeHeapInfo : ZeroInit<DacpJitCodeHeapInfo> |
1006 | { |
1007 | DWORD codeHeapType; // for union below |
1008 | |
1009 | union |
1010 | { |
1011 | CLRDATA_ADDRESS LoaderHeap; // if CODEHEAP_LOADER |
1012 | struct MSLAYOUT |
1013 | { |
1014 | CLRDATA_ADDRESS baseAddr; // if CODEHEAP_HOST |
1015 | CLRDATA_ADDRESS currentAddr; |
1016 | } HostData; |
1017 | }; |
1018 | }; |
1019 | |
1020 | #include "static_assert.h" |
1021 | |
1022 | /* DAC datastructures are frozen as of dev11 shipping. Do NOT add fields, remove fields, or change the fields of |
1023 | * these structs in any way. The correct way to get new data out of the runtime is to create a new struct and |
1024 | * add a new function to the latest Dac<-->SOS interface to produce this data. |
1025 | */ |
1026 | static_assert(sizeof(DacpAllocData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility." ); |
1027 | static_assert(sizeof(DacpGenerationAllocData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility." ); |
1028 | static_assert(sizeof(DacpSyncBlockCleanupData) == 0x28, "Dacp structs cannot be modified due to backwards compatibility." ); |
1029 | static_assert(sizeof(DacpThreadStoreData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility." ); |
1030 | static_assert(sizeof(DacpAppDomainStoreData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility." ); |
1031 | static_assert(sizeof(DacpAppDomainData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility." ); |
1032 | static_assert(sizeof(DacpAssemblyData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility." ); |
1033 | static_assert(sizeof(DacpThreadData) == 0x68, "Dacp structs cannot be modified due to backwards compatibility." ); |
1034 | static_assert(sizeof(DacpMethodDescData) == 0x98, "Dacp structs cannot be modified due to backwards compatibility." ); |
1035 | static_assert(sizeof(DacpCodeHeaderData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility." ); |
1036 | static_assert(sizeof(DacpThreadpoolData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility." ); |
1037 | static_assert(sizeof(DacpObjectData) == 0x60, "Dacp structs cannot be modified due to backwards compatibility." ); |
1038 | static_assert(sizeof(DacpMethodTableData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility." ); |
1039 | static_assert(sizeof(DacpWorkRequestData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility." ); |
1040 | static_assert(sizeof(DacpFieldDescData) == 0x40, "Dacp structs cannot be modified due to backwards compatibility." ); |
1041 | static_assert(sizeof(DacpModuleData) == 0xa0, "Dacp structs cannot be modified due to backwards compatibility." ); |
1042 | static_assert(sizeof(DacpGcHeapData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility." ); |
1043 | static_assert(sizeof(DacpJitManagerInfo) == 0x18, "Dacp structs cannot be modified due to backwards compatibility." ); |
1044 | static_assert(sizeof(DacpHeapSegmentData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility." ); |
1045 | static_assert(sizeof(DacpDomainLocalModuleData) == 0x30, "Dacp structs cannot be modified due to backwards compatibility." ); |
1046 | static_assert(sizeof(DacpUsefulGlobalsData) == 0x28, "Dacp structs cannot be modified due to backwards compatibility." ); |
1047 | static_assert(sizeof(DACEHInfo) == 0x58, "Dacp structs cannot be modified due to backwards compatibility." ); |
1048 | static_assert(sizeof(DacpRCWData) == 0x58, "Dacp structs cannot be modified due to backwards compatibility." ); |
1049 | static_assert(sizeof(DacpCCWData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility." ); |
1050 | static_assert(sizeof(DacpMethodTableFieldData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility." ); |
1051 | static_assert(sizeof(DacpMethodTableTransparencyData) == 0xc, "Dacp structs cannot be modified due to backwards compatibility." ); |
1052 | static_assert(sizeof(DacpThreadLocalModuleData) == 0x30, "Dacp structs cannot be modified due to backwards compatibility." ); |
1053 | static_assert(sizeof(DacpCOMInterfacePointerData) == 0x18, "Dacp structs cannot be modified due to backwards compatibility." ); |
1054 | static_assert(sizeof(DacpMethodDescTransparencyData) == 0xc, "Dacp structs cannot be modified due to backwards compatibility." ); |
1055 | static_assert(sizeof(DacpHillClimbingLogEntry) == 0x18, "Dacp structs cannot be modified due to backwards compatibility." ); |
1056 | static_assert(sizeof(DacpGenerationData) == 0x20, "Dacp structs cannot be modified due to backwards compatibility." ); |
1057 | static_assert(sizeof(DacpGcHeapDetails) == 0x120, "Dacp structs cannot be modified due to backwards compatibility." ); |
1058 | static_assert(sizeof(DacpOomData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility." ); |
1059 | static_assert(sizeof(DacpGcHeapAnalyzeData) == 0x20, "Dacp structs cannot be modified due to backwards compatibility." ); |
1060 | static_assert(sizeof(DacpSyncBlockData) == 0x48, "Dacp structs cannot be modified due to backwards compatibility." ); |
1061 | static_assert(sizeof(DacpGetModuleAddress) == 0x8, "Dacp structs cannot be modified due to backwards compatibility." ); |
1062 | static_assert(sizeof(DacpFrameData) == 0x8, "Dacp structs cannot be modified due to backwards compatibility." ); |
1063 | static_assert(sizeof(DacpJitCodeHeapInfo) == 0x18, "Dacp structs cannot be modified due to backwards compatibility." ); |
1064 | static_assert(sizeof(DacpExceptionObjectData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility." ); |
1065 | static_assert(sizeof(DacpMethodTableCollectibleData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility." ); |
1066 | |
1067 | #endif // _DACPRIVATE_H_ |
1068 | |