Add a fourth parameter to the DEFINE_DACVAR macro that is the actual fully qualified...
[platform/upstream/coreclr.git] / src / inc / daccess.h
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 //
5 //*****************************************************************************
6 // File: daccess.h
7 // 
8
9 //
10 // Support for external access of runtime data structures.  These
11 // macros and templates hide the details of pointer and data handling
12 // so that data structures and code can be compiled to work both
13 // in-process and through a special memory access layer.
14 //
15 // This code assumes the existence of two different pieces of code,
16 // the target, the runtime code that is going to be examined, and
17 // the host, the code that's doing the examining.  Access to the
18 // target is abstracted so the target may be a live process on the
19 // same machine, a live process on a different machine, a dump file
20 // or whatever.  No assumptions should be made about accessibility
21 // of the target.
22 //
23 // This code assumes that the data in the target is static.  Any
24 // time the target's data changes the interfaces must be reset so
25 // that potentially stale data is discarded.
26 //
27 // This code is intended for read access and there is no
28 // way to write data back currently.
29 //
30 // DAC-ized code:
31 // - is read-only (non-invasive). So DACized codepaths can not trigger a GC. 
32 // - has no Thread* object.  In reality, DAC-ized codepaths are
33 //   ReadProcessMemory calls from out-of-process. Conceptually, they 
34 //   are like a pure-native (preemptive) thread. 
35 ////
36 // This means that in particular, you cannot DACize a GCTRIGGERS function. 
37 // Neither can you DACize a function that throws if this will involve
38 // allocating a new exception object. There may be 
39 // exceptions to these rules if you can guarantee that the DACized 
40 // part of the code path cannot cause a garbage collection (see 
41 // EditAndContinueModule::ResolveField for an example). 
42 // If you need to DACize a function that may trigger 
43 // a GC, it is probably best to refactor the function so that the DACized
44 // part of the code path is in a separate function. For instance,
45 // functions with GetOrCreate() semantics are hard to DAC-ize because 
46 // they the Create portion is inherently invasive. Instead, consider refactoring
47 // into a GetOrFail() function that DAC can call; and then make GetOrCreate() 
48 // a wrapper around that. 
49
50 //
51 // This code works by hiding the details of access to target memory.
52 // Access is divided into two types:
53 // 1. DPTR - access to a piece of data.
54 // 2. VPTR - access to a class with a vtable.  The class can only have
55 //           a single vtable pointer at the beginning of the class instance.
56 // Things only need to be declared as VPTRs when it is necessary to
57 // call virtual functions in the host.  In that case the access layer
58 // must do extra work to provide a host vtable for the object when
59 // it is retrieved so that virtual functions can be called.
60 //
61 // When compiling with DACCESS_COMPILE the macros turn into templates
62 // which replace pointers with smart pointers that know how to fetch
63 // data from the target process and provide a host process version of it.
64 // Normal data structure access will transparently receive a host copy
65 // of the data and proceed, so code such as
66 //     typedef DPTR(Class) PTR_Class;
67 //     PTR_Class cls;
68 //     int val = cls->m_Int;
69 // will work without modification.  The appropriate operators are overloaded
70 // to provide transparent access, such as the -> operator in this case.
71 // Note that the convention is to create an appropriate typedef for
72 // each type that will be accessed.  This hides the particular details
73 // of the type declaration and makes the usage look more like regular code.
74 //
75 // The ?PTR classes also have an implicit base type cast operator to
76 // produce a host-pointer instance of the given type.  For example
77 //     Class* cls = PTR_Class(addr);
78 // works by implicit conversion from the PTR_Class created by wrapping
79 // to a host-side Class instance.  Again, this means that existing code
80 // can work without modification.
81 //
82 // Code Example:
83 //
84 // typedef struct _rangesection
85 // {
86 //     PTR_IJitManager pjit;
87 //     PTR_RangeSection pright;
88 //     PTR_RangeSection pleft;
89 //     ... Other fields omitted ...
90 // } RangeSection;
91 // 
92 //     RangeSection* pRS = m_RangeTree;
93 //
94 //     while (pRS != NULL)
95 //     {
96 //         if (currentPC < pRS->LowAddress)
97 //             pRS=pRS->pleft;
98 //         else if (currentPC > pRS->HighAddress)
99 //             pRS=pRS->pright;
100 //         else
101 //         {
102 //             return pRS->pjit;
103 //         }
104 //     }
105 //
106 // This code does not require any modifications.  The global reference
107 // provided by m_RangeTree will be a host version of the RangeSection
108 // instantiated by conversion.  The references to pRS->pleft and
109 // pRS->pright will refer to DPTRs due to the modified declaration.
110 // In the assignment statement the compiler will automatically use
111 // the implicit conversion from PTR_RangeSection to RangeSection*,
112 // causing a host instance to be created.  Finally, if an appropriate
113 // section is found the use of pRS->pjit will cause an implicit
114 // conversion from PTR_IJitManager to IJitManager.  The VPTR code
115 // will look at target memory to determine the actual derived class
116 // for the JitManager and instantiate the right class in the host so
117 // that host virtual functions can be used just as they would in
118 // the target.
119 //
120 // There are situations where code modifications are required, though.
121 //
122 // 1.  Any time the actual value of an address matters, such as using
123 //     it as a search key in a tree, the target address must be used.
124 //
125 // An example of this is the RangeSection tree used to locate JIT
126 // managers.  A portion of this code is shown above.  Each
127 // RangeSection node in the tree describes a range of addresses
128 // managed by the JitMan.  These addresses are just being used as
129 // values, not to dereference through, so there are not DPTRs.  When
130 // searching the range tree for an address the address used in the
131 // search must be a target address as that's what values are kept in
132 // the RangeSections.  In the code shown above, currentPC must be a
133 // target address as the RangeSections in the tree are all target
134 // addresses.  Use dac_cast<TADDR> to retrieve the target address
135 // of a ?PTR, as well as to convert a host address to the
136 // target address used to retrieve that particular instance. Do not
137 // use dac_cast with any raw target pointer types (such as BYTE*).
138 //
139 // 2.  Any time an address is modified, such as by address arithmetic,
140 //     the arithmetic must be performed on the target address.
141 //
142 // When a host instance is created it is created for the type in use.
143 // There is no particular relation to any other instance, so address
144 // arithmetic cannot be used to get from one instance to any other
145 // part of memory.  For example
146 //     char* Func(Class* cls)
147 //     {
148 //         // String follows the basic Class data.
149 //         return (char*)(cls + 1);
150 //     }
151 // does not work with external access because the Class* used would
152 // have retrieved only a Class worth of data.  There is no string
153 // following the host instance.  Instead, this code should use
154 // dac_cast<TADDR> to get the target address of the Class
155 // instance, add sizeof(*cls) and then create a new ?PTR to access
156 // the desired data.  Note that the newly retrieved data will not
157 // be contiguous with the Class instance, so address arithmetic
158 // will still not work.
159 //
160 // Previous Code:
161 //
162 //     BOOL IsTarget(LPVOID ip)
163 //     {
164 //         StubCallInstrs* pStubCallInstrs = GetStubCallInstrs();
165 //
166 //         if (ip == (LPVOID) &(pStubCallInstrs->m_op))
167 //         {
168 //             return TRUE;
169 //         }
170 //
171 // Modified Code:
172 //
173 //     BOOL IsTarget(LPVOID ip)
174 //     {
175 //         StubCallInstrs* pStubCallInstrs = GetStubCallInstrs();
176 //
177 //         if ((TADDR)ip == dac_cast<TADDR>(pStubCallInstrs) +
178 //             (TADDR)offsetof(StubCallInstrs, m_op))
179 //         {
180 //             return TRUE;
181 //         }
182 //
183 // The parameter ip is a target address, so the host pStubCallInstrs
184 // cannot be used to derive an address from.  The member & reference
185 // has to be replaced with a conversion from host to target address
186 // followed by explicit offsetting for the field.
187 //
188 // PTR_HOST_MEMBER_TADDR is a convenience macro that encapsulates
189 // these two operations, so the above code could also be:
190 //
191 //     if ((TADDR)ip ==
192 //         PTR_HOST_MEMBER_TADDR(StubCallInstrs, pStubCallInstrs, m_op))
193 //
194 // 3.  Any time the amount of memory referenced through an address
195 //     changes, such as by casting to a different type, a new ?PTR
196 //     must be created.
197 //
198 // Host instances are created and stored based on both the target
199 // address and size of access.  The access code has no way of knowing
200 // all possible ways that data will be retrieved for a given address
201 // so if code changes the way it accesses through an address a new
202 // ?PTR must be used, which may lead to a difference instance and
203 // different host address.  This means that pointer identity does not hold
204 // across casts, so code like
205 //     Class* cls = PTR_Class(addr);
206 //     Class2* cls2 = PTR_Class2(addr);
207 //     return cls == cls2;
208 // will fail because the host-side instances have no relation to each
209 // other.  That isn't a problem, since by rule #1 you shouldn't be
210 // relying on specific host address values.
211 //
212 // Previous Code:
213 //
214 //     return (ArrayClass *) m_pMethTab->GetClass();
215 //
216 // Modified Code:
217 //
218 //     return PTR_ArrayClass(m_pMethTab->GetClass());
219 //
220 // The ?PTR templates have an implicit conversion from a host pointer
221 // to a target address, so the cast above constructs a new
222 // PTR_ArrayClass by implicitly converting the host pointer result
223 // from GetClass() to its target address and using that as the address
224 // of the new PTR_ArrayClass.  As mentioned, the actual host-side
225 // pointer values may not be the same.
226 //
227 // Host pointer identity can be assumed as long as the type of access
228 // is the same.  In the example above, if both accesses were of type
229 // Class then the host pointer will be the same, so it is safe to
230 // retrieve the target address of an instance and then later get
231 // a new host pointer for the target address using the same type as
232 // the host pointer in that case will be the same.  This is enabled
233 // by caching all of the retrieved host instances.  This cache is searched
234 // by the addr:size pair and when there's a match the existing instance
235 // is reused.  This increases performance and also allows simple
236 // pointer identity to hold.  It does mean that host memory grows
237 // in proportion to the amount of target memory being referenced,
238 // so retrieving extraneous data should be avoided.
239 // The host-side data cache grows until the Flush() method is called,
240 // at which point all host-side data is discarded.  No host
241 // instance pointers should be held across a Flush().
242 //
243 // Accessing into an object can lead to some unusual behavior.  For
244 // example, the SList class relies on objects to contain an SLink
245 // instance that it uses for list maintenance.  This SLink can be
246 // embedded anywhere in the larger object.  The SList access is always
247 // purely to an SLink, so when using the access layer it will only
248 // retrieve an SLink's worth of data.  The SList template will then
249 // do some address arithmetic to determine the start of the real
250 // object and cast the resulting pointer to the final object type.
251 // When using the access layer this results in a new ?PTR being
252 // created and used, so a new instance will result.  The internal
253 // SLink instance will have no relation to the new object instance
254 // even though in target address terms one is embedded in the other.
255 // The assumption of data stability means that this won't cause
256 // a problem, but care must be taken with the address arithmetic,
257 // as layed out in rules #2 and #3.
258 //
259 // 4.  Global address references cannot be used.  Any reference to a
260 //     global piece of code or data, such as a function address, global
261 //     variable or class static variable, must be changed.
262 //
263 // The external access code may load at a different base address than
264 // the target process code.  Global addresses are therefore not
265 // meaningful and must be replaced with something else.  There isn't
266 // a single solution, so replacements must be done on a case-by-case
267 // basis.
268 //
269 // The simplest case is a global or class static variable.  All
270 // declarations must be replaced with a special declaration that
271 // compiles into a modified accessor template value when compiled for
272 // external data access.  Uses of the variable automatically are fixed
273 // up by the template instance.  Note that assignment to the global
274 // must be independently ifdef'ed as the external access layer should
275 // not make any modifications.
276 //
277 // Macros allow for simple declaration of a class static and global
278 // values that compile into an appropriate templated value.
279 //
280 // Previous Code:
281 //
282 //     static RangeSection* m_RangeTree;
283 //     RangeSection* ExecutionManager::m_RangeTree;
284 //
285 //     extern ThreadStore* g_pThreadStore;
286 //     ThreadStore* g_pThreadStore = &StaticStore;
287 //     class SystemDomain : public BaseDomain {
288 //         ...
289 //         ArrayListStatic m_appDomainIndexList;
290 //         ...
291 //     }
292 //
293 //     SystemDomain::m_appDomainIndexList; 
294 //
295 //     extern DWORD gThreadTLSIndex;
296 //
297 //     DWORD gThreadTLSIndex = TLS_OUT_OF_INDEXES;
298 //
299 // Modified Code:
300 //
301 //     typedef DPTR(RangeSection) PTR_RangeSection;
302 //     SPTR_DECL(RangeSection, m_RangeTree);
303 //     SPTR_IMPL(RangeSection, ExecutionManager, m_RangeTree);
304 //
305 //     typedef DPTR(ThreadStore) PTR_ThreadStore
306 //     GPTR_DECL(ThreadStore, g_pThreadStore);
307 //     GPTR_IMPL_INIT(ThreadStore, g_pThreadStore, &StaticStore);
308 //
309 //     class SystemDomain : public BaseDomain {
310 //         ...
311 //         SVAL_DECL(ArrayListStatic; m_appDomainIndexList);
312 //         ...
313 //     }
314 //
315 //     SVAL_IMPL(ArrayListStatic, SystemDomain, m_appDomainIndexList);
316 //
317 //     GVAL_DECL(DWORD, gThreadTLSIndex);
318 // 
319 //     GVAL_IMPL_INIT(DWORD, gThreadTLSIndex, TLS_OUT_OF_INDEXES);
320 //
321 // When declaring the variable, the first argument declares the
322 // variable's type and the second argument declares the variable's
323 // name.  When defining the variable the arguments are similar, with
324 // an extra class name parameter for the static class variable case.
325 // If an initializer is needed the IMPL_INIT macro should be used.
326 //
327 // Things get slightly more complicated when declaring an embedded
328 // array.  In this case the data element is not a single element and
329 // therefore cannot be represented by a ?PTR. In the case of a global 
330 // array, you should use the GARY_DECL and GARY_IMPL macros.
331 // We durrently have no support for declaring static array data members
332 // or initialized arrays. Array data members that are dynamically allocated
333 // need to be treated as pointer members. To reference individual elements
334 // you must use pointer arithmetic (see rule 2 above). An array declared
335 // as a local variable within a function does not need to be DACized. 
336 //
337 //
338 // All uses of ?VAL_DECL must have a corresponding entry given in the
339 // DacGlobals structure in src\inc\dacvars.h.  For SVAL_DECL the entry
340 // is class__name.  For GVAL_DECL the entry is dac__name. You must add 
341 // these entries in dacvars.h using the DEFINE_DACVAR macro. Note that
342 // these entries also are used for dumping memory in mini dumps and 
343 // heap dumps. If it's not appropriate to dump a variable, (e.g., 
344 // it's an array or some other value that is not important to have 
345 // in a minidump) a second macro, DEFINE_DACVAR_NO_DUMP, will allow 
346 // you to make the required entry in the DacGlobals structure without
347 // dumping its value. 
348 //
349 // For convenience, here is a list of the various variable declaration and 
350 // initialization macros:
351 // SVAL_DECL(type, name)      static non-pointer data   class MyClass
352 //                            member declared within    {
353 //                            the class declaration        // static int i;
354 //                                                         SVAL_DECL(int, i);
355 //                                                      }
356 //
357 // SVAL_IMPL(type, cls, name) static non-pointer data   // int MyClass::i;
358 //                            member defined outside    SVAL_IMPL(int, MyClass, i);
359 //                            the class declaration    
360 //
361 // SVAL_IMPL_INIT(type, cls,  static non-pointer data   // int MyClass::i = 0;
362 //                name, val)  member defined and        SVAL_IMPL_INIT(int, MyClass, i, 0);
363 //                            initialized outside the 
364 //                            class declaration
365 // ------------------------------------------------------------------------------------------------
366 // SPTR_DECL(type, name)      static pointer data       class MyClass
367 //                            member declared within    {
368 //                            the class declaration        // static int * pInt;
369 //                                                         SPTR_DECL(int, pInt);
370 //                                                      }
371 //
372 // SPTR_IMPL(type, cls, name) static pointer data       // int * MyClass::pInt;
373 //                            member defined outside    SPTR_IMPL(int, MyClass, pInt);
374 //                            the class declaration    
375 //
376 // SPTR_IMPL_INIT(type, cls,  static pointer data       // int * MyClass::pInt = NULL;
377 //                name, val)  member defined and        SPTR_IMPL_INIT(int, MyClass, pInt, NULL);
378 //                            initialized outside the 
379 //                            class declaration
380 // ------------------------------------------------------------------------------------------------
381 // GVAL_DECL(type, name)      extern declaration of     // extern int g_i
382 //                            global non-pointer        GVAL_DECL(int, g_i);
383 //                            variable 
384 //
385 // GVAL_IMPL(type, name)      declaration of a          // int g_i
386 //                            global non-pointer        GVAL_IMPL(int, g_i);
387 //                            variable 
388 //
389 // GVAL_IMPL_INIT (type,      declaration and           // int g_i = 0;
390 //                 name,      initialization of a       GVAL_IMPL_INIT(int, g_i, 0);
391 //                 val)       global non-pointer
392 //                            variable
393 // ****Note****
394 // If you use GVAL_? to declare a global variable of a structured type and you need to 
395 // access a member of the type, you cannot use the dot operator. Instead, you must take the
396 // address of the variable and use the arrow operator. For example:
397 // struct
398 // {
399 //    int x;
400 //    char ch;
401 // } MyStruct;
402 // GVAL_IMPL(MyStruct, g_myStruct);
403 // int i = (&g_myStruct)->x;
404 // ------------------------------------------------------------------------------------------------ 
405 // GPTR_DECL(type, name)      extern declaration of     // extern int * g_pInt
406 //                            global pointer            GPTR_DECL(int, g_pInt);
407 //                            variable 
408 //
409 // GPTR_IMPL(type, name)      declaration of a          // int * g_pInt
410 //                            global pointer            GPTR_IMPL(int, g_pInt);
411 //                            variable 
412 //
413 // GPTR_IMPL_INIT (type,      declaration and           // int * g_pInt = 0;
414 //                 name,      initialization of a       GPTR_IMPL_INIT(int, g_pInt, NULL);
415 //                 val)       global pointer
416 //                            variable
417 // ------------------------------------------------------------------------------------------------
418 // GARY_DECL(type, name)      extern declaration of     // extern int g_rgIntList[MAX_ELEMENTS];
419 //                            a global array            GPTR_DECL(int, g_rgIntList, MAX_ELEMENTS);
420 //                            variable 
421 //
422 // GARY_IMPL(type, name)      declaration of a          // int g_rgIntList[MAX_ELEMENTS];
423 //                            global pointer            GPTR_IMPL(int, g_rgIntList, MAX_ELEMENTS);
424 //                            variable 
425 //
426 //
427 // Certain pieces of code, such as the stack walker, rely on identifying
428 // an object from its vtable address.  As the target vtable addresses
429 // do not necessarily correspond to the vtables used in the host, these
430 // references must be translated.  The access layer maintains translation
431 // tables for all classes used with VPTR and can return the target
432 // vtable pointer for any host vtable in the known list of VPTR classes.
433 //
434 // ----- Errors:
435 //
436 // All errors in the access layer are reported via exceptions.  The
437 // formal access layer methods catch all such exceptions and turn
438 // them into the appropriate error, so this generally isn't visible
439 // to users of the access layer.
440 //
441 // ----- DPTR Declaration:
442 //
443 // Create a typedef for the type with typedef DPTR(type) PTR_type;
444 // Replace type* with PTR_type.
445 //
446 // ----- VPTR Declaration:
447 //
448 // VPTR can only be used on classes that have a single vtable
449 // pointer at the beginning of the object.  This should be true
450 // for a normal single-inheritance object.
451 //
452 // All of the classes that may be instantiated need to be identified
453 // and marked.  In the base class declaration add either
454 // VPTR_BASE_VTABLE_CLASS if the class is abstract or
455 // VPTR_BASE_CONCRETE_VTABLE_CLASS if the class is concrete.  In each
456 // derived class add VPTR_VTABLE_CLASS.  If you end up with compile or
457 // link errors for an unresolved method called VPtrSize you missed a
458 // derived class declaration.
459 //
460 // As described above, dac can only handle classes with a single
461 // vtable.  However, there's a special case for multiple inheritance
462 // situations when only one of the classes is needed for dac.  If
463 // the base class needed is the first class in the derived class's
464 // layout then it can be used with dac via using the VPTR_MULTI_CLASS
465 // macros.  Use with extreme care.
466 //
467 // All classes to be instantiated must be listed in src\inc\vptr_list.h.
468 //
469 // Create a typedef for the type with typedef VPTR(type) PTR_type;
470 // When using a VPTR, replace Class* with PTR_Class.
471 //
472 // ----- Specific Macros:
473 //
474 // PTR_TO_TADDR(ptr)
475 // Retrieves the raw target address for a ?PTR.
476 // See code:dac_cast for the preferred alternative
477 //
478 // PTR_HOST_TO_TADDR(host)
479 // Given a host address of an instance produced by a ?PTR reference,
480 // return the original target address.  The host address must
481 // be an exact match for an instance.
482 // See code:dac_cast for the preferred alternative
483 //
484 // PTR_HOST_INT_TO_TADDR(host)
485 // Given a host address which resides somewhere within an instance
486 // produced by a ?PTR reference (a host interior pointer) return the
487 // corresponding target address. This is useful for evaluating
488 // relative pointers (e.g. RelativePointer<T>) where calculating the
489 // target address requires knowledge of the target address of the
490 // relative pointer field itself. This lookup is slower than that for
491 // a non-interior host pointer so use it sparingly.
492 //
493 // VPTR_HOST_VTABLE_TO_TADDR(host)
494 // Given the host vtable pointer for a known VPTR class, return
495 // the target vtable pointer.
496 //
497 // PTR_HOST_MEMBER_TADDR(type, host, memb)
498 // Retrieves the target address of a host instance pointer and
499 // offsets it by the given member's offset within the type.
500 //
501 // PTR_HOST_INT_MEMBER_TADDR(type, host, memb)
502 // As above but will work for interior host pointers (see the
503 // description of PTR_HOST_INT_TO_TADDR for an explanation of host
504 // interior pointers).
505 //
506 // PTR_READ(addr, size)
507 // Reads a block of memory from the target and returns a host
508 // pointer for it.  Useful for reading blocks of data from the target
509 // whose size is only known at runtime, such as raw code for a jitted
510 // method.  If the data being read is actually an object, use SPTR
511 // instead to get better type semantics.
512 //
513 // DAC_EMPTY()
514 // DAC_EMPTY_ERR()
515 // DAC_EMPTY_RET(retVal)
516 // DAC_UNEXPECTED()
517 // Provides an empty method implementation when compiled
518 // for DACCESS_COMPILE.  For example, use to stub out methods needed
519 // for vtable entries but otherwise unused.
520 //
521 // These macros are designed to turn into normal code when compiled
522 // without DACCESS_COMPILE.
523 //
524 //*****************************************************************************
525
526
527 #ifndef __daccess_h__
528 #define __daccess_h__
529
530 #include "switches.h"
531 #include "safemath.h"
532 #include "corerror.h"
533
534 #ifndef __in
535 #include <specstrings.h>
536 #endif
537
538 #define DACCESS_TABLE_RESOURCE "COREXTERNALDATAACCESSRESOURCE"
539
540 #include "clr_std/type_traits"
541 #include "crosscomp.h"
542
543 // Information stored in the DAC table of interest to the DAC implementation
544 // Note that this information is shared between all instantiations of ClrDataAccess, so initialize
545 // it just once in code:ClrDataAccess.GetDacGlobals (rather than use fields in ClrDataAccess);
546 struct DacTableInfo
547 {
548     // On Windows, the first DWORD is the 32-bit timestamp read out of the runtime dll's debug directory.
549     // The remaining 3 DWORDS must all be 0.
550     // On Mac, this is the 16-byte UUID of the runtime dll.
551     // It is used to validate that mscorwks is the same version as mscordacwks
552     DWORD dwID0;
553     DWORD dwID1;
554     DWORD dwID2;
555     DWORD dwID3;
556 };
557
558 // The header of the DAC table.  This includes the number of globals, the number of vptrs, and
559 // the DacTableInfo structure.  We need the DacTableInfo and DacTableHeader structs outside
560 // of a DACCESS_COMPILE since soshost walks the Dac table headers to find the UUID of CoreCLR
561 // in the target process.
562 struct DacTableHeader
563 {
564     ULONG numGlobals;
565     ULONG numVptrs;
566     DacTableInfo info;
567 };
568
569 //
570 // This version of things wraps pointer access in
571 // templates which understand how to retrieve data
572 // through an access layer.  In this case no assumptions
573 // can be made that the current compilation processor or
574 // pointer types match the target's processor or pointer types.
575 //
576
577 // Define TADDR as a non-pointer value so use of it as a pointer
578 // will not work properly.  Define it as unsigned so
579 // pointer comparisons aren't affected by sign.
580 // This requires special casting to ULONG64 to sign-extend if necessary.
581 typedef ULONG_PTR TADDR;
582
583 // TSIZE_T used for counts or ranges that need to span the size of a 
584 // target pointer.  For cross-plat, this may be different than SIZE_T
585 // which reflects the host pointer size.
586 typedef SIZE_T TSIZE_T;
587
588
589 //
590 // The following table contains all the global information that data access needs to begin 
591 // operation.  All of the values stored here are RVAs.  DacGlobalBase() returns the current 
592 // base address to combine with to get a full target address.
593 //
594
595 typedef struct _DacGlobals
596 {
597 #ifdef FEATURE_PAL
598     static void Initialize();
599     void InitializeEntries(TADDR baseAddress);
600 #ifdef FEATURE_SVR_GC
601     void InitializeSVREntries(TADDR baseAddress);
602 #endif // FEATURE_SVR_GC
603 #endif // FEATURE_PAL
604
605 // These will define all of the dac related mscorwks static and global variables    
606 #define DEFINE_DACVAR(id_type, size, id, var)                 id_type id;
607 #define DEFINE_DACVAR_SVR(id_type, size, id, var)             id_type id;
608 #define DEFINE_DACVAR_NO_DUMP(id_type, size, id, var)         id_type id;
609 #include "dacvars.h"
610
611     // Global functions.
612     ULONG fn__ThreadpoolMgr__AsyncTimerCallbackCompletion;
613     ULONG fn__DACNotifyCompilationFinished;
614     ULONG fn__ThePreStub;
615     ULONG fn__ThePreStubPatchLabel;
616     ULONG fn__PrecodeFixupThunk;
617     ULONG fn__StubDispatchFixupStub;
618     ULONG fn__StubDispatchFixupPatchLabel;;
619 #ifdef FEATURE_COMINTEROP
620     ULONG fn__Unknown_AddRef;
621     ULONG fn__Unknown_AddRefSpecial;
622     ULONG fn__Unknown_AddRefInner;
623 #endif
624
625     // Vtable pointer values for all classes that must
626     // be instanted using vtable pointers as the identity.
627 #define VPTR_CLASS(name) ULONG name##__vtAddr;
628 #define VPTR_MULTI_CLASS(name, keyBase) ULONG name##__##keyBase##__mvtAddr;
629 #include <vptr_list.h>
630 #undef VPTR_CLASS
631 #undef VPTR_MULTI_CLASS
632 } DacGlobals;
633
634 #ifdef DACCESS_COMPILE
635
636 extern DacTableInfo g_dacTableInfo;
637 extern DacGlobals g_dacGlobals;
638
639 #ifdef __cplusplus
640 extern "C" {
641 #endif
642
643 // These two functions are largely just for marking code
644 // that is not fully converted.  DacWarning prints a debug
645 // message, while DacNotImpl throws a not-implemented exception.
646 void __cdecl DacWarning(__in __in_z char* format, ...);
647 void DacNotImpl(void);
648
649 void    DacError(HRESULT err);
650 void    DECLSPEC_NORETURN DacError_NoRet(HRESULT err);
651 TADDR   DacGlobalBase(void);
652 HRESULT DacReadAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx);
653 HRESULT DacWriteAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx);
654 HRESULT DacAllocVirtual(TADDR addr, ULONG32 size,
655                         ULONG32 typeFlags, ULONG32 protectFlags,
656                         bool throwEx, TADDR* mem);
657 HRESULT DacFreeVirtual(TADDR mem, ULONG32 size, ULONG32 typeFlags,
658                        bool throwEx);
659 PVOID   DacInstantiateTypeByAddress(TADDR addr, ULONG32 size, bool throwEx);
660 PVOID   DacInstantiateTypeByAddressNoReport(TADDR addr, ULONG32 size, bool throwEx);
661 PVOID   DacInstantiateClassByVTable(TADDR addr, ULONG32 minSize, bool throwEx);
662
663 // Copy a null-terminated ascii or unicode string from the target to the host.
664 // Note that most of the work here is to find the null terminator.  If you know the exact length,
665 // then you can also just call DacInstantiateTypebyAddress.
666 PSTR    DacInstantiateStringA(TADDR addr, ULONG32 maxChars, bool throwEx);
667 PWSTR   DacInstantiateStringW(TADDR addr, ULONG32 maxChars, bool throwEx);
668
669 TADDR   DacGetTargetAddrForHostAddr(LPCVOID ptr, bool throwEx);
670 TADDR   DacGetTargetAddrForHostInteriorAddr(LPCVOID ptr, bool throwEx);
671 TADDR   DacGetTargetVtForHostVt(LPCVOID vtHost, bool throwEx);
672 PWSTR   DacGetVtNameW(TADDR targetVtable);
673
674 // Report a region of memory to the debugger
675 bool    DacEnumMemoryRegion(TADDR addr, TSIZE_T size, bool fExpectSuccess = true);
676
677 // Report a region of memory to the debugger
678 bool DacUpdateMemoryRegion(TADDR addr, TSIZE_T bufferSize, BYTE* buffer);
679
680 HRESULT DacWriteHostInstance(PVOID host, bool throwEx);
681
682 // This is meant to mimic the RethrowTerminalExceptions/
683 // SwallowAllExceptions/RethrowTransientExceptions macros to allow minidump
684 // gathering cancelation for details see 
685 // code:ClrDataAccess.EnumMemoryRegionsWrapper
686
687 // This is usable in EX_TRY exactly how RethrowTerminalExceptions et cetera
688 #define RethrowCancelExceptions                                         \
689     if (GET_EXCEPTION()->GetHR() == COR_E_OPERATIONCANCELED)            \
690     {                                                                   \
691         EX_RETHROW;                                                     \
692     }             
693
694 // Occasionally it's necessary to allocate some host memory for
695 // instance data that's created on the fly and so doesn't directly
696 // correspond to target memory.  These are held and freed on flush
697 // like other instances but can't be looked up by address.
698 PVOID DacAllocHostOnlyInstance(ULONG32 size, bool throwEx);
699
700 // Determines whether ASSERTs should be raised when inconsistencies in the target are detected
701 bool DacTargetConsistencyAssertsEnabled();
702
703 // Host instances can be marked as they are enumerated in
704 // order to break cycles.  This function returns true if
705 // the instance is already marked, otherwise it marks the
706 // instance and returns false.
707 bool DacHostPtrHasEnumMark(LPCVOID host);
708
709 // Determines if EnumMemoryRegions has been called on a method descriptor.
710 // This helps perf for minidumps of apps with large managed stacks.
711 bool DacHasMethodDescBeenEnumerated(LPCVOID pMD);
712
713 // Sets a flag indicating that EnumMemoryRegions on a method desciptor 
714 // has been successfully called. The function returns true if
715 // this flag had been previously set.
716 bool DacSetMethodDescEnumerated(LPCVOID pMD);
717
718 // Determines if a method descriptor is valid
719 BOOL DacValidateMD(LPCVOID pMD);
720
721 // Enumerate the instructions around a call site to help debugger stack walking heuristics
722 void DacEnumCodeForStackwalk(TADDR taCallEnd);
723
724 // Given the address and the size of a memory range which is stored in the buffer, replace all the patches 
725 // in the buffer with the real opcodes.  This is especially important on X64 where the unwinder needs to 
726 // disassemble the native instructions.
727 class MemoryRange;
728 HRESULT DacReplacePatchesInHostMemory(MemoryRange range, PVOID pBuffer);
729
730 //
731 // Convenience macros for EnumMemoryRegions implementations.
732 //
733     
734 // Enumerate the given host instance and return
735 // true if the instance hasn't already been enumerated.
736 #define DacEnumHostDPtrMem(host) \
737     (!DacHostPtrHasEnumMark(host) ? \
738      (DacEnumMemoryRegion(PTR_HOST_TO_TADDR(host), sizeof(*host)), \
739       true) : false)
740 #define DacEnumHostSPtrMem(host, type) \
741     (!DacHostPtrHasEnumMark(host) ? \
742      (DacEnumMemoryRegion(PTR_HOST_TO_TADDR(host), \
743                           type::DacSize(PTR_HOST_TO_TADDR(host))), \
744       true) : false)
745 #define DacEnumHostVPtrMem(host) \
746     (!DacHostPtrHasEnumMark(host) ? \
747      (DacEnumMemoryRegion(PTR_HOST_TO_TADDR(host), (host)->VPtrSize()), \
748       true) : false)
749
750 // Check enumeration of 'this' and return if this has already been
751 // enumerated.  Making this the first line of an object's EnumMemoryRegions
752 // method will prevent cycles.
753 #define DAC_CHECK_ENUM_THIS() \
754     if (DacHostPtrHasEnumMark(this)) return
755 #define DAC_ENUM_DTHIS() \
756     if (!DacEnumHostDPtrMem(this)) return
757 #define DAC_ENUM_STHIS(type) \
758     if (!DacEnumHostSPtrMem(this, type)) return
759 #define DAC_ENUM_VTHIS() \
760     if (!DacEnumHostVPtrMem(this)) return
761     
762 #ifdef __cplusplus
763 }
764 class ReflectionModule;
765 interface IMDInternalImport* DacGetMDImport(const class PEFile* peFile,
766                                             bool throwEx);
767 interface IMDInternalImport* DacGetMDImport(const ReflectionModule* reflectionModule, 
768                                             bool throwEx);
769
770 int DacGetIlMethodSize(TADDR methAddr);
771 struct COR_ILMETHOD* DacGetIlMethod(TADDR methAddr);
772 #if defined(WIN64EXCEPTIONS)
773 struct _UNWIND_INFO * DacGetUnwindInfo(TADDR taUnwindInfo);
774
775 // virtually unwind a CONTEXT out-of-process
776 struct _KNONVOLATILE_CONTEXT_POINTERS;
777 BOOL DacUnwindStackFrame(T_CONTEXT * pContext, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers);
778 #endif // _WIN64
779
780 #ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
781 class SString;
782 void DacMdCacheAddEEName(TADDR taEE, const SString& ssEEName);
783 bool DacMdCacheGetEEName(TADDR taEE, SString & ssEEName);
784 #endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
785
786 // 
787 // Computes (taBase + (dwIndex * dwElementSize()), with overflow checks.
788 // 
789 // Arguments:
790 //     taBase          the base TADDR value
791 //     dwIndex         the index of the offset
792 //     dwElementSize   the size of each element (to multiply the offset by)
793 //     
794 // Return value:
795 //     The resulting TADDR, or throws CORDB_E_TARGET_INCONSISTENT on overlow.
796 //     
797 // Notes:
798 //     The idea here is that overflows during address arithmetic suggest that we're operating on corrupt
799 //     pointers.  It helps to improve reliability to detect the cases we can (like overflow) and fail.  Note
800 //     that this is just a heuristic, not a security measure.  We can't trust target data regardless -
801 //     failing on overflow is just one easy case of corruption to detect.  There is no need to use checked
802 //     arithmetic everywhere in the DAC infrastructure, this is intended just for the places most likely to
803 //     help catch bugs (eg. __DPtr::operator[]).
804 // 
805 inline TADDR DacTAddrOffset( TADDR taBase, TSIZE_T dwIndex, TSIZE_T dwElementSize )
806 {
807     ClrSafeInt<TADDR> t(taBase);
808     t += ClrSafeInt<TSIZE_T>(dwIndex) * ClrSafeInt<TSIZE_T>(dwElementSize);
809     if( t.IsOverflow() )
810     {
811         // Pointer arithmetic overflow - probably due to corrupt target data
812         DacError(CORDBG_E_TARGET_INCONSISTENT);
813     }
814     return t.Value();
815 }
816
817
818 // Base pointer wrapper which provides common behavior.
819 class __TPtrBase
820 {
821 public:
822     __TPtrBase(void)
823     {
824         // Make uninitialized pointers obvious.
825         m_addr = (TADDR)-1;
826     }
827     __TPtrBase(TADDR addr)
828     {
829         m_addr = addr;
830     }
831
832     bool operator!() const
833     {
834         return m_addr == 0;
835     }
836     // We'd like to have an implicit conversion to bool here since the C++
837     // standard says all pointer types are implicitly converted to bool. 
838     // Unfortunately, that would cause ambiguous overload errors for uses
839     // of operator== and operator!=.  Instead callers will have to compare
840     // directly against NULL. 
841
842     bool operator==(TADDR addr) const
843     {
844         return m_addr == addr;
845     }
846     bool operator!=(TADDR addr) const
847     {
848         return m_addr != addr;
849     }
850     bool operator<(TADDR addr) const
851     {
852         return m_addr < addr;
853     }
854     bool operator>(TADDR addr) const
855     {
856         return m_addr > addr;
857     }
858     bool operator<=(TADDR addr) const
859     {
860         return m_addr <= addr;
861     }
862     bool operator>=(TADDR addr) const
863     {
864         return m_addr >= addr;
865     }
866
867     TADDR GetAddr(void) const
868     {
869         return m_addr;
870     }
871     TADDR SetAddr(TADDR addr)
872     {
873         m_addr = addr;
874         return addr;
875     }
876
877 protected:
878     TADDR m_addr;
879 };
880
881 // Pointer wrapper base class for various forms of normal data.
882 // This has the common functionality between __DPtr and __ArrayDPtr.
883 // The DPtrType type parameter is the actual derived type in use.  This is necessary so that 
884 // inhereted functions preserve exact return types. 
885 template<typename type, typename DPtrType>
886 class __DPtrBase : public __TPtrBase
887 {
888 public:
889     typedef type _Type;
890     typedef type* _Ptr;
891     
892 protected:
893     // Constructors 
894     // All protected - this type should not be used directly - use one of the derived types instead.
895     __DPtrBase< type, DPtrType >(void) : __TPtrBase() {}
896     __DPtrBase< type, DPtrType >(TADDR addr) : __TPtrBase(addr) {}
897     
898     explicit __DPtrBase< type, DPtrType >(__TPtrBase addr)
899     {
900         m_addr = addr.GetAddr();
901     }
902     explicit __DPtrBase< type, DPtrType >(type const * host)
903     {
904         m_addr = DacGetTargetAddrForHostAddr(host, true);
905     }
906
907 public:
908     DPtrType& operator=(const __TPtrBase& ptr)
909     {
910         m_addr = ptr.GetAddr();
911         return DPtrType(m_addr);
912     }
913     DPtrType& operator=(TADDR addr)
914     {
915         m_addr = addr;
916         return DPtrType(m_addr);
917     }
918
919     type& operator*(void) const
920     {
921         return *(type*)DacInstantiateTypeByAddress(m_addr, sizeof(type), true);
922     }
923
924     bool operator==(const DPtrType& ptr) const
925     {
926         return m_addr == ptr.GetAddr();
927     }
928     bool operator==(TADDR addr) const
929     {
930         return m_addr == addr;
931     }
932     bool operator!=(const DPtrType& ptr) const
933     {
934         return !operator==(ptr);
935     }
936     bool operator!=(TADDR addr) const
937     {
938         return m_addr != addr;
939     }
940     bool operator<(const DPtrType& ptr) const
941     {
942         return m_addr < ptr.GetAddr();
943     }
944     bool operator>(const DPtrType& ptr) const
945     {
946         return m_addr > ptr.GetAddr();
947     }
948     bool operator<=(const DPtrType& ptr) const
949     {
950         return m_addr <= ptr.GetAddr();
951     }
952     bool operator>=(const DPtrType& ptr) const
953     {
954         return m_addr >= ptr.GetAddr();
955     }
956
957     // Array index operator
958     // we want an operator[] for all possible numeric types (rather than rely on
959     // implicit numeric conversions on the argument) to prevent ambiguity with 
960     // DPtr's implicit conversion to type* and the built-in operator[].
961     // @dbgtodo : we could also use this technique to simplify other operators below.
962     template<typename indexType>
963     type& operator[](indexType index)
964     {
965         // Compute the address of the element.
966         TADDR elementAddr;
967         if( index >= 0 )
968         {
969             elementAddr = DacTAddrOffset(m_addr, index, sizeof(type));
970         }
971         else
972         {
973             // Don't bother trying to do overflow checking for negative indexes - they are rare compared to
974             // positive ones.  ClrSafeInt doesn't support signed datatypes yet (although we should be able to add it
975             // pretty easily).
976             elementAddr = m_addr + index * sizeof(type);
977         }
978
979         // Marshal over a single instance and return a reference to it.
980         return *(type*) DacInstantiateTypeByAddress(elementAddr, sizeof(type), true);
981     }
982
983     template<typename indexType>
984     type const & operator[](indexType index) const
985     {
986         return (*const_cast<__DPtrBase*>(this))[index];
987     }
988
989     //-------------------------------------------------------------------------
990     // operator+
991     
992     DPtrType operator+(unsigned short val)
993     {
994         return DPtrType(DacTAddrOffset(m_addr, val, sizeof(type)));
995     }
996     DPtrType operator+(short val)
997     {
998         return DPtrType(m_addr + val * sizeof(type));
999     }
1000     // size_t is unsigned int on Win32, so we need
1001     // to ifdef here to make sure the unsigned int
1002     // and size_t overloads don't collide.  size_t
1003     // is marked __w64 so a simple unsigned int
1004     // will not work on Win32, it has to be size_t.
1005     DPtrType operator+(size_t val)
1006     {
1007         return DPtrType(DacTAddrOffset(m_addr, val, sizeof(type)));
1008     }
1009 #if defined (_WIN64)
1010     DPtrType operator+(unsigned int val)
1011     {
1012         return DPtrType(DacTAddrOffset(m_addr, val, sizeof(type)));
1013     }
1014 #endif
1015     DPtrType operator+(int val)
1016     {
1017         return DPtrType(m_addr + val * sizeof(type));
1018     }
1019     // Because of the size difference between long and int on non MS compilers,
1020     // we only need to define these operators on Windows. These provide compatible
1021     // overloads for DWORD addition operations.
1022 #ifdef _MSC_VER
1023     DPtrType operator+(unsigned long val)
1024     {
1025         return DPtrType(DacTAddrOffset(m_addr, val, sizeof(type)));
1026     }
1027     DPtrType operator+(long val)
1028     {
1029         return DPtrType(m_addr + val * sizeof(type));
1030     }
1031 #endif
1032
1033     //-------------------------------------------------------------------------
1034     // operator-
1035     
1036     DPtrType operator-(unsigned short val)
1037     {
1038         return DPtrType(m_addr - val * sizeof(type));
1039     }
1040     DPtrType operator-(short val)
1041     {
1042         return DPtrType(m_addr - val * sizeof(type));
1043     }
1044     // size_t is unsigned int on Win32, so we need
1045     // to ifdef here to make sure the unsigned int
1046     // and size_t overloads don't collide.  size_t
1047     // is marked __w64 so a simple unsigned int
1048     // will not work on Win32, it has to be size_t.
1049     DPtrType operator-(size_t val)
1050     {
1051         return DPtrType(m_addr - val * sizeof(type));
1052     }
1053 #ifdef _WIN64
1054     DPtrType operator-(unsigned int val)
1055     {
1056         return DPtrType(m_addr - val * sizeof(type));
1057     }
1058 #endif
1059     DPtrType operator-(int val)
1060     {
1061         return DPtrType(m_addr - val * sizeof(type));
1062     }
1063     // Because of the size difference between long and int on non MS compilers,
1064     // we only need to define these operators on Windows. These provide compatible
1065     // overloads for DWORD addition operations.
1066 #ifdef _MSC_VER // for now, everything else is 32 bit
1067     DPtrType operator-(unsigned long val)
1068     {
1069         return DPtrType(m_addr - val * sizeof(type));
1070     }
1071     DPtrType operator-(long val)
1072     {
1073         return DPtrType(m_addr - val * sizeof(type));
1074     }
1075 #endif
1076     size_t operator-(const DPtrType& val)
1077     {
1078         return (m_addr - val.m_addr) / sizeof(type);
1079     }
1080
1081     //-------------------------------------------------------------------------
1082     
1083     DPtrType& operator+=(size_t val)
1084     {
1085         m_addr += val * sizeof(type);
1086         return static_cast<DPtrType&>(*this);
1087     }
1088     DPtrType& operator-=(size_t val)
1089     {
1090         m_addr -= val * sizeof(type);
1091         return static_cast<DPtrType&>(*this);
1092     }
1093     
1094     DPtrType& operator++()
1095     {
1096         m_addr += sizeof(type);
1097         return static_cast<DPtrType&>(*this);
1098     }
1099     DPtrType& operator--()
1100     {
1101         m_addr -= sizeof(type);
1102         return static_cast<DPtrType&>(*this);
1103     }
1104     DPtrType operator++(int postfix)
1105     {
1106         DPtrType orig = DPtrType(*this);
1107         m_addr += sizeof(type);
1108         return orig;
1109     }
1110     DPtrType operator--(int postfix)
1111     {
1112         DPtrType orig = DPtrType(*this);
1113         m_addr -= sizeof(type);
1114         return orig;
1115     }
1116
1117     bool IsValid(void) const
1118     {
1119         return m_addr &&
1120             DacInstantiateTypeByAddress(m_addr, sizeof(type),
1121                                         false) != NULL;
1122     }
1123     void EnumMem(void) const
1124     {
1125         DacEnumMemoryRegion(m_addr, sizeof(type));
1126     }
1127 };
1128
1129 // forward declaration
1130 template<typename acc_type, typename store_type>
1131 class __GlobalPtr;
1132
1133 // Pointer wrapper for objects which are just plain data
1134 // and need no special handling.
1135 template<typename type>
1136 class __DPtr : public __DPtrBase<type,__DPtr<type> >
1137 {
1138 public:
1139     // constructors - all chain to __DPtrBase constructors
1140     __DPtr< type >(void) : __DPtrBase<type,__DPtr<type> >() {}
1141     __DPtr< type >(TADDR addr) : __DPtrBase<type,__DPtr<type> >(addr) {}
1142
1143     // construct const from non-const
1144     typedef typename std::remove_const<type>::type mutable_type;
1145     __DPtr< type >(__DPtr<mutable_type> const & rhs) : __DPtrBase<type,__DPtr<type> >(rhs.GetAddr()) {}
1146
1147     // construct from GlobalPtr
1148     explicit __DPtr< type >(__GlobalPtr< type*, __DPtr< type > > globalPtr) : 
1149         __DPtrBase<type,__DPtr<type> >(globalPtr.GetAddr()) {} 
1150
1151     explicit __DPtr< type >(__TPtrBase addr) : __DPtrBase<type,__DPtr<type> >(addr) {}
1152     explicit __DPtr< type >(type const * host) : __DPtrBase<type,__DPtr<type> >(host) {}
1153
1154     operator type*() const
1155     {
1156         return (type*)DacInstantiateTypeByAddress(this->m_addr, sizeof(type), true);
1157     }
1158     type* operator->() const
1159     {
1160         return (type*)DacInstantiateTypeByAddress(this->m_addr, sizeof(type), true);
1161     }
1162 };
1163
1164 #define DPTR(type) __DPtr< type >
1165
1166 // A restricted form of DPtr that doesn't have any conversions to pointer types.
1167 // This is useful for pointer types that almost always represent arrays, as opposed
1168 // to pointers to single instances (eg. PTR_BYTE).  In these cases, allowing implicit
1169 // conversions to (for eg.) BYTE* would usually result in incorrect usage (eg. pointer 
1170 // arithmetic and array indexing), since only a single instance has been marshalled to the host.
1171 // If you really must marshal a single instance (eg. converting T* to PTR_T is too painful for now),
1172 // then use code:DacUnsafeMarshalSingleElement so we can identify such unsafe code.
1173 template<typename type>
1174 class __ArrayDPtr : public __DPtrBase<type,__ArrayDPtr<type> >
1175 {
1176 public:
1177     // constructors - all chain to __DPtrBase constructors
1178     __ArrayDPtr< type >(void) : __DPtrBase<type,__ArrayDPtr<type> >() {}
1179     __ArrayDPtr< type >(TADDR addr) : __DPtrBase<type,__ArrayDPtr<type> >(addr) {}
1180
1181     // construct const from non-const
1182     typedef typename std::remove_const<type>::type mutable_type;
1183     __ArrayDPtr< type >(__ArrayDPtr<mutable_type> const & rhs) : __DPtrBase<type,__ArrayDPtr<type> >(rhs.GetAddr()) {}  
1184
1185     explicit __ArrayDPtr< type >(__TPtrBase addr) : __DPtrBase<type,__ArrayDPtr<type> >(addr) {}
1186
1187     // Note that there is also no explicit constructor from host instances (type*).
1188     // Going this direction is less problematic, but often still represents risky coding.
1189 };
1190
1191 #define ArrayDPTR(type) __ArrayDPtr< type >
1192
1193
1194 // Pointer wrapper for objects which are just plain data
1195 // but whose size is not the same as the base type size.
1196 // This can be used for prefetching data for arrays or
1197 // for cases where an object has a variable size.
1198 template<typename type>
1199 class __SPtr : public __TPtrBase
1200 {
1201 public:
1202     typedef type _Type;
1203     typedef type* _Ptr;
1204     
1205     __SPtr< type >(void) : __TPtrBase() {}
1206     __SPtr< type >(TADDR addr) : __TPtrBase(addr) {}
1207     explicit __SPtr< type >(__TPtrBase addr)
1208     {
1209         m_addr = addr.GetAddr();
1210     }
1211     explicit __SPtr< type >(type* host)
1212     {
1213         m_addr = DacGetTargetAddrForHostAddr(host, true);
1214     }
1215
1216     __SPtr< type >& operator=(const __TPtrBase& ptr)
1217     {
1218         m_addr = ptr.GetAddr();
1219         return *this;
1220     }
1221     __SPtr< type >& operator=(TADDR addr)
1222     {
1223         m_addr = addr;
1224         return *this;
1225     }
1226
1227     operator type*() const
1228     {
1229         if (m_addr)
1230         {
1231             return (type*)DacInstantiateTypeByAddress(m_addr,
1232                                                       type::DacSize(m_addr),
1233                                                       true);
1234         }
1235         else
1236         {
1237             return (type*)NULL;
1238         }
1239     }
1240     type* operator->() const
1241     {
1242         if (m_addr)
1243         {
1244             return (type*)DacInstantiateTypeByAddress(m_addr,
1245                                                       type::DacSize(m_addr),
1246                                                       true);
1247         }
1248         else
1249         {
1250             return (type*)NULL;
1251         }
1252     }
1253     type& operator*(void) const
1254     {
1255         if (!m_addr)
1256         {
1257             DacError(E_INVALIDARG);
1258         }
1259         
1260         return *(type*)DacInstantiateTypeByAddress(m_addr,
1261                                                    type::DacSize(m_addr),
1262                                                    true);
1263     }
1264
1265     bool IsValid(void) const
1266     {
1267         return m_addr &&
1268             DacInstantiateTypeByAddress(m_addr, type::DacSize(m_addr),
1269                                         false) != NULL;
1270     }
1271     void EnumMem(void) const
1272     {
1273         if (m_addr)
1274         {
1275             DacEnumMemoryRegion(m_addr, type::DacSize(m_addr));
1276         }
1277     }
1278 };
1279
1280 #define SPTR(type) __SPtr< type >
1281
1282 // Pointer wrapper for objects which have a single leading
1283 // vtable, such as objects in a single-inheritance tree.
1284 // The base class of all such trees must have use
1285 // VPTR_BASE_VTABLE_CLASS in their declaration and all
1286 // instantiable members of the tree must be listed in vptr_list.h.
1287 template<class type>
1288 class __VPtr : public __TPtrBase
1289 {
1290 public:
1291     // VPtr::_Type has to be a pointer as
1292     // often the type is an abstract class.
1293     // This type is not expected to be used anyway.
1294     typedef type* _Type;
1295     typedef type* _Ptr;
1296     
1297     __VPtr< type >(void) : __TPtrBase() {}
1298     __VPtr< type >(TADDR addr) : __TPtrBase(addr) {}
1299     explicit __VPtr< type >(__TPtrBase addr)
1300     {
1301         m_addr = addr.GetAddr();
1302     }
1303     explicit __VPtr< type >(type* host)
1304     {
1305         m_addr = DacGetTargetAddrForHostAddr(host, true);
1306     }
1307     
1308     __VPtr< type >& operator=(const __TPtrBase& ptr)
1309     {
1310         m_addr = ptr.GetAddr();
1311         return *this;
1312     }
1313     __VPtr< type >& operator=(TADDR addr)
1314     {
1315         m_addr = addr;
1316         return *this;
1317     }
1318
1319     operator type*() const
1320     {
1321         return (type*)DacInstantiateClassByVTable(m_addr, sizeof(type), true);
1322     }
1323     type* operator->() const
1324     {
1325         return (type*)DacInstantiateClassByVTable(m_addr, sizeof(type), true);
1326     }
1327     
1328     bool operator==(const __VPtr< type >& ptr) const
1329     {
1330         return m_addr == ptr.m_addr;
1331     }
1332     bool operator==(TADDR addr) const
1333     {
1334         return m_addr == addr;
1335     }
1336     bool operator!=(const __VPtr< type >& ptr) const
1337     {
1338         return !operator==(ptr);
1339     }
1340     bool operator!=(TADDR addr) const
1341     {
1342         return m_addr != addr;
1343     }
1344
1345     bool IsValid(void) const
1346     {
1347         return m_addr &&
1348             DacInstantiateClassByVTable(m_addr, sizeof(type), false) != NULL;
1349     }
1350     void EnumMem(void) const
1351     {
1352         if (IsValid())
1353         {
1354             DacEnumMemoryRegion(m_addr, (operator->())->VPtrSize());
1355         }
1356     }
1357 };
1358
1359 #define VPTR(type) __VPtr< type >
1360
1361 // Pointer wrapper for 8-bit strings.
1362 template<typename type, ULONG32 maxChars = 32760>
1363 class __Str8Ptr : public __DPtr<char>
1364 {
1365 public:
1366     typedef type _Type;
1367     typedef type* _Ptr;
1368     
1369     __Str8Ptr< type, maxChars >(void) : __DPtr<char>() {}
1370     __Str8Ptr< type, maxChars >(TADDR addr) : __DPtr<char>(addr) {}
1371     explicit __Str8Ptr< type, maxChars >(__TPtrBase addr)
1372     {
1373         m_addr = addr.GetAddr();
1374     }
1375     explicit __Str8Ptr< type, maxChars >(type* host)
1376     {
1377         m_addr = DacGetTargetAddrForHostAddr(host, true);
1378     }
1379
1380     __Str8Ptr< type, maxChars >& operator=(const __TPtrBase& ptr)
1381     {
1382         m_addr = ptr.GetAddr();
1383         return *this;
1384     }
1385     __Str8Ptr< type, maxChars >& operator=(TADDR addr)
1386     {
1387         m_addr = addr;
1388         return *this;
1389     }
1390
1391     operator type*() const
1392     {
1393         return (type*)DacInstantiateStringA(m_addr, maxChars, true);
1394     }
1395
1396     bool IsValid(void) const
1397     {
1398         return m_addr &&
1399             DacInstantiateStringA(m_addr, maxChars, false) != NULL;
1400     }
1401     void EnumMem(void) const
1402     {
1403         char* str = DacInstantiateStringA(m_addr, maxChars, false);
1404         if (str)
1405         {
1406             DacEnumMemoryRegion(m_addr, strlen(str) + 1);
1407         }
1408     }
1409 };
1410
1411 #define S8PTR(type) __Str8Ptr< type >
1412 #define S8PTRMAX(type, maxChars) __Str8Ptr< type, maxChars >
1413
1414 // Pointer wrapper for 16-bit strings.
1415 template<typename type, ULONG32 maxChars = 32760>
1416 class __Str16Ptr : public __DPtr<wchar_t>
1417 {
1418 public:
1419     typedef type _Type;
1420     typedef type* _Ptr;
1421     
1422     __Str16Ptr< type, maxChars >(void) : __DPtr<wchar_t>() {}
1423     __Str16Ptr< type, maxChars >(TADDR addr) : __DPtr<wchar_t>(addr) {}
1424     explicit __Str16Ptr< type, maxChars >(__TPtrBase addr)
1425     {
1426         m_addr = addr.GetAddr();
1427     }
1428     explicit __Str16Ptr< type, maxChars >(type* host)
1429     {
1430         m_addr = DacGetTargetAddrForHostAddr(host, true);
1431     }
1432
1433     __Str16Ptr< type, maxChars >& operator=(const __TPtrBase& ptr)
1434     {
1435         m_addr = ptr.GetAddr();
1436         return *this;
1437     }
1438     __Str16Ptr< type, maxChars >& operator=(TADDR addr)
1439     {
1440         m_addr = addr;
1441         return *this;
1442     }
1443
1444     operator type*() const
1445     {
1446         return (type*)DacInstantiateStringW(m_addr, maxChars, true);
1447     }
1448
1449     bool IsValid(void) const
1450     {
1451         return m_addr &&
1452             DacInstantiateStringW(m_addr, maxChars, false) != NULL;
1453     }
1454     void EnumMem(void) const
1455     {
1456         char* str = DacInstantiateStringW(m_addr, maxChars, false);
1457         if (str)
1458         {
1459             DacEnumMemoryRegion(m_addr, strlen(str) + 1);
1460         }
1461     }
1462 };
1463
1464 #define S16PTR(type) __Str16Ptr< type >
1465 #define S16PTRMAX(type, maxChars) __Str16Ptr< type, maxChars >
1466
1467 template<typename type>
1468 class __GlobalVal
1469 {
1470 public:
1471     __GlobalVal< type >(PULONG rvaPtr)
1472     {
1473         m_rvaPtr = rvaPtr;
1474     }
1475
1476     operator type() const
1477     {
1478         return (type)*__DPtr< type >(DacGlobalBase() + *m_rvaPtr);
1479     }
1480
1481     __DPtr< type > operator&() const
1482     {
1483         return __DPtr< type >(DacGlobalBase() + *m_rvaPtr);
1484     }
1485
1486     // @dbgtodo  dac support: This updates values in the host.  This seems extremely dangerous
1487     // to do silently.  I'd prefer that a specific (searchable) write function
1488     // was used.  Try disabling this and see what fails...
1489     __GlobalVal<type> & operator=(const type & val)
1490     {
1491         type* ptr = __DPtr< type >(DacGlobalBase() + *m_rvaPtr);
1492         // Update the host copy;
1493         *ptr = val;
1494         // Write back to the target.
1495         DacWriteHostInstance(ptr, true);
1496         return *this;
1497     }
1498     
1499     bool IsValid(void) const
1500     {
1501         return __DPtr< type >(DacGlobalBase() + *m_rvaPtr).IsValid();
1502     }
1503     void EnumMem(void) const
1504     {
1505         TADDR p = DacGlobalBase() + *m_rvaPtr;
1506         __DPtr< type >(p).EnumMem();
1507     }
1508
1509 private:
1510     PULONG m_rvaPtr;
1511 };
1512
1513 template<typename type, size_t size>
1514 class __GlobalArray
1515 {
1516 public:
1517     __GlobalArray< type, size >(PULONG rvaPtr)
1518     {
1519         m_rvaPtr = rvaPtr;
1520     }
1521
1522     __DPtr< type > operator&() const
1523     {
1524         return __DPtr< type >(DacGlobalBase() + *m_rvaPtr);
1525     }
1526     
1527     type& operator[](unsigned int index) const
1528     {
1529         return __DPtr< type >(DacGlobalBase() + *m_rvaPtr)[index];
1530     }
1531     
1532     bool IsValid(void) const
1533     {
1534         // Only validates the base pointer, not the full array range.
1535         return __DPtr< type >(DacGlobalBase() + *m_rvaPtr).IsValid();
1536     }
1537     void EnumMem(void) const
1538     {
1539         DacEnumMemoryRegion(DacGlobalBase() + *m_rvaPtr, sizeof(type) * size);
1540     }
1541
1542 private:
1543     PULONG m_rvaPtr;
1544 };
1545
1546 template<typename acc_type, typename store_type>
1547 class __GlobalPtr
1548 {
1549 public:
1550     __GlobalPtr< acc_type, store_type >(PULONG rvaPtr)
1551     {
1552         m_rvaPtr = rvaPtr;
1553     }
1554
1555     __DPtr< store_type > operator&() const
1556     {
1557         return __DPtr< store_type >(DacGlobalBase() + *m_rvaPtr);
1558     }
1559       
1560     store_type & operator=(store_type & val)
1561     {
1562         store_type* ptr = __DPtr< store_type >(DacGlobalBase() + *m_rvaPtr);
1563         // Update the host copy;
1564         *ptr = val;
1565         // Write back to the target.
1566         DacWriteHostInstance(ptr, true);
1567         return val;
1568     }
1569     
1570     acc_type operator->() const
1571     {
1572         return (acc_type)*__DPtr< store_type >(DacGlobalBase() + *m_rvaPtr);
1573     }
1574     operator acc_type() const
1575     {
1576         return (acc_type)*__DPtr< store_type >(DacGlobalBase() + *m_rvaPtr);
1577     }
1578     operator store_type() const
1579     {
1580         return *__DPtr< store_type >(DacGlobalBase() + *m_rvaPtr);
1581     }
1582     bool operator!() const
1583     {
1584         return !*__DPtr< store_type >(DacGlobalBase() + *m_rvaPtr);
1585     }
1586
1587     typename store_type::_Type& operator[](int index)
1588     {
1589         return (*__DPtr< store_type >(DacGlobalBase() + *m_rvaPtr))[index];
1590     }
1591     
1592     typename store_type::_Type& operator[](unsigned int index)
1593     {
1594         return (*__DPtr< store_type >(DacGlobalBase() + *m_rvaPtr))[index];
1595     }
1596
1597     TADDR GetAddr() const
1598     {
1599         return (*__DPtr< store_type >(DacGlobalBase() + *m_rvaPtr)).GetAddr();
1600     }
1601
1602     TADDR GetAddrRaw () const
1603     {
1604         return DacGlobalBase() + *m_rvaPtr;
1605     }
1606     
1607     // This is only testing the the pointer memory is available but does not verify
1608     // the memory that it points to.
1609     //
1610     bool IsValidPtr(void) const
1611     {
1612         return __DPtr< store_type >(DacGlobalBase() + *m_rvaPtr).IsValid();
1613     }
1614     
1615     bool IsValid(void) const
1616     {
1617         return __DPtr< store_type >(DacGlobalBase() + *m_rvaPtr).IsValid() &&
1618             (*__DPtr< store_type >(DacGlobalBase() + *m_rvaPtr)).IsValid();
1619     }
1620     void EnumMem(void) const
1621     {
1622         __DPtr< store_type > ptr(DacGlobalBase() + *m_rvaPtr);
1623         ptr.EnumMem();
1624         if (ptr.IsValid())
1625         {
1626             (*ptr).EnumMem();
1627         }
1628     }
1629
1630     PULONG m_rvaPtr;
1631 };
1632
1633 template<typename acc_type, typename store_type>
1634 inline bool operator==(const __GlobalPtr<acc_type, store_type>& gptr,
1635                        acc_type host)
1636 {
1637     return DacGetTargetAddrForHostAddr(host, true) ==
1638         *__DPtr< TADDR >(DacGlobalBase() + *gptr.m_rvaPtr);
1639 }
1640 template<typename acc_type, typename store_type>
1641 inline bool operator!=(const __GlobalPtr<acc_type, store_type>& gptr,
1642                        acc_type host)
1643 {
1644     return !operator==(gptr, host);
1645 }
1646
1647 template<typename acc_type, typename store_type>
1648 inline bool operator==(acc_type host,
1649                        const __GlobalPtr<acc_type, store_type>& gptr)
1650 {
1651     return DacGetTargetAddrForHostAddr(host, true) ==
1652         *__DPtr< TADDR >(DacGlobalBase() + *gptr.m_rvaPtr);
1653 }
1654 template<typename acc_type, typename store_type>
1655 inline bool operator!=(acc_type host,
1656                        const __GlobalPtr<acc_type, store_type>& gptr)
1657 {
1658     return !operator==(host, gptr);
1659 }
1660
1661
1662 // 
1663 // __VoidPtr is a type that behaves like void* but for target pointers.
1664 // Behavior of PTR_VOID:
1665 // * has void* semantics. Will compile to void* in non-DAC builds (just like
1666 //     other PTR types. Unlike TADDR, we want pointer semantics.
1667 // * NOT assignable from host pointer types or convertible to host pointer
1668 //     types - ensures we can't confuse host and target pointers (we'll get
1669 //     compiler errors if we try and cast between them).
1670 // * like void*, no pointer arithmetic or dereferencing is allowed
1671 // * like TADDR, can be used to construct any __DPtr / __VPtr instance
1672 // * representation is the same as a void* (for marshalling / casting)
1673 //     
1674 // One way in which __VoidPtr is unlike void* is that it can't be cast to
1675 // pointer or integer types. On the one hand, this is a good thing as it forces
1676 // us to keep target pointers separate from other data types. On the other hand
1677 // in practice this means we have to use dac_cast<TADDR> in places where we used
1678 // to use a (TADDR) cast. Unfortunately C++ provides us no way to allow the
1679 // explicit cast to primitive types without also allowing implicit conversions.
1680 // 
1681 // This is very similar in spirit to TADDR. The primary difference is that
1682 // PTR_VOID has pointer semantics, where TADDR has integer semantics. When
1683 // dacizing uses of void* to TADDR, casts must be inserted everywhere back to
1684 // pointer types. If we switch a use of TADDR to PTR_VOID, those casts in
1685 // DACCESS_COMPILE regions no longer compile (see above). Also, TADDR supports
1686 // pointer arithmetic, but that might not be necessary (could use PTR_BYTE
1687 // instead etc.). Ideally we'd probably have just one type for this purpose
1688 // (named TADDR but with the semantics of PTR_VOID), but outright conversion
1689 // would require too much work.
1690 // 
1691 class __VoidPtr : public __TPtrBase
1692 {
1693 public:
1694     __VoidPtr(void) : __TPtrBase() {}
1695     __VoidPtr(TADDR addr) : __TPtrBase(addr) {}
1696
1697     // Note, unlike __DPtr, this ctor form is not explicit.  We allow implicit
1698     // conversions from any pointer type (just like for void*).
1699     __VoidPtr(__TPtrBase addr)
1700     {
1701         m_addr = addr.GetAddr();
1702     }
1703
1704     // Like TPtrBase, VoidPtrs can also be created impicitly from all GlobalPtrs 
1705     template<typename acc_type, typename store_type>
1706     __VoidPtr(__GlobalPtr<acc_type, store_type> globalPtr)
1707     {
1708         m_addr = globalPtr.GetAddr();
1709     }
1710
1711     // Note, unlike __DPtr, there is no explicit conversion from host pointer
1712     // types.  Since void* cannot be marshalled, there is no such thing as
1713     // a void* DAC instance in the host.
1714
1715     // Also, we don't want an implicit conversion to TADDR because then the
1716     // compiler will allow pointer arithmetic (which it wouldn't allow for
1717     // void*).  Instead, callers can use dac_cast<TADDR> if they want.
1718
1719     // Note, unlike __DPtr, any pointer type can be assigned to a __VoidPtr
1720     // This is to mirror the assignability of any pointer type to a void*
1721     __VoidPtr& operator=(const __TPtrBase& ptr)
1722     {
1723         m_addr = ptr.GetAddr();
1724         return *this;
1725     }
1726     __VoidPtr& operator=(TADDR addr)
1727     {
1728         m_addr = addr;
1729         return *this;
1730     }
1731
1732     // note, no marshalling operators (type* conversion, operator ->, operator*)
1733     // A void* can't be marshalled because we don't know how much to copy
1734
1735     // PTR_Void can be compared to any other pointer type (because conceptually,
1736     // any other pointer type should be implicitly convertible to void*)
1737     bool operator==(const __TPtrBase& ptr) const
1738     {
1739         return m_addr == ptr.GetAddr();
1740     }
1741     bool operator==(TADDR addr) const
1742     {
1743         return m_addr == addr;
1744     }
1745     bool operator!=(const __TPtrBase& ptr) const
1746     {
1747         return !operator==(ptr);
1748     }
1749     bool operator!=(TADDR addr) const
1750     {
1751         return m_addr != addr;
1752     }
1753     bool operator<(const __TPtrBase& ptr) const
1754     {
1755         return m_addr < ptr.GetAddr();
1756     }
1757     bool operator>(const __TPtrBase& ptr) const
1758     {
1759         return m_addr > ptr.GetAddr();
1760     }
1761     bool operator<=(const __TPtrBase& ptr) const
1762     {
1763         return m_addr <= ptr.GetAddr();
1764     }
1765     bool operator>=(const __TPtrBase& ptr) const
1766     {
1767         return m_addr >= ptr.GetAddr();
1768     }   
1769 };
1770
1771 typedef __VoidPtr PTR_VOID;
1772 typedef DPTR(PTR_VOID) PTR_PTR_VOID;
1773
1774 // For now we treat pointers to const and non-const void the same in DAC
1775 // builds. In general, DAC is read-only anyway and so there isn't a danger of
1776 // writing to these pointers. Also, the non-dac builds will ensure
1777 // const-correctness. However, if we wanted to support true void* / const void*
1778 // behavior, we could probably build the follow functionality by templating
1779 // __VoidPtr:
1780 //  * A PTR_VOID would be implicitly convertable to PTR_CVOID
1781 //  * An explicit coercion (ideally const_cast) would be required to convert a
1782 //      PTR_CVOID to a PTR_VOID
1783 //  * Similarily, an explicit coercion would be required to convert a cost PTR
1784 //      type (eg. PTR_CBYTE) to a PTR_VOID.
1785 typedef __VoidPtr PTR_CVOID;
1786
1787
1788 // The special empty ctor declared here allows the whole
1789 // class hierarchy to be instantiated easily by the
1790 // external access code.  The actual class body will be
1791 // read externally so no members should be initialized.
1792
1793 //
1794 // VPTR_ANY_CLASS_METHODS - Defines the following methods for all VPTR classes
1795 // 
1796 // VPtrSize 
1797 //     Returns the size of the dynamic type of the object (as opposed to sizeof
1798 //     which is based only on the static type). 
1799 //     
1800 // VPtrHostVTable
1801 //     Returns the address of the vtable for this type.
1802 //     We create a temporary instance of this type in order to read it's vtable pointer 
1803 //     (at offset 0).  For this temporary instance, we do not want to initialize any fields,
1804 //     so we use the marshalling ctor.  Since we didn't initialize any fields, we also don't
1805 //     wan't to run the dtor (marshaled data structures don't normally expect their destructor 
1806 //     or non-DAC constructors to be called in DAC builds anyway).  So, rather than create a 
1807 //     normal stack object, or put the object on the heap, we create the temporary object 
1808 //     on the stack using placement-new and alloca, and don't destruct it.
1809 //     
1810 #define VPTR_ANY_CLASS_METHODS(name)                            \
1811         virtual ULONG32 VPtrSize(void) { SUPPORTS_DAC; return sizeof(name); } \
1812         static PVOID VPtrHostVTable() {                         \
1813             void * pBuf = _alloca(sizeof(name));                \
1814             name * dummy = new (pBuf) name((TADDR)0, (TADDR)0); \
1815             return *((PVOID*)dummy); }
1816
1817 #define VPTR_CLASS_METHODS(name)                                \
1818         VPTR_ANY_CLASS_METHODS(name)                            \
1819         static TADDR VPtrTargetVTable() {                       \
1820             SUPPORTS_DAC;                                       \
1821             return DacGlobalBase() + g_dacGlobals.name##__vtAddr; }
1822
1823 #define VPTR_MULTI_CLASS_METHODS(name, keyBase)                 \
1824         VPTR_ANY_CLASS_METHODS(name)                            \
1825         static TADDR VPtrTargetVTable() {                       \
1826             SUPPORTS_DAC;                                       \
1827             return DacGlobalBase() + g_dacGlobals.name##__##keyBase##__mvtAddr; }
1828
1829 #define VPTR_VTABLE_CLASS(name, base)                           \
1830 public: name(TADDR addr, TADDR vtAddr) : base(addr, vtAddr) {}  \
1831         VPTR_CLASS_METHODS(name)
1832
1833 #define VPTR_VTABLE_CLASS_AND_CTOR(name, base)                  \
1834         VPTR_VTABLE_CLASS(name, base)
1835
1836 #define VPTR_MULTI_VTABLE_CLASS(name, base)                     \
1837 public: name(TADDR addr, TADDR vtAddr) : base(addr, vtAddr) {}  \
1838         VPTR_MULTI_CLASS_METHODS(name, base)
1839
1840 // Used for base classes that can be instantiated directly.
1841 // The fake vfn is still used to force a vtable even when
1842 // all the normal vfns are ifdef'ed out.
1843 #define VPTR_BASE_CONCRETE_VTABLE_CLASS(name)                   \
1844 public: name(TADDR addr, TADDR vtAddr) {}                       \
1845         VPTR_CLASS_METHODS(name)
1846
1847 #define VPTR_BASE_CONCRETE_VTABLE_CLASS_NO_CTOR_BODY(name)      \
1848 public: name(TADDR addr, TADDR vtAddr);                         \
1849         VPTR_CLASS_METHODS(name)
1850
1851 // The pure virtual method forces all derivations to use
1852 // VPTR_VTABLE_CLASS to compile.
1853 #define VPTR_BASE_VTABLE_CLASS(name)                            \
1854 public: name(TADDR addr, TADDR vtAddr) {}                       \
1855         virtual ULONG32 VPtrSize(void) = 0;
1856
1857 #define VPTR_BASE_VTABLE_CLASS_AND_CTOR(name)                   \
1858         VPTR_BASE_VTABLE_CLASS(name)
1859
1860 #define VPTR_BASE_VTABLE_CLASS_NO_CTOR_BODY(name)               \
1861 public: name(TADDR addr, TADDR vtAddr);                         \
1862         virtual ULONG32 VPtrSize(void) = 0;
1863
1864 #define VPTR_ABSTRACT_VTABLE_CLASS(name, base)                  \
1865 public: name(TADDR addr, TADDR vtAddr) : base(addr, vtAddr) {}
1866
1867 #define VPTR_ABSTRACT_VTABLE_CLASS_NO_CTOR_BODY(name, base)     \
1868 public: name(TADDR addr, TADDR vtAddr);
1869
1870 // helper macro to make the vtables unique for DAC
1871 #define VPTR_UNIQUE(unique)
1872
1873 // Safe access for retrieving the target address of a PTR.
1874 #define PTR_TO_TADDR(ptr) ((ptr).GetAddr())
1875
1876 #define GFN_TADDR(name) (DacGlobalBase() + g_dacGlobals.fn__ ## name)
1877
1878 // ROTORTODO - g++ 3 doesn't like the use of the operator& in __GlobalVal
1879 // here. Putting GVAL_ADDR in to get things to compile while I discuss
1880 // this matter with the g++ authors.
1881
1882 #define GVAL_ADDR(g) \
1883     ((g).operator&())
1884
1885 //
1886 // References to class static and global data.
1887 // These all need to be redirected through the global
1888 // data table.
1889 //
1890
1891 #define _SPTR_DECL(acc_type, store_type, var) \
1892     static __GlobalPtr< acc_type, store_type > var
1893 #define _SPTR_IMPL(acc_type, store_type, cls, var) \
1894     __GlobalPtr< acc_type, store_type > cls::var(&g_dacGlobals.cls##__##var)
1895 #define _SPTR_IMPL_INIT(acc_type, store_type, cls, var, init) \
1896     __GlobalPtr< acc_type, store_type > cls::var(&g_dacGlobals.cls##__##var)
1897 #define _SPTR_IMPL_NS(acc_type, store_type, ns, cls, var) \
1898     __GlobalPtr< acc_type, store_type > cls::var(&g_dacGlobals.ns##__##cls##__##var)
1899 #define _SPTR_IMPL_NS_INIT(acc_type, store_type, ns, cls, var, init) \
1900     __GlobalPtr< acc_type, store_type > cls::var(&g_dacGlobals.ns##__##cls##__##var)
1901
1902 #define _GPTR_DECL(acc_type, store_type, var) \
1903     extern __GlobalPtr< acc_type, store_type > var
1904 #define _GPTR_IMPL(acc_type, store_type, var) \
1905     __GlobalPtr< acc_type, store_type > var(&g_dacGlobals.dac__##var)
1906 #define _GPTR_IMPL_INIT(acc_type, store_type, var, init) \
1907     __GlobalPtr< acc_type, store_type > var(&g_dacGlobals.dac__##var)
1908
1909 #define SVAL_DECL(type, var) \
1910     static __GlobalVal< type > var
1911 #define SVAL_IMPL(type, cls, var) \
1912     __GlobalVal< type > cls::var(&g_dacGlobals.cls##__##var)
1913 #define SVAL_IMPL_INIT(type, cls, var, init) \
1914     __GlobalVal< type > cls::var(&g_dacGlobals.cls##__##var)
1915 #define SVAL_IMPL_NS(type, ns, cls, var) \
1916     __GlobalVal< type > cls::var(&g_dacGlobals.ns##__##cls##__##var)
1917 #define SVAL_IMPL_NS_INIT(type, ns, cls, var, init) \
1918     __GlobalVal< type > cls::var(&g_dacGlobals.ns##__##cls##__##var)
1919
1920 #define GVAL_DECL(type, var) \
1921     extern __GlobalVal< type > var
1922 #define GVAL_IMPL(type, var) \
1923     __GlobalVal< type > var(&g_dacGlobals.dac__##var)
1924 #define GVAL_IMPL_INIT(type, var, init) \
1925     __GlobalVal< type > var(&g_dacGlobals.dac__##var)
1926
1927 #define GARY_DECL(type, var, size) \
1928     extern __GlobalArray< type, size > var
1929 #define GARY_IMPL(type, var, size) \
1930     __GlobalArray< type, size > var(&g_dacGlobals.dac__##var)
1931
1932 // Translation from a host pointer back to the target address
1933 // that was used to retrieve the data for the host pointer.
1934 #define PTR_HOST_TO_TADDR(host) DacGetTargetAddrForHostAddr(host, true)
1935 // Translation from a host interior pointer back to the corresponding
1936 // target address. The host address must reside within a previously
1937 // retrieved instance.
1938 #define PTR_HOST_INT_TO_TADDR(host) DacGetTargetAddrForHostInteriorAddr(host, true)
1939 // Translation from a host vtable pointer to a target vtable pointer.
1940 #define VPTR_HOST_VTABLE_TO_TADDR(host) DacGetTargetVtForHostVt(host, true)
1941
1942 // Construct a pointer to a member of the given type.
1943 #define PTR_HOST_MEMBER_TADDR(type, host, memb) \
1944     (PTR_HOST_TO_TADDR(host) + (TADDR)offsetof(type, memb))
1945
1946 // Construct a pointer to a member of the given type given an interior
1947 // host address.
1948 #define PTR_HOST_INT_MEMBER_TADDR(type, host, memb) \
1949     (PTR_HOST_INT_TO_TADDR(host) + (TADDR)offsetof(type, memb))
1950
1951 #define PTR_TO_MEMBER_TADDR(type, ptr, memb) \
1952     (PTR_TO_TADDR(ptr) + (TADDR)offsetof(type, memb))
1953
1954 // Constructs an arbitrary data instance for a piece of
1955 // memory in the target.
1956 #define PTR_READ(addr, size) \
1957     DacInstantiateTypeByAddress(addr, size, true)
1958
1959 // This value is used to intiailize target pointers to NULL.  We want this to be TADDR type
1960 // (as opposed to, say, __TPtrBase) so that it can be used in the non-explicit ctor overloads,
1961 // eg. as an argument default value.  
1962 // We can't always just use NULL because that's 0 which (in C++) can be any integer or pointer 
1963 // type (causing an ambiguous overload compiler error when used in explicit ctor forms).
1964 #define PTR_NULL ((TADDR)0)
1965
1966 // Provides an empty method implementation when compiled
1967 // for DACCESS_COMPILE.  For example, use to stub out methods needed
1968 // for vtable entries but otherwise unused.
1969 // Note that these functions are explicitly NOT marked SUPPORTS_DAC so that we'll get a 
1970 // DacCop warning if any calls to them are detected.
1971 // @dbgtodo : It's probably almost always wrong to call any such function, so
1972 // we should probably throw a better error (DacNotImpl), and ideally mark the function
1973 // DECLSPEC_NORETURN so we don't have to deal with fabricating return values and we can
1974 // get compiler warnings (unreachable code) anytime functions marked this way are called.
1975 #define DAC_EMPTY() { LIMITED_METHOD_CONTRACT; }
1976 #define DAC_EMPTY_ERR() { LIMITED_METHOD_CONTRACT; DacError(E_UNEXPECTED); }
1977 #define DAC_EMPTY_RET(retVal) { LIMITED_METHOD_CONTRACT; DacError(E_UNEXPECTED); return retVal; }
1978 #define DAC_UNEXPECTED() { LIMITED_METHOD_CONTRACT; DacError_NoRet(E_UNEXPECTED); }
1979
1980 #endif // #ifdef __cplusplus
1981
1982 // Implementation details for dac_cast, should never be accessed directly.
1983 // See code:dac_cast for details and discussion.
1984 namespace dac_imp
1985 {
1986     // Helper functions to get the target address of specific types
1987     inline TADDR getTaddr(TADDR addr) { return addr; }
1988     inline TADDR getTaddr(__TPtrBase const &tptr) { return PTR_TO_TADDR(tptr); }
1989     inline TADDR getTaddr(void const * host) { return PTR_HOST_TO_TADDR((void *)host); }
1990     template<typename acc_type, typename store_type>
1991     inline TADDR getTaddr(__GlobalPtr<acc_type, store_type> const &gptr) { return PTR_TO_TADDR(gptr); }
1992
1993     // It is an error to try dac_cast on a __GlobalVal or a __GlobalArray. Declare
1994     // but do not define the methods so that a compile-time error results.
1995     template<typename type>
1996     TADDR getTaddr(__GlobalVal<type> const &gval);
1997     template<typename type, size_t size>
1998     TADDR getTaddr(__GlobalArray<type, size> const &garr);
1999
2000     // Helper class to instantiate DAC instances from a TADDR
2001     // The default implementation assumes we want to create an instance of a PTR type
2002     template<typename T> struct makeDacInst
2003     {
2004         static inline T fromTaddr(TADDR addr)
2005         {
2006             static_assert((std::is_base_of<__TPtrBase, T>::value), "is_base_of constraint violation");
2007             return T(addr);
2008         }
2009     };
2010
2011     // Partial specialization for creating TADDRs
2012     // This is the only other way to create a DAC type instance other than PTR types (above)
2013     template<> struct makeDacInst<TADDR>
2014     {
2015         static inline TADDR fromTaddr(TADDR addr) { return addr; }
2016     };
2017 } // namespace dac_imp
2018
2019
2020 // DacCop in-line exclusion mechanism
2021
2022 // Warnings - official home is DacCop\Shared\Warnings.cs, but we want a way for users to indicate
2023 // warning codes in a way that is descriptive to readers (not just code numbers).  The names here
2024 // don't matter - DacCop just looks at the value
2025 enum DacCopWarningCode
2026 {
2027     // General Rules
2028     FieldAccess = 1,
2029     PointerArith = 2,
2030     PointerComparison = 3,
2031     InconsistentMarshalling = 4,
2032     CastBetweenAddressSpaces = 5,
2033     CastOfMarshalledType = 6,
2034     VirtualCallToNonVPtr = 7,
2035     UndacizedGlobalVariable = 8,
2036
2037     // Function graph related
2038     CallUnknown = 701,
2039     CallNonDac = 702,
2040     CallVirtualUnknown = 704,
2041     CallVirtualNonDac = 705,
2042 };
2043
2044 // DACCOP_IGNORE is a mechanism to suppress DacCop violations from within the source-code.
2045 // See the DacCop wiki for guidance on how best to use this: http://mswikis/clr/dev/Pages/DacCop.aspx
2046 //
2047 // DACCOP_IGNORE will suppress a DacCop violation for the following (non-compound) statement.
2048 // For example:
2049 //      // The "dual-mode DAC problem" occurs in a few places where a class is used both
2050 //      // in the host, and marshalled from the target ... <further details>
2051 //      DACCOP_IGNORE(CastBetweenAddressSpaces,"SBuffer has the dual-mode DAC problem");
2052 //      TADDR bufAddr = (TADDR)m_buffer;
2053 //
2054 // A call to DACCOP_IGNORE must occur as it's own statement, and can apply only to following
2055 // single-statements (not to compound statement blocks).  Occasionally it is necessary to hoist
2056 // violation-inducing code out to its own statement (e.g., if it occurs in the conditional of an
2057 // if).
2058 //
2059 // Arguments:
2060 //   code: a literal value from DacCopWarningCode indicating which violation should be suppressed.  
2061 //   szReasonString: a short description of why this exclusion is necessary.  This is intended just
2062 //        to help readers of the code understand the source of the problem, and what would be required
2063 //        to fix it.  More details can be provided in comments if desired.
2064 //
2065 inline void DACCOP_IGNORE(DacCopWarningCode code, const char * szReasonString)
2066 {
2067     // DacCop detects calls to this function.  No implementation is necessary.
2068 }
2069
2070 #else // #ifdef DACCESS_COMPILE
2071
2072 //
2073 // This version of the macros turns into normal pointers
2074 // for unmodified in-proc compilation.
2075
2076 // *******************************************************
2077 // !!!!!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!
2078 // 
2079 // Please search this file for the type name to find the 
2080 // DAC versions of these definitions
2081 // 
2082 // !!!!!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!
2083 // *******************************************************
2084
2085
2086 // Declare TADDR as a non-pointer type so that arithmetic
2087 // can be done on it directly, as with the DACCESS_COMPILE definition.
2088 // This also helps expose pointer usage that may need to be changed.
2089 typedef ULONG_PTR TADDR;
2090     
2091 typedef void* PTR_VOID;
2092 typedef LPVOID* PTR_PTR_VOID;
2093 typedef const void* PTR_CVOID;
2094
2095 #define DPTR(type) type*
2096 #define ArrayDPTR(type) type*
2097 #define SPTR(type) type*
2098 #define VPTR(type) type*
2099 #define S8PTR(type) type*
2100 #define S8PTRMAX(type, maxChars) type*
2101 #define S16PTR(type) type*
2102 #define S16PTRMAX(type, maxChars) type*
2103
2104 #if defined(FEATURE_PAL)
2105
2106 #define VPTR_VTABLE_CLASS(name, base) \
2107         friend struct _DacGlobals; \
2108 public: name(int dummy) : base(dummy) {}
2109
2110 #define VPTR_VTABLE_CLASS_AND_CTOR(name, base) \
2111         VPTR_VTABLE_CLASS(name, base) \
2112         name() : base() {}
2113
2114 #define VPTR_MULTI_VTABLE_CLASS(name, base) \
2115         friend struct _DacGlobals; \
2116 public: name(int dummy) : base(dummy) {}
2117
2118 #define VPTR_BASE_CONCRETE_VTABLE_CLASS(name) \
2119         friend struct _DacGlobals; \
2120 public: name(int dummy) {}
2121
2122 #define VPTR_BASE_VTABLE_CLASS(name) \
2123         friend struct _DacGlobals; \
2124 public: name(int dummy) {}
2125
2126 #define VPTR_BASE_VTABLE_CLASS_AND_CTOR(name) \
2127         VPTR_BASE_VTABLE_CLASS(name) \
2128         name() {}
2129
2130 #define VPTR_ABSTRACT_VTABLE_CLASS(name, base) \
2131         friend struct _DacGlobals; \
2132 public: name(int dummy) : base(dummy) {}
2133
2134 #else // FEATURE_PAL
2135
2136 #define VPTR_VTABLE_CLASS(name, base)
2137 #define VPTR_VTABLE_CLASS_AND_CTOR(name, base)
2138 #define VPTR_MULTI_VTABLE_CLASS(name, base)
2139 #define VPTR_BASE_CONCRETE_VTABLE_CLASS(name)
2140 #define VPTR_BASE_VTABLE_CLASS(name)
2141 #define VPTR_BASE_VTABLE_CLASS_AND_CTOR(name)
2142 #define VPTR_ABSTRACT_VTABLE_CLASS(name, base)
2143
2144 #endif // FEATURE_PAL
2145
2146 // helper macro to make the vtables unique for DAC
2147 #define VPTR_UNIQUE(unique) virtual int MakeVTableUniqueForDAC() {    STATIC_CONTRACT_SO_TOLERANT; return unique; }
2148 #define VPTR_UNIQUE_BaseDomain                          (100000)
2149 #define VPTR_UNIQUE_SystemDomain                        (VPTR_UNIQUE_BaseDomain + 1)
2150 #define VPTR_UNIQUE_ComMethodFrame                      (VPTR_UNIQUE_SystemDomain + 1)
2151 #define VPTR_UNIQUE_StubHelperFrame                     (VPTR_UNIQUE_ComMethodFrame + 1)
2152 #define VPTR_UNIQUE_RedirectedThreadFrame               (VPTR_UNIQUE_StubHelperFrame + 1)
2153 #define VPTR_UNIQUE_HijackFrame                         (VPTR_UNIQUE_RedirectedThreadFrame + 1)
2154
2155 #define PTR_TO_TADDR(ptr) ((TADDR)(ptr))
2156 #define GFN_TADDR(name) ((TADDR)(name))
2157
2158 #define GVAL_ADDR(g) (&(g))
2159 #define _SPTR_DECL(acc_type, store_type, var) \
2160     static store_type var
2161 #define _SPTR_IMPL(acc_type, store_type, cls, var) \
2162     store_type cls::var
2163 #define _SPTR_IMPL_INIT(acc_type, store_type, cls, var, init) \
2164     store_type cls::var = init
2165 #define _SPTR_IMPL_NS(acc_type, store_type, ns, cls, var) \
2166     store_type cls::var
2167 #define _SPTR_IMPL_NS_INIT(acc_type, store_type, ns, cls, var, init) \
2168     store_type cls::var = init
2169 #define _GPTR_DECL(acc_type, store_type, var) \
2170     extern store_type var
2171 #define _GPTR_IMPL(acc_type, store_type, var) \
2172     store_type var
2173 #define _GPTR_IMPL_INIT(acc_type, store_type, var, init) \
2174     store_type var = init
2175 #define SVAL_DECL(type, var) \
2176     static type var
2177 #define SVAL_IMPL(type, cls, var) \
2178     type cls::var
2179 #define SVAL_IMPL_INIT(type, cls, var, init) \
2180     type cls::var = init
2181 #define SVAL_IMPL_NS(type, ns, cls, var) \
2182     type cls::var
2183 #define SVAL_IMPL_NS_INIT(type, ns, cls, var, init) \
2184     type cls::var = init
2185 #define GVAL_DECL(type, var) \
2186     extern type var
2187 #define GVAL_IMPL(type, var) \
2188     type var
2189 #define GVAL_IMPL_INIT(type, var, init) \
2190     type var = init
2191 #define GARY_DECL(type, var, size) \
2192     extern type var[size]
2193 #define GARY_IMPL(type, var, size) \
2194     type var[size]
2195 #define PTR_HOST_TO_TADDR(host) ((TADDR)(host))
2196 #define PTR_HOST_INT_TO_TADDR(host) ((TADDR)(host))
2197 #define VPTR_HOST_VTABLE_TO_TADDR(host) ((TADDR)(host))
2198 #define PTR_HOST_MEMBER_TADDR(type, host, memb) ((TADDR)&(host)->memb)
2199 #define PTR_HOST_INT_MEMBER_TADDR(type, host, memb) ((TADDR)&(host)->memb)
2200 #define PTR_TO_MEMBER_TADDR(type, ptr, memb) ((TADDR)&((ptr)->memb))
2201 #define PTR_READ(addr, size) ((PVOID)(addr))
2202
2203 #define PTR_NULL NULL
2204
2205 #define DAC_EMPTY()
2206 #define DAC_EMPTY_ERR()
2207 #define DAC_EMPTY_RET(retVal)
2208 #define DAC_UNEXPECTED() 
2209
2210 #define DACCOP_IGNORE(warningCode, reasonString)
2211
2212 #endif // #ifdef DACCESS_COMPILE
2213
2214 //----------------------------------------------------------------------------
2215 // dac_cast
2216 // Casting utility, to be used for casting one class pointer type to another.
2217 // Use as you would use static_cast
2218 //
2219 // dac_cast is designed to act just as static_cast does when
2220 // dealing with pointers and their DAC abstractions. Specifically,
2221 // it handles these coversions:
2222 //
2223 //      dac_cast<TargetType>(SourceTypeVal)
2224 //
2225 // where TargetType <- SourceTypeVal are
2226 //
2227 //      ?PTR(Tgt) <- TADDR     - Create PTR type (DPtr etc.) from TADDR
2228 //      ?PTR(Tgt) <- ?PTR(Src) - Convert one PTR type to another
2229 //      ?PTR(Tgt) <- Src *     - Create PTR type from dac host object instance
2230 //      TADDR <- ?PTR(Src)     - Get TADDR of PTR object (DPtr etc.) 
2231 //      TADDR <- Src *         - Get TADDR of dac host object instance 
2232 //
2233 // Note that there is no direct convertion to other host-pointer types (because we don't
2234 // know if you want a DPTR or VPTR etc.).  However, due to the implicit DAC conversions,
2235 // you can just use dac_cast<PTR_Foo> and assign that to a Foo*.
2236 // 
2237 // The beauty of this syntax is that it is consistent regardless
2238 // of source and target casting types. You just use dac_cast
2239 // and the partial template specialization will do the right thing.
2240 //
2241 // One important thing to realise is that all "Foo *" types are
2242 // assumed to be pointers to host instances that were marshalled by DAC.  This should
2243 // fail at runtime if it's not the case.
2244 //
2245 // Some examples would be:
2246 //
2247 //   - Host pointer of one type to a related host pointer of another
2248 //     type, i.e., MethodDesc * <-> InstantiatedMethodDesc *
2249 //     Syntax: with MethodDesc *pMD, InstantiatedMethodDesc *pInstMD
2250 //             pInstMd = dac_cast<PTR_InstantiatedMethodDesc>(pMD)
2251 //             pMD = dac_cast<PTR_MethodDesc>(pInstMD)
2252 //
2253 //   - (D|V)PTR of one encapsulated pointer type to a (D|V)PTR of
2254 //     another type, i.e., PTR_AppDomain <-> PTR_BaseDomain
2255 //     Syntax: with PTR_AppDomain pAD, PTR_BaseDomain pBD
2256 //             dac_cast<PTR_AppDomain>(pBD)
2257 //             dac_cast<PTR_BaseDomain>(pAD)
2258 //
2259 // Example comparsions of some old and new syntax, where
2260 //    h is a host pointer, such as "Foo *h;"
2261 //    p is a DPTR, such as "PTR_Foo p;"
2262 // 
2263 //      PTR_HOST_TO_TADDR(h)           ==> dac_cast<TADDR>(h)
2264 //      PTR_TO_TADDR(p)                ==> dac_cast<TADDR>(p)
2265 //      PTR_Foo(PTR_HOST_TO_TADDR(h))  ==> dac_cast<PTR_Foo>(h)
2266 //
2267 //----------------------------------------------------------------------------
2268 template <typename Tgt, typename Src>
2269 inline Tgt dac_cast(Src src)
2270 {
2271 #ifdef DACCESS_COMPILE
2272     // In DAC builds, first get a TADDR for the source, then create the
2273     // appropriate destination instance.
2274     TADDR addr = dac_imp::getTaddr(src);
2275     return dac_imp::makeDacInst<Tgt>::fromTaddr(addr);
2276 #else
2277     // In non-DAC builds, dac_cast is the same as a C-style cast because we need to support:
2278     //  - casting away const
2279     //  - conversions between pointers and TADDR
2280     // Perhaps we should more precisely restrict it's usage, but we get the precise 
2281     // restrictions in DAC builds, so it wouldn't buy us much.
2282     return (Tgt)(src);
2283 #endif
2284 }
2285
2286 //----------------------------------------------------------------------------
2287 //
2288 // Convenience macros which work for either mode.
2289 //
2290 //----------------------------------------------------------------------------
2291
2292 #define SPTR_DECL(type, var) _SPTR_DECL(type*, PTR_##type, var)
2293 #define SPTR_IMPL(type, cls, var) _SPTR_IMPL(type*, PTR_##type, cls, var)
2294 #define SPTR_IMPL_INIT(type, cls, var, init) _SPTR_IMPL_INIT(type*, PTR_##type, cls, var, init)
2295 #define SPTR_IMPL_NS(type, ns, cls, var) _SPTR_IMPL_NS(type*, PTR_##type, ns, cls, var)
2296 #define SPTR_IMPL_NS_INIT(type, ns, cls, var, init) _SPTR_IMPL_NS_INIT(type*, PTR_##type, ns, cls, var, init)
2297 #define GPTR_DECL(type, var) _GPTR_DECL(type*, PTR_##type, var)
2298 #define GPTR_IMPL(type, var) _GPTR_IMPL(type*, PTR_##type, var)
2299 #define GPTR_IMPL_INIT(type, var, init) _GPTR_IMPL_INIT(type*, PTR_##type, var, init)
2300
2301
2302 // If you want to marshal a single instance of an ArrayDPtr over to the host and
2303 // return a pointer to it, you can use this function.  However, this is unsafe because
2304 // users of value may assume they can do pointer arithmetic on it.  This is exactly
2305 // the bugs ArrayDPtr is designed to prevent.  See code:__ArrayDPtr for details.
2306 template<typename type>
2307 inline type* DacUnsafeMarshalSingleElement( ArrayDPTR(type) arrayPtr )
2308 {
2309     return (DPTR(type))(arrayPtr);
2310 }
2311
2312 //----------------------------------------------------------------------------
2313 //
2314 // Forward typedefs for system types.  This is a convenient place
2315 // to declare things for system types, plus it gives us a central
2316 // place to look at when deciding what types may cause issues for
2317 // cross-platform compilation.
2318 //
2319 //----------------------------------------------------------------------------
2320
2321 typedef ArrayDPTR(BYTE)    PTR_BYTE;
2322 typedef DPTR(PTR_BYTE) PTR_PTR_BYTE;
2323 typedef DPTR(PTR_PTR_BYTE) PTR_PTR_PTR_BYTE;
2324 typedef ArrayDPTR(signed char) PTR_SBYTE;
2325 typedef ArrayDPTR(const BYTE) PTR_CBYTE;
2326 typedef DPTR(INT8)    PTR_INT8;
2327 typedef DPTR(INT16)   PTR_INT16;
2328 typedef DPTR(WORD)    PTR_WORD;
2329 typedef DPTR(USHORT)  PTR_USHORT;
2330 typedef DPTR(DWORD)   PTR_DWORD;
2331 typedef DPTR(LONG)    PTR_LONG;
2332 typedef DPTR(ULONG)   PTR_ULONG;
2333 typedef DPTR(INT32)   PTR_INT32;
2334 typedef DPTR(UINT32)  PTR_UINT32;
2335 typedef DPTR(ULONG64) PTR_ULONG64;
2336 typedef DPTR(INT64)   PTR_INT64;
2337 typedef DPTR(UINT64)  PTR_UINT64;
2338 typedef DPTR(SIZE_T)  PTR_SIZE_T;
2339 typedef DPTR(size_t)  PTR_size_t;
2340 typedef DPTR(TADDR)   PTR_TADDR;
2341 typedef DPTR(int)     PTR_int;
2342 typedef DPTR(BOOL)    PTR_BOOL;
2343 typedef DPTR(unsigned) PTR_unsigned;
2344
2345 typedef S8PTR(char)           PTR_STR;
2346 typedef S8PTR(const char)     PTR_CSTR;
2347 typedef S8PTR(char)           PTR_UTF8;
2348 typedef S8PTR(const char)     PTR_CUTF8;
2349 typedef S16PTR(wchar_t)       PTR_WSTR;
2350 typedef S16PTR(const wchar_t) PTR_CWSTR;
2351
2352 typedef DPTR(T_CONTEXT)                  PTR_CONTEXT;
2353 typedef DPTR(PTR_CONTEXT)                PTR_PTR_CONTEXT;
2354 typedef DPTR(struct _EXCEPTION_POINTERS) PTR_EXCEPTION_POINTERS;
2355 typedef DPTR(struct _EXCEPTION_RECORD)   PTR_EXCEPTION_RECORD;
2356
2357 typedef DPTR(struct _EXCEPTION_REGISTRATION_RECORD) PTR_EXCEPTION_REGISTRATION_RECORD;
2358
2359 typedef DPTR(struct IMAGE_COR_VTABLEFIXUP) PTR_IMAGE_COR_VTABLEFIXUP;
2360 typedef DPTR(IMAGE_DATA_DIRECTORY)  PTR_IMAGE_DATA_DIRECTORY;
2361 typedef DPTR(IMAGE_DEBUG_DIRECTORY)  PTR_IMAGE_DEBUG_DIRECTORY;
2362 typedef DPTR(IMAGE_DOS_HEADER)      PTR_IMAGE_DOS_HEADER;
2363 typedef DPTR(IMAGE_NT_HEADERS)      PTR_IMAGE_NT_HEADERS;
2364 typedef DPTR(IMAGE_NT_HEADERS32)    PTR_IMAGE_NT_HEADERS32;
2365 typedef DPTR(IMAGE_NT_HEADERS64)    PTR_IMAGE_NT_HEADERS64;
2366 typedef DPTR(IMAGE_SECTION_HEADER)  PTR_IMAGE_SECTION_HEADER;
2367 typedef DPTR(IMAGE_TLS_DIRECTORY)   PTR_IMAGE_TLS_DIRECTORY;
2368
2369 #if defined(DACCESS_COMPILE)
2370 #include <corhdr.h>
2371 #include <clrdata.h>
2372 #include <xclrdata.h>
2373 #endif
2374
2375 #ifdef _WIN64
2376 typedef DPTR(T_RUNTIME_FUNCTION) PTR_RUNTIME_FUNCTION;
2377 typedef DPTR(struct _UNWIND_INFO)      PTR_UNWIND_INFO;
2378 #if defined(_TARGET_AMD64_)
2379 typedef DPTR(union _UNWIND_CODE)       PTR_UNWIND_CODE;
2380 #endif // _TARGET_AMD64_
2381 #endif // _WIN64
2382
2383 #ifdef _TARGET_ARM_
2384 typedef DPTR(RUNTIME_FUNCTION) PTR_RUNTIME_FUNCTION;
2385 #endif
2386
2387 //----------------------------------------------------------------------------
2388 //
2389 // A PCODE is a valid PC/IP value -- a pointer to an instruction, possibly including some processor mode bits.
2390 // (On ARM, for example, a PCODE value should should have the low-order THUMB_CODE bit set if the code should
2391 // be executed in that mode.)
2392 //
2393 typedef TADDR PCODE;
2394 typedef DPTR(PCODE) PTR_PCODE;
2395 typedef DPTR(PTR_PCODE) PTR_PTR_PCODE;
2396
2397 // There is another concept we should have, "pointer to the start of an instruction" -- a PCODE with any mode bits masked off.  
2398 // Attempts to introduce this concept, and classify uses of PCODE as one or the other,
2399 // turned out to be too hard: either name choice required *many* code changes, and decisions in unfamiliar code.  So despite the
2400 // the comment above, the PCODE is currently sometimes used for the PINSTR concept.
2401
2402 // See PCODEToPINSTR in utilcode.h for conversion from PCODE to PINSTR.
2403
2404 //----------------------------------------------------------------------------
2405 //
2406 // The access code compile must compile data structures that exactly
2407 // match the real structures for access to work.  The access code
2408 // doesn't want all of the debugging validation code, though, so
2409 // distinguish between _DEBUG, for declaring general debugging data
2410 // and always-on debug code, and _DEBUG_IMPL, for debugging code
2411 // which will be disabled when compiling for external access.
2412 //
2413 //----------------------------------------------------------------------------
2414
2415 #if !defined(_DEBUG_IMPL) && defined(_DEBUG) && !defined(DACCESS_COMPILE)
2416 #define _DEBUG_IMPL 1
2417 #endif
2418
2419 // Helper macro for tracking EnumMemoryRegions progress.
2420 #if 0
2421 #define EMEM_OUT(args) DacWarning args
2422 #else
2423 #define EMEM_OUT(args)
2424 #endif
2425
2426 // Macros like MAIN_CLR_MODULE_NAME* for the DAC module
2427 #ifdef FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME
2428 #define MAIN_DAC_MODULE_NAME_W  W("mscordaccore")
2429 #define MAIN_DAC_MODULE_DLL_NAME_W  W("mscordaccore.dll")
2430 #else
2431 #define MAIN_DAC_MODULE_NAME_W  W("mscordacwks")
2432 #define MAIN_DAC_MODULE_DLL_NAME_W  W("mscordacwks.dll")
2433 #endif
2434
2435 // TARGET_CONSISTENCY_CHECK represents a condition that should not fail unless the DAC target is corrupt. 
2436 // This is in contrast to ASSERTs in DAC infrastructure code which shouldn't fail regardless of the memory
2437 // read from the target.  At the moment we treat these the same, but in the future we will want a mechanism
2438 // for disabling just the target consistency checks (eg. for tests that intentionally use corrupted targets).
2439 // @dbgtodo : Separating asserts and target consistency checks is tracked by DevDiv Bugs 31674
2440 #define TARGET_CONSISTENCY_CHECK(expr,msg) _ASSERTE_MSG(expr,msg)
2441
2442 #endif // #ifndef __daccess_h__